Skip to content

Commit 14f0b6e

Browse files
authored
fix(opentelemetry): Always use active span in Propagator.inject (#13381)
This PR removes the check for `hasTracingEnabled` in `getInjectionData` and simply always takes the non-recording span if there is one. Which is always the case in server applications when handling a request. For non-request-handling situations, we fall back anyway to the propagation context.
1 parent 479aa11 commit 14f0b6e

File tree

4 files changed

+103
-2
lines changed

4 files changed

+103
-2
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
const { loggingTransport } = require('@sentry-internal/node-integration-tests');
2+
const Sentry = require('@sentry/node');
3+
4+
Sentry.init({
5+
dsn: 'https://[email protected]/1337',
6+
release: '1.0',
7+
transport: loggingTransport,
8+
beforeSend(event) {
9+
event.contexts = {
10+
...event.contexts,
11+
traceData: {
12+
...Sentry.getTraceData(),
13+
metaTags: Sentry.getTraceMetaTags(),
14+
},
15+
};
16+
return event;
17+
},
18+
});
19+
20+
Sentry.captureException(new Error('test error'));
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
const { loggingTransport, startExpressServerAndSendPortToRunner } = require('@sentry-internal/node-integration-tests');
2+
const Sentry = require('@sentry/node');
3+
4+
Sentry.init({
5+
dsn: 'https://[email protected]/1337',
6+
transport: loggingTransport,
7+
beforeSend(event) {
8+
event.contexts = {
9+
...event.contexts,
10+
traceData: {
11+
...Sentry.getTraceData(),
12+
metaTags: Sentry.getTraceMetaTags(),
13+
},
14+
};
15+
return event;
16+
},
17+
});
18+
19+
// express must be required after Sentry is initialized
20+
const express = require('express');
21+
22+
const app = express();
23+
24+
app.get('/test', () => {
25+
throw new Error('test error');
26+
});
27+
28+
Sentry.setupExpressErrorHandler(app);
29+
30+
startExpressServerAndSendPortToRunner(app);
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
import { cleanupChildProcesses, createRunner } from '../../../utils/runner';
2+
3+
describe('errors in TwP mode have same trace in trace context and getTraceData()', () => {
4+
afterAll(() => {
5+
cleanupChildProcesses();
6+
});
7+
8+
test('in incoming request', async () => {
9+
createRunner(__dirname, 'server.js')
10+
.expect({
11+
event: event => {
12+
const { contexts } = event;
13+
const { trace_id, span_id } = contexts?.trace || {};
14+
expect(trace_id).toMatch(/^[a-f0-9]{32}$/);
15+
expect(span_id).toMatch(/^[a-f0-9]{16}$/);
16+
17+
const traceData = contexts?.traceData || {};
18+
19+
expect(traceData['sentry-trace']).toEqual(`${trace_id}-${span_id}`);
20+
expect(traceData.baggage).toContain(`sentry-trace_id=${trace_id}`);
21+
22+
expect(traceData.metaTags).toContain(`<meta name="sentry-trace" content="${trace_id}-${span_id}"/>`);
23+
expect(traceData.metaTags).toContain(`sentr y-trace_id=${trace_id}`);
24+
expect(traceData.metaTags).not.toContain('sentry-sampled=');
25+
},
26+
})
27+
.start()
28+
.makeRequest('get', '/test');
29+
});
30+
31+
test('outside of a request handler', done => {
32+
createRunner(__dirname, 'no-server.js')
33+
.expect({
34+
event: event => {
35+
const { contexts } = event;
36+
const { trace_id, span_id } = contexts?.trace || {};
37+
expect(trace_id).toMatch(/^[a-f0-9]{32}$/);
38+
expect(span_id).toMatch(/^[a-f0-9]{16}$/);
39+
40+
const traceData = contexts?.traceData || {};
41+
42+
expect(traceData['sentry-trace']).toEqual(`${trace_id}-${span_id}`);
43+
expect(traceData.baggage).toContain(`sentry-trace_id=${trace_id}`);
44+
45+
expect(traceData.metaTags).toContain(`<meta name="sentry-trace" content="${trace_id}-${span_id}"/>`);
46+
expect(traceData.metaTags).toContain(`sentry-trace_id=${trace_id}`);
47+
expect(traceData.metaTags).not.toContain('sentry-sampled=');
48+
},
49+
})
50+
.start(done);
51+
});
52+
});

packages/opentelemetry/src/propagator.ts

+1-2
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ import { propagation, trace } from '@opentelemetry/api';
55
import { W3CBaggagePropagator, isTracingSuppressed } from '@opentelemetry/core';
66
import { ATTR_URL_FULL, SEMATTRS_HTTP_URL } from '@opentelemetry/semantic-conventions';
77
import type { continueTrace } from '@sentry/core';
8-
import { hasTracingEnabled } from '@sentry/core';
98
import { getRootSpan } from '@sentry/core';
109
import { spanToJSON } from '@sentry/core';
1110
import {
@@ -198,7 +197,7 @@ function getInjectionData(context: Context): {
198197
spanId: string | undefined;
199198
sampled: boolean | undefined;
200199
} {
201-
const span = hasTracingEnabled() ? trace.getSpan(context) : undefined;
200+
const span = trace.getSpan(context);
202201
const spanIsRemote = span?.spanContext().isRemote;
203202

204203
// If we have a local span, we can just pick everything from it

0 commit comments

Comments
 (0)