Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit e798a09

Browse files
committed
feat(node): Update httpIntegration handling of incoming requests
1 parent f307a22 commit e798a09

File tree

10 files changed

+339
-161
lines changed

10 files changed

+339
-161
lines changed

‎CHANGELOG.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,15 @@
44

55
- "You miss 100 percent of the chances you don't take. — Wayne Gretzky" — Michael Scott
66

7+
### Important Changes
8+
9+
- \*\*feat(node): Update `httpIntegration` handling of incoming requests
10+
11+
This version updates the handling of the Node SDK of incoming requests. Instead of relying on @opentelemetry/instrumentation-http for this, we now handle this internally, ensuring that we can optimize performance as much as possible and avoid interop problems.
12+
13+
This change should not affect users, unless they are relying on very in-depth implementation details. Importantly, this also drops the `_experimentalConfig` option of the integration - this will no longer do anything.
14+
Finally, you can still pass `instrumentation.{requestHook,responseHook,applyCustomAttributesOnSpan}` options, but they are deprecated and will be removed in v11. Instead, you can use the new `incomingRequestSpanHook` configuration option if you want to adjust the incoming request span.
15+
716
## 10.3.0
817

918
- feat(core): MCP Server - Capture prompt results from prompt function calls (#17284)

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,11 +29,11 @@ describe('express tracing', () => {
2929

3030
// Also calling `updateName` AND setting a source doesn't change anything - Otel has no concept of source, this is sentry-internal.
3131
// Therefore, only the source is updated but the name is still overwritten by Otel.
32-
test("calling `span.updateName` and setting attribute source doesn't update the final name in express but it updates the source", async () => {
32+
test('calling `span.updateName` and setting attribute source updates the final name in express', async () => {
3333
const runner = createRunner(__dirname, 'server.js')
3434
.expect({
3535
transaction: {
36-
transaction: 'GET /test/:id/span-updateName-source',
36+
transaction: 'new-name',
3737
transaction_info: {
3838
source: 'custom',
3939
},

‎dev-packages/node-integration-tests/suites/tracing/httpIntegration/instrument.mjs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,15 @@ Sentry.init({
1111

1212
integrations: [
1313
Sentry.httpIntegration({
14+
incomingRequestSpanHook: (span, req, res) => {
15+
span.setAttribute('incomingRequestSpanHook', 'yes');
16+
Sentry.setExtra('incomingRequestSpanHookCalled', {
17+
reqUrl: req.url,
18+
reqMethod: req.method,
19+
resUrl: res.req.url,
20+
resMethod: res.req.method,
21+
});
22+
},
1423
instrumentation: {
1524
requestHook: (span, req) => {
1625
span.setAttribute('attr1', 'yes');

‎dev-packages/node-integration-tests/suites/tracing/httpIntegration/server-experimental.js

Lines changed: 0 additions & 38 deletions
This file was deleted.

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

Lines changed: 28 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -49,30 +49,38 @@ describe('httpIntegration', () => {
4949
runner.makeRequest('get', '/test');
5050
await runner.completed();
5151
});
52-
});
5352

54-
test('allows to pass experimental config through to integration', async () => {
55-
const runner = createRunner(__dirname, 'server-experimental.js')
56-
.expect({
57-
transaction: {
58-
contexts: {
59-
trace: {
60-
span_id: expect.stringMatching(/[a-f0-9]{16}/),
61-
trace_id: expect.stringMatching(/[a-f0-9]{32}/),
62-
data: {
63-
url: expect.stringMatching(/\/test$/),
64-
'http.response.status_code': 200,
65-
'http.server_name': 'sentry-test-server-name',
53+
test('allows to configure incomingRequestSpanHook', async () => {
54+
const runner = createRunner()
55+
.expect({
56+
transaction: {
57+
contexts: {
58+
trace: {
59+
span_id: expect.stringMatching(/[a-f0-9]{16}/),
60+
trace_id: expect.stringMatching(/[a-f0-9]{32}/),
61+
data: {
62+
url: expect.stringMatching(/\/test$/),
63+
'http.response.status_code': 200,
64+
incomingRequestSpanHook: 'yes',
65+
},
66+
op: 'http.server',
67+
status: 'ok',
6668
},
67-
op: 'http.server',
68-
status: 'ok',
6969
},
70+
extra: expect.objectContaining({
71+
incomingRequestSpanHookCalled: {
72+
reqUrl: expect.stringMatching(/\/test$/),
73+
reqMethod: 'GET',
74+
resUrl: expect.stringMatching(/\/test$/),
75+
resMethod: 'GET',
76+
},
77+
}),
7078
},
71-
},
72-
})
73-
.start();
74-
runner.makeRequest('get','/test');
75-
awaitrunner.completed();
79+
})
80+
.start();
81+
runner.makeRequest('get','/test');
82+
awaitrunner.completed();
83+
});
7684
});
7785

7886
describe("doesn't create a root span for incoming requests ignored via `ignoreIncomingRequests`", () => {

‎packages/node-core/src/integrations/http/SentryHttpInstrumentation.ts

Lines changed: 44 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import type { ChannelListener } from 'node:diagnostics_channel';
22
import { subscribe, unsubscribe } from 'node:diagnostics_channel';
33
import type * as http from 'node:http';
44
import type * as https from 'node:https';
5+
import type { Span } from '@opentelemetry/api';
56
import { context } from '@opentelemetry/api';
67
import { isTracingSuppressed } from '@opentelemetry/core';
78
import type { InstrumentationConfig } from '@opentelemetry/instrumentation';
@@ -28,12 +29,22 @@ export type SentryHttpInstrumentationOptions = InstrumentationConfig & {
2829
*/
2930
breadcrumbs?: boolean;
3031

32+
/**
33+
* Whether to create spans for requests or not.
34+
* As of now, creates spans for incoming requests, but not outgoing requests.
35+
*
36+
* @default `true`
37+
*/
38+
spans?: boolean;
39+
3140
/**
3241
* Whether to extract the trace ID from the `sentry-trace` header for incoming requests.
3342
* By default this is done by the HttpInstrumentation, but if that is not added (e.g. because tracing is disabled, ...)
3443
* then this instrumentation can take over.
3544
*
36-
* @default `false`
45+
* @deprecated This is always true and the option will be removed in the future.
46+
*
47+
* @default `true`
3748
*/
3849
extractIncomingTraceFromHeader?: boolean;
3950

@@ -57,6 +68,14 @@ export type SentryHttpInstrumentationOptions = InstrumentationConfig & {
5768
*/
5869
ignoreOutgoingRequests?: (url: string, request: http.RequestOptions) => boolean;
5970

71+
/**
72+
* Do not capture spans for incoming HTTP requests to URLs where the given callback returns `true`.
73+
*
74+
* @param urlPath Contains the URL path and query string (if any) of the incoming request.
75+
* @param request Contains the {@type IncomingMessage} object of the incoming request.
76+
*/
77+
ignoreSpansForIncomingRequests?: (urlPath: string, request: http.IncomingMessage) => boolean;
78+
6079
/**
6180
* Do not capture the request body for incoming HTTP requests to URLs where the given callback returns `true`.
6281
* This can be useful for long running requests where the body is not needed and we want to avoid capturing it.
@@ -66,6 +85,12 @@ export type SentryHttpInstrumentationOptions = InstrumentationConfig & {
6685
*/
6786
ignoreIncomingRequestBody?: (url: string, request: http.RequestOptions) => boolean;
6887

88+
/**
89+
* A hook that can be used to mutate the span for incoming requests.
90+
* This is triggered after the span is created, but before it is recorded.
91+
*/
92+
incomingRequestSpanHook?: (span: Span, request: http.IncomingMessage, response: http.ServerResponse) => void;
93+
6994
/**
7095
* Controls the maximum size of incoming HTTP request bodies attached to events.
7196
*
@@ -90,6 +115,19 @@ export type SentryHttpInstrumentationOptions = InstrumentationConfig & {
90115
*/
91116
trackIncomingRequestsAsSessions?: boolean;
92117

118+
/**
119+
* @deprecated This is deprecated in favor of `incomingRequestSpanHook`.
120+
*/
121+
instrumentation?: {
122+
requestHook?: (span: Span, req: http.ClientRequest | http.IncomingMessage) => void;
123+
responseHook?: (span: Span, response: http.IncomingMessage | http.ServerResponse) => void;
124+
applyCustomAttributesOnSpan?: (
125+
span: Span,
126+
request: http.ClientRequest | http.IncomingMessage,
127+
response: http.IncomingMessage | http.ServerResponse,
128+
) => void;
129+
};
130+
93131
/**
94132
* Number of milliseconds until sessions tracked with `trackIncomingRequestsAsSessions` will be flushed as a session aggregate.
95133
*
@@ -131,10 +169,15 @@ export class SentryHttpInstrumentation extends InstrumentationBase<SentryHttpIns
131169
const onHttpServerRequestStart = ((_data: unknown) => {
132170
const data = _data as { server: http.Server };
133171
instrumentServer(data.server, {
172+
// eslint-disable-next-line deprecation/deprecation
173+
instrumentation: this.getConfig().instrumentation,
134174
ignoreIncomingRequestBody: this.getConfig().ignoreIncomingRequestBody,
175+
ignoreSpansForIncomingRequests: this.getConfig().ignoreSpansForIncomingRequests,
176+
incomingRequestSpanHook: this.getConfig().incomingRequestSpanHook,
135177
maxIncomingRequestBodySize: this.getConfig().maxIncomingRequestBodySize,
136178
trackIncomingRequestsAsSessions: this.getConfig().trackIncomingRequestsAsSessions,
137179
sessionFlushingDelayMS: this.getConfig().sessionFlushingDelayMS ?? 60_000,
180+
spans: this.getConfig().spans ?? true,
138181
});
139182
}) satisfies ChannelListener;
140183

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /