-
Notifications
You must be signed in to change notification settings - Fork 3
feat: slog-native Handler with context field injection and typed attrs #27
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
4 commits
Select commit
Hold shift + click to select a range
ddc99ef
feat: slog-native Handler with context field injection and typed attrs
ankurs 071cdb5
fix: address PR review comments
ankurs 0f25977
fix: Enabled respects per-request override over inner handler level
ankurs 83bcc79
fix: nil inner panic, SetLevel propagation to baseLoggerAdapter, wrap…
ankurs File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,36 +1,63 @@ | ||
| /* | ||
| Package log provides a minimal interface for structured logging in services. ColdBrew uses this log package for all logs. | ||
| It provides a simple interface to log errors, warnings, info and debug messages. | ||
| It also provides a mechanism to add contextual information to logs. | ||
| available implementations of BaseLogger are in loggers package. You can also implement your own BaseLogger to use with this package. | ||
| Package log provides structured logging for ColdBrew microservices. | ||
|
|
||
| # How To Use | ||
| It uses a custom slog.Handler that automatically injects per-request context | ||
| fields (added via [AddToContext] or [AddAttrsToContext]) into every log record. | ||
|
|
||
| The simplest way to use this package is by calling static log functions to report particular level (error/warning/info/debug) | ||
| # Quick Start | ||
|
|
||
| log.Error(...) | ||
| log.Warn(...) | ||
| log.Info(...) | ||
| log.Debug(...) | ||
| Use the package-level functions for simple logging: | ||
|
|
||
| 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) | ||
| log.Info(ctx, "msg", "order processed", "order_id", "ORD-123") | ||
| log.Error(ctx, "msg", "connection failed", "host", "db.internal") | ||
|
|
||
| logger := log.NewLogger(gokit.NewLogger()) | ||
| logger.Info(ctx, "key", "value") | ||
| # Native slog Support | ||
|
|
||
| Note: | ||
| After calling [SetDefault], native slog calls automatically get ColdBrew | ||
| context fields: | ||
|
|
||
| Preferred logging output is in either logfmt or json format, so to facilitate these log function arguments should be in pairs of key-value | ||
| log.SetDefault(log.NewHandler()) | ||
| ctx := context.Background() | ||
| ctx = log.AddToContext(ctx, "trace_id", "abc-123") | ||
| slog.InfoContext(ctx, "request handled", "status", 200) // includes trace_id | ||
|
|
||
| # Contextual Logs | ||
| # Adding Context Fields | ||
|
|
||
| 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 | ||
| Use [AddAttrsToContext] to add typed slog.Attr fields, or [AddToContext] for | ||
| untyped key-value pairs. Both are included in all subsequent logs for that | ||
| request: | ||
|
|
||
| {"@timestamp":"2018-07-30T09:58:18.262948679Z","caller":"http/http.go:66","error":null,"grpcMethod":"/AuthSvc.AuthService/Authenticate","level":"info","method":"POST","path":"/2.0/authenticate/","took":"1.356812ms","trace":"15592e1b-93df-11e8-bdfd-0242ac110002","transport":"http"} | ||
| ctx := context.Background() | ||
| ctx = log.AddAttrsToContext(ctx, | ||
| slog.String("trace_id", id), | ||
| slog.Int("user_id", uid), | ||
| ) | ||
|
|
||
| we pass 'grpcMethod' from context, this information gets automatically added to all log calls called inside the service and makes debugging services much easier. | ||
| ColdBrew also generates a 'trace' ID per request, this can be used to trace an entire request path in logs. | ||
| [AddAttrsToContext] stores each slog.Attr in the context. At log time, the | ||
| Handler recovers the typed Attr and emits it directly. Context storage goes | ||
| through an any-typed API internally (one boxing per field per request), but | ||
| the Attr's type information is preserved for emission. | ||
|
|
||
| this package is based on https://github.com/carousell/Orion/tree/master/utils/log | ||
| # High-Performance Logging | ||
|
|
||
| Combine [AddAttrsToContext] with [slog.LogAttrs] for the lowest-overhead path. | ||
| Per-call attributes passed to [slog.LogAttrs] avoid interface boxing entirely: | ||
|
|
||
| slog.LogAttrs(ctx, slog.LevelInfo, "request handled", | ||
| slog.Int("status", 200), | ||
| slog.Duration("latency", elapsed), | ||
| ) | ||
|
|
||
| # Custom Handlers | ||
|
|
||
| Use [NewHandlerWithInner] to compose ColdBrew's context injection with any | ||
| slog.Handler: | ||
|
|
||
| multi := slogmulti.Fanout(jsonHandler, textHandler) | ||
| h := log.NewHandlerWithInner(multi) | ||
| log.SetDefault(h) | ||
|
|
||
| ColdBrew interceptors automatically add grpcMethod, trace ID, and HTTP path | ||
| to the context, so these fields appear in all service logs. | ||
| */ | ||
| package log | ||
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.