Skip to content

Commit 9273afa

Browse files
committed
feat(node): Ensure tracing without performance (TWP) works
TODO....
1 parent 38b0dae commit 9273afa

File tree

6 files changed

+180
-7
lines changed

6 files changed

+180
-7
lines changed

dev-packages/node-integration-tests/suites/tracing/tracePropagationTargets/test.ts

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,18 @@ import { createRunner } from '../../../utils/runner';
22
import { createTestServer } from '../../../utils/server';
33

44
test('HttpIntegration should instrument correct requests when tracePropagationTargets option is provided', done => {
5-
expect.assertions(9);
5+
expect.assertions(11);
66

77
createTestServer(done)
88
.get('/api/v0', headers => {
9-
expect(typeof headers['baggage']).toBe('string');
10-
expect(typeof headers['sentry-trace']).toBe('string');
9+
expect(headers['baggage']).toEqual(expect.any(String));
10+
expect(headers['sentry-trace']).toEqual(expect.stringMatching(/^([a-f0-9]{32})-([a-f0-9]{16})-1$/));
11+
expect(headers['sentry-trace']).not.toEqual('00000000000000000000000000000000-0000000000000000-1');
1112
})
1213
.get('/api/v1', headers => {
13-
expect(typeof headers['baggage']).toBe('string');
14-
expect(typeof headers['sentry-trace']).toBe('string');
14+
expect(headers['baggage']).toEqual(expect.any(String));
15+
expect(headers['sentry-trace']).toEqual(expect.stringMatching(/^([a-f0-9]{32})-([a-f0-9]{16})-1$/));
16+
expect(headers['sentry-trace']).not.toEqual('00000000000000000000000000000000-0000000000000000-1');
1517
})
1618
.get('/api/v2', headers => {
1719
expect(headers['baggage']).toBeUndefined();
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
import { loggingTransport } from '@sentry-internal/node-integration-tests';
2+
import * as Sentry from '@sentry/node';
3+
4+
Sentry.init({
5+
dsn: 'https://public@dsn.ingest.sentry.io/1337',
6+
release: '1.0',
7+
tracePropagationTargets: [/\/v0/, 'v1'],
8+
integrations: [],
9+
transport: loggingTransport,
10+
});
11+
12+
import * as http from 'http';
13+
14+
async function run(): Promise<void> {
15+
await makeHttpRequest(`${process.env.SERVER_URL}/api/v0`);
16+
await makeHttpRequest(`${process.env.SERVER_URL}/api/v1`);
17+
await makeHttpRequest(`${process.env.SERVER_URL}/api/v2`);
18+
await makeHttpRequest(`${process.env.SERVER_URL}/api/v3`);
19+
20+
Sentry.captureException(new Error('foo'));
21+
}
22+
23+
// eslint-disable-next-line @typescript-eslint/no-floating-promises
24+
run();
25+
26+
function makeHttpRequest(url: string): Promise<void> {
27+
return new Promise<void>(resolve => {
28+
http
29+
.request(url, httpRes => {
30+
httpRes.on('data', () => {
31+
// we don't care about data
32+
});
33+
httpRes.on('end', () => {
34+
resolve();
35+
});
36+
})
37+
.end();
38+
});
39+
}
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
import { createRunner } from '../../../utils/runner';
2+
import { createTestServer } from '../../../utils/server';
3+
4+
test('HttpIntegration should instrument correct requests even without tracesSampleRate xxx', done => {
5+
expect.assertions(11);
6+
7+
createTestServer(done)
8+
.get('/api/v0', headers => {
9+
expect(headers['baggage']).toBeUndefined();
10+
expect(headers['sentry-trace']).toEqual(expect.stringMatching(/^([a-f0-9]{32})-([a-f0-9]{16})$/));
11+
expect(headers['sentry-trace']).not.toEqual('00000000000000000000000000000000-0000000000000000');
12+
})
13+
.get('/api/v1', headers => {
14+
expect(headers['baggage']).toBeUndefined();
15+
expect(headers['sentry-trace']).toEqual(expect.stringMatching(/^([a-f0-9]{32})-([a-f0-9]{16})$/));
16+
expect(headers['sentry-trace']).not.toEqual('00000000000000000000000000000000-0000000000000000');
17+
})
18+
.get('/api/v2', headers => {
19+
expect(headers['baggage']).toBeUndefined();
20+
expect(headers['sentry-trace']).toBeUndefined();
21+
})
22+
.get('/api/v3', headers => {
23+
expect(headers['baggage']).toBeUndefined();
24+
expect(headers['sentry-trace']).toBeUndefined();
25+
})
26+
.start()
27+
.then(SERVER_URL => {
28+
createRunner(__dirname, 'scenario.ts')
29+
.withEnv({ SERVER_URL })
30+
.ensureNoErrorOutput()
31+
.ignore('session', 'sessions')
32+
.expect({
33+
event: {
34+
exception: {
35+
values: [
36+
{
37+
type: 'Error',
38+
value: 'foo',
39+
},
40+
],
41+
},
42+
},
43+
})
44+
.start(done);
45+
});
46+
});
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
import { loggingTransport } from '@sentry-internal/node-integration-tests';
2+
import * as Sentry from '@sentry/node';
3+
4+
Sentry.init({
5+
dsn: 'https://public@dsn.ingest.sentry.io/1337',
6+
release: '1.0',
7+
tracePropagationTargets: [/\/v0/, 'v1'],
8+
tracesSampleRate: 0,
9+
integrations: [],
10+
transport: loggingTransport,
11+
});
12+
13+
import * as http from 'http';
14+
15+
async function run(): Promise<void> {
16+
await makeHttpRequest(`${process.env.SERVER_URL}/api/v0`);
17+
await makeHttpRequest(`${process.env.SERVER_URL}/api/v1`);
18+
await makeHttpRequest(`${process.env.SERVER_URL}/api/v2`);
19+
await makeHttpRequest(`${process.env.SERVER_URL}/api/v3`);
20+
21+
Sentry.captureException(new Error('foo'));
22+
}
23+
24+
// eslint-disable-next-line @typescript-eslint/no-floating-promises
25+
run();
26+
27+
function makeHttpRequest(url: string): Promise<void> {
28+
return new Promise<void>(resolve => {
29+
http
30+
.request(url, httpRes => {
31+
httpRes.on('data', () => {
32+
// we don't care about data
33+
});
34+
httpRes.on('end', () => {
35+
resolve();
36+
});
37+
})
38+
.end();
39+
});
40+
}
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
import { createRunner } from '../../../utils/runner';
2+
import { createTestServer } from '../../../utils/server';
3+
4+
test('HttpIntegration should instrument correct requests even when not sampled', done => {
5+
expect.assertions(11);
6+
7+
createTestServer(done)
8+
.get('/api/v0', headers => {
9+
expect(headers['baggage']).toBeUndefined();
10+
expect(headers['sentry-trace']).toEqual(expect.stringMatching(/^([a-f0-9]{32})-([a-f0-9]{16})-0$/));
11+
expect(headers['sentry-trace']).not.toEqual('00000000000000000000000000000000-0000000000000000-0');
12+
})
13+
.get('/api/v1', headers => {
14+
expect(headers['baggage']).toBeUndefined();
15+
expect(headers['sentry-trace']).toEqual(expect.stringMatching(/^([a-f0-9]{32})-([a-f0-9]{16})-0$/));
16+
expect(headers['sentry-trace']).not.toEqual('00000000000000000000000000000000-0000000000000000-0');
17+
})
18+
.get('/api/v2', headers => {
19+
expect(headers['baggage']).toBeUndefined();
20+
expect(headers['sentry-trace']).toBeUndefined();
21+
})
22+
.get('/api/v3', headers => {
23+
expect(headers['baggage']).toBeUndefined();
24+
expect(headers['sentry-trace']).toBeUndefined();
25+
})
26+
.start()
27+
.then(SERVER_URL => {
28+
createRunner(__dirname, 'scenario.ts')
29+
.withEnv({ SERVER_URL })
30+
.ignore('session', 'sessions')
31+
.expect({
32+
event: {
33+
exception: {
34+
values: [
35+
{
36+
type: 'Error',
37+
value: 'foo',
38+
},
39+
],
40+
},
41+
},
42+
})
43+
.start(done);
44+
});
45+
});

packages/opentelemetry/src/propagator.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import { context } from '@opentelemetry/api';
33
import { TraceFlags, propagation, trace } from '@opentelemetry/api';
44
import { TraceState, W3CBaggagePropagator, isTracingSuppressed } from '@opentelemetry/core';
55
import { SemanticAttributes } from '@opentelemetry/semantic-conventions';
6-
import type { continueTrace } from '@sentry/core';
6+
import { continueTrace, hasTracingEnabled } from '@sentry/core';
77
import { getRootSpan } from '@sentry/core';
88
import { spanToJSON } from '@sentry/core';
99
import { getClient, getCurrentScope, getDynamicSamplingContextFromClient, getIsolationScope } from '@sentry/core';
@@ -212,7 +212,7 @@ function getInjectionData(context: Context): {
212212
spanId: string | undefined;
213213
sampled: boolean | undefined;
214214
} {
215-
const span = trace.getSpan(context);
215+
const span = hasTracingEnabled() ? trace.getSpan(context) : undefined;
216216
const spanIsRemote = span?.spanContext().isRemote;
217217

218218
// If we have a local span, we can just pick everything from it
@@ -231,6 +231,7 @@ function getInjectionData(context: Context): {
231231

232232
// Else we try to use the propagation context from the scope
233233
const scope = getScopesFromContext(context)?.scope;
234+
234235
if (scope) {
235236
const propagationContext = scope.getPropagationContext();
236237
const dynamicSamplingContext = getDynamicSamplingContext(propagationContext, propagationContext.traceId);

0 commit comments

Comments
 (0)