Skip to content

Commit a820fa2

Browse files
authored
feat(node): Add incoming request headers as OTel span attributes (#17475)
Extracting incoming request data to span attributes. It's a very long PR but most of it are test edits as the new http attributes are added to existing tests (otherwise, they would fail). Those are the most important changes: - add a function `httpHeadersToSpanAttributes` in core that is used for generating the attributes - adding extra logic in astro, bun, cloudflare, nextjs, remix and sveltekit (custom handler instrumentation) to include the attributes ⚠️ There is one test in Next.js that fails when turbopack is enabled (see [diff snippet](https://github.com/getsentry/sentry-javascript/pull/17475/files#diff-a2882f52b1398a7c6f987463b5d38c375edd391bff5665cb82257e2280c8ffeeR26-R30)). As turbopack for build is still beta (in version v15.5.0), this test is excluded for now. Issue: #17568 Closes #17452
1 parent 3f45ae8 commit a820fa2

File tree

59 files changed

+1020
-13
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

59 files changed

+1020
-13
lines changed

.size-limit.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -233,7 +233,7 @@ module.exports = [
233233
import: createImport('init'),
234234
ignore: [...builtinModules, ...nodePrefixedBuiltinModules],
235235
gzip: true,
236-
limit: '152 KB',
236+
limit: '154 KB',
237237
},
238238
{
239239
name: '@sentry/node - without tracing',

dev-packages/e2e-tests/test-applications/astro-4/tests/tracing.dynamic.test.ts

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,11 @@ test.describe('tracing in dynamically rendered (ssr) routes', () => {
7878
'sentry.sample_rate': 1,
7979
'sentry.source': 'route',
8080
url: expect.stringContaining('/test-ssr'),
81+
'http.request.header.accept': expect.any(String),
82+
'http.request.header.accept_encoding': 'gzip, deflate, br, zstd',
83+
'http.request.header.accept_language': 'en-US',
84+
'http.request.header.sec_fetch_mode': 'navigate',
85+
'http.request.header.user_agent': expect.any(String),
8186
},
8287
op: 'http.server',
8388
origin: 'auto.http.astro',
@@ -223,6 +228,11 @@ test.describe('nested SSR routes (client, server, server request)', () => {
223228
'sentry.origin': 'auto.http.astro',
224229
'sentry.source': 'route',
225230
url: expect.stringContaining('/user-page/myUsername123'),
231+
'http.request.header.accept': expect.any(String),
232+
'http.request.header.accept_encoding': 'gzip, deflate, br, zstd',
233+
'http.request.header.accept_language': 'en-US',
234+
'http.request.header.sec_fetch_mode': 'navigate',
235+
'http.request.header.user_agent': expect.any(String),
226236
},
227237
},
228238
},
@@ -256,6 +266,11 @@ test.describe('nested SSR routes (client, server, server request)', () => {
256266
'sentry.origin': 'auto.http.astro',
257267
'sentry.source': 'route',
258268
url: expect.stringContaining('/api/user/myUsername123.json'),
269+
'http.request.header.accept': expect.any(String),
270+
'http.request.header.accept_encoding': 'gzip, deflate',
271+
'http.request.header.accept_language': '*',
272+
'http.request.header.sec_fetch_mode': 'cors',
273+
'http.request.header.user_agent': expect.any(String),
259274
},
260275
},
261276
},
@@ -308,6 +323,11 @@ test.describe('nested SSR routes (client, server, server request)', () => {
308323
'sentry.origin': 'auto.http.astro',
309324
'sentry.source': 'route',
310325
url: expect.stringContaining('/catchAll/hell0/whatever-do'),
326+
'http.request.header.accept': expect.any(String),
327+
'http.request.header.accept_encoding': 'gzip, deflate, br, zstd',
328+
'http.request.header.accept_language': 'en-US',
329+
'http.request.header.sec_fetch_mode': 'navigate',
330+
'http.request.header.user_agent': expect.any(String),
311331
},
312332
},
313333
},
@@ -360,6 +380,11 @@ test.describe('parametrized vs static paths', () => {
360380
'sentry.origin': 'auto.http.astro',
361381
'sentry.source': 'route',
362382
url: expect.stringContaining('/user-page/settings'),
383+
'http.request.header.accept': expect.any(String),
384+
'http.request.header.accept_encoding': 'gzip, deflate, br, zstd',
385+
'http.request.header.accept_language': 'en-US',
386+
'http.request.header.sec_fetch_mode': 'navigate',
387+
'http.request.header.user_agent': expect.any(String),
363388
},
364389
},
365390
},

dev-packages/e2e-tests/test-applications/astro-5/tests/tracing.dynamic.test.ts

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,11 @@ test.describe('tracing in dynamically rendered (ssr) routes', () => {
7979
'sentry.sample_rate': 1,
8080
'sentry.source': 'route',
8181
url: expect.stringContaining('/test-ssr'),
82+
'http.request.header.accept': expect.any(String),
83+
'http.request.header.accept_encoding': 'gzip, deflate, br, zstd',
84+
'http.request.header.accept_language': 'en-US',
85+
'http.request.header.sec_fetch_mode': 'navigate',
86+
'http.request.header.user_agent': expect.any(String),
8287
},
8388
op: 'http.server',
8489
origin: 'auto.http.astro',
@@ -226,6 +231,11 @@ test.describe('nested SSR routes (client, server, server request)', () => {
226231
'sentry.origin': 'auto.http.astro',
227232
'sentry.source': 'route',
228233
url: expect.stringContaining('/user-page/myUsername123'),
234+
'http.request.header.accept': expect.any(String),
235+
'http.request.header.accept_encoding': 'gzip, deflate, br, zstd',
236+
'http.request.header.accept_language': 'en-US',
237+
'http.request.header.sec_fetch_mode': 'navigate',
238+
'http.request.header.user_agent': expect.any(String),
229239
},
230240
},
231241
},
@@ -259,6 +269,11 @@ test.describe('nested SSR routes (client, server, server request)', () => {
259269
'sentry.origin': 'auto.http.astro',
260270
'sentry.source': 'route',
261271
url: expect.stringContaining('/api/user/myUsername123.json'),
272+
'http.request.header.accept': expect.any(String),
273+
'http.request.header.accept_encoding': 'gzip, deflate',
274+
'http.request.header.accept_language': '*',
275+
'http.request.header.sec_fetch_mode': 'cors',
276+
'http.request.header.user_agent': expect.any(String),
262277
},
263278
},
264279
},
@@ -311,6 +326,11 @@ test.describe('nested SSR routes (client, server, server request)', () => {
311326
'sentry.origin': 'auto.http.astro',
312327
'sentry.source': 'route',
313328
url: expect.stringContaining('/catchAll/hell0/whatever-do'),
329+
'http.request.header.accept': expect.any(String),
330+
'http.request.header.accept_encoding': 'gzip, deflate, br, zstd',
331+
'http.request.header.accept_language': 'en-US',
332+
'http.request.header.sec_fetch_mode': 'navigate',
333+
'http.request.header.user_agent': expect.any(String),
314334
},
315335
},
316336
},
@@ -363,6 +383,11 @@ test.describe('parametrized vs static paths', () => {
363383
'sentry.origin': 'auto.http.astro',
364384
'sentry.source': 'route',
365385
url: expect.stringContaining('/user-page/settings'),
386+
'http.request.header.accept': expect.any(String),
387+
'http.request.header.accept_encoding': 'gzip, deflate, br, zstd',
388+
'http.request.header.accept_language': 'en-US',
389+
'http.request.header.sec_fetch_mode': 'navigate',
390+
'http.request.header.user_agent': expect.any(String),
366391
},
367392
},
368393
},

dev-packages/e2e-tests/test-applications/astro-5/tests/tracing.serverIslands.test.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,11 @@ test.describe('tracing in static routes with server islands', () => {
7070
'sentry.op': 'http.server',
7171
'sentry.origin': 'auto.http.astro',
7272
'sentry.source': 'route',
73+
'http.request.header.accept': expect.any(String),
74+
'http.request.header.accept_encoding': 'gzip, deflate, br, zstd',
75+
'http.request.header.accept_language': 'en-US',
76+
'http.request.header.sec_fetch_mode': 'cors',
77+
'http.request.header.user_agent': expect.any(String),
7378
}),
7479
op: 'http.server',
7580
origin: 'auto.http.astro',

dev-packages/e2e-tests/test-applications/nestjs-11/tests/transactions.test.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,13 @@ test('Sends an API route transaction', async ({ baseURL }) => {
3838
'http.status_code': 200,
3939
'http.status_text': 'OK',
4040
'http.route': '/test-transaction',
41+
'http.request.header.accept': '*/*',
42+
'http.request.header.accept_encoding': 'gzip, deflate',
43+
'http.request.header.accept_language': '*',
44+
'http.request.header.connection': 'keep-alive',
45+
'http.request.header.host': expect.any(String),
46+
'http.request.header.sec_fetch_mode': 'cors',
47+
'http.request.header.user_agent': 'node',
4148
},
4249
op: 'http.server',
4350
span_id: expect.stringMatching(/[a-f0-9]{16}/),

dev-packages/e2e-tests/test-applications/nestjs-8/tests/transactions.test.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,13 @@ test('Sends an API route transaction', async ({ baseURL }) => {
3838
'http.status_code': 200,
3939
'http.status_text': 'OK',
4040
'http.route': '/test-transaction',
41+
'http.request.header.accept': '*/*',
42+
'http.request.header.accept_encoding': 'gzip, deflate',
43+
'http.request.header.accept_language': '*',
44+
'http.request.header.connection': 'keep-alive',
45+
'http.request.header.host': expect.any(String),
46+
'http.request.header.sec_fetch_mode': 'cors',
47+
'http.request.header.user_agent': 'node',
4148
},
4249
op: 'http.server',
4350
span_id: expect.stringMatching(/[a-f0-9]{16}/),

dev-packages/e2e-tests/test-applications/nestjs-basic/tests/transactions.test.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,13 @@ test('Sends an API route transaction', async ({ baseURL }) => {
3838
'http.status_code': 200,
3939
'http.status_text': 'OK',
4040
'http.route': '/test-transaction',
41+
'http.request.header.accept': '*/*',
42+
'http.request.header.accept_encoding': 'gzip, deflate',
43+
'http.request.header.accept_language': '*',
44+
'http.request.header.connection': 'keep-alive',
45+
'http.request.header.host': expect.any(String),
46+
'http.request.header.sec_fetch_mode': 'cors',
47+
'http.request.header.user_agent': 'node',
4148
},
4249
op: 'http.server',
4350
span_id: expect.stringMatching(/[a-f0-9]{16}/),

dev-packages/e2e-tests/test-applications/nestjs-distributed-tracing/tests/propagation.test.ts

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,10 @@ test('Propagates trace for outgoing http requests', async ({ baseURL }) => {
3232

3333
const outgoingHttpSpanId = outgoingHttpSpan?.span_id;
3434

35+
const outgoingHttpSpanData = outgoingHttpSpan?.data || {};
36+
// Outgoing span (`http.client`) does not include headers as attributes
37+
expect(Object.keys(outgoingHttpSpanData).some(key => key.startsWith('http.request.header.'))).toBe(false);
38+
3539
expect(traceId).toEqual(expect.any(String));
3640

3741
// data is passed through from the inbound request, to verify we have the correct headers set
@@ -75,6 +79,13 @@ test('Propagates trace for outgoing http requests', async ({ baseURL }) => {
7579
'http.status_code': 200,
7680
'http.status_text': 'OK',
7781
'http.route': '/test-outgoing-http/:id',
82+
'http.request.header.accept': '*/*',
83+
'http.request.header.accept_encoding': 'gzip, deflate',
84+
'http.request.header.accept_language': '*',
85+
'http.request.header.connection': 'keep-alive',
86+
'http.request.header.host': expect.any(String),
87+
'http.request.header.sec_fetch_mode': 'cors',
88+
'http.request.header.user_agent': 'node',
7889
},
7990
op: 'http.server',
8091
span_id: expect.stringMatching(/[a-f0-9]{16}/),
@@ -106,6 +117,10 @@ test('Propagates trace for outgoing http requests', async ({ baseURL }) => {
106117
'http.status_code': 200,
107118
'http.status_text': 'OK',
108119
'http.route': '/test-inbound-headers/:id',
120+
'http.request.header.baggage': expect.any(String),
121+
'http.request.header.connection': 'keep-alive',
122+
'http.request.header.host': expect.any(String),
123+
'http.request.header.sentry_trace': expect.stringMatching(/[a-f0-9]{32}-[a-f0-9]{16}-1/),
109124
},
110125
op: 'http.server',
111126
parent_span_id: outgoingHttpSpanId,
@@ -146,6 +161,10 @@ test('Propagates trace for outgoing fetch requests', async ({ baseURL }) => {
146161

147162
const outgoingHttpSpanId = outgoingHttpSpan?.span_id;
148163

164+
const outgoingHttpSpanData = outgoingHttpSpan?.data || {};
165+
// Outgoing span (`http.client`) does not include headers as attributes
166+
expect(Object.keys(outgoingHttpSpanData).some(key => key.startsWith('http.request.header.'))).toBe(false);
167+
149168
expect(traceId).toEqual(expect.any(String));
150169

151170
// data is passed through from the inbound request, to verify we have the correct headers set
@@ -189,6 +208,13 @@ test('Propagates trace for outgoing fetch requests', async ({ baseURL }) => {
189208
'http.status_code': 200,
190209
'http.status_text': 'OK',
191210
'http.route': '/test-outgoing-fetch/:id',
211+
'http.request.header.accept': '*/*',
212+
'http.request.header.accept_encoding': 'gzip, deflate',
213+
'http.request.header.accept_language': '*',
214+
'http.request.header.connection': 'keep-alive',
215+
'http.request.header.host': expect.any(String),
216+
'http.request.header.sec_fetch_mode': 'cors',
217+
'http.request.header.user_agent': 'node',
192218
},
193219
op: 'http.server',
194220
span_id: expect.stringMatching(/[a-f0-9]{16}/),

dev-packages/e2e-tests/test-applications/nestjs-fastify/tests/transactions.test.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,13 @@ test('Sends an API route transaction', async ({ baseURL }) => {
3838
'http.status_code': 200,
3939
'http.status_text': 'OK',
4040
'http.route': '/test-transaction',
41+
'http.request.header.accept': '*/*',
42+
'http.request.header.accept_encoding': 'gzip, deflate',
43+
'http.request.header.accept_language': '*',
44+
'http.request.header.connection': 'keep-alive',
45+
'http.request.header.host': expect.any(String),
46+
'http.request.header.sec_fetch_mode': 'cors',
47+
'http.request.header.user_agent': 'node',
4148
},
4249
op: 'http.server',
4350
span_id: expect.stringMatching(/[a-f0-9]{16}/),

dev-packages/e2e-tests/test-applications/nestjs-with-submodules-decorator/tests/transactions.test.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,13 @@ test('Sends an API route transaction from module', async ({ baseURL }) => {
3838
'http.status_code': 200,
3939
'http.status_text': 'OK',
4040
'http.route': '/example-module/transaction',
41+
'http.request.header.accept': '*/*',
42+
'http.request.header.accept_encoding': 'gzip, deflate',
43+
'http.request.header.accept_language': '*',
44+
'http.request.header.connection': 'keep-alive',
45+
'http.request.header.host': expect.any(String),
46+
'http.request.header.sec_fetch_mode': 'cors',
47+
'http.request.header.user_agent': 'node',
4148
},
4249
op: 'http.server',
4350
span_id: expect.stringMatching(/[a-f0-9]{16}/),

0 commit comments

Comments
 (0)