Skip to content

Commit e63a037

Browse files
committed
don't emit ignored outcome on suppressed and ignored span
1 parent dc7b16b commit e63a037

File tree

3 files changed

+61
-13
lines changed

3 files changed

+61
-13
lines changed

.size-limit.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -255,7 +255,7 @@ module.exports = [
255255
path: createCDNPath('bundle.tracing.logs.metrics.min.js'),
256256
gzip: false,
257257
brotli: false,
258-
limit: '133 KB',
258+
limit: '134 KB',
259259
},
260260
{
261261
name: 'CDN Bundle (incl. Replay, Logs, Metrics) - uncompressed',

packages/core/src/tracing/trace.ts

Lines changed: 22 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -212,7 +212,7 @@ export function startInactiveSpan(options: StartSpanOptions): Span {
212212
if (_shouldIgnoreStreamedSpan(client, spanArguments)) {
213213
// purposefully not passing in the scope here because we don't want to set an
214214
// inactive span onto the scope (no exception for ignored spans)
215-
return _createIgnoredSpan(client, parentSpan);
215+
return _createIgnoredSpan(client, parentSpan, scope, false);
216216
}
217217

218218
const shouldSkipSpan = options.onlyIfParent && !parentSpan;
@@ -469,9 +469,9 @@ function _startRootSpan(spanArguments: SentrySpanArguments, scope: Scope, parent
469469
const finalAttributes = mutableSpanSamplingData.spanAttributes;
470470

471471
const currentPropagationContext = scope.getPropagationContext();
472-
const [sampled, sampleRate, localSampleRateWasApplied] = scope.getScopeData().sdkProcessingMetadata[
473-
SUPPRESS_TRACING_KEY
474-
]
472+
const isTracingSuppressed = _isTracingSuppressed(scope);
473+
474+
const [sampled, sampleRate, localSampleRateWasApplied] = isTracingSuppressed
475475
? [false]
476476
: sampleSpan(
477477
options,
@@ -495,7 +495,7 @@ function _startRootSpan(spanArguments: SentrySpanArguments, scope: Scope, parent
495495
sampled,
496496
});
497497

498-
if (!sampled && client && !scope.getScopeData().sdkProcessingMetadata[SUPPRESS_TRACING_KEY]) {
498+
if (!sampled && client && !isTracingSuppressed) {
499499
DEBUG_BUILD && debug.log('[Tracing] Discarding root span because its trace was not chosen to be sampled.');
500500
client.recordDroppedEvent('sample_rate', hasSpanStreamingEnabled(client) ? 'span' : 'transaction');
501501
}
@@ -513,7 +513,8 @@ function _startRootSpan(spanArguments: SentrySpanArguments, scope: Scope, parent
513513
*/
514514
function _startChildSpan(parentSpan: Span, scope: Scope, spanArguments: SentrySpanArguments): Span {
515515
const { spanId, traceId } = parentSpan.spanContext();
516-
const sampled = scope.getScopeData().sdkProcessingMetadata[SUPPRESS_TRACING_KEY] ? false : spanIsSampled(parentSpan);
516+
const isTracingSuppressed = _isTracingSuppressed(scope);
517+
const sampled = isTracingSuppressed ? false : spanIsSampled(parentSpan);
517518

518519
const childSpan = sampled
519520
? new SentrySpan({
@@ -539,7 +540,7 @@ function _startChildSpan(parentSpan: Span, scope: Scope, spanArguments: SentrySp
539540
// record a client outcome for the child.
540541
childSpan.dropReason = parentSpan.dropReason;
541542
client.recordDroppedEvent(parentSpan.dropReason, 'span');
542-
} else if (!scope.getScopeData().sdkProcessingMetadata[SUPPRESS_TRACING_KEY]) {
543+
} else if (!isTracingSuppressed) {
543544
// Otherwise, the child is not sampled due to sampling of the parent span,
544545
// hence we record a sample_rate client outcome for the child.
545546
childSpan.dropReason = 'sample_rate';
@@ -612,17 +613,22 @@ function _shouldIgnoreStreamedSpan(client: Client | undefined, spanArguments: Se
612613
function _createIgnoredSpan(
613614
client: Client | undefined,
614615
parentSpan: SentrySpan | undefined,
615-
scope?: Scope | undefined,
616+
scope: Scope,
617+
setSpanOnScope: boolean = true,
616618
): SentryNonRecordingSpan {
617-
client?.recordDroppedEvent('ignored', 'span');
619+
if (!_isTracingSuppressed(scope)) {
620+
// if someone actively suppressed tracing,
621+
// we don't want to record a client outcome for the ignored span
622+
client?.recordDroppedEvent('ignored', 'span');
623+
}
618624

619625
const nonRecordingSpan = new SentryNonRecordingSpan({
620626
dropReason: 'ignored',
621627
// if there is a parent span, set the traceId of the parent span
622-
traceId: parentSpan?.spanContext().traceId,
628+
traceId: parentSpan?.spanContext().traceId ?? scope.getPropagationContext().traceId,
623629
});
624630

625-
if (scope && !parentSpan) {
631+
if (setSpanOnScope && !parentSpan) {
626632
// Put the ignored non-recording segment span onto the scope so that `getActiveSpan()` returns it
627633
// For child spans, we don't do this because there _is_ an active span on the scope. We can change
628634
// this if necessary.
@@ -632,6 +638,10 @@ function _createIgnoredSpan(
632638
return nonRecordingSpan;
633639
}
634640

635-
function _isIgnoredSpan(span: Span): boolean {
641+
function _isIgnoredSpan(span: Span): span is SentryNonRecordingSpan {
636642
return span instanceof SentryNonRecordingSpan && span.dropReason === 'ignored';
637643
}
644+
645+
function _isTracingSuppressed(scope: Scope): boolean {
646+
return scope.getScopeData().sdkProcessingMetadata[SUPPRESS_TRACING_KEY] === true;
647+
}

packages/core/test/lib/tracing/trace.test.ts

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2739,4 +2739,42 @@ describe('ignoreSpans (core path, streaming)', () => {
27392739

27402740
expect(getActiveSpan()).toBeUndefined();
27412741
});
2742+
2743+
it("doesn't record a client outcome for a suppressed and ignored span", () => {
2744+
const options = getDefaultTestClientOptions({
2745+
tracesSampleRate: 1,
2746+
traceLifecycle: 'stream',
2747+
ignoreSpans: ['ignored'],
2748+
});
2749+
2750+
client = new TestClient(options);
2751+
setCurrentClient(client);
2752+
client.init();
2753+
const spyOnDroppedEvent = vi.spyOn(client, 'recordDroppedEvent');
2754+
2755+
suppressTracing(() => {
2756+
startInactiveSpan({ name: 'ignored-inactive-span' });
2757+
startSpan({ name: 'ignored-active-span' }, () => {});
2758+
startSpanManual({ name: 'ignored-manual-span' }, () => {});
2759+
});
2760+
2761+
expect(spyOnDroppedEvent).not.toHaveBeenCalled();
2762+
});
2763+
2764+
it('sets the propagation context trace on ignored segment spans', () => {
2765+
const options = getDefaultTestClientOptions({
2766+
tracesSampleRate: 1,
2767+
traceLifecycle: 'stream',
2768+
ignoreSpans: ['ignored'],
2769+
});
2770+
client = new TestClient(options);
2771+
setCurrentClient(client);
2772+
client.init();
2773+
2774+
getCurrentScope().setPropagationContext({ traceId: 'abc', propagationSpanId: 'xxx', sampleRand: 0.5 });
2775+
2776+
const span = startInactiveSpan({ name: 'ignored-segment' });
2777+
expect(span.spanContext().traceId).toBe(getCurrentScope().getPropagationContext().traceId);
2778+
expect(span.spanContext().traceId).toBe('abc');
2779+
});
27422780
});

0 commit comments

Comments
 (0)