package main import ( "log/slog" "os" "strings" ) // newLogger builds the process logger from the environment: LOG_LEVEL // (debug|info|warn|error, default info) and LOG_FORMAT (text|json, default // text). It writes to stderr with UTC timestamps (matching the previous // log.LUTC behaviour). Built from getenv directly — not Config — so it exists // before LoadConfig (the generate-registration path logs before config loads). func newLogger() *slog.Logger { opts := &slog.HandlerOptions{ Level: parseLogLevel(getenv("LOG_LEVEL", "info")), ReplaceAttr: func(_ []string, a slog.Attr) slog.Attr { if a.Key == slog.TimeKey && a.Value.Kind() == slog.KindTime { a.Value = slog.TimeValue(a.Value.Time().UTC()) } return a }, } var h slog.Handler if strings.EqualFold(strings.TrimSpace(getenv("LOG_FORMAT", "text")), "json") { h = slog.NewJSONHandler(os.Stderr, opts) } else { h = slog.NewTextHandler(os.Stderr, opts) } return slog.New(h) } func parseLogLevel(s string) slog.Level { switch strings.ToLower(strings.TrimSpace(s)) { case "debug": return slog.LevelDebug case "warn", "warning": return slog.LevelWarn case "error": return slog.LevelError default: return slog.LevelInfo } }