// Copyright 2023 wanderer // SPDX-License-Identifier: AGPL-3.0-only package slogging import ( "fmt" "os" "golang.org/x/exp/slog" ) type Slogger struct { *slog.Logger } const ( LevelInfo int = iota LevelDebug LevelWarn LevelError ) var logger *Slogger var opts slog.HandlerOptions func Logger() *Slogger { return logger } func Init(jsonHandler bool) *Slogger { opts = slog.HandlerOptions{ Level: slog.LevelInfo, } if jsonHandler { logger = &Slogger{slog.New(opts.NewJSONHandler(os.Stderr))} } else { logger = &Slogger{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) *Slogger { 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 = &Slogger{slog.New(opts.NewJSONHandler(os.Stderr))} } else { logger = &Slogger{slog.New(opts.NewTextHandler(os.Stderr))} } slog.SetDefault(logger.Logger) return logger } func (l *Slogger) Debugf(msg string, args ...any) { l.Debug(fmt.Sprintf(msg, args...)) } func (l *Slogger) Infof(msg string, args ...any) { l.Info(fmt.Sprintf(msg, args...)) } func (l *Slogger) Warnf(msg string, args ...any) { l.Warn(fmt.Sprintf(msg, args...)) } func (l *Slogger) Errorf(msg string, args ...any) { l.Error(fmt.Sprintf(msg, args...)) }