From 388a88c2498a134f6c1f36fe14f76cb0af149cbe Mon Sep 17 00:00:00 2001 From: Karsten Bruhns Date: Mon, 13 Nov 2023 19:23:37 +0100 Subject: [PATCH 1/2] feat: propagate tracing context as headers in outbound response --- otelfiber/fiber.go | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/otelfiber/fiber.go b/otelfiber/fiber.go index e999c1b2..a5dfd521 100644 --- a/otelfiber/fiber.go +++ b/otelfiber/fiber.go @@ -158,6 +158,13 @@ func Middleware(opts ...Option) fiber.Handler { spanStatus, spanMessage := semconv.SpanStatusFromHTTPStatusCodeAndSpanKind(c.Response().StatusCode(), oteltrace.SpanKindServer) span.SetStatus(spanStatus, spanMessage) + //Propagate tracing context as headers in outbound response + tracingHeaders := make(propagation.HeaderCarrier) + cfg.Propagators.Inject(c.UserContext(), tracingHeaders) + for _, headerKey := range tracingHeaders.Keys() { + c.Set(headerKey, tracingHeaders.Get(headerKey)) + } + return nil } } From 659c51f17378254e360fc3830a33978fd922eff2 Mon Sep 17 00:00:00 2001 From: Karsten Bruhns Date: Fri, 17 Nov 2023 15:24:02 +0100 Subject: [PATCH 2/2] test: add tests for header propagation --- otelfiber/otelfiber_test/fiber_test.go | 50 ++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) diff --git a/otelfiber/otelfiber_test/fiber_test.go b/otelfiber/otelfiber_test/fiber_test.go index a42fabc0..130802b4 100644 --- a/otelfiber/otelfiber_test/fiber_test.go +++ b/otelfiber/otelfiber_test/fiber_test.go @@ -446,3 +446,53 @@ func TestCustomAttributes(t *testing.T) { assert.Contains(t, attr, attribute.String("http.route", "/user/:id")) assert.Contains(t, attr, attribute.String("http.query_params", "foo=bar")) } + +func TestOutboundTracingPropagation(t *testing.T) { + sr := new(tracetest.SpanRecorder) + provider := sdktrace.NewTracerProvider(sdktrace.WithSpanProcessor(sr)) + + app := fiber.New() + app.Use(otelfiber.Middleware( + otelfiber.WithTracerProvider(provider), + otelfiber.WithPropagators(b3prop.New(b3prop.WithInjectEncoding(b3prop.B3MultipleHeader))), + )) + app.Get("/foo", func(ctx *fiber.Ctx) error { + return ctx.SendStatus(http.StatusNoContent) + }) + + resp, _ := app.Test(httptest.NewRequest("GET", "/foo", nil), 3000) + + assert.Equal(t, "1", resp.Header.Get("X-B3-Sampled")) + assert.NotEmpty(t, resp.Header.Get("X-B3-SpanId")) + assert.NotEmpty(t, resp.Header.Get("X-B3-TraceId")) + +} + +func TestOutboundTracingPropagationWithInboundContext(t *testing.T) { + const spanId = "619907d88b766fb8" + const traceId = "813dd2766ff711bf02b60e9883014964" + + sr := new(tracetest.SpanRecorder) + provider := sdktrace.NewTracerProvider(sdktrace.WithSpanProcessor(sr)) + + app := fiber.New() + app.Use(otelfiber.Middleware( + otelfiber.WithTracerProvider(provider), + otelfiber.WithPropagators(b3prop.New(b3prop.WithInjectEncoding(b3prop.B3MultipleHeader))), + )) + app.Get("/foo", func(ctx *fiber.Ctx) error { + return ctx.SendStatus(http.StatusNoContent) + }) + + req := httptest.NewRequest("GET", "/foo", nil) + + req.Header.Set("X-B3-SpanId", spanId) + req.Header.Set("X-B3-TraceId", traceId) + req.Header.Set("X-B3-Sampled", "1") + + resp, _ := app.Test(req, 3000) + + assert.NotEmpty(t, resp.Header.Get("X-B3-SpanId")) + assert.Equal(t, traceId, resp.Header.Get("X-B3-TraceId")) + assert.Equal(t, "1", resp.Header.Get("X-B3-Sampled")) +}