Documentation
¶
Overview ¶
Package xlog provides a Go logging toolkit for context-aware structured logging.
It stores loggers in context, falls back to a global logger, supports zap and slog adapters, and includes OpenTelemetry tracing helpers.
Index ¶
- func AddSpanEvent(ctx context.Context, name string, options ...trace.EventOption)
- func ContextWithLogger(ctx context.Context, logger Logger) context.Context
- func ContextWithTracer(ctx context.Context, tracer trace.Tracer) context.Context
- func Debug(ctx context.Context, msg string, fields ...xfield.Field)
- func Debugf(ctx context.Context, template string, args ...any)
- func Error(ctx context.Context, msg string, fields ...xfield.Field)
- func Errorf(ctx context.Context, template string, args ...any)
- func Fatal(ctx context.Context, msg string, fields ...xfield.Field)
- func Fatalf(ctx context.Context, template string, args ...any)
- func Info(ctx context.Context, msg string, fields ...xfield.Field)
- func Infof(ctx context.Context, template string, args ...any)
- func Panic(ctx context.Context, msg string, fields ...xfield.Field)
- func Panicf(ctx context.Context, template string, args ...any)
- func RecordSpanError(ctx context.Context, err error, options ...trace.EventOption)
- func ReplaceGlobalLogger(logger Logger) func()
- func ReplaceTracerName(name string) func()
- func SetSpanAttributes(ctx context.Context, kv ...attribute.KeyValue)
- func SpanFromContext(ctx context.Context) trace.Span
- func TracerFromContext(ctx context.Context) trace.Tracer
- func Unwrap[T any](logger Logger) (T, bool)
- func Warn(ctx context.Context, msg string, fields ...xfield.Field)
- func Warnf(ctx context.Context, template string, args ...any)
- func WithFields(ctx context.Context, fields ...xfield.Field) context.Context
- func WithOperation(ctx context.Context, operation string, fields ...xfield.Field) context.Context
- func WithOperationSpan(ctx context.Context, operation string, fields ...xfield.Field) (context.Context, trace.Span)
- type Logger
- func GlobalLogger() Logger
- func L() Logger
- func LoggerFromContext(ctx context.Context) Logger
- func NewNoopLogger() Logger
- func NewSlogAdapter(logger *slog.Logger, options ...SlogOption) Logger
- func NewSlogAdapterWithContext(ctx context.Context, logger *slog.Logger, options ...SlogOption) Logger
- func NewZapAdapter(logger *zap.Logger) Logger
- type NoopLogger
- func (l *NoopLogger) Debug(_ string, _ ...xfield.Field)
- func (l *NoopLogger) Error(_ string, _ ...xfield.Field)
- func (l *NoopLogger) Fatal(_ string, _ ...xfield.Field)
- func (l *NoopLogger) Info(_ string, _ ...xfield.Field)
- func (l *NoopLogger) Named(_ string) Logger
- func (l *NoopLogger) Panic(msg string, _ ...xfield.Field)
- func (l *NoopLogger) Sync() error
- func (l *NoopLogger) Warn(_ string, _ ...xfield.Field)
- func (l *NoopLogger) With(_ ...xfield.Field) Logger
- type SlogAdapter
- func (s *SlogAdapter) Debug(msg string, fields ...xfield.Field)
- func (s *SlogAdapter) Error(msg string, fields ...xfield.Field)
- func (s *SlogAdapter) Fatal(msg string, fields ...xfield.Field)
- func (s *SlogAdapter) Info(msg string, fields ...xfield.Field)
- func (s *SlogAdapter) Named(name string) Logger
- func (s *SlogAdapter) Panic(msg string, fields ...xfield.Field)
- func (s *SlogAdapter) Sync() error
- func (s *SlogAdapter) Unwrap() *slog.Logger
- func (s *SlogAdapter) Warn(msg string, fields ...xfield.Field)
- func (s *SlogAdapter) With(fields ...xfield.Field) Logger
- func (s *SlogAdapter) WithContext(ctx context.Context, fields ...xfield.Field) Logger
- type SlogOption
- type Unwrapper
- type ZapAdapter
- func (z *ZapAdapter) Debug(msg string, fields ...xfield.Field)
- func (z *ZapAdapter) Error(msg string, fields ...xfield.Field)
- func (z *ZapAdapter) Fatal(msg string, fields ...xfield.Field)
- func (z *ZapAdapter) Info(msg string, fields ...xfield.Field)
- func (z *ZapAdapter) Named(name string) Logger
- func (z *ZapAdapter) Panic(msg string, fields ...xfield.Field)
- func (z *ZapAdapter) Sync() error
- func (z *ZapAdapter) Unwrap() *zap.Logger
- func (z *ZapAdapter) Warn(msg string, fields ...xfield.Field)
- func (z *ZapAdapter) With(fields ...xfield.Field) Logger
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func AddSpanEvent ¶
func AddSpanEvent(ctx context.Context, name string, options ...trace.EventOption)
AddSpanEvent adds an event to the span extracted from the context. Events are timestamped occurrences that can include additional attributes. If no span is found or if the span is not recording, this is a no-op.
Example:
xlog.AddSpanEvent(ctx, "cache-miss")
xlog.AddSpanEvent(ctx, "retry", trace.WithAttributes(
attribute.Int("attempt", 3),
))
func ContextWithLogger ¶
ContextWithLogger adds a logger to the context and returns a new context.
Example:
logger, _ := zap.NewProduction() ctx := xlog.ContextWithLogger(context.Background(), logger)
func ContextWithTracer ¶
ContextWithTracer returns a new context with the provided tracer attached. The tracer can be retrieved later using TracerFromContext.
func Debug ¶
Debug logs a Debug level message with structured fields. Logger is extracted from context. If logger is not found, the global logger is used.
Example:
xlog.Debug(ctx, "debug message", xlog.String("key", "value"))
func Debugf ¶
Debugf logs a formatted Debug level message. Logger is extracted from context. If logger is not found, the global logger is used.
Example:
xlog.Debugf(ctx, "value: %d, status: %s", 42, "ok")
func Error ¶
Error logs an Error level message with structured fields. Logger is extracted from context. If logger is not found, the global logger is used.
Example:
xlog.Error(ctx, "database query error", xlog.Error(err))
func Errorf ¶
Errorf logs a formatted Error level message. Logger is extracted from context. If logger is not found, the global logger is used.
Example:
xlog.Errorf(ctx, "failed to process request: %v", err)
func Fatal ¶
Fatal logs a Fatal level message with structured fields and terminates the program. Logger is extracted from context. If logger is not found, the global logger is used. Calls os.Exit(1) after logging.
Example:
xlog.Fatal(ctx, "critical error", xlog.Error(err))
func Fatalf ¶
Fatalf logs a formatted Fatal level message and terminates the program. Logger is extracted from context. If logger is not found, the global logger is used. Calls os.Exit(1) after logging.
Example:
xlog.Fatalf(ctx, "failed to start server: %v", err)
func Info ¶
Info logs an Info level message with structured fields. Logger is extracted from context. If logger is not found, the global logger is used.
Example:
xlog.Info(ctx, "request processed", xlog.Duration("took", time.Second))
func Infof ¶
Infof logs a formatted Info level message. Logger is extracted from context. If logger is not found, the global logger is used.
Example:
xlog.Infof(ctx, "user %s logged in", userID)
func Panic ¶
Panic logs a Panic level message with structured fields and panics. Logger is extracted from context. If logger is not found, the global logger is used.
Example:
xlog.Panic(ctx, "unexpected state", xlog.String("state", state))
func Panicf ¶
Panicf logs a formatted Panic level message and panics. Logger is extracted from context. If logger is not found, the global logger is used.
Example:
xlog.Panicf(ctx, "invalid value: %v", value)
func RecordSpanError ¶
func RecordSpanError(ctx context.Context, err error, options ...trace.EventOption)
RecordSpanError records an error on the span extracted from the context. It also sets the span status to Error with the error message. If no span is found or if the span is not recording, this is a no-op.
Example:
if err := doSomething(); err != nil {
xlog.RecordSpanError(ctx, err, trace.WithStackTrace(true))
return err
}
func ReplaceGlobalLogger ¶
func ReplaceGlobalLogger(logger Logger) func()
ReplaceGlobalLogger replaces the global logger and returns a function to restore the previous logger. This function is thread-safe and can be called concurrently.
This is similar to zap.ReplaceGlobals() but works with any Logger implementation.
Example:
logger := xlog.NewZapAdapter(zapLogger) restore := xlog.ReplaceGlobalLogger(logger) defer restore() // Restore previous logger when done
func ReplaceTracerName ¶
func ReplaceTracerName(name string) func()
ReplaceTracerName sets the global tracer name used when creating new tracers. This should be called during application initialization before any tracing operations. The default tracer name is "github.com/ruko1202/xlog". This function is thread-safe and can be called concurrently. Returns the previous tracer name.
func SetSpanAttributes ¶
SetSpanAttributes adds attributes to the span extracted from the context. If no span is found or if the span is not recording, this is a no-op.
Example:
xlog.SetSpanAttributes(ctx,
attribute.String("user_id", "123"),
attribute.Int64("count", 42),
)
func SpanFromContext ¶
SpanFromContext extracts span from context using OpenTelemetry's standard API. If span is not found, returns a NoopSpan.
Example:
span := xlog.SpanFromContext(ctx)
span.SetAttributes(attribute.String("key", "value"))
func TracerFromContext ¶
TracerFromContext extracts a tracer from the context. If no tracer is found, returns the global tracer from otel.GetTracerProvider().
Example:
tracer := xlog.TracerFromContext(ctx) ctx, span := tracer.Start(ctx, "my-operation") defer span.End()
func Unwrap ¶
Unwrap returns the underlying backend logger of type T. Returns (zero, false) if the logger does not implement Unwrapper or the type does not match.
Example:
zapLogger, ok := xlog.Unwrap[*zap.Logger](logger) slogLogger, ok := xlog.Unwrap[*slog.Logger](logger)
func Warn ¶
Warn logs a Warn level message with structured fields. Logger is extracted from context. If logger is not found, the global logger is used.
Example:
xlog.Warn(ctx, "slow query", xlog.Duration("took", time.Second*5))
func Warnf ¶
Warnf logs a formatted Warn level message. Logger is extracted from context. If logger is not found, the global logger is used.
Example:
xlog.Warnf(ctx, "retry attempts: %d", retryCount)
func WithFields ¶
WithFields creates a new context with additional fields added to the logger. It extracts the logger from the context and adds the specified fields.
func WithOperation ¶
WithOperation creates a new context with a named logger for a specific operation. It extracts the logger from the context, adds the operation name, and includes any additional fields.
func WithOperationSpan ¶
func WithOperationSpan(ctx context.Context, operation string, fields ...xfield.Field) (context.Context, trace.Span)
WithOperationSpan creates a new span for the given operation and attaches it to the context. It also creates a named logger with the operation name and the provided fields. The fields are added both to the logger and as span attributes. Returns the updated context with both the logger and span attached, along with the span itself.
Example:
ctx, span := xlog.WithOperationSpan(ctx, "process-payment",
xlog.String("user_id", "123"),
xlog.String("payment_id", "pay_xyz"),
)
defer span.End()
Types ¶
type Logger ¶
type Logger interface {
// Debug logs a debug-level message with structured fields.
Debug(msg string, fields ...xfield.Field)
// Info logs an info-level message with structured fields.
Info(msg string, fields ...xfield.Field)
// Warn logs a warning-level message with structured fields.
Warn(msg string, fields ...xfield.Field)
// Error logs an error-level message with structured fields.
Error(msg string, fields ...xfield.Field)
// Fatal logs a fatal-level message with structured fields and terminates the program.
Fatal(msg string, fields ...xfield.Field)
// Panic logs a panic-level message with structured fields and panics.
Panic(msg string, fields ...xfield.Field)
// With creates a child logger with the given fields pre-attached.
// All subsequent logs from this logger will include these fields.
With(fields ...xfield.Field) Logger
// Named creates a child logger with the given name appended.
// This is useful for adding operation or component names to logs.
Named(name string) Logger
// Sync flushes any buffered log entries.
// Applications should call Sync before exiting to ensure all logs are written.
Sync() error
}
Logger is the interface that wraps the basic logging methods. This interface allows xlog to work with any logging backend (zap, slog, logrus, etc).
func GlobalLogger ¶
func GlobalLogger() Logger
GlobalLogger returns the global logger. If no logger has been set via ReplaceGlobalLogger, returns NoopLogger. This function is thread-safe.
func L ¶
func L() Logger
L is a shorthand for GlobalLogger(). This is similar to zap.L() and provides quick access to the global logger.
Example:
xlog.L().Info("message", xlog.String("key", "value"))
func LoggerFromContext ¶
LoggerFromContext extracts logger from context. If logger is not found, returns the global logger.
Example:
logger := xlog.LoggerFromContext(ctx)
logger.Info("direct zap logger usage")
func NewSlogAdapter ¶
func NewSlogAdapter(logger *slog.Logger, options ...SlogOption) Logger
NewSlogAdapter creates a new SlogAdapter wrapping the given slog.Logger.
func NewSlogAdapterWithContext ¶
func NewSlogAdapterWithContext(ctx context.Context, logger *slog.Logger, options ...SlogOption) Logger
NewSlogAdapterWithContext creates a new SlogAdapter with a context. If logger is nil, it uses slog.Default(). The context is used for all logging operations.
func NewZapAdapter ¶
NewZapAdapter creates a new ZapAdapter wrapping the given zap.Logger.
type NoopLogger ¶
type NoopLogger struct{}
NoopLogger is a logger that does nothing. This is used as a fallback when no logger is configured.
func (*NoopLogger) Debug ¶
func (l *NoopLogger) Debug(_ string, _ ...xfield.Field)
Debug is a no-op implementation.
func (*NoopLogger) Error ¶
func (l *NoopLogger) Error(_ string, _ ...xfield.Field)
Error is a no-op implementation.
func (*NoopLogger) Fatal ¶
func (l *NoopLogger) Fatal(_ string, _ ...xfield.Field)
Fatal is a no-op implementation.
func (*NoopLogger) Info ¶
func (l *NoopLogger) Info(_ string, _ ...xfield.Field)
Info is a no-op implementation.
func (*NoopLogger) Named ¶
func (l *NoopLogger) Named(_ string) Logger
Named returns the same logger instance.
func (*NoopLogger) Panic ¶
func (l *NoopLogger) Panic(msg string, _ ...xfield.Field)
Panic panics with the given message.
type SlogAdapter ¶
type SlogAdapter struct {
// contains filtered or unexported fields
}
SlogAdapter adapts a slog.Logger to the xlog.Logger interface.
func (*SlogAdapter) Debug ¶
func (s *SlogAdapter) Debug(msg string, fields ...xfield.Field)
Debug logs a debug-level message.
func (*SlogAdapter) Error ¶
func (s *SlogAdapter) Error(msg string, fields ...xfield.Field)
Error logs an error-level message.
func (*SlogAdapter) Fatal ¶
func (s *SlogAdapter) Fatal(msg string, fields ...xfield.Field)
Fatal logs a fatal-level message and terminates the program. Note: slog doesn't have a Fatal level, so we log as Error with a special marker and exit.
func (*SlogAdapter) Info ¶
func (s *SlogAdapter) Info(msg string, fields ...xfield.Field)
Info logs an info-level message.
func (*SlogAdapter) Named ¶
func (s *SlogAdapter) Named(name string) Logger
Named creates a child logger with the given name. In slog, this is implemented by adding a "logger" field with the name.
func (*SlogAdapter) Panic ¶
func (s *SlogAdapter) Panic(msg string, fields ...xfield.Field)
Panic logs a panic-level message and panics. Note: slog doesn't have a Panic level, so we log as Error with a special marker and panic.
func (*SlogAdapter) Sync ¶
func (s *SlogAdapter) Sync() error
Sync flushes any buffered log entries. Note: slog doesn't have a Sync method, so this is a no-op.
func (*SlogAdapter) Unwrap ¶
func (s *SlogAdapter) Unwrap() *slog.Logger
Unwrap returns the underlying slog.Logger. This is useful for cases where you need direct access to slog-specific features.
func (*SlogAdapter) Warn ¶
func (s *SlogAdapter) Warn(msg string, fields ...xfield.Field)
Warn logs a warning-level message.
func (*SlogAdapter) With ¶
func (s *SlogAdapter) With(fields ...xfield.Field) Logger
With creates a child logger with pre-attached fields.
func (*SlogAdapter) WithContext ¶
WithContext returns a new adapter with the given context.
type SlogOption ¶
type SlogOption func(*SlogAdapter)
SlogOption is a function that configures a SlogAdapter.
func WithExitFunc ¶
func WithExitFunc(fn func()) SlogOption
WithExitFunc sets a custom exit function (for testing).
func WithPanicFunc ¶
func WithPanicFunc(fn func(string)) SlogOption
WithPanicFunc sets a custom panic function (for testing).
type Unwrapper ¶
type Unwrapper[T any] interface { Unwrap() T }
Unwrapper is an optional interface that a Logger may implement to expose the underlying backend logger (e.g. *zap.Logger, *slog.Logger).
type ZapAdapter ¶
type ZapAdapter struct {
// contains filtered or unexported fields
}
ZapAdapter adapts a zap.Logger to the xlog.Logger interface.
func (*ZapAdapter) Debug ¶
func (z *ZapAdapter) Debug(msg string, fields ...xfield.Field)
Debug logs a debug-level message.
func (*ZapAdapter) Error ¶
func (z *ZapAdapter) Error(msg string, fields ...xfield.Field)
Error logs an error-level message.
func (*ZapAdapter) Fatal ¶
func (z *ZapAdapter) Fatal(msg string, fields ...xfield.Field)
Fatal logs a fatal-level message and terminates the program.
func (*ZapAdapter) Info ¶
func (z *ZapAdapter) Info(msg string, fields ...xfield.Field)
Info logs an info-level message.
func (*ZapAdapter) Named ¶
func (z *ZapAdapter) Named(name string) Logger
Named creates a child logger with the given name.
func (*ZapAdapter) Panic ¶
func (z *ZapAdapter) Panic(msg string, fields ...xfield.Field)
Panic logs a panic-level message and panics.
func (*ZapAdapter) Unwrap ¶
func (z *ZapAdapter) Unwrap() *zap.Logger
Unwrap returns the underlying zap.Logger. This is useful for cases where you need direct access to zap-specific features.