package slogging import ( "fmt" "os" "golang.org/x/exp/slog" ) type Logger struct { *slog.Logger } const ( LevelInfo int = iota LevelDebug LevelWarn LevelError ) var logger *Logger var opts slog.HandlerOptions func GetLogger() *Logger { return logger } func Init(jsonHandler bool) *Logger { opts = slog.HandlerOptions{ Level: slog.LevelInfo, } if jsonHandler { logger = &Logger{slog.New(opts.NewJSONHandler(os.Stderr))} } else { logger = &Logger{slog.New(opts.NewTextHandler(os.Stderr))} } slog.SetDefault(logger.Logger) logger.Info("slog logger initialised") return logger } // SetLevel allows setting log level and returns the pointer to the re-created // logger. func SetLevel(level int) *Logger { switch level { case LevelInfo: opts.Level = slog.LevelInfo case LevelDebug: opts.Level = slog.LevelDebug case LevelWarn: opts.Level = slog.LevelWarn case LevelError: opts.Level = slog.LevelError default: logger.Infof("unknown level '%d', resetting to level INFO", level) opts.Level = slog.LevelInfo } if _, ok := logger.Handler().(*slog.JSONHandler); ok { logger = &Logger{slog.New(opts.NewJSONHandler(os.Stderr))} } else { logger = &Logger{slog.New(opts.NewTextHandler(os.Stderr))} } slog.SetDefault(logger.Logger) return logger } func (l *Logger) Debugf(msg string, args ...any) { l.Debug(fmt.Sprintf(msg, args...)) } func (l *Logger) Infof(msg string, args ...any) { l.Info(fmt.Sprintf(msg, args...)) } func (l *Logger) Warnf(msg string, args ...any) { l.Warn(fmt.Sprintf(msg, args...)) } func (l *Logger) Errorf(msg string, args ...any) { l.Error(fmt.Sprintf(msg, args...)) }