Skip to content

Commit c38d1f4

Browse files
committed
feat(node): Populate propagation context using env variables
1 parent cdc93d6 commit c38d1f4

File tree

2 files changed

+84
-3
lines changed

2 files changed

+84
-3
lines changed

packages/node/src/sdk.ts

Lines changed: 41 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,16 @@ import {
66
initAndBind,
77
Integrations as CoreIntegrations,
88
} from '@sentry/core';
9-
import type { SessionStatus, StackParser } from '@sentry/types';
9+
import type { DynamicSamplingContext, PropagationContext, SessionStatus, StackParser } from '@sentry/types';
1010
import {
11+
baggageHeaderToDynamicSamplingContext,
1112
createStackParser,
13+
extractTraceparentData,
1214
GLOBAL_OBJ,
1315
logger,
1416
nodeStackLineParser,
1517
stackParserFromStackParserOptions,
18+
uuid4,
1619
} from '@sentry/utils';
1720

1821
import { setNodeAsyncContextStrategy } from './async';
@@ -129,8 +132,9 @@ export function init(options: NodeOptions = {}): void {
129132
options.dsn = process.env.SENTRY_DSN;
130133
}
131134

132-
if (options.tracesSampleRate === undefined && process.env.SENTRY_TRACES_SAMPLE_RATE) {
133-
const tracesSampleRate = parseFloat(process.env.SENTRY_TRACES_SAMPLE_RATE);
135+
const sentryTracesSampleRate = process.env.SENTRY_TRACES_SAMPLE_RATE;
136+
if (options.tracesSampleRate === undefined && sentryTracesSampleRate) {
137+
const tracesSampleRate = parseFloat(sentryTracesSampleRate);
134138
if (isFinite(tracesSampleRate)) {
135139
options.tracesSampleRate = tracesSampleRate;
136140
}
@@ -171,6 +175,8 @@ export function init(options: NodeOptions = {}): void {
171175
if (options.autoSessionTracking) {
172176
startSessionTracking();
173177
}
178+
179+
updateScopeFromEnvVariables();
174180
}
175181

176182
/**
@@ -285,3 +291,35 @@ function startSessionTracking(): void {
285291
if (session && !terminalStates.includes(session.status)) hub.endSession();
286292
});
287293
}
294+
295+
/**
296+
* Update scope and propagation context based on environmental variables.
297+
*
298+
* See https://github.com/getsentry/rfcs/blob/main/text/0071-continue-trace-over-process-boundaries.md
299+
* for more details.
300+
*/
301+
function updateScopeFromEnvVariables(): void {
302+
const sentryUseEnvironment = process.env.SENTRY_USE_ENVIRONMENT;
303+
if (
304+
!['false', 'False', 'FALSE', 'n', 'no', 'No', 'NO', 'off', 'Off', 'OFF', '0'].includes(
305+
sentryUseEnvironment as string,
306+
)
307+
) {
308+
const sentryTraceEnv = process.env.SENTRY_TRACE || '';
309+
const baggageEnv = process.env.SENTRY_BAGGAGE;
310+
311+
const traceparentData = extractTraceparentData(sentryTraceEnv) || {};
312+
const { traceId, parentSpanId, parentSampled } = traceparentData;
313+
const propagationContext: PropagationContext = {
314+
traceId: traceId || uuid4(),
315+
spanId: uuid4().substring(16),
316+
parentSpanId,
317+
sampled: parentSampled === undefined ? false : parentSampled,
318+
};
319+
const dynamicSamplingContext = baggageHeaderToDynamicSamplingContext(baggageEnv);
320+
if (dynamicSamplingContext) {
321+
propagationContext.dsc = dynamicSamplingContext as DynamicSamplingContext;
322+
}
323+
getCurrentHub().getScope().setPropagationContext(propagationContext);
324+
}
325+
}

packages/node/test/index.test.ts

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -488,4 +488,47 @@ describe('SentryNode initialization', () => {
488488
expect(instrumenter).toEqual('otel');
489489
});
490490
});
491+
492+
describe('propagation context', () => {
493+
beforeEach(() => {
494+
process.env.SENTRY_TRACE = '12312012123120121231201212312012-1121201211212012-0';
495+
process.env.SENTRY_BAGGAGE = 'sentry-release=1.0.0,sentry-environment=production';
496+
497+
getCurrentHub().getScope().clear();
498+
});
499+
500+
afterEach(() => {
501+
delete process.env.SENTRY_TRACE;
502+
delete process.env.SENTRY_BAGGAGE;
503+
});
504+
505+
it('reads from environmental variables', () => {
506+
init({ dsn });
507+
508+
// @ts-expect-error accessing private method for test
509+
expect(getCurrentHub().getScope()._propagationContext).toEqual({
510+
traceId: '12312012123120121231201212312012',
511+
parentSpanId: '1121201211212012',
512+
spanId: expect.any(String),
513+
sampled: false,
514+
dsc: {
515+
release: '1.0.0',
516+
environment: 'production',
517+
},
518+
});
519+
});
520+
521+
it.each(['false', 'False', 'FALSE', 'n', 'no', 'No', 'NO', 'off', 'Off', 'OFF', '0'])(
522+
'does not read from environmental variable if SENTRY_USE_ENVIRONMENT is set to %s',
523+
useEnvValue => {
524+
process.env.SENTRY_USE_ENVIRONMENT = useEnvValue;
525+
init({ dsn });
526+
527+
// @ts-expect-error accessing private method for test
528+
expect(getCurrentHub().getScope()._propagationContext.traceId).not.toEqual('12312012123120121231201212312012');
529+
530+
delete process.env.SENTRY_USE_ENVIRONMENT;
531+
},
532+
);
533+
});
491534
});

0 commit comments

Comments
 (0)