patterngoTip
Structured logging with log/slog (Go 1.21+)
Viewed 0 times
Go 1.21+
slogstructured logginglog/slogJSON logginggo 1.21observabilitylog handler
Problem
The standard log package produces unstructured text lines that are hard to parse, query, and correlate in log aggregation systems. Third-party structured loggers (zap, zerolog) fragment the ecosystem.
Solution
Use the built-in log/slog package:
import "log/slog"
func main() {
// JSON output for production
logger := slog.New(slog.NewJSONHandler(os.Stdout, &slog.HandlerOptions{
Level: slog.LevelInfo,
}))
slog.SetDefault(logger)
// Structured log calls
slog.Info("server started", "addr", ":8080", "pid", os.Getpid())
slog.Error("request failed", "error", err, "path", r.URL.Path)
// With context (for trace ID propagation)
slog.InfoContext(ctx, "processing job", "job_id", job.ID)
// Group related attributes
logger.With(slog.Group("request",
"method", r.Method,
"path", r.URL.Path,
)).Info("handled")
}Why
slog provides a standard interface for structured logging. Handlers are pluggable — swap JSON for text or connect to OpenTelemetry without changing call sites. The default handler is the standard log package output.
Gotchas
- slog.SetDefault affects only the package-level functions (slog.Info, etc.) — pass the logger explicitly for library code
- Key-value pairs must come in pairs; an odd number of args causes the last key to be logged with a BadKey marker
- slog.Any wraps any value; prefer slog.Group for nested structures to keep keys flat in JSON
Revisions (0)
No revisions yet.