You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
feat: slog-native Handler with context field injection and typed attrs (#27)
* feat: slog-native Handler with context field injection and typed attrs
Replace BaseLogger abstraction with a custom slog.Handler as the extension
point. Native slog.LogAttrs calls now automatically get ColdBrew context
fields (trace ID, gRPC method, etc.) after SetDefault wires the Handler.
Key changes:
- New Handler implementing slog.Handler with context field injection,
caller caching, per-request level override, composable WithAttrs/WithGroup
- SetDefault(h) sets global handler + slog.SetDefault for native slog support
- AddAttrsToContext for typed slog.Attr context fields (zero interface boxing)
- toAttr handles slog.Attr and slog.Value to prevent double-wrapping
- Exported ToSlogLevel/FromSlogLevel for cross-package use
- Deprecated: BaseLogger, SetLogger, NewLogger (backward compat kept)
- Deleted: gokit, logrus, zap, stdlog, slog backends; gokitwrap bridge
- Removed direct deps: go-kit/log, logrus, zap
Performance: 16B/1alloc per log call (down from 80B/3allocs), native slog
path adds ~30ns overhead over raw slog.
* fix: address PR review comments
- Fix NewHandler creating double levelVar (Copilot) — construct Handler
directly instead of calling NewHandlerWithInner
- Fix SetLevel not propagating to BaseLogger adapter (Copilot) — add
type assertion to forward level changes to inner handler
- Fix AddAttrsToContext doc overstating zero-boxing (Copilot) — clarify
that context storage still goes through any, boxing is avoided at log
emission time via toAttr type switch
- Fix tests leaking slog.Default global state (Copilot + CodeRabbit) —
extract setDefaultForTest helper that saves/restores both defaultHandler
and slog.Default in t.Cleanup
- Fix ExampleAddAttrsToContext missing SetDefault call (Copilot)
- Fix documentation.go using undefined ctx variable (CodeRabbit)
- Fix wrap test not restoring slog.Default (Copilot)
* fix: Enabled respects per-request override over inner handler level
* fix: nil inner panic, SetLevel propagation to baseLoggerAdapter, wrap test cleanup
Package log provides a minimal interface for structured logging in services. ColdBrew uses this log package for all logs.
3
-
It provides a simple interface to log errors, warnings, info and debug messages.
4
-
It also provides a mechanism to add contextual information to logs.
5
-
available implementations of BaseLogger are in loggers package. You can also implement your own BaseLogger to use with this package.
2
+
Package log provides structured logging for ColdBrew microservices.
6
3
7
-
# How To Use
4
+
It uses a custom slog.Handler that automatically injects per-request context
5
+
fields (added via [AddToContext] or [AddAttrsToContext]) into every log record.
8
6
9
-
The simplest way to use this package is by calling static log functions to report particular level (error/warning/info/debug)
7
+
# Quick Start
10
8
11
-
log.Error(...)
12
-
log.Warn(...)
13
-
log.Info(...)
14
-
log.Debug(...)
9
+
Use the package-level functions for simple logging:
15
10
16
-
You can also initialize a new logger by calling 'log.NewLogger' and passing a loggers.BaseLogger implementation (loggers package provides a number of pre built implementations)
slog.InfoContext(ctx, "request handled", "status", 200) // includes trace_id
24
23
25
-
# Contextual Logs
24
+
# Adding Context Fields
26
25
27
-
log package uses context.Context to pass additional information to logs, you can use 'loggers.AddToLogContext' function to add additional information to logs. For example in access log from service
26
+
Use [AddAttrsToContext] to add typed slog.Attr fields, or [AddToContext] for
27
+
untyped key-value pairs. Both are included in all subsequent logs for that
we pass 'grpcMethod' from context, this information gets automatically added to all log calls called inside the service and makes debugging services much easier.
32
-
ColdBrew also generates a 'trace' ID per request, this can be used to trace an entire request path in logs.
36
+
[AddAttrsToContext] stores each slog.Attr in the context. At log time, the
37
+
Handler recovers the typed Attr and emits it directly. Context storage goes
38
+
through an any-typed API internally (one boxing per field per request), but
39
+
the Attr's type information is preserved for emission.
33
40
34
-
this package is based on https://github.com/carousell/Orion/tree/master/utils/log
41
+
# High-Performance Logging
42
+
43
+
Combine [AddAttrsToContext] with [slog.LogAttrs] for the lowest-overhead path.
44
+
Per-call attributes passed to [slog.LogAttrs] avoid interface boxing entirely:
0 commit comments