Skip to content

Commit 37b6ca2

Browse files
author
Luca Forstner
committed
beep boop actually do what I am supposed to beep boop
1 parent 52ea3d2 commit 37b6ca2

File tree

5 files changed

+39
-9
lines changed

5 files changed

+39
-9
lines changed

packages/core/src/semanticAttributes.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,11 @@ export const SEMANTIC_ATTRIBUTE_SENTRY_SOURCE = 'sentry.source';
1212
*/
1313
export const SEMANTIC_ATTRIBUTE_SENTRY_SAMPLE_RATE = 'sentry.sample_rate';
1414

15+
/**
16+
* Use this attribute on a root span to propagate the spans sample rate downstream as parent sample rate in the DSC, overriding anything that was previously set on the DSC.
17+
*/
18+
export const SEMANTIC_ATTRIBUTE_SENTRY_OVERRIDE_TRACE_SAMPLE_RATE = 'sentry.override_trace_sample_rate';
19+
1520
/**
1621
* Use this attribute to represent the operation of a span.
1722
*/

packages/core/src/tracing/dynamicSamplingContext.ts

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,11 @@ import type { Client } from '../client';
22
import { DEFAULT_ENVIRONMENT } from '../constants';
33
import { getClient } from '../currentScopes';
44
import type { Scope } from '../scope';
5-
import { SEMANTIC_ATTRIBUTE_SENTRY_SAMPLE_RATE, SEMANTIC_ATTRIBUTE_SENTRY_SOURCE } from '../semanticAttributes';
5+
import {
6+
SEMANTIC_ATTRIBUTE_SENTRY_OVERRIDE_TRACE_SAMPLE_RATE,
7+
SEMANTIC_ATTRIBUTE_SENTRY_SAMPLE_RATE,
8+
SEMANTIC_ATTRIBUTE_SENTRY_SOURCE,
9+
} from '../semanticAttributes';
610
import type { DynamicSamplingContext, Span } from '../types-hoist';
711
import {
812
baggageHeaderToDynamicSamplingContext,
@@ -77,12 +81,14 @@ export function getDynamicSamplingContextFromSpan(span: Span): Readonly<Partial<
7781
const rootSpan = getRootSpan(span);
7882
const rootSpanJson = spanToJSON(rootSpan);
7983
const rootSpanAttributes = rootSpanJson.data;
84+
const shouldOverrideDscSampleRate = rootSpanAttributes[SEMANTIC_ATTRIBUTE_SENTRY_OVERRIDE_TRACE_SAMPLE_RATE];
8085
const maybeSampleRate = rootSpanAttributes[SEMANTIC_ATTRIBUTE_SENTRY_SAMPLE_RATE];
8186

8287
// The root span sample rate should always be applied to the DSC, even if the DSC is frozen.
8388
// This is so that the downstream traces/services can use parentSampleRate in their `tracesSampler` to make consistent sampling decisions across the entire trace.
8489
function applyRootSpanSampleRateToDsc(dsc: Partial<DynamicSamplingContext>): Partial<DynamicSamplingContext> {
85-
if (maybeSampleRate != null) {
90+
// Note: This is a `!= null` check meaning "nullish"
91+
if (shouldOverrideDscSampleRate && maybeSampleRate != null) {
8692
dsc.sample_rate = `${maybeSampleRate}`;
8793
}
8894
return dsc;
@@ -108,6 +114,11 @@ export function getDynamicSamplingContextFromSpan(span: Span): Readonly<Partial<
108114
// Else, we generate it from the span
109115
const dsc = getDynamicSamplingContextFromClient(span.spanContext().traceId, client);
110116

117+
// Note: This is a `!= null` check meaning "nullish"
118+
if (maybeSampleRate != null) {
119+
dsc.sample_rate = `${maybeSampleRate}`;
120+
}
121+
111122
// We don't want to have a transaction name in the DSC if the source is "url" because URLs might contain PII
112123
const source = rootSpanAttributes[SEMANTIC_ATTRIBUTE_SENTRY_SOURCE];
113124

packages/core/src/tracing/sampling.ts

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,24 +15,29 @@ export function sampleSpan(
1515
options: Pick<Options, 'tracesSampleRate' | 'tracesSampler' | 'enableTracing'>,
1616
samplingContext: SamplingContext,
1717
sampleRand: number,
18-
): [sampled: boolean, sampleRate?: number] {
18+
): [sampled: boolean, sampleRate?: number, shouldUpdateSampleRateOnDsc?: boolean] {
1919
// nothing to do if tracing is not enabled
2020
if (!hasTracingEnabled(options)) {
2121
return [false];
2222
}
2323

24+
let shouldUpdateSampleRateOnDsc = false;
25+
2426
// we would have bailed already if neither `tracesSampler` nor `tracesSampleRate` nor `enableTracing` were defined, so one of these should
2527
// work; prefer the hook if so
2628
let sampleRate;
2729
if (typeof options.tracesSampler === 'function') {
2830
sampleRate = options.tracesSampler(samplingContext);
31+
shouldUpdateSampleRateOnDsc = true;
2932
} else if (samplingContext.parentSampled !== undefined) {
3033
sampleRate = samplingContext.parentSampled;
3134
} else if (typeof options.tracesSampleRate !== 'undefined') {
3235
sampleRate = options.tracesSampleRate;
36+
shouldUpdateSampleRateOnDsc = true;
3337
} else {
3438
// When `enableTracing === true`, we use a sample rate of 100%
3539
sampleRate = 1;
40+
shouldUpdateSampleRateOnDsc = true;
3641
}
3742

3843
// Since this is coming from the user (or from a function provided by the user), who knows what we might get.
@@ -54,7 +59,7 @@ export function sampleSpan(
5459
: 'a negative sampling decision was inherited or tracesSampleRate is set to 0'
5560
}`,
5661
);
57-
return [false, parsedSampleRate];
62+
return [false, parsedSampleRate, shouldUpdateSampleRateOnDsc];
5863
}
5964

6065
// Now we roll the dice. Math.random is inclusive of 0, but not of 1, so strict < is safe here. In case sampleRate is
@@ -69,8 +74,8 @@ export function sampleSpan(
6974
sampleRate,
7075
)})`,
7176
);
72-
return [false, parsedSampleRate];
77+
return [false, parsedSampleRate, shouldUpdateSampleRateOnDsc];
7378
}
7479

75-
return [true, parsedSampleRate];
80+
return [true, parsedSampleRate, shouldUpdateSampleRateOnDsc];
7681
}

packages/core/src/tracing/trace.ts

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,11 @@ import { getClient, getCurrentScope, getIsolationScope, withScope } from '../cur
1616
import { getAsyncContextStrategy } from '../asyncContext';
1717
import { DEBUG_BUILD } from '../debug-build';
1818
import type { Scope } from '../scope';
19-
import { SEMANTIC_ATTRIBUTE_SENTRY_SAMPLE_RATE, SEMANTIC_ATTRIBUTE_SENTRY_SOURCE } from '../semanticAttributes';
19+
import {
20+
SEMANTIC_ATTRIBUTE_SENTRY_OVERRIDE_TRACE_SAMPLE_RATE,
21+
SEMANTIC_ATTRIBUTE_SENTRY_SAMPLE_RATE,
22+
SEMANTIC_ATTRIBUTE_SENTRY_SOURCE,
23+
} from '../semanticAttributes';
2024
import { logger } from '../utils-hoist/logger';
2125
import { generateTraceId } from '../utils-hoist/propagationContext';
2226
import { propagationContextFromHeaders } from '../utils-hoist/tracing';
@@ -407,7 +411,9 @@ function _startRootSpan(spanArguments: SentrySpanArguments, scope: Scope, parent
407411

408412
const { name = '', attributes } = spanArguments;
409413
const currentPropagationContext = scope.getPropagationContext();
410-
const [sampled, sampleRate] = scope.getScopeData().sdkProcessingMetadata[SUPPRESS_TRACING_KEY]
414+
const [sampled, sampleRate, shouldUpdateSampleRateOnDsc] = scope.getScopeData().sdkProcessingMetadata[
415+
SUPPRESS_TRACING_KEY
416+
]
411417
? [false]
412418
: sampleSpan(
413419
options,
@@ -436,6 +442,7 @@ function _startRootSpan(spanArguments: SentrySpanArguments, scope: Scope, parent
436442

437443
if (sampleRate !== undefined) {
438444
rootSpan.setAttribute(SEMANTIC_ATTRIBUTE_SENTRY_SAMPLE_RATE, sampleRate);
445+
rootSpan.setAttribute(SEMANTIC_ATTRIBUTE_SENTRY_OVERRIDE_TRACE_SAMPLE_RATE, shouldUpdateSampleRateOnDsc);
439446
}
440447

441448
if (client) {

packages/opentelemetry/src/sampler.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import {
1313
import type { Client, SpanAttributes } from '@sentry/core';
1414
import {
1515
SEMANTIC_ATTRIBUTE_SENTRY_OP,
16+
SEMANTIC_ATTRIBUTE_SENTRY_OVERRIDE_TRACE_SAMPLE_RATE,
1617
SEMANTIC_ATTRIBUTE_SENTRY_SAMPLE_RATE,
1718
hasTracingEnabled,
1819
logger,
@@ -106,7 +107,7 @@ export class SentrySampler implements Sampler {
106107
// Non-root-spans simply inherit the sampling decision from their parent.
107108
if (isRootSpan) {
108109
const currentPropagationContext = scope?.getPropagationContext();
109-
const [sampled, sampleRate] = sampleSpan(
110+
const [sampled, sampleRate, shouldUpdateSampleRateOnDsc] = sampleSpan(
110111
options,
111112
{
112113
name: inferredSpanName,
@@ -120,6 +121,7 @@ export class SentrySampler implements Sampler {
120121

121122
const attributes: Attributes = {
122123
[SEMANTIC_ATTRIBUTE_SENTRY_SAMPLE_RATE]: sampleRate,
124+
[SEMANTIC_ATTRIBUTE_SENTRY_OVERRIDE_TRACE_SAMPLE_RATE]: shouldUpdateSampleRateOnDsc,
123125
};
124126

125127
const method = `${maybeSpanHttpMethod}`.toUpperCase();

0 commit comments

Comments
 (0)