UNPKG

@sentry/node

Version:

Sentry Node SDK using OpenTelemetry for performance instrumentation

79 lines (75 loc) • 3.39 kB
Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' }); const api = require('@opentelemetry/api'); const core = require('@sentry/core'); const server = require('@sentry/core/server'); const serverUtils = require('@sentry/server-utils'); const debugBuild = require('../../debug-build.js'); const HTTP_SERVER_INSTRUMENTED_KEY = api.createContextKey("sentry_http_server_instrumented"); const INTEGRATION_NAME = "Http.Server"; function addStartSpanCallback(request, callback) { core.addNonEnumerableProperty(request, "_startSpanCallback", new WeakRef(callback)); } const _httpServerIntegration = ((options = {}) => { const _options = { sessions: options.sessions ?? true, sessionFlushingDelayMS: options.sessionFlushingDelayMS ?? 6e4, maxRequestBodySize: options.maxRequestBodySize, // Server spans are created by `httpServerSpansIntegration` via the // `httpServerRequest` client event + `_startSpanCallback`, not by the // core subscription helper. Explicitly opt out so the helper does not // double-create spans when the client has tracing enabled. spans: false, // Cast: core uses HttpIncomingMessage; node consumers pass // RequestOptions-typed callbacks. // The two are structurally compatible for the fields the callback reads // (url, method, headers). ignoreRequestBody: options.ignoreRequestBody, /** * Hook called by core's `instrumentServer` to wrap the upstream * `emit('request')` call. * * We use it to extract OTel context from request headers and re-enter * the OTel context before the framework sees the request, so subsequent * spans (eg from `httpServerSpansIntegration`) attach to the right trace. */ wrapServerEmitRequest(request, response, normalizedRequest, next) { const client = core.getClient(); if (!client) return next(); if (api.context.active().getValue(HTTP_SERVER_INSTRUMENTED_KEY)) { return next(); } const ctx = api.propagation.extract(api.context.active(), normalizedRequest.headers).setValue(HTTP_SERVER_INSTRUMENTED_KEY, true); api.context.with(ctx, () => { client.emit("httpServerRequest", request, response, normalizedRequest); const callback = request._startSpanCallback?.deref(); if (callback) { callback(() => { next(); return true; }); } else { next(); } }); } }; return { name: INTEGRATION_NAME, setupOnce() { const { [server.HTTP_ON_SERVER_REQUEST]: onHttpServerRequestStart } = server.getHttpServerSubscriptions(_options); serverUtils.subscribeDiagnosticsChannel(server.HTTP_ON_SERVER_REQUEST, onHttpServerRequestStart); }, afterAllSetup(client) { if (debugBuild.DEBUG_BUILD && client.getIntegrationByName("Http")) { core.debug.warn( "It seems that you have manually added `httpServerIntegration` while `httpIntegration` is also present. Make sure to remove `httpServerIntegration` when adding `httpIntegration`." ); } } }; }); const httpServerIntegration = _httpServerIntegration; exports.recordRequestSession = server.recordRequestSession; exports.addStartSpanCallback = addStartSpanCallback; exports.httpServerIntegration = httpServerIntegration; //# sourceMappingURL=httpServerIntegration.js.map