From 5ce086fa085d9a0a1efebbbc8f58d15c9d0169df Mon Sep 17 00:00:00 2001 From: Samuel Berthe Date: Fri, 26 Apr 2024 01:59:37 +0200 Subject: [PATCH] feat: load attributes from context --- README.md | 37 +++++++++++++++++++++++++++++++++++++ go.mod | 2 +- go.sum | 4 ++-- handler.go | 9 ++++++++- 4 files changed, 48 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index a97811d..2e413b7 100644 --- a/README.md +++ b/README.md @@ -79,6 +79,8 @@ type Option struct { // optional: customize webhook event builder Converter Converter + // optional: fetch attributes from context + AttrFromContext []func(ctx context.Context) []slog.Attr // optional: see slog.HandlerOptions AddSource bool @@ -127,6 +129,41 @@ func main() { } ``` +### Tracing + +Import the samber/slog-otel library. + +```go +import ( + slogloki "github.com/samber/slog-loki" + slogotel "github.com/samber/slog-otel" + "go.opentelemetry.io/otel/sdk/trace" +) + +func main() { + tp := trace.NewTracerProvider( + trace.WithSampler(trace.AlwaysSample()), + ) + tracer := tp.Tracer("hello/world") + + ctx, span := tracer.Start(context.Background(), "foo") + defer span.End() + + span.AddEvent("bar") + + logger := slog.New( + slogloki.Option{ + // ... + AttrFromContext: []func(ctx context.Context) []slog.Attr{ + slogotel.ExtractOtelAttrFromContext([]string{"tracing"}, "trace_id", "span_id"), + }, + }.NewLokiHandler(), + ) + + logger.ErrorContext(ctx, "a message") +} +``` + ## 🤝 Contributing - Ping me on twitter [@samuelberthe](https://twitter.com/samuelberthe) (DMs, mentions, whatever :)) diff --git a/go.mod b/go.mod index 517654e..8165d7e 100644 --- a/go.mod +++ b/go.mod @@ -5,7 +5,7 @@ go 1.21 require ( github.com/grafana/loki-client-go v0.0.0-20230116142646-e7494d0ef70c github.com/prometheus/common v0.34.0 - github.com/samber/slog-common v0.15.2 + github.com/samber/slog-common v0.16.0 go.uber.org/goleak v1.2.1 ) diff --git a/go.sum b/go.sum index 7d35abb..f067976 100644 --- a/go.sum +++ b/go.sum @@ -1005,8 +1005,8 @@ github.com/safchain/ethtool v0.0.0-20190326074333-42ed695e3de8/go.mod h1:Z0q5wiB github.com/safchain/ethtool v0.0.0-20210803160452-9aa261dae9b1/go.mod h1:Z0q5wiBQGYcxhMZ6gUqHn6pYNLypFAvaL3UvgZLR0U4= github.com/samber/lo v1.38.1 h1:j2XEAqXKb09Am4ebOg31SpvzUTTs6EN3VfgeLUhPdXM= github.com/samber/lo v1.38.1/go.mod h1:+m/ZKRl6ClXCE2Lgf3MsQlWfh4bn1bz6CXEOxnEXnEA= -github.com/samber/slog-common v0.15.2 h1:jQQK2MzJ1kfEsUyxI/mpwkqB2xI0qCo9Ne1D1yziuP0= -github.com/samber/slog-common v0.15.2/go.mod h1:Qjrfhwk79XiCIhBj8+jTq1Cr0u9rlWbjawh3dWXzaHk= +github.com/samber/slog-common v0.16.0 h1:2/t1EcFd1Ru77mh2ab+8B6NBHnEXsBBHtOJc7PSH0aI= +github.com/samber/slog-common v0.16.0/go.mod h1:Qjrfhwk79XiCIhBj8+jTq1Cr0u9rlWbjawh3dWXzaHk= github.com/samuel/go-zookeeper v0.0.0-20190923202752-2cc03de413da/go.mod h1:gi+0XIa01GRL2eRQVjQkKGqKF3SF9vZR/HnPullcV2E= github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0= github.com/scaleway/scaleway-sdk-go v1.0.0-beta.9/go.mod h1:fCa7OJZ/9DRTnOKmxvT6pn+LPWUptQAmHF/SBJUGEcg= diff --git a/handler.go b/handler.go index ca152ea..e637bb0 100644 --- a/handler.go +++ b/handler.go @@ -19,6 +19,8 @@ type Option struct { // optional: customize webhook event builder Converter Converter + // optional: fetch attributes from context + AttrFromContext []func(ctx context.Context) []slog.Attr // optional: see slog.HandlerOptions AddSource bool @@ -40,6 +42,10 @@ func (o Option) NewLokiHandler() slog.Handler { o.Converter = DefaultConverter } + if o.AttrFromContext == nil { + o.AttrFromContext = []func(ctx context.Context) []slog.Attr{} + } + return &LokiHandler{ option: o, attrs: []slog.Attr{}, @@ -60,7 +66,8 @@ func (h *LokiHandler) Enabled(_ context.Context, level slog.Level) bool { } func (h *LokiHandler) Handle(ctx context.Context, record slog.Record) error { - attrs := h.option.Converter(h.option.AddSource, h.option.ReplaceAttr, h.attrs, h.groups, &record) + fromContext := slogcommon.ContextExtractor(ctx, h.option.AttrFromContext) + attrs := h.option.Converter(h.option.AddSource, h.option.ReplaceAttr, append(h.attrs, fromContext...), h.groups, &record) return h.option.Client.Handle(attrs, record.Time, record.Message) }