feat(http/fiber-middleware): trace propagation

This commit is contained in:
DevMiner 2024-08-24 14:14:55 +02:00
parent 8c63bfc3c5
commit 9dc9d99379
3 changed files with 41 additions and 26 deletions

View file

@ -32,7 +32,7 @@ func AddBreadcrumbToContext(c context.Context, breadcrumb *sentry.Breadcrumb) {
} }
} }
func (o *Telemetry) Trace(ctx context.Context, op string, options []ConfigureSpanStartFunc, fn func(context.Context)) { func (o *Telemetry) Trace(ctx context.Context, op string, options []SpanStartOpt, fn func(context.Context)) {
tx := o.StartSpan(ctx, op, op, options...) tx := o.StartSpan(ctx, op, op, options...)
defer tx.End() defer tx.End()

View file

@ -23,9 +23,9 @@ var (
tracerContextKey = contextKey{"tracer"} tracerContextKey = contextKey{"tracer"}
) )
type ConfigureSpanStartFunc = func(context.Context) (context.Context, []trace.SpanStartOption, []sentry.SpanOption) type SpanStartOpt = func(context.Context) (context.Context, []trace.SpanStartOption, []sentry.SpanOption)
func (t *Telemetry) StartSpan(ctx context.Context, operation, name string, cfgs ...ConfigureSpanStartFunc) *Span { func (t *Telemetry) StartSpan(ctx context.Context, operation, name string, cfgs ...SpanStartOpt) *Span {
otelStartOpts := make([]trace.SpanStartOption, 0) otelStartOpts := make([]trace.SpanStartOption, 0)
sentryStartOpts := []sentry.SpanOption{sentry.WithTransactionName(name), sentry.WithDescription(name)} sentryStartOpts := []sentry.SpanOption{sentry.WithTransactionName(name), sentry.WithDescription(name)}
@ -55,7 +55,7 @@ func (t *Telemetry) StartSpan(ctx context.Context, operation, name string, cfgs
} }
} }
func WithOtelOptions(opts ...trace.SpanStartOption) ConfigureSpanStartFunc { func WithOtelOptions(opts ...trace.SpanStartOption) SpanStartOpt {
return func(ctx context.Context) (context.Context, []trace.SpanStartOption, []sentry.SpanOption) { return func(ctx context.Context) (context.Context, []trace.SpanStartOption, []sentry.SpanOption) {
return ctx, opts, []sentry.SpanOption{} return ctx, opts, []sentry.SpanOption{}
} }
@ -85,7 +85,7 @@ func (t *Telemetry) InjectIntoMap(ctx context.Context, m map[string]string) {
} }
} }
func (t *Telemetry) ContinueFromHeaders(h http.Header) ConfigureSpanStartFunc { func (t *Telemetry) ContinueFromHeaders(h http.Header) SpanStartOpt {
return func(ctx context.Context) (context.Context, []trace.SpanStartOption, []sentry.SpanOption) { return func(ctx context.Context) (context.Context, []trace.SpanStartOption, []sentry.SpanOption) {
ctx = t.Propagator.Extract(ctx, propagation.HeaderCarrier(h)) ctx = t.Propagator.Extract(ctx, propagation.HeaderCarrier(h))
@ -98,7 +98,7 @@ func (t *Telemetry) ContinueFromHeaders(h http.Header) ConfigureSpanStartFunc {
} }
} }
func (t *Telemetry) ContinueFromMap(m map[string]string) ConfigureSpanStartFunc { func (t *Telemetry) ContinueFromMap(m map[string]string) SpanStartOpt {
return func(ctx context.Context) (context.Context, []trace.SpanStartOption, []sentry.SpanOption) { return func(ctx context.Context) (context.Context, []trace.SpanStartOption, []sentry.SpanOption) {
ctx = t.Propagator.Extract(ctx, propagation.MapCarrier(m)) ctx = t.Propagator.Extract(ctx, propagation.MapCarrier(m))
@ -114,7 +114,7 @@ func (t *Telemetry) ContinueFromMap(m map[string]string) ConfigureSpanStartFunc
} }
} }
func WithOtelTracer(tracer trace.Tracer) ConfigureSpanStartFunc { func WithOtelTracer(tracer trace.Tracer) SpanStartOpt {
return func(ctx context.Context) (context.Context, []trace.SpanStartOption, []sentry.SpanOption) { return func(ctx context.Context) (context.Context, []trace.SpanStartOption, []sentry.SpanOption) {
return context.WithValue(ctx, tracerContextKey, tracer), []trace.SpanStartOption{}, []sentry.SpanOption{} return context.WithValue(ctx, tracerContextKey, tracer), []trace.SpanStartOption{}, []sentry.SpanOption{}
} }

View file

@ -17,7 +17,6 @@ import (
"go.opentelemetry.io/otel/attribute" "go.opentelemetry.io/otel/attribute"
"go.opentelemetry.io/otel/codes" "go.opentelemetry.io/otel/codes"
"go.opentelemetry.io/otel/metric" "go.opentelemetry.io/otel/metric"
"go.opentelemetry.io/otel/propagation"
semconv "go.opentelemetry.io/otel/semconv/v1.26.0" semconv "go.opentelemetry.io/otel/semconv/v1.26.0"
"go.opentelemetry.io/otel/trace" "go.opentelemetry.io/otel/trace"
) )
@ -32,6 +31,7 @@ type FiberMiddlewareConfig struct {
TraceResponseHeaders []string TraceResponseHeaders []string
IgnoredRoutes []string IgnoredRoutes []string
Logger logr.Logger Logger logr.Logger
TracePropagator TracePropagator
} }
var fiberMiddlewareConfigDefault = FiberMiddlewareConfig{ var fiberMiddlewareConfigDefault = FiberMiddlewareConfig{
@ -42,6 +42,7 @@ var fiberMiddlewareConfigDefault = FiberMiddlewareConfig{
TraceResponseHeaders: []string{}, TraceResponseHeaders: []string{},
IgnoredRoutes: []string{}, IgnoredRoutes: []string{},
Logger: logr.Discard(), Logger: logr.Discard(),
TracePropagator: PropagateNoTraces,
} }
func FiberMiddleware(t *unitel.Telemetry, config ...FiberMiddlewareConfig) fiber.Handler { func FiberMiddleware(t *unitel.Telemetry, config ...FiberMiddlewareConfig) fiber.Handler {
@ -61,6 +62,9 @@ func FiberMiddleware(t *unitel.Telemetry, config ...FiberMiddlewareConfig) fiber
if cfg.IgnoredRoutes == nil { if cfg.IgnoredRoutes == nil {
cfg.IgnoredRoutes = []string{} cfg.IgnoredRoutes = []string{}
} }
if cfg.TracePropagator == nil {
cfg.TracePropagator = PropagateNoTraces
}
meter := t.MeterProvider.Meter(fiberMwClientID, metric.WithInstrumentationVersion(unitelutils.Version)) meter := t.MeterProvider.Meter(fiberMwClientID, metric.WithInstrumentationVersion(unitelutils.Version))
tracer := t.TracerProvider.Tracer(fiberMwClientID, trace.WithInstrumentationVersion(unitelutils.Version)) tracer := t.TracerProvider.Tracer(fiberMwClientID, trace.WithInstrumentationVersion(unitelutils.Version))
@ -128,27 +132,21 @@ func FiberMiddleware(t *unitel.Telemetry, config ...FiberMiddlewareConfig) fiber
return err return err
} }
// FIXME: Only extract the headers from trusted servers opts := []unitel.SpanStartOpt{
ctx = t.Propagator.Extract(ctx, propagation.HeaderCarrier(stdRequest.Header)) unitel.WithOtelOptions(trace.WithSpanKind(trace.SpanKindServer)),
unitel.WithOtelTracer(tracer),
hub := sentry.CurrentHub().Clone() }
if client := hub.Client(); client != nil { shouldPropagate := cfg.TracePropagator(&stdRequest)
client.SetSDKIdentifier(fiberMwClientID) if shouldPropagate {
opts = append(opts, t.ContinueFromHeaders(stdRequest.Header))
} }
scope := hub.Scope()
scope.SetRequest(&stdRequest)
scope.SetRequestBody(utils.CopyBytes(c.Body()))
ctx = sentry.SetHubOnContext(ctx, hub)
description := fmt.Sprintf("%s %s", c.Method(), c.Path()) description := fmt.Sprintf("%s %s", c.Method(), c.Path())
span := t.StartSpan( span := t.StartSpan(
ctx, ctx,
"http.server", "http.server",
description, description,
unitel.WithOtelOptions(trace.WithSpanKind(trace.SpanKindServer)), opts...,
unitel.WithOtelTracer(tracer),
t.ContinueFromHeaders(stdRequest.Header),
) )
defer func() { defer func() {
if err := recover(); err != nil { if err := recover(); err != nil {
@ -172,11 +170,17 @@ func FiberMiddleware(t *unitel.Telemetry, config ...FiberMiddlewareConfig) fiber
defer span.End() defer span.End()
defer func() { defer func() {
h := propagation.HeaderCarrier{} if !shouldPropagate {
t.Propagator.Inject(ctx, h) return
}
for _, k := range h.Keys() { h := http.Header{}
c.Set(k, h.Get(k)) t.InjectIntoHeaders(ctx, h)
for k, v := range h {
for _, vv := range v {
c.Response().Header.Add(k, vv)
}
} }
}() }()
@ -187,6 +191,17 @@ func FiberMiddleware(t *unitel.Telemetry, config ...FiberMiddlewareConfig) fiber
} }
} }
ctx = span.Context() ctx = span.Context()
hub := sentry.CurrentHub().Clone()
if client := hub.Client(); client != nil {
client.SetSDKIdentifier(fiberMwClientID)
}
scope := hub.Scope()
scope.SetRequest(&stdRequest)
scope.SetRequestBody(utils.CopyBytes(c.Body()))
ctx = sentry.SetHubOnContext(ctx, hub)
c.SetUserContext(ctx) c.SetUserContext(ctx)
var err error = nil var err error = nil