package adapter import ( "log/slog" "os" ) // SlogLogger implements Logger interface using slog type SlogLogger struct { logger *slog.Logger } // NewSlogLogger creates a new slog-based logger func NewSlogLogger(level slog.Level) *SlogLogger { opts := &slog.HandlerOptions{ Level: level, } handler := slog.NewJSONHandler(os.Stdout, opts) logger := slog.New(handler) return &SlogLogger{ logger: logger, } } // NewSlogLoggerWithHandler creates a new slog-based logger with a custom handler func NewSlogLoggerWithHandler(handler slog.Handler) *SlogLogger { return &SlogLogger{ logger: slog.New(handler), } } // Debug logs a debug message func (l *SlogLogger) Debug(msg string, args ...interface{}) { l.logger.Debug(msg, l.convertArgs(args)...) } // Info logs an info message func (l *SlogLogger) Info(msg string, args ...interface{}) { l.logger.Info(msg, l.convertArgs(args)...) } // Warn logs a warning message func (l *SlogLogger) Warn(msg string, args ...interface{}) { l.logger.Warn(msg, l.convertArgs(args)...) } // Error logs an error message func (l *SlogLogger) Error(msg string, args ...interface{}) { l.logger.Error(msg, l.convertArgs(args)...) } // Fatal logs a fatal message and exits func (l *SlogLogger) Fatal(msg string, args ...interface{}) { l.logger.Error(msg, l.convertArgs(args)...) os.Exit(1) } // With returns a new logger with additional context func (l *SlogLogger) With(key string, value interface{}) Logger { return &SlogLogger{ logger: l.logger.With(key, value), } } // convertArgs converts variadic args to slog.Attr pairs func (l *SlogLogger) convertArgs(args []interface{}) []any { if len(args) == 0 { return nil } // Convert pairs of key-value to slog format attrs := make([]any, 0, len(args)) for i := 0; i < len(args); i += 2 { if i+1 < len(args) { attrs = append(attrs, args[i], args[i+1]) } } return attrs }