From 5389e1a5d26fdbf2441fa5a1e101999e8449b9d1 Mon Sep 17 00:00:00 2001 From: Benjamin Chausse Date: Mon, 3 Feb 2025 01:12:45 -0500 Subject: Batman --- internal/logging/logging.go | 92 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 92 insertions(+) create mode 100644 internal/logging/logging.go (limited to 'internal/logging/logging.go') diff --git a/internal/logging/logging.go b/internal/logging/logging.go new file mode 100644 index 0000000..91a9734 --- /dev/null +++ b/internal/logging/logging.go @@ -0,0 +1,92 @@ +package logging + +import ( + "errors" + "io" + "log/slog" + "os" + "strings" + "time" + + "github.com/ChausseBenjamin/rafta/internal/util" + "github.com/charmbracelet/log" +) + +const ( + ErrKey = "error_message" +) + +var ( + ErrInvalidLevel = errors.New("invalid log level") + ErrInvalidFormat = errors.New("invalid log format") +) + +func Setup(lvlStr, fmtStr, outStr string) error { + output, outputErr := setOutput(outStr) + format, formatErr := setFormat(fmtStr) + level, levelErr := setLevel(lvlStr) + + prefixStr := "" + if format != log.JSONFormatter { + prefixStr = "Rafta 🚢" + } + + var h slog.Handler = log.NewWithOptions( + output, + log.Options{ + TimeFormat: time.DateTime, + Prefix: prefixStr, + Level: level, + ReportCaller: true, + Formatter: format, + }, + ) + + h = withTrackedContext(h, util.ReqIDKey, "request_id") + h = withStackTrace(h) + slog.SetDefault(slog.New(h)) + return errors.Join(outputErr, formatErr, levelErr) +} + +func setLevel(target string) (log.Level, error) { + for _, l := range []struct { + prefix string + level log.Level + }{ + {"deb", log.DebugLevel}, + {"inf", log.InfoLevel}, + {"warn", log.WarnLevel}, + {"err", log.ErrorLevel}, + } { + if strings.HasPrefix(strings.ToLower(target), l.prefix) { + return l.level, nil + } + } + return log.InfoLevel, ErrInvalidLevel +} + +func setFormat(f string) (log.Formatter, error) { + switch f { + case "plain", "text": + return log.TextFormatter, nil + case "json", "structured": + return log.JSONFormatter, nil + } + return log.TextFormatter, ErrInvalidFormat +} + +func setOutput(path string) (io.Writer, error) { + switch path { + case "stdout": + return os.Stdout, nil + case "stderr": + return os.Stderr, nil + default: + f, err := os.OpenFile(path, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0644) + if err != nil { + return os.Stdout, err + } else { + return f, nil + } + } +} -- cgit v1.2.3