Documentation ¶
Overview ¶
Package ctxslog provides helpers around slog.
Example ¶
package main import ( "context" "log/slog" "net/http" "os" "go.yhsif.com/ctxslog" ) func EndpointHandler(ctx context.Context, traceID string) { // Inside an endpoint handler, attach trace id for all logs in this context ctx = ctxslog.Attach(ctx, "trace", traceID) // Now slog's global log functions with ctx will also have trace info slog.ErrorContext(ctx, "Not implemented") thirdPartyLibCall := func(ctx context.Context) { // Some third party library that uses slog and spams logs a lot. slog.ErrorContext(ctx, "not really an error") } thirdPartyLibCall( ctxslog.AttachLogLevel(ctx, ctxslog.MaxLevel), // now even if it logs at error level it won't shown ) } func HttpHandler(w http.ResponseWriter, r *http.Request) { ctx := ctxslog.Attach( r.Context(), // Add httpRequest group to every log within this context "httpRequest", ctxslog.HTTPRequest(r, ctxslog.RemoteAddrIP), ) // Enable callstack even at debug level for this context ctx = ctxslog.AttachCallstackLevel(ctx, slog.LevelDebug) slog.DebugContext(ctx, "foo") // this log will contain httpRequest group and callstack. } func main() { // Sets the global slog logger ctxslog.New( ctxslog.WithWriter(os.Stderr), // This is the default and can be omitted ctxslog.WithJSON, // This is the default, use ctxslog.WithText instead if you want non-json logs ctxslog.WithAddSource(true), // Add source info ctxslog.WithLevel(slog.LevelDebug), // Keep debug level logs ctxslog.WithCallstack(slog.LevelError), // For error and above levels, also add callstack info ctxslog.WithGlobalKVs("version", os.Getenv("VERSION_TAG")), // Add version info to every log ctxslog.WithReplaceAttr(ctxslog.ChainReplaceAttr( ctxslog.GCPKeys, // Use Google Cloud Structured logging friendly log keys ctxslog.StringDuration, // Log time durations as strings )), ) // Now you can just use slog's global log functions slog.Info("Hello, world!", "key", "value") }
Output:
Index ¶
- Constants
- func Attach(ctx context.Context, args ...any) context.Context
- func AttachCallstackLevel(ctx context.Context, level slog.Leveler) context.Context
- func AttachLogLevel(ctx context.Context, level slog.Leveler) context.Context
- func CallstackHandler(h slog.Handler, min slog.Leveler) slog.Handler
- func ContextHandler(h slog.Handler) slog.Handler
- func GCPKeys(groups []string, a slog.Attr) slog.Attr
- func GCPRealIP(r *http.Request) netip.Addr
- func HTTPRequest(r *http.Request, ip func(*http.Request) netip.Addr) slog.Value
- func New(opts ...Option) *slog.Logger
- func RemoteAddrIP(r *http.Request) netip.Addr
- func StringDuration(groups []string, a slog.Attr) slog.Attr
- func StringInt(groups []string, a slog.Attr) slog.Attr
- func WithJSON(o *options)
- func WithText(o *options)
- type Option
- type ReplaceAttrFunc
Examples ¶
Constants ¶
Minimal and maximal possible log levels.
You can use MinLevel as the log level or callstack level in context/logger to include all logs, or use MaxLevel to exclude all logs (except logs logged explicitly at MaxLevel).
Variables ¶
This section is empty.
Functions ¶
func AttachCallstackLevel ¶
AttachCallstackLevel attaches min callstack level to the context, overriding the global one set on the logger.
func AttachLogLevel ¶
AttachLogLevel attaches min log level to the context, overriding the global one set on the logger.
func CallstackHandler ¶
CallstackHandler wraps handler to print out full callstack at minimal level.
func ContextHandler ¶
ContextHandler wraps handler to handle contexts from Attach.
func GCPKeys ¶
GCPKeys is a ReplaceAttrFunc that replaces certain keys from Attr to meet Google Cloud Structured logging's expectations.
func GCPRealIP ¶
GCPRealIP gets the real IP form an GCP request (cloud run or app engine).
It picks the last non-local IP from X-Forwarded-For header, fallback to RemoteAddrIP if none found.
func HTTPRequest ¶
HTTPRequest returns a group value for some common HTTP request data.
The ip lambda is used to determine the real ip of the request. If it's nil, RemoteAddrIP will be used.
func New ¶
New creates a *slog.Logger that can handle contexts.
It also calls slog.SetDefault before returning.
Note that importing this package also has side-effect of calling New with all default options (setting global, default logger for slog to be context aware logger).
func RemoteAddrIP ¶
RemoteAddrIP returns the ip parsed from r.RemoteAddr.
func StringDuration ¶
StringDuration is a ReplaceAttrFunc that renders duration values as strings.
func StringInt ¶
StringInt is a ReplaceAttrFunc that renders int64 and uint64 values as strings.
It's useful in cases that your log ingester parses all number values as float64 and cause loss of precision.
Types ¶
type Option ¶
type Option func(*options)
Option define logger options for New.
func WithCallstack ¶
WithCallstack adds callstack at min level.
Set it to MaxLevel to disable callstack at all levels (except logs logged explicitly at MaxLevel). To add callstack at all levels, use MinLevel.
Default: MaxLevel.
func WithGlobalKVs ¶
WithGlobalKVs sets global key-value pairs.
func WithReplaceAttr ¶
func WithReplaceAttr(f ReplaceAttrFunc) Option
WithReplaceAttr sets the ReplaceAttr option.
Note that this option is overwriting not cumulative. To chain several ReplaceAttr functions, use ChainReplaceAttr.
type ReplaceAttrFunc ¶
Type alias for slog.HandlerOptions.ReplaceAttr.
func ChainReplaceAttr ¶
func ChainReplaceAttr(fs ...ReplaceAttrFunc) ReplaceAttrFunc
ChainReplaceAttr chains multiple ReplaceAttrFunc together.