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/
3.0 KiB
3.0 KiB
Changelog
All notable changes to this module will be documented in this file.
The format is based on Keep a Changelog, and this module adheres to Semantic Versioning.
0.9.0 - 2026-03-18
Added
Loggerinterface —Debug(msg string, args ...any),Info(msg string, args ...any),Warn(msg string, args ...any),Error(msg string, err error, args ...any),With(args ...any) Logger,WithContext(ctx context.Context) LoggerOptionsstruct —Level slog.Level(minimum log level; defaultslog.LevelInfo),JSON bool(JSON vs text output; default text),StaticArgs []any(key-value pairs attached to every record); zero value is validNew(opts Options) Logger— constructs aLoggerbacked bylog/slog, writing toos.Stdout; returns theLoggerinterface, never the concrete typeWithRequestID(ctx context.Context, id string) context.Context— stores a request correlation ID in the context under a private unexported key owned by this packageGetRequestID(ctx context.Context) string— retrieves the correlation ID; returns""if absent or if ctx is nilWithField(ctx context.Context, key string, value any) context.Context— adds a single key-value logging field to the contextWithFields(ctx context.Context, fields map[string]any) context.Context— merges multiple key-value fields into the context without overwriting existing fieldsLogger.WithContext(ctx context.Context) Logger— returns a child logger pre-enriched withrequest_idand any extra fields stored in the context viaWithRequestID/WithField/WithFields; returns the same logger unchanged if ctx is nil or carries no relevant valuesLogger.With(args ...any) Logger— returns a child logger with the given key-value attributes permanently attached to every subsequent record- Automatic
error_codefield enrichment inLogger.Errorwhenerrsatisfies the privateerrorWithCodeduck-type interface (ErrorCode() string) - Automatic context-field enrichment in
Logger.Errorwhenerrsatisfies the privateerrorWithContextduck-type interface (ErrorContext() map[string]any)
Design Notes
Newreturns theLoggerinterface (not*slogLogger), andWithlikewise returnsLogger; the concrete type is never exported, making the interface the only public surface and enabling safe local re-declaration in downstream libraries without importing this package.- This package owns the context keys
ctxRequestIDKey{}andctxExtraFieldsKey{}as unexported struct types, preventing collisions; any module that needs to attach a request ID to logs imports onlylogz. - The xerrors integration is zero-import:
Logger.Erroruseserrors.Asagainst two private interfaces (errorWithCode,errorWithContext) thatxerrors.Errsatisfies — no import between the two packages is required in either direction.