feat(http/fiber-middleware): trace propagation
This commit is contained in:
parent
f3bbc9ae88
commit
18125db231
3 changed files with 41 additions and 26 deletions
|
@ -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()
|
||||||
|
|
||||||
|
|
12
tracing.go
12
tracing.go
|
@ -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{}
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,7 +16,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"
|
||||||
)
|
)
|
||||||
|
@ -31,6 +30,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{
|
||||||
|
@ -41,6 +41,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 {
|
||||||
|
@ -60,6 +61,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))
|
||||||
|
@ -127,27 +131,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 {
|
||||||
|
@ -168,11 +166,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)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
||||||
|
@ -183,6 +187,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
|
||||||
|
|
Loading…
Reference in a new issue