Go Structured Logging with slog
Context
Go tooling requires production-grade logging with:
- Structured fields for machine parsing
- Context propagation through call stacks
- High performance (minimal overhead)
- Integration with observability systems
- Standard library compatibility
Decision
Use slog (Go standard library) for structured logging with context management.
Rationale
Why slog (Go 1.21+ Standard Library)
- Standard Library: No external dependency, guaranteed compatibility
- Performance: Designed for high-throughput logging
- Structured by Default: Key-value pairs, not string formatting
- Context Integration: First-class
context.Contextsupport - Handlers: JSON, Text, and custom handlers
- Levels: Debug, Info, Warn, Error
- Attributes: Rich type support (string, int, bool, time, error, etc.)
Why NOT zap or logrus?
- zap: Excellent performance, but slog is now in stdlib with comparable speed
- logrus: Mature but slower, maintenance mode, superseded by slog
- zerolog: Fast but non-standard API, less idiomatic
Context Propagation Pattern
Logging flows through context to maintain operation correlation:
// Add logger to context
ctx := log.WithContext(ctx, logger.With("operation", "migrate", "namespace", ns))
// Extract logger from context
logger := log.FromContext(ctx)
logger.Info("starting migration")
Logging Schema
Log Levels
- Debug: Detailed diagnostic information (disabled in production)
- Info: General informational messages (normal operations)
- Warn: Warning conditions that don't prevent operation
- Error: Error conditions that prevent specific operation