Skip to content

Commit 6fa3797

Browse files
authored
feat(v8/core): Add normalizedRequest to samplingContext (#14903)
Backport of #14902
1 parent 845b7aa commit 6fa3797

File tree

5 files changed

+76
-6
lines changed

5 files changed

+76
-6
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
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+
tracesSampler: samplingContext => {
9+
// The sampling decision is based on whether the data in `normalizedRequest` is available --> this is what we want to test for
10+
return (
11+
samplingContext.normalizedRequest.url.includes('/test-normalized-request?query=123') &&
12+
samplingContext.normalizedRequest.method &&
13+
samplingContext.normalizedRequest.query_string === 'query=123' &&
14+
!!samplingContext.normalizedRequest.headers
15+
);
16+
},
17+
});
18+
19+
// express must be required after Sentry is initialized
20+
const express = require('express');
21+
const cors = require('cors');
22+
const { startExpressServerAndSendPortToRunner } = require('@sentry-internal/node-integration-tests');
23+
24+
const app = express();
25+
26+
app.use(cors());
27+
28+
app.get('/test-normalized-request', (_req, res) => {
29+
res.send('Success');
30+
});
31+
32+
Sentry.setupExpressErrorHandler(app);
33+
34+
startExpressServerAndSendPortToRunner(app);

dev-packages/node-integration-tests/suites/express/tracing/tracesSampler/server.js

-1
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@ Sentry.init({
1515
samplingContext.attributes['http.method'] === 'GET'
1616
);
1717
},
18-
debug: true,
1918
});
2019

2120
// express must be required after Sentry is initialized

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

+20
Original file line numberDiff line numberDiff line change
@@ -22,3 +22,23 @@ describe('express tracesSampler', () => {
2222
});
2323
});
2424
});
25+
26+
describe('express tracesSampler includes normalizedRequest data', () => {
27+
afterAll(() => {
28+
cleanupChildProcesses();
29+
});
30+
31+
describe('CJS', () => {
32+
test('correctly samples & passes data to tracesSampler', done => {
33+
const runner = createRunner(__dirname, 'scenario-normalizedRequest.js')
34+
.expect({
35+
transaction: {
36+
transaction: 'GET /test-normalized-request',
37+
},
38+
})
39+
.start(done);
40+
41+
runner.makeRequest('get', '/test-normalized-request?query=123');
42+
});
43+
});
44+
});

packages/core/src/tracing/sampling.ts

+14-4
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
1-
import type { Options, SamplingContext } from '../types-hoist';
1+
import type { Options, RequestEventData, SamplingContext } from '../types-hoist';
22

3+
import { getIsolationScope } from '../currentScopes';
34
import { DEBUG_BUILD } from '../debug-build';
45
import { logger } from '../utils-hoist/logger';
56
import { hasTracingEnabled } from '../utils/hasTracingEnabled';
@@ -20,13 +21,22 @@ export function sampleSpan(
2021
return [false];
2122
}
2223

24+
// Casting this from unknown, as the type of `sdkProcessingMetadata` is only changed in v9 and `normalizedRequest` is set in SentryHttpInstrumentation
25+
const normalizedRequest = getIsolationScope().getScopeData().sdkProcessingMetadata
26+
.normalizedRequest as RequestEventData;
27+
28+
const enhancedSamplingContext = {
29+
...samplingContext,
30+
normalizedRequest: samplingContext.normalizedRequest || normalizedRequest,
31+
};
32+
2333
// we would have bailed already if neither `tracesSampler` nor `tracesSampleRate` nor `enableTracing` were defined, so one of these should
2434
// work; prefer the hook if so
2535
let sampleRate;
2636
if (typeof options.tracesSampler === 'function') {
27-
sampleRate = options.tracesSampler(samplingContext);
28-
} else if (samplingContext.parentSampled !== undefined) {
29-
sampleRate = samplingContext.parentSampled;
37+
sampleRate = options.tracesSampler(enhancedSamplingContext);
38+
} else if (enhancedSamplingContext.parentSampled !== undefined) {
39+
sampleRate = enhancedSamplingContext.parentSampled;
3040
} else if (typeof options.tracesSampleRate !== 'undefined') {
3141
sampleRate = options.tracesSampleRate;
3242
} else {

packages/core/src/types-hoist/samplingcontext.ts

+8-1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import type { RequestEventData } from '../types-hoist/request';
12
import type { ExtractedNodeRequestData, WorkerLocation } from './misc';
23
import type { SpanAttributes } from './span';
34

@@ -35,10 +36,16 @@ export interface SamplingContext extends CustomSamplingContext {
3536
location?: WorkerLocation;
3637

3738
/**
38-
* Object representing the incoming request to a node server. Passed by default when using the TracingHandler.
39+
* Object representing the incoming request to a node server.
40+
* @deprecated This attribute is currently never defined and will be removed in v9. Use `normalizedRequest` instead
3941
*/
4042
request?: ExtractedNodeRequestData;
4143

44+
/**
45+
* Object representing the incoming request to a node server in a normalized format.
46+
*/
47+
normalizedRequest?: RequestEventData;
48+
4249
/** The name of the span being sampled. */
4350
name: string;
4451

0 commit comments

Comments
 (0)