Structured logger backed by log/slog with request-context enrichment, extra-field context helpers, and duck-typed automatic error enrichment. What's included: - `Logger` interface with Debug / Info / Warn / Error / With / WithContext; `New(Options)` constructor writing to os.Stdout - `WithRequestID` / `GetRequestID` and `WithField` / `WithFields` context helpers — package owns both context keys - Automatic error_code and context-field enrichment in Logger.Error via duck-typed errorWithCode / errorWithContext interfaces (no xerrors import) Tested-via: todo-api POC integration Reviewed-against: docs/adr/
40 lines
1.8 KiB
Markdown
40 lines
1.8 KiB
Markdown
# ADR-001: log/slog as the Logging Backend
|
|
|
|
**Status:** Accepted
|
|
**Date:** 2026-03-18
|
|
|
|
## Context
|
|
|
|
Structured logging is a cross-cutting concern required by nearly every module in
|
|
the ecosystem. External logging libraries (zerolog, zap, logrus) add transitive
|
|
dependencies, pin dependency versions, and require every module that accepts a
|
|
logger to either import the concrete library or define an adapter interface. Go 1.21
|
|
shipped `log/slog` as a stdlib structured logging API, providing JSON and text
|
|
handlers, level filtering, and attribute chaining with no external dependencies.
|
|
|
|
## Decision
|
|
|
|
`logz` wraps `log/slog` exclusively. The concrete type `slogLogger` holds a
|
|
`*slog.Logger`. `New(opts Options) Logger` constructs either a JSON handler
|
|
(`slog.NewJSONHandler`) or a text handler (`slog.NewTextHandler`) backed by
|
|
`os.Stdout`, controlled by `Options.JSON`.
|
|
|
|
`Options` exposes:
|
|
- `Level slog.Level` — minimum log level (zero value = `slog.LevelInfo`).
|
|
- `JSON bool` — JSON vs text output.
|
|
- `StaticArgs []any` — key-value pairs attached to every record via `slog.Logger.With`.
|
|
|
|
The `slog` dependency is internal to the `logz` package. Consumers depend only on
|
|
the `logz.Logger` interface and are not required to import `log/slog` at all.
|
|
|
|
## Consequences
|
|
|
|
- Zero external dependencies: `logz` stays at Tier 1 (stdlib only).
|
|
- The `slog` structured attribute system (`slog.String`, `slog.Int`, etc.) is
|
|
available internally but is not exposed through the `Logger` interface — callers
|
|
pass plain `key, value` pairs, which `slog` handles via its `any` variadic.
|
|
- Output always goes to `os.Stdout`. Log routing (to files, remote sinks) is the
|
|
responsibility of the process supervisor or log collector, not this package.
|
|
- If a future Go version modifies the `slog` API, only `logz` needs to be updated —
|
|
all consumers remain unaffected.
|