Structured Logging in Go with slog
Feb 5, 2025 / 4 minutes to read / Tags: go, observability
Go 1.21 shipped log/slog — structured, leveled logging in the standard library. No more reaching for zerolog or zap for basic use cases.
Why Structured Logging
Plain text logs are for humans. Structured logs (JSON or key-value) are for machines — log aggregators, alerting pipelines, and dashboards can query them without regex.
Basic Usage
import "log/slog"
slog.Info("request handled", "method", "GET", "path", "/api/users", "status", 200, "latency_ms", 12,)Output (JSON handler):
{"time":"2025-02-05T10:00:00Z","level":"INFO","msg":"request handled","method":"GET","path":"/api/users","status":200,"latency_ms":12}JSON Handler
logger := slog.New(slog.NewJSONHandler(os.Stdout, &slog.HandlerOptions{ Level: slog.LevelInfo,}))slog.SetDefault(logger)Adding Context
Use With to attach fields that apply to all subsequent logs — useful for request IDs:
reqLogger := logger.With("request_id", requestID)reqLogger.Info("starting request")reqLogger.Info("request done", "status", 200)Both lines will carry request_id automatically.
← Back to blog