package log import ( "errors" "log/slog" ) import "github.com/rs/zerolog/log" var AuditLogger = NewSlogAuditLogger(slog.Default()) func NewSlogAuditLogger(logger *slog.Logger) Logger { return SlogLogger{logger: logger} } func NewZerologAuditLogger() Logger { return ZeroLogLogger{} } type Logger interface { Debug(msg string, err ...error) Info(msg string, err ...error) Warn(msg string, err ...error) Error(msg string, err ...error) } type SlogLogger struct { logger *slog.Logger } func (s SlogLogger) Debug(msg string, err ...error) { s.logger.Debug(msg, s.getWrappedError(err)) } func (s SlogLogger) Info(msg string, err ...error) { s.logger.Info(msg, s.getWrappedError(err)) } func (s SlogLogger) Warn(msg string, err ...error) { s.logger.Warn(msg, s.getWrappedError(err)) } func (s SlogLogger) Error(msg string, err ...error) { s.logger.Error(msg, s.getWrappedError(err)) } func (s SlogLogger) getWrappedError(err []error) slog.Attr { var wrappedErr slog.Attr if err != nil { wrappedErr = slog.Any("error", wrapErr(err)) } return wrappedErr } type ZeroLogLogger struct{} func (l ZeroLogLogger) Debug(msg string, err ...error) { log.Debug().Err(wrapErr(err)).Msg(msg) } func (l ZeroLogLogger) Info(msg string, err ...error) { log.Info().Err(wrapErr(err)).Msg(msg) } func (l ZeroLogLogger) Warn(msg string, err ...error) { log.Warn().Err(wrapErr(err)).Msg(msg) } func (l ZeroLogLogger) Error(msg string, err ...error) { log.Error().Err(wrapErr(err)).Msg(msg) } func wrapErr(err []error) error { var e error if len(err) == 0 { e = nil } else if len(err) == 1 { e = err[0] } else { e = errors.Join(err...) } return e }