Skip to content
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 0 additions & 2 deletions dart/lib/sentry.dart
Original file line number Diff line number Diff line change
Expand Up @@ -53,8 +53,6 @@ export 'src/type_check_hint.dart';
// ignore: invalid_export_of_internal_element
export 'src/utils.dart';
// ignore: invalid_export_of_internal_element
export 'src/utils/add_tracing_headers_to_http_request.dart';
// ignore: invalid_export_of_internal_element
export 'src/utils/http_header_utils.dart';
// ignore: invalid_export_of_internal_element
export 'src/utils/http_sanitizer.dart';
Expand Down
1 change: 0 additions & 1 deletion dart/lib/src/http_client/tracing_client.dart
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import '../hub_adapter.dart';
import '../protocol.dart';
import '../sentry_trace_origins.dart';
import '../tracing.dart';
import '../utils/add_tracing_headers_to_http_request.dart';
import '../utils/http_sanitizer.dart';
import '../utils/tracing_utils.dart';

Expand Down
10 changes: 3 additions & 7 deletions dart/lib/src/propagation_context.dart
Original file line number Diff line number Diff line change
@@ -1,17 +1,12 @@
import 'package:meta/meta.dart';

import 'protocol.dart';
import 'sentry_baggage.dart';
import '../sentry.dart';

@internal
class PropagationContext {
/// Either represents the incoming `traceId` or the `traceId` generated by the current SDK, if there was no incoming trace.
SentryId traceId = SentryId.newId();

/// A span ID that should be used for the `trace` context of various event type, when performance is disabled or when there is no active span.
/// If this value is undefined on the propagation context, the SDK will generate a random span ID for `trace` contexts and trace propagation.
final SpanId spanId = SpanId.newId();

/// The dynamic sampling context.
SentryBaggage? baggage;

Expand All @@ -20,5 +15,6 @@ class PropagationContext {
baggage != null ? SentryBaggageHeader.fromBaggage(baggage!) : null;

/// Sentry trace header to attach to http headers.
SentryTraceHeader toSentryTrace() => SentryTraceHeader(traceId, spanId);
SentryTraceHeader toSentryTrace() =>
generateSentryTraceHeader(traceId: traceId);
}
6 changes: 3 additions & 3 deletions dart/lib/src/protocol/sentry_span.dart
Original file line number Diff line number Diff line change
Expand Up @@ -213,9 +213,9 @@ class SentrySpan extends ISentrySpan {
Map<String, dynamic> get data => _data;

@override
SentryTraceHeader toSentryTrace() => SentryTraceHeader(
_context.traceId,
_context.spanId,
SentryTraceHeader toSentryTrace() => generateSentryTraceHeader(
traceId: _context.traceId,
spanId: _context.spanId,
sampled: samplingDecision?.sampled,
);

Expand Down
2 changes: 1 addition & 1 deletion dart/lib/src/protocol/sentry_trace_context.dart
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ class SentryTraceContext {
PropagationContext propagationContext) {
return SentryTraceContext(
traceId: propagationContext.traceId,
spanId: propagationContext.spanId,
spanId: SpanId.newId(),
operation: 'default',
replayId: propagationContext.baggage?.getReplayId());
}
Expand Down
27 changes: 0 additions & 27 deletions dart/lib/src/utils/add_tracing_headers_to_http_request.dart

This file was deleted.

39 changes: 39 additions & 0 deletions dart/lib/src/utils/tracing_utils.dart
Original file line number Diff line number Diff line change
@@ -1,5 +1,33 @@
import '../../sentry.dart';

SentryTraceHeader generateSentryTraceHeader(
{SentryId? traceId, SpanId? spanId, bool? sampled}) {
traceId ??= SentryId.newId();
spanId ??= SpanId.newId();
return SentryTraceHeader(traceId, spanId, sampled: sampled);
}

void addTracingHeadersToHttpHeader(Map<String, dynamic> headers, Hub hub,
{ISentrySpan? span}) {
if (span != null) {
addSentryTraceHeaderFromSpan(span, headers);
addBaggageHeaderFromSpan(
span,
headers,
log: hub.options.log,
);
} else {
addSentryTraceHeaderFromScope(hub.scope, headers);
addBaggageHeaderFromScope(hub.scope, headers, log: hub.options.log);
}
}

void addSentryTraceHeaderFromScope(Scope scope, Map<String, dynamic> headers) {
final propagationContext = scope.propagationContext;
final traceHeader = propagationContext.toSentryTrace();
headers[traceHeader.name] = traceHeader.value;
}

void addSentryTraceHeaderFromSpan(
ISentrySpan span, Map<String, dynamic> headers) {
final traceHeader = span.toSentryTrace();
Expand All @@ -11,6 +39,17 @@ void addSentryTraceHeader(
headers[traceHeader.name] = traceHeader.value;
}

void addBaggageHeaderFromScope(
Scope scope,
Map<String, dynamic> headers, {
SdkLogCallback? log,
}) {
final baggageHeader = scope.propagationContext.toBaggageHeader();
if (baggageHeader != null) {
addBaggageHeader(baggageHeader, headers, log: log);
}
}

void addBaggageHeaderFromSpan(
ISentrySpan span,
Map<String, dynamic> headers, {
Expand Down
22 changes: 22 additions & 0 deletions dart/test/http_client/tracing_client_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,28 @@ void main() {
sentryTraceHeader.value);
});

test(
'tracing header from propagation context should generate new span ids for new events',
() async {
fixture._hub.options.tracesSampleRate = null;
fixture._hub.options.tracesSampler = null;
final sut = fixture.getSut(
client: fixture.getClient(statusCode: 200, reason: 'OK'),
);
final propagationContext = fixture._hub.scope.propagationContext;
propagationContext.baggage = SentryBaggage({'foo': 'bar'});

final response1 = await sut.get(requestUri);
final response2 = await sut.get(requestUri);

final traceHeader1 = SentryTraceHeader.fromTraceHeader(
response1.request!.headers['sentry-trace']!);
final traceHeader2 = SentryTraceHeader.fromTraceHeader(
response2.request!.headers['sentry-trace']!);

expect(traceHeader1.spanId, isNot(traceHeader2.spanId));
});

test(
'should not add tracing headers when URL does not match tracePropagationTargets with tracing enabled',
() async {
Expand Down
25 changes: 23 additions & 2 deletions dart/test/scope_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -463,13 +463,34 @@ void main() {
true);
});

test('apply trace context to event', () async {
test('apply trace context to event with active span', () async {
final event = SentryEvent();
final scope = Scope(defaultTestOptions())..span = fixture.sentryTracer;

final updatedEvent = await scope.applyToEvent(event, Hint());

expect(updatedEvent?.contexts['trace'] is SentryTraceContext, true);
expect(updatedEvent?.contexts['trace'] is SentryTraceContext, isTrue);
});

test('apply trace context to event with propagation context', () async {
final event = SentryEvent();
final event2 = SentryEvent();
final scope = Scope(defaultTestOptions());

final updatedEvent = await scope.applyToEvent(event, Hint());

final traceContext =
updatedEvent?.contexts['trace'] as SentryTraceContext;
final spanId1 = traceContext.spanId;
expect(traceContext.traceId, scope.propagationContext.traceId);

final updatedEvent2 = await scope.applyToEvent(event2, Hint());
final traceContext2 =
updatedEvent2?.contexts['trace'] as SentryTraceContext;
final spanId2 = traceContext2.spanId;

// trace contexts from the scope should always re-generate span ids
expect(spanId1, isNot(spanId2));
});

test('should not apply the scope properties when event already has it ',
Expand Down
Loading
Loading