68 lines
1.8 KiB
Go
68 lines
1.8 KiB
Go
package logging
|
|
|
|
import (
|
|
"context"
|
|
"log/slog"
|
|
)
|
|
|
|
type contextFieldsKey struct{}
|
|
|
|
// ContextFields contains request metadata attached to logs emitted with a
|
|
// request context.
|
|
type ContextFields struct {
|
|
RequestID string
|
|
TraceID string
|
|
SpanID string
|
|
ParentSpanID string
|
|
DeviceID string
|
|
ClientIP string
|
|
HTTPMethod string
|
|
HTTPPath string
|
|
}
|
|
|
|
func WithContextFields(ctx context.Context, fields *ContextFields) context.Context {
|
|
return context.WithValue(ctx, contextFieldsKey{}, fields)
|
|
}
|
|
|
|
func ContextFieldsFrom(ctx context.Context) *ContextFields {
|
|
if ctx == nil {
|
|
return nil
|
|
}
|
|
fields, _ := ctx.Value(contextFieldsKey{}).(*ContextFields)
|
|
return fields
|
|
}
|
|
|
|
type contextHandler struct{ handler slog.Handler }
|
|
|
|
func (h *contextHandler) Enabled(ctx context.Context, level slog.Level) bool {
|
|
return h.handler.Enabled(ctx, level)
|
|
}
|
|
|
|
func (h *contextHandler) Handle(ctx context.Context, record slog.Record) error {
|
|
if fields := ContextFieldsFrom(ctx); fields != nil {
|
|
record.AddAttrs(
|
|
slog.String("request_id", fields.RequestID),
|
|
slog.String("trace_id", fields.TraceID),
|
|
slog.String("device_id", fields.DeviceID),
|
|
slog.String("client_ip", fields.ClientIP),
|
|
slog.String("http_method", fields.HTTPMethod),
|
|
slog.String("http_path", fields.HTTPPath),
|
|
)
|
|
if fields.SpanID != "" {
|
|
record.AddAttrs(slog.String("span_id", fields.SpanID))
|
|
}
|
|
if fields.ParentSpanID != "" {
|
|
record.AddAttrs(slog.String("parent_span_id", fields.ParentSpanID))
|
|
}
|
|
}
|
|
return h.handler.Handle(ctx, record)
|
|
}
|
|
|
|
func (h *contextHandler) WithAttrs(attrs []slog.Attr) slog.Handler {
|
|
return &contextHandler{handler: h.handler.WithAttrs(attrs)}
|
|
}
|
|
|
|
func (h *contextHandler) WithGroup(name string) slog.Handler {
|
|
return &contextHandler{handler: h.handler.WithGroup(name)}
|
|
}
|