logger

package
v0.3.5 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Feb 17, 2026 License: Apache-2.0 Imports: 7 Imported by: 0

Documentation

Overview

Package logger provides structured logging with context extraction and Sentry integration.

This package extends the standard library's log/slog with two key capabilities: automatic context-based attribute injection and optional Sentry error reporting. It is designed for production applications that need consistent, enriched logs with minimal boilerplate.

Overview

The package provides:

  • Context extractors that automatically inject request-scoped values (e.g., request IDs, user IDs)
  • A decorator pattern that wraps any slog.Handler to add extraction behavior
  • Sentry integration for error tracking with graceful fallback when unconfigured
  • Multi-handler support for routing logs to multiple destinations

Basic Usage

Create a logger with context extractors:

// Define an extractor for request ID
requestIDExtractor := func(ctx context.Context) (slog.Attr, bool) {
	if reqID, ok := ctx.Value("request_id").(string); ok && reqID != "" {
		return slog.String("request_id", reqID), true
	}
	return slog.Attr{}, false
}

// Create logger with extractors
log := logger.New(requestIDExtractor)

// Use with context - request_id is automatically included
ctx := context.WithValue(context.Background(), "request_id", "abc-123")
log.InfoContext(ctx, "request processed", slog.Int("status", 200))
// Output: {"level":"INFO","msg":"request processed","status":200,"request_id":"abc-123"}

Sentry Integration

For production error tracking, use NewWithSentry:

cfg := logger.SentryConfig{
	DSN:         os.Getenv("SENTRY_DSN"),
	Environment: "production",
	MinLevel:    slog.LevelWarn, // Send warnings and errors to Sentry
}

log := logger.NewWithSentry(cfg, requestIDExtractor)

// Errors create Issues in Sentry, warnings are stored for context
log.ErrorContext(ctx, "payment failed", slog.String("user_id", "user-456"))

If SENTRY_DSN is empty, the logger gracefully falls back to stdout-only logging, making it safe to use the same code path in development and production.

Context Extractors

A ContextExtractor is a function that extracts a log attribute from context:

type ContextExtractor func(ctx context.Context) (slog.Attr, bool)

Extractors are called on every log call, ensuring fresh values for request-scoped data. Return false from the extractor to skip adding the attribute for that log entry.

Common extractors include:

  • Request ID extractor for HTTP request tracing
  • User ID extractor for authentication context
  • Tenant ID extractor for multi-tenant applications

Handler Decoration

The LogHandlerDecorator can wrap any slog.Handler to add context extraction:

// Wrap a custom handler
jsonHandler := slog.NewJSONHandler(os.Stdout, &slog.HandlerOptions{Level: slog.LevelDebug})
decorated := logger.NewLogHandlerDecorator(jsonHandler, extractors...)
log := slog.New(decorated)

This allows using context extractors with any handler implementation.

Architecture

The package uses several design patterns:

Decorator Pattern: LogHandlerDecorator wraps any slog.Handler, intercepting Handle calls to inject extracted attributes before delegating to the underlying handler.

Multi-Handler Pattern: An internal multiHandler forwards logs to multiple destinations, enabling simultaneous stdout and Sentry logging.

Graceful Degradation: Sentry integration fails gracefully - if DSN is missing or initialization fails, logging continues to stdout without disruption.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func New

func New(extractors ...ContextExtractor) *slog.Logger

New creates a JSON-formatted logger with optional context extractors.

func NewLogHandlerDecorator

func NewLogHandlerDecorator(next slog.Handler, extractors ...ContextExtractor) slog.Handler

NewLogHandlerDecorator creates a new decorated handler with context extractors. Filters nil extractors to prevent runtime panics from misconfigured options.

func NewNope

func NewNope() *slog.Logger

NewNope creates a no-op logger that discards all output. Use this as a default when logging is not configured.

func NewWithSentry

func NewWithSentry(cfg SentryConfig, extractors ...ContextExtractor) *slog.Logger

NewWithSentry creates a logger that sends logs to both stdout and Sentry. If DSN is empty, only stdout logging is enabled (graceful fallback for local dev). Context extractors are applied to logs sent to both destinations.

Types

type ContextExtractor

type ContextExtractor func(ctx context.Context) (slog.Attr, bool)

ContextExtractor extracts a slog attribute from context.

type LogHandlerDecorator

type LogHandlerDecorator struct {
	// contains filtered or unexported fields
}

LogHandlerDecorator wraps a slog.Handler and injects context-extracted attributes during logging. Extraction occurs per-log-call to capture fresh request-scoped values (e.g., request IDs).

func (*LogHandlerDecorator) Enabled

func (h *LogHandlerDecorator) Enabled(ctx context.Context, level slog.Level) bool

func (*LogHandlerDecorator) Handle

func (h *LogHandlerDecorator) Handle(ctx context.Context, rec slog.Record) error

Handle extracts context attributes and delegates to the underlying handler.

func (*LogHandlerDecorator) WithAttrs

func (h *LogHandlerDecorator) WithAttrs(attrs []slog.Attr) slog.Handler

WithAttrs creates a new decorated handler with additional static attributes.

func (*LogHandlerDecorator) WithGroup

func (h *LogHandlerDecorator) WithGroup(name string) slog.Handler

WithGroup creates a new decorated handler with attribute grouping.

type SentryConfig

type SentryConfig struct {
	DSN         string `env:"DSN"`
	Environment string `env:"ENVIRONMENT" envDefault:"production"`
	MinLevel    string `env:"MIN_LEVEL"   envDefault:"warn"`
}

SentryConfig holds Sentry integration configuration.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL