# 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.