bifocal/node_modules/@sentry/node/cjs/integrations/undici/index.js

313 lines
9.2 KiB
JavaScript

var {
_optionalChain
} = require('@sentry/utils');
Object.defineProperty(exports, '__esModule', { value: true });
const core = require('@sentry/core');
const utils = require('@sentry/utils');
const nodeVersion = require('../../nodeVersion.js');
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
//
// 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 = core.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 utils.LRUMap(100);}
__init3() {this._headersUrlMap = new utils.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 (nodeVersion.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(exports.ChannelName.RequestCreate, this._onRequestCreate);
ds.subscribe(exports.ChannelName.RequestEnd, this._onRequestEnd);
ds.subscribe(exports.ChannelName.RequestError, this._onRequestError);
}
/** Helper that wraps shouldCreateSpanForRequest option */
_shouldCreateSpan(url) {
if (this._options.tracing === false || (this._options.tracing === undefined && !core.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([core.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 = core.getClient();
if (!client) {
return;
}
if (core.isSentryRequestUrl(stringUrl, client) || request.__sentry_span__ !== undefined) {
return;
}
const clientOptions = client.getOptions();
const scope = core.getCurrentScope();
const isolationScope = core.getIsolationScope();
const parentSpan = core.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 = utils.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 ? core.spanToTraceHeader(span) : utils.generateSentryTraceHeader(traceId, spanId, sampled);
const sentryBaggageHeader = utils.dynamicSamplingContextToSentryBaggageHeader(
dsc ||
(span
? core.getDynamicSamplingContextFromSpan(span)
: core.getDynamicSamplingContextFromClient(traceId, client, scope)),
);
setHeadersOnRequest(request, sentryTraceHeader, sentryBaggageHeader);
}
};}
__init5() {this._onRequestEnd = (message) => {
// eslint-disable-next-line deprecation/deprecation
if (!_optionalChain([core.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 (core.isSentryRequestUrl(stringUrl, core.getClient())) {
return;
}
const span = request.__sentry_span__;
if (span) {
core.setHttpStatus(span, response.statusCode);
span.end();
}
if (this._options.breadcrumbs) {
core.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([core.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 (core.isSentryRequestUrl(stringUrl, core.getClient())) {
return;
}
const span = request.__sentry_span__;
if (span) {
span.setStatus('internal_error');
span.end();
}
if (this._options.breadcrumbs) {
core.addBreadcrumb(
{
category: 'http',
data: {
method: request.method,
url: stringUrl,
},
level: 'error',
type: 'http',
},
{
event: 'error',
request,
},
);
}
};}
}Undici.__initStatic();
function setHeadersOnRequest(
request,
sentryTrace,
sentryBaggageHeader,
) {
let hasSentryHeaders;
if (Array.isArray(request.headers)) {
hasSentryHeaders = request.headers.some(headerLine => headerLine === 'sentry-trace');
} else {
const headerLines = request.headers.split('\r\n');
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 = utils.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} ${utils.getSanitizedUrlString(url)}`,
data,
})]);
}
exports.Undici = Undici;
exports.nativeNodeFetchintegration = nativeNodeFetchintegration;
//# sourceMappingURL=index.js.map