package logger import ( "context" "log/slog" "os" "strings" "time" "github.com/go-logr/logr" "edge-infra.dev/pkg/lib/fog" ) type opts struct { logLvl slog.Level } type Option func(*opts) const LevelTrace = slog.Level(-8) // align with edges log levels and slog log levels var levels = map[slog.Level]int{ LevelTrace: -2, slog.LevelDebug: fog.DEBUG, slog.LevelInfo: fog.INFO, slog.LevelWarn: fog.WARN, slog.LevelError: fog.ERROR, } // Sets linkerd control plane priority class func WithLevel(lvl slog.Level) Option { return func(o *opts) { o.logLvl = lvl } } // New returns a new logger with slog func New(o ...Option) *slog.Logger { options := &opts{} for _, o := range o { o(options) } return slog.New(slog.NewJSONHandler(os.Stdout, &slog.HandlerOptions{Level: options.logLvl, ReplaceAttr: replaceAttrs()})).With("severity", options.logLvl.String()) } // IntoContext will pass the slog into the current context func IntoContext(ctx context.Context, log *slog.Logger) context.Context { return logr.NewContextWithSlogLogger(ctx, log) } // FromContext will return the slog from context. If one does not exist, it will return a new instance. func FromContext(ctx context.Context) *slog.Logger { newLog := logr.FromContextAsSlogLogger(ctx) if newLog == nil { return New() } return newLog } // ToLevel converts the log level from string to slog.Level func ToLevel(logLevel string) slog.Level { switch strings.ToLower(logLevel) { case "trace": return LevelTrace case "debug": return slog.LevelDebug case "error": return slog.LevelError case "info": return slog.LevelInfo case "warn": return slog.LevelWarn default: return slog.LevelInfo } } // replaceAttrs will replace attributes in the logger func replaceAttrs() func(groups []string, a slog.Attr) slog.Attr { return func(_ []string, attr slog.Attr) slog.Attr { if attr.Key == slog.LevelKey { level := attr.Value.Any().(slog.Level) attr.Value = slog.IntValue(levels[level]) } value := attr.Value if value.Kind() != slog.KindTime { return attr } attr.Value = slog.StringValue(value.Time().Format(time.RFC3339)) return attr } }