// Package observability provides logging and metrics infrastructure package observability import ( "context" "log/slog" "os" ) // Logger defines the logging interface type Logger interface { // Debug logs a debug message Debug(msg string, args ...any) // Info logs an info message Info(msg string, args ...any) // Warn logs a warning message Warn(msg string, args ...any) // Error logs an error message Error(msg string, args ...any) // With returns a logger with additional context fields With(args ...any) Logger // WithContext returns a logger with context WithContext(ctx context.Context) Logger } // slogLogger wraps slog.Logger to implement our Logger interface type slogLogger struct { logger *slog.Logger } // NewLogger creates a new structured logger func NewLogger(level slog.Level) Logger { opts := &slog.HandlerOptions{ Level: level, AddSource: true, } handler := slog.NewJSONHandler(os.Stdout, opts) logger := slog.New(handler) return &slogLogger{ logger: logger, } } func (l *slogLogger) Debug(msg string, args ...any) { l.logger.Debug(msg, args...) } func (l *slogLogger) Info(msg string, args ...any) { l.logger.Info(msg, args...) } func (l *slogLogger) Warn(msg string, args ...any) { l.logger.Warn(msg, args...) } func (l *slogLogger) Error(msg string, args ...any) { l.logger.Error(msg, args...) } func (l *slogLogger) With(args ...any) Logger { return &slogLogger{ logger: l.logger.With(args...), } } func (l *slogLogger) WithContext(ctx context.Context) Logger { // Could extract trace ID, request ID, etc. from context return l }