css-verify-1770193392/pkg/logging/context.go
jordan 3be24bfbde
Some checks failed
ci/woodpecker/push/woodpecker Pipeline failed
ci/woodpecker/manual/woodpecker Pipeline was successful
Initialize project from skeleton template
2026-02-04 08:23:13 +00:00

100 lines
2.5 KiB
Go

package logging
import (
"context"
"log/slog"
)
type contextKey int
const (
loggerKey contextKey = iota
requestIDKey
userIDKey
traceIDKey
)
// NewContext returns a new context with the logger attached.
func NewContext(ctx context.Context, logger *Logger) context.Context {
return context.WithValue(ctx, loggerKey, logger)
}
// FromContext extracts the logger from the context.
// Returns a no-op logger if none is found.
func FromContext(ctx context.Context) *Logger {
if logger, ok := ctx.Value(loggerKey).(*Logger); ok {
return logger
}
return Nop()
}
// WithRequestID adds a request ID to the context.
func WithRequestID(ctx context.Context, requestID string) context.Context {
return context.WithValue(ctx, requestIDKey, requestID)
}
// RequestIDFromContext extracts the request ID from the context.
func RequestIDFromContext(ctx context.Context) string {
if id, ok := ctx.Value(requestIDKey).(string); ok {
return id
}
return ""
}
// WithUserID adds a user ID to the context.
func WithUserID(ctx context.Context, userID string) context.Context {
return context.WithValue(ctx, userIDKey, userID)
}
// UserIDFromContext extracts the user ID from the context.
func UserIDFromContext(ctx context.Context) string {
if id, ok := ctx.Value(userIDKey).(string); ok {
return id
}
return ""
}
// WithTraceID adds a trace ID to the context.
func WithTraceID(ctx context.Context, traceID string) context.Context {
return context.WithValue(ctx, traceIDKey, traceID)
}
// TraceIDFromContext extracts the trace ID from the context.
func TraceIDFromContext(ctx context.Context) string {
if id, ok := ctx.Value(traceIDKey).(string); ok {
return id
}
return ""
}
// ContextAttrs returns slog attributes from context values.
func ContextAttrs(ctx context.Context) []slog.Attr {
var attrs []slog.Attr
if id := RequestIDFromContext(ctx); id != "" {
attrs = append(attrs, slog.String("request_id", id))
}
if id := UserIDFromContext(ctx); id != "" {
attrs = append(attrs, slog.String("user_id", id))
}
if id := TraceIDFromContext(ctx); id != "" {
attrs = append(attrs, slog.String("trace_id", id))
}
return attrs
}
// LoggerWithContext returns a logger enriched with context attributes.
func LoggerWithContext(ctx context.Context, logger *Logger) *Logger {
attrs := ContextAttrs(ctx)
if len(attrs) == 0 {
return logger
}
args := make([]any, 0, len(attrs)*2)
for _, attr := range attrs {
args = append(args, attr.Key, attr.Value.Any())
}
return logger.With(args...)
}