123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301 |
- import { _optionalChain } from '@sentry/utils';
- import { defineIntegration, hasTracingEnabled, getClient, isSentryRequestUrl, getCurrentScope, getIsolationScope, getActiveSpan, spanToTraceHeader, getDynamicSamplingContextFromSpan, getDynamicSamplingContextFromClient, setHttpStatus, addBreadcrumb } from '@sentry/core';
- import { LRUMap, generateSentryTraceHeader, dynamicSamplingContextToSentryBaggageHeader, parseUrl, stringMatchesSomePattern, getSanitizedUrlString } from '@sentry/utils';
- import { NODE_VERSION } from '../../nodeVersion.js';
- var ChannelName;(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;
- })(ChannelName || (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
- //
- // import { writeFileSync } from 'fs';
- // import { format } from 'util';
- //
- // function debug(...args: any): void {
- // // Use a function like this one when debugging inside an AsyncHook callback
- // // @ts-expect-error any
- // writeFileSync('log.out', `${format(...args)}\n`, { flag: 'a' });
- // }
- const _nativeNodeFetchintegration = ((options) => {
- // eslint-disable-next-line deprecation/deprecation
- return new Undici(options) ;
- }) ;
- const nativeNodeFetchintegration = defineIntegration(_nativeNodeFetchintegration);
- /**
- * 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.
- *
- * @deprecated Use `nativeNodeFetchintegration()` instead.
- */
- class Undici {
- /**
- * @inheritDoc
- */
- static __initStatic() {this.id = 'Undici';}
- /**
- * @inheritDoc
- */
- // eslint-disable-next-line deprecation/deprecation
- __init() {this.name = Undici.id;}
- __init2() {this._createSpanUrlMap = new LRUMap(100);}
- __init3() {this._headersUrlMap = new LRUMap(100);}
- constructor(_options = {}) {Undici.prototype.__init.call(this);Undici.prototype.__init2.call(this);Undici.prototype.__init3.call(this);Undici.prototype.__init4.call(this);Undici.prototype.__init5.call(this);Undici.prototype.__init6.call(this);
- this._options = {
- breadcrumbs: _options.breadcrumbs === undefined ? true : _options.breadcrumbs,
- tracing: _options.tracing,
- shouldCreateSpanForRequest: _options.shouldCreateSpanForRequest,
- };
- }
- /**
- * @inheritDoc
- */
- setupOnce(_addGlobalEventProcessor) {
- // Requires Node 16+ to use the diagnostics_channel API.
- if (NODE_VERSION.major < 16) {
- return;
- }
- let ds;
- try {
- // eslint-disable-next-line @typescript-eslint/no-var-requires
- ds = require('diagnostics_channel') ;
- } catch (e) {
- // no-op
- }
- if (!ds || !ds.subscribe) {
- return;
- }
- // https://github.com/nodejs/undici/blob/e6fc80f809d1217814c044f52ed40ef13f21e43c/docs/api/DiagnosticsChannel.md
- ds.subscribe(ChannelName.RequestCreate, this._onRequestCreate);
- ds.subscribe(ChannelName.RequestEnd, this._onRequestEnd);
- ds.subscribe(ChannelName.RequestError, this._onRequestError);
- }
- /** Helper that wraps shouldCreateSpanForRequest option */
- _shouldCreateSpan(url) {
- if (this._options.tracing === false || (this._options.tracing === undefined && !hasTracingEnabled())) {
- return false;
- }
- if (this._options.shouldCreateSpanForRequest === undefined) {
- return true;
- }
- const cachedDecision = this._createSpanUrlMap.get(url);
- if (cachedDecision !== undefined) {
- return cachedDecision;
- }
- const decision = this._options.shouldCreateSpanForRequest(url);
- this._createSpanUrlMap.set(url, decision);
- return decision;
- }
- __init4() {this._onRequestCreate = (message) => {
- // eslint-disable-next-line deprecation/deprecation
- if (!_optionalChain([getClient, 'call', _10 => _10(), 'optionalAccess', _11 => _11.getIntegration, 'call', _12 => _12(Undici)])) {
- return;
- }
- const { request } = message ;
- const stringUrl = request.origin ? request.origin.toString() + request.path : request.path;
- const client = getClient();
- if (!client) {
- return;
- }
- if (isSentryRequestUrl(stringUrl, client) || request.__sentry_span__ !== undefined) {
- return;
- }
- const clientOptions = client.getOptions();
- const scope = getCurrentScope();
- const isolationScope = getIsolationScope();
- const parentSpan = getActiveSpan();
- const span = this._shouldCreateSpan(stringUrl) ? createRequestSpan(parentSpan, request, stringUrl) : undefined;
- if (span) {
- request.__sentry_span__ = span;
- }
- const shouldAttachTraceData = (url) => {
- if (clientOptions.tracePropagationTargets === undefined) {
- return true;
- }
- const cachedDecision = this._headersUrlMap.get(url);
- if (cachedDecision !== undefined) {
- return cachedDecision;
- }
- const decision = stringMatchesSomePattern(url, clientOptions.tracePropagationTargets);
- this._headersUrlMap.set(url, decision);
- return decision;
- };
- if (shouldAttachTraceData(stringUrl)) {
- const { traceId, spanId, sampled, dsc } = {
- ...isolationScope.getPropagationContext(),
- ...scope.getPropagationContext(),
- };
- const sentryTraceHeader = span ? spanToTraceHeader(span) : generateSentryTraceHeader(traceId, spanId, sampled);
- const sentryBaggageHeader = dynamicSamplingContextToSentryBaggageHeader(
- dsc ||
- (span
- ? getDynamicSamplingContextFromSpan(span)
- : getDynamicSamplingContextFromClient(traceId, client, scope)),
- );
- setHeadersOnRequest(request, sentryTraceHeader, sentryBaggageHeader);
- }
- };}
- __init5() {this._onRequestEnd = (message) => {
- // eslint-disable-next-line deprecation/deprecation
- if (!_optionalChain([getClient, 'call', _13 => _13(), 'optionalAccess', _14 => _14.getIntegration, 'call', _15 => _15(Undici)])) {
- return;
- }
- const { request, response } = message ;
- const stringUrl = request.origin ? request.origin.toString() + request.path : request.path;
- if (isSentryRequestUrl(stringUrl, getClient())) {
- return;
- }
- const span = request.__sentry_span__;
- if (span) {
- setHttpStatus(span, response.statusCode);
- span.end();
- }
- if (this._options.breadcrumbs) {
- addBreadcrumb(
- {
- category: 'http',
- data: {
- method: request.method,
- status_code: response.statusCode,
- url: stringUrl,
- },
- type: 'http',
- },
- {
- event: 'response',
- request,
- response,
- },
- );
- }
- };}
- __init6() {this._onRequestError = (message) => {
- // eslint-disable-next-line deprecation/deprecation
- if (!_optionalChain([getClient, 'call', _16 => _16(), 'optionalAccess', _17 => _17.getIntegration, 'call', _18 => _18(Undici)])) {
- return;
- }
- const { request } = message ;
- const stringUrl = request.origin ? request.origin.toString() + request.path : request.path;
- if (isSentryRequestUrl(stringUrl, getClient())) {
- return;
- }
- const span = request.__sentry_span__;
- if (span) {
- span.setStatus('internal_error');
- span.end();
- }
- if (this._options.breadcrumbs) {
- addBreadcrumb(
- {
- category: 'http',
- data: {
- method: request.method,
- url: stringUrl,
- },
- level: 'error',
- type: 'http',
- },
- {
- event: 'error',
- request,
- },
- );
- }
- };}
- }Undici.__initStatic();
- function setHeadersOnRequest(
- request,
- sentryTrace,
- sentryBaggageHeader,
- ) {
- const headerLines = request.headers.split('\r\n');
- const hasSentryHeaders = headerLines.some(headerLine => headerLine.startsWith('sentry-trace:'));
- if (hasSentryHeaders) {
- return;
- }
- request.addHeader('sentry-trace', sentryTrace);
- if (sentryBaggageHeader) {
- request.addHeader('baggage', sentryBaggageHeader);
- }
- }
- function createRequestSpan(
- activeSpan,
- request,
- stringUrl,
- ) {
- const url = parseUrl(stringUrl);
- const method = request.method || 'GET';
- const data = {
- 'http.method': method,
- };
- if (url.search) {
- data['http.query'] = url.search;
- }
- if (url.hash) {
- data['http.fragment'] = url.hash;
- }
- // eslint-disable-next-line deprecation/deprecation
- return _optionalChain([activeSpan, 'optionalAccess', _19 => _19.startChild, 'call', _20 => _20({
- op: 'http.client',
- origin: 'auto.http.node.undici',
- description: `${method} ${getSanitizedUrlString(url)}`,
- data,
- })]);
- }
- export { ChannelName, Undici, nativeNodeFetchintegration };
- //# sourceMappingURL=index.js.map
|