diff --git a/CHANGELOG.md b/CHANGELOG.md index 2b5894ca47..e29cf911aa 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -38,6 +38,8 @@ await SentryFlutter.init( ); ``` +- Outgoing HTTP requests now contain the `traceparent` header to facilitate integration with servers that only support the [W3C Trace Context](https://www.w3.org/TR/trace-context/). ([#2843](https://github.com/getsentry/sentry-dart/pull/2843)) + ### Fixes - Trace propagation in HTTP tracing clients not correctly set up if performance is disabled ([#2850](https://github.com/getsentry/sentry-dart/pull/2850)) diff --git a/dart/lib/src/utils/add_tracing_headers_to_http_request.dart b/dart/lib/src/utils/add_tracing_headers_to_http_request.dart index fc4e21fe04..38f40df490 100644 --- a/dart/lib/src/utils/add_tracing_headers_to_http_request.dart +++ b/dart/lib/src/utils/add_tracing_headers_to_http_request.dart @@ -7,6 +7,7 @@ void addTracingHeadersToHttpHeader(Map headers, Hub hub, {ISentrySpan? span}) { if (span != null) { addSentryTraceHeaderFromSpan(span, headers); + addW3CHeaderFromSpan(span, headers); addBaggageHeaderFromSpan( span, headers, @@ -18,6 +19,7 @@ void addTracingHeadersToHttpHeader(Map headers, Hub hub, final traceHeader = propagationContext.toSentryTrace(); addSentryTraceHeader(traceHeader, headers); + addW3CHeaderFromSentryTrace(traceHeader, headers); final baggageHeader = propagationContext.toBaggageHeader(); if (baggageHeader != null) { diff --git a/dart/lib/src/utils/tracing_utils.dart b/dart/lib/src/utils/tracing_utils.dart index 5a14311d1c..ec6184a82d 100644 --- a/dart/lib/src/utils/tracing_utils.dart +++ b/dart/lib/src/utils/tracing_utils.dart @@ -11,6 +11,22 @@ void addSentryTraceHeader( headers[traceHeader.name] = traceHeader.value; } +void addW3CHeaderFromSpan(ISentrySpan span, Map headers) { + final traceHeader = span.toSentryTrace(); + addW3CHeaderFromSentryTrace(traceHeader, headers); +} + +void addW3CHeaderFromSentryTrace( + SentryTraceHeader traceHeader, Map headers) { + headers['traceparent'] = formatAsW3CHeader(traceHeader); +} + +String formatAsW3CHeader(SentryTraceHeader traceHeader) { + final sampled = traceHeader.sampled; + final traceFlags = sampled != null && sampled ? '01' : '00'; + return '00-${traceHeader.traceId}-${traceHeader.spanId}-$traceFlags'; +} + void addBaggageHeaderFromSpan( ISentrySpan span, Map headers, { diff --git a/dart/test/utils/tracing_utils_test.dart b/dart/test/utils/tracing_utils_test.dart index 8c73a1a54a..2541ab240e 100644 --- a/dart/test/utils/tracing_utils_test.dart +++ b/dart/test/utils/tracing_utils_test.dart @@ -112,6 +112,41 @@ void main() { expect(headers[baggage.name], newValue); }); + group('$addW3CHeaderFromSentryTrace', () { + final fixture = Fixture(); + final headerName = 'traceparent'; + final headerValue = + '00-${fixture._context.traceId}-${fixture._context.spanId}-01'; + + test('formats SentryTraceHeader as W3C header', () { + final sut = fixture.getSut(); + final sentryHeader = sut.toSentryTrace(); + + final w3cHeader = formatAsW3CHeader(sentryHeader); + + expect(w3cHeader, headerValue); + }); + + test('adds W3C traceparent from span', () { + final headers = {}; + final sut = fixture.getSut(); + + addW3CHeaderFromSpan(sut, headers); + + expect(headers[headerName], headerValue); + }); + + test('adds W3C traceparent header', () { + final headers = {}; + final sut = fixture.getSut(); + final sentryHeader = sut.toSentryTrace(); + + addW3CHeaderFromSentryTrace(sentryHeader, headers); + + expect(headers[headerName], headerValue); + }); + }); + test('overwrites duplicate key values', () { final headers = {}; final oldValue =