Skip to content

Commit f8129a7

Browse files
committed
fixup! feat(http): portable node:http client instrumentation (#20393)
1 parent 1a8d51e commit f8129a7

File tree

4 files changed

+30
-11
lines changed

4 files changed

+30
-11
lines changed

packages/core/src/index.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -147,7 +147,11 @@ export { growthbookIntegration } from './integrations/featureFlags';
147147
export { conversationIdIntegration } from './integrations/conversationId';
148148
export { patchHttpModuleClient, patchHttpsModuleClient } from './integrations/http/client-patch';
149149
export { getHttpClientSubscriptions } from './integrations/http/client-subscriptions';
150-
export { HTTP_ON_CLIENT_REQUEST, HTTP_ON_SERVER_REQUEST } from './integrations/http/constants';
150+
export {
151+
HTTP_ON_CLIENT_REQUEST,
152+
HTTP_ON_CLIENT_REQUEST_FALLBACK,
153+
HTTP_ON_SERVER_REQUEST,
154+
} from './integrations/http/constants';
151155
export type {
152156
HttpInstrumentationOptions,
153157
HttpClientRequest,

packages/core/src/integrations/http/client-subscriptions.ts

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -41,17 +41,17 @@ export type HttpClientSubscriptions = Record<ClientSubscriptionName, ChannelList
4141

4242
export function getHttpClientSubscriptions(options: HttpInstrumentationOptions): HttpClientSubscriptions {
4343
const propagationDecisionMap = new LRUMap<string, boolean>(100);
44-
const client = getClient();
45-
const clientOptions = client?.getOptions();
46-
47-
const {
48-
errorMonitor = 'error',
49-
spans: createSpans = clientOptions ? hasSpansEnabled(clientOptions) : true,
50-
propagateTrace = false,
51-
breadcrumbs = true,
52-
} = options;
44+
const getConfig = () => getClient()?.getOptions();
5345

5446
const onHttpClientRequestCreated: ChannelListener = (data: unknown): void => {
47+
const clientOptions = getConfig();
48+
const {
49+
errorMonitor = 'error',
50+
spans: createSpans = clientOptions ? hasSpansEnabled(clientOptions) : true,
51+
propagateTrace = false,
52+
breadcrumbs = true,
53+
} = options;
54+
5555
const { request } = data as { request: HttpClientRequest };
5656

5757
// Skip if tracing is suppressed (e.g., inside Sentry.suppressTracing())
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
export const LOG_PREFIX = '@sentry/instrumentation-http';
22
export const HTTP_ON_CLIENT_REQUEST = 'http.client.request.created';
3+
/** Used by node-light SDK to instrument on older node versions */
4+
export const HTTP_ON_CLIENT_REQUEST_FALLBACK = 'http.client.request.start';
35
export const HTTP_ON_SERVER_REQUEST = 'http.server.request.start';
46
export type ClientSubscriptionName = typeof HTTP_ON_CLIENT_REQUEST;
57
export type ServerSubscriptionName = typeof HTTP_ON_SERVER_REQUEST;

packages/node-core/src/light/integrations/httpIntegration.ts

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import {
99
getHttpClientSubscriptions,
1010
getIsolationScope,
1111
HTTP_ON_CLIENT_REQUEST,
12+
HTTP_ON_CLIENT_REQUEST_FALLBACK,
1213
httpRequestToRequestData,
1314
stripUrlQueryAndFragment,
1415
withIsolationScope,
@@ -19,9 +20,15 @@ import { patchRequestToCaptureBody } from '../../utils/captureRequestBody';
1920
import { getRequestOptions } from '../../utils/outgoingHttpRequest';
2021
import type { LightNodeClient } from '../client';
2122
import { errorMonitor } from 'node:events';
23+
import { NODE_VERSION } from '../../nodeVersion';
2224

2325
const INTEGRATION_NAME = 'Http';
2426

27+
const FULLY_SUPPORTS_HTTP_DIAGNOSTICS_CHANNEL =
28+
(NODE_VERSION.major === 22 && NODE_VERSION.minor >= 12) ||
29+
(NODE_VERSION.major === 23 && NODE_VERSION.minor >= 2) ||
30+
NODE_VERSION.major >= 24;
31+
2532
// We keep track of emit functions we wrapped, to avoid double wrapping
2633
const wrappedEmitFns = new WeakSet<typeof Server.prototype.emit>();
2734

@@ -99,6 +106,10 @@ const _httpIntegration = ((options: HttpIntegrationOptions = {}) => {
99106

100107
const { ignoreOutgoingRequests } = _options;
101108

109+
const channel = FULLY_SUPPORTS_HTTP_DIAGNOSTICS_CHANNEL
110+
? HTTP_ON_CLIENT_REQUEST
111+
: HTTP_ON_CLIENT_REQUEST_FALLBACK;
112+
102113
const { [HTTP_ON_CLIENT_REQUEST]: onHttpClientRequestCreated } = getHttpClientSubscriptions({
103114
breadcrumbs: _options.breadcrumbs,
104115
propagateTrace: _options.tracePropagation,
@@ -111,7 +122,9 @@ const _httpIntegration = ((options: HttpIntegrationOptions = {}) => {
111122
});
112123

113124
subscribe('http.server.request.start', onHttpServerRequestStart);
114-
subscribe(HTTP_ON_CLIENT_REQUEST, onHttpClientRequestCreated);
125+
// Subscribe on the request creation in node versions that support it,
126+
// or to the request start (ie, .end() being called) on older versions.
127+
subscribe(channel, onHttpClientRequestCreated);
115128
},
116129
};
117130
}) satisfies IntegrationFn;

0 commit comments

Comments
 (0)