UNPKG

@sentry/node

Version:
211 lines (176 loc) 6.05 kB
Object.defineProperty(exports, '__esModule', { value: true }); const utils = require('@sentry/utils'); const http = require('../utils/http.js'); const NODE_VERSION = utils.parseSemver(process.versions.node); exports.ChannelName = void 0; (function (ChannelName) { // https://github.com/nodejs/undici/blob/e6fc80f809d1217814c044f52ed40ef13f21e43c/docs/api/DiagnosticsChannel.md#undicirequestcreate const RequestCreate = 'undici:request:create'; ChannelName["RequestCreate"] = RequestCreate; const RequestEnd = 'undici:request:headers'; ChannelName["RequestEnd"] = RequestEnd; const RequestError = 'undici:request:error'; ChannelName["RequestError"] = RequestError; })(exports.ChannelName || (exports.ChannelName = {})); // Please note that you cannot use `console.log` to debug the callbacks registered to the `diagnostics_channel` API. // To debug, you can use `writeFileSync` to write to a file: // https://nodejs.org/api/async_hooks.html#printing-in-asynchook-callbacks /** * Instruments outgoing HTTP requests made with the `undici` package via * Node's `diagnostics_channel` API. * * Supports Undici 4.7.0 or higher. * * Requires Node 16.17.0 or higher. */ class Undici { /** * @inheritDoc */ static __initStatic() {this.id = 'Undici';} /** * @inheritDoc */ __init() {this.name = Undici.id;} constructor(_options = {}) {Undici.prototype.__init.call(this); this._options = { breadcrumbs: _options.breadcrumbs === undefined ? true : _options.breadcrumbs, shouldCreateSpanForRequest: _options.shouldCreateSpanForRequest || (() => true), }; } /** * @inheritDoc */ setupOnce(_addGlobalEventProcessor, getCurrentHub) { // Requires Node 16+ to use the diagnostics_channel API. if (NODE_VERSION.major && NODE_VERSION.major < 16) { return; } let ds; try { // eslint-disable-next-line @typescript-eslint/no-var-requires ds = utils.dynamicRequire(module, 'diagnostics_channel') ; } catch (e) { // no-op } if (!ds || !ds.subscribe) { return; } // https://github.com/nodejs/undici/blob/e6fc80f809d1217814c044f52ed40ef13f21e43c/docs/api/DiagnosticsChannel.md ds.subscribe(exports.ChannelName.RequestCreate, message => { const hub = getCurrentHub(); if (!hub.getIntegration(Undici)) { return; } const { request } = message ; const url = new URL(request.path, request.origin); const stringUrl = url.toString(); if (http.isSentryRequest(stringUrl) || request.__sentry__ !== undefined) { return; } const client = hub.getClient(); const scope = hub.getScope(); const activeSpan = scope.getSpan(); if (activeSpan && client) { const clientOptions = client.getOptions(); const shouldCreateSpan = this._options.shouldCreateSpanForRequest(stringUrl); if (shouldCreateSpan) { const data = {}; const params = url.searchParams.toString(); if (params) { data['http.query'] = `?${params}`; } if (url.hash) { data['http.fragment'] = url.hash; } const span = activeSpan.startChild({ op: 'http.client', description: `${request.method || 'GET'} ${utils.stripUrlQueryAndFragment(stringUrl)}`, data, }); request.__sentry__ = span; const shouldPropagate = clientOptions.tracePropagationTargets ? utils.stringMatchesSomePattern(stringUrl, clientOptions.tracePropagationTargets) : true; if (shouldPropagate) { request.addHeader('sentry-trace', span.toTraceparent()); if (span.transaction) { const dynamicSamplingContext = span.transaction.getDynamicSamplingContext(); const sentryBaggageHeader = utils.dynamicSamplingContextToSentryBaggageHeader(dynamicSamplingContext); if (sentryBaggageHeader) { request.addHeader('baggage', sentryBaggageHeader); } } } } } }); ds.subscribe(exports.ChannelName.RequestEnd, message => { const hub = getCurrentHub(); if (!hub.getIntegration(Undici)) { return; } const { request, response } = message ; const url = new URL(request.path, request.origin); const stringUrl = url.toString(); if (http.isSentryRequest(stringUrl)) { return; } const span = request.__sentry__; if (span) { span.setHttpStatus(response.statusCode); span.finish(); } if (this._options.breadcrumbs) { hub.addBreadcrumb( { category: 'http', data: { method: request.method, status_code: response.statusCode, url: stringUrl, }, type: 'http', }, { event: 'response', request, response, }, ); } }); ds.subscribe(exports.ChannelName.RequestError, message => { const hub = getCurrentHub(); if (!hub.getIntegration(Undici)) { return; } const { request } = message ; const url = new URL(request.path, request.origin); const stringUrl = url.toString(); if (http.isSentryRequest(stringUrl)) { return; } const span = request.__sentry__; if (span) { span.setStatus('internal_error'); span.finish(); } if (this._options.breadcrumbs) { hub.addBreadcrumb( { category: 'http', data: { method: request.method, url: stringUrl, }, level: 'error', type: 'http', }, { event: 'error', request, }, ); } }); } } Undici.__initStatic(); exports.Undici = Undici; //# sourceMappingURL=index.js.map