@sentry/core 10.51.0 → 10.52.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/build/cjs/client.js +6 -2
- package/build/cjs/client.js.map +1 -1
- package/build/cjs/fetch.js +7 -4
- package/build/cjs/fetch.js.map +1 -1
- package/build/cjs/index.js +27 -8
- package/build/cjs/index.js.map +1 -1
- package/build/cjs/integrations/express/index.js +2 -4
- package/build/cjs/integrations/express/index.js.map +1 -1
- package/build/cjs/integrations/express/utils.js +0 -7
- package/build/cjs/integrations/express/utils.js.map +1 -1
- package/build/cjs/integrations/http/add-outgoing-request-breadcrumb.js +43 -0
- package/build/cjs/integrations/http/add-outgoing-request-breadcrumb.js.map +1 -0
- package/build/cjs/integrations/http/client-patch.js +113 -0
- package/build/cjs/integrations/http/client-patch.js.map +1 -0
- package/build/cjs/integrations/http/client-subscriptions.js +166 -0
- package/build/cjs/integrations/http/client-subscriptions.js.map +1 -0
- package/build/cjs/integrations/http/constants.js +10 -0
- package/build/cjs/integrations/http/constants.js.map +1 -0
- package/build/cjs/integrations/http/double-wrap-warning.js +29 -0
- package/build/cjs/integrations/http/double-wrap-warning.js.map +1 -0
- package/build/cjs/integrations/http/get-outgoing-span-data.js +88 -0
- package/build/cjs/integrations/http/get-outgoing-span-data.js.map +1 -0
- package/build/cjs/integrations/http/get-request-url.js +54 -0
- package/build/cjs/integrations/http/get-request-url.js.map +1 -0
- package/build/cjs/integrations/http/inject-trace-propagation-headers.js +81 -0
- package/build/cjs/integrations/http/inject-trace-propagation-headers.js.map +1 -0
- package/build/cjs/integrations/requestdata.js +85 -3
- package/build/cjs/integrations/requestdata.js.map +1 -1
- package/build/cjs/logs/envelope.js +12 -2
- package/build/cjs/logs/envelope.js.map +1 -1
- package/build/cjs/logs/internal.js +7 -1
- package/build/cjs/logs/internal.js.map +1 -1
- package/build/cjs/metrics/envelope.js +15 -2
- package/build/cjs/metrics/envelope.js.map +1 -1
- package/build/cjs/metrics/internal.js +7 -1
- package/build/cjs/metrics/internal.js.map +1 -1
- package/build/cjs/tracing/spans/captureSpan.js +58 -23
- package/build/cjs/tracing/spans/captureSpan.js.map +1 -1
- package/build/cjs/tracing/trace.js +1 -0
- package/build/cjs/tracing/trace.js.map +1 -1
- package/build/cjs/tracing/vercel-ai/constants.js +8 -0
- package/build/cjs/tracing/vercel-ai/constants.js.map +1 -1
- package/build/cjs/tracing/vercel-ai/index.js +93 -14
- package/build/cjs/tracing/vercel-ai/index.js.map +1 -1
- package/build/cjs/utils/baggage.js +73 -0
- package/build/cjs/utils/baggage.js.map +1 -1
- package/build/cjs/utils/chain-and-copy-promiselike.js +1 -0
- package/build/cjs/utils/chain-and-copy-promiselike.js.map +1 -1
- package/build/cjs/utils/get-default-export.js +32 -0
- package/build/cjs/utils/get-default-export.js.map +1 -0
- package/build/cjs/utils/request.js +129 -0
- package/build/cjs/utils/request.js.map +1 -1
- package/build/cjs/utils/spanUtils.js +1 -1
- package/build/cjs/utils/spanUtils.js.map +1 -1
- package/build/cjs/utils/version.js +1 -1
- package/build/esm/client.js +6 -2
- package/build/esm/client.js.map +1 -1
- package/build/esm/fetch.js +7 -4
- package/build/esm/fetch.js.map +1 -1
- package/build/esm/index.js +8 -3
- package/build/esm/index.js.map +1 -1
- package/build/esm/integrations/express/index.js +3 -5
- package/build/esm/integrations/express/index.js.map +1 -1
- package/build/esm/integrations/express/utils.js +1 -7
- package/build/esm/integrations/express/utils.js.map +1 -1
- package/build/esm/integrations/http/add-outgoing-request-breadcrumb.js +41 -0
- package/build/esm/integrations/http/add-outgoing-request-breadcrumb.js.map +1 -0
- package/build/esm/integrations/http/client-patch.js +111 -0
- package/build/esm/integrations/http/client-patch.js.map +1 -0
- package/build/esm/integrations/http/client-subscriptions.js +164 -0
- package/build/esm/integrations/http/client-subscriptions.js.map +1 -0
- package/build/esm/integrations/http/constants.js +6 -0
- package/build/esm/integrations/http/constants.js.map +1 -0
- package/build/esm/integrations/http/double-wrap-warning.js +26 -0
- package/build/esm/integrations/http/double-wrap-warning.js.map +1 -0
- package/build/esm/integrations/http/get-outgoing-span-data.js +85 -0
- package/build/esm/integrations/http/get-outgoing-span-data.js.map +1 -0
- package/build/esm/integrations/http/get-request-url.js +49 -0
- package/build/esm/integrations/http/get-request-url.js.map +1 -0
- package/build/esm/integrations/http/inject-trace-propagation-headers.js +79 -0
- package/build/esm/integrations/http/inject-trace-propagation-headers.js.map +1 -0
- package/build/esm/integrations/requestdata.js +85 -3
- package/build/esm/integrations/requestdata.js.map +1 -1
- package/build/esm/logs/envelope.js +12 -2
- package/build/esm/logs/envelope.js.map +1 -1
- package/build/esm/logs/internal.js +7 -1
- package/build/esm/logs/internal.js.map +1 -1
- package/build/esm/metrics/envelope.js +15 -2
- package/build/esm/metrics/envelope.js.map +1 -1
- package/build/esm/metrics/internal.js +7 -1
- package/build/esm/metrics/internal.js.map +1 -1
- package/build/esm/package.json +1 -1
- package/build/esm/tracing/spans/captureSpan.js +58 -23
- package/build/esm/tracing/spans/captureSpan.js.map +1 -1
- package/build/esm/tracing/trace.js +1 -1
- package/build/esm/tracing/trace.js.map +1 -1
- package/build/esm/tracing/vercel-ai/constants.js +8 -1
- package/build/esm/tracing/vercel-ai/constants.js.map +1 -1
- package/build/esm/tracing/vercel-ai/index.js +95 -17
- package/build/esm/tracing/vercel-ai/index.js.map +1 -1
- package/build/esm/utils/baggage.js +73 -1
- package/build/esm/utils/baggage.js.map +1 -1
- package/build/esm/utils/chain-and-copy-promiselike.js +1 -0
- package/build/esm/utils/chain-and-copy-promiselike.js.map +1 -1
- package/build/esm/utils/get-default-export.js +30 -0
- package/build/esm/utils/get-default-export.js.map +1 -0
- package/build/esm/utils/request.js +127 -1
- package/build/esm/utils/request.js.map +1 -1
- package/build/esm/utils/spanUtils.js +1 -1
- package/build/esm/utils/spanUtils.js.map +1 -1
- package/build/esm/utils/version.js +1 -1
- package/build/types/client.d.ts.map +1 -1
- package/build/types/fetch.d.ts.map +1 -1
- package/build/types/index.d.ts +13 -4
- package/build/types/index.d.ts.map +1 -1
- package/build/types/integrations/express/index.d.ts.map +1 -1
- package/build/types/integrations/express/utils.d.ts +1 -5
- package/build/types/integrations/express/utils.d.ts.map +1 -1
- package/build/types/integrations/http/add-outgoing-request-breadcrumb.d.ts +6 -0
- package/build/types/integrations/http/add-outgoing-request-breadcrumb.d.ts.map +1 -0
- package/build/types/integrations/http/client-patch.d.ts +46 -0
- package/build/types/integrations/http/client-patch.d.ts.map +1 -0
- package/build/types/integrations/http/client-subscriptions.d.ts +21 -0
- package/build/types/integrations/http/client-subscriptions.d.ts.map +1 -0
- package/build/types/integrations/http/constants.d.ts +6 -0
- package/build/types/integrations/http/constants.d.ts.map +1 -0
- package/build/types/integrations/http/double-wrap-warning.d.ts +4 -0
- package/build/types/integrations/http/double-wrap-warning.d.ts.map +1 -0
- package/build/types/integrations/http/get-outgoing-span-data.d.ts +13 -0
- package/build/types/integrations/http/get-outgoing-span-data.d.ts.map +1 -0
- package/build/types/integrations/http/get-request-url.d.ts +10 -0
- package/build/types/integrations/http/get-request-url.d.ts.map +1 -0
- package/build/types/integrations/http/index.d.ts +4 -0
- package/build/types/integrations/http/index.d.ts.map +1 -0
- package/build/types/integrations/http/inject-trace-propagation-headers.d.ts +12 -0
- package/build/types/integrations/http/inject-trace-propagation-headers.d.ts.map +1 -0
- package/build/types/integrations/http/types.d.ts +249 -0
- package/build/types/integrations/http/types.d.ts.map +1 -0
- package/build/types/integrations/requestdata.d.ts.map +1 -1
- package/build/types/logs/envelope.d.ts +5 -2
- package/build/types/logs/envelope.d.ts.map +1 -1
- package/build/types/logs/internal.d.ts.map +1 -1
- package/build/types/metrics/envelope.d.ts +5 -2
- package/build/types/metrics/envelope.d.ts.map +1 -1
- package/build/types/metrics/internal.d.ts.map +1 -1
- package/build/types/tracing/index.d.ts +1 -1
- package/build/types/tracing/index.d.ts.map +1 -1
- package/build/types/tracing/spans/captureSpan.d.ts +4 -4
- package/build/types/tracing/spans/captureSpan.d.ts.map +1 -1
- package/build/types/tracing/trace.d.ts +1 -0
- package/build/types/tracing/trace.d.ts.map +1 -1
- package/build/types/tracing/vercel-ai/constants.d.ts +1 -0
- package/build/types/tracing/vercel-ai/constants.d.ts.map +1 -1
- package/build/types/tracing/vercel-ai/index.d.ts +9 -0
- package/build/types/tracing/vercel-ai/index.d.ts.map +1 -1
- package/build/types/types-hoist/log.d.ts +5 -0
- package/build/types/types-hoist/log.d.ts.map +1 -1
- package/build/types/types-hoist/metric.d.ts +5 -0
- package/build/types/types-hoist/metric.d.ts.map +1 -1
- package/build/types/types-hoist/webfetchapi.d.ts +2 -0
- package/build/types/types-hoist/webfetchapi.d.ts.map +1 -1
- package/build/types/utils/baggage.d.ts +13 -0
- package/build/types/utils/baggage.d.ts.map +1 -1
- package/build/types/utils/get-default-export.d.ts +22 -0
- package/build/types/utils/get-default-export.d.ts.map +1 -0
- package/build/types/utils/request.d.ts +30 -0
- package/build/types/utils/request.d.ts.map +1 -1
- package/build/types/utils/spanUtils.d.ts +1 -1
- package/build/types-ts3.8/index.d.ts +13 -4
- package/build/types-ts3.8/integrations/express/utils.d.ts +1 -5
- package/build/types-ts3.8/integrations/http/add-outgoing-request-breadcrumb.d.ts +6 -0
- package/build/types-ts3.8/integrations/http/client-patch.d.ts +46 -0
- package/build/types-ts3.8/integrations/http/client-subscriptions.d.ts +21 -0
- package/build/types-ts3.8/integrations/http/constants.d.ts +6 -0
- package/build/types-ts3.8/integrations/http/double-wrap-warning.d.ts +4 -0
- package/build/types-ts3.8/integrations/http/get-outgoing-span-data.d.ts +13 -0
- package/build/types-ts3.8/integrations/http/get-request-url.d.ts +10 -0
- package/build/types-ts3.8/integrations/http/index.d.ts +4 -0
- package/build/types-ts3.8/integrations/http/inject-trace-propagation-headers.d.ts +12 -0
- package/build/types-ts3.8/integrations/http/types.d.ts +252 -0
- package/build/types-ts3.8/logs/envelope.d.ts +5 -2
- package/build/types-ts3.8/metrics/envelope.d.ts +5 -2
- package/build/types-ts3.8/tracing/index.d.ts +1 -1
- package/build/types-ts3.8/tracing/spans/captureSpan.d.ts +4 -4
- package/build/types-ts3.8/tracing/trace.d.ts +1 -0
- package/build/types-ts3.8/tracing/vercel-ai/constants.d.ts +1 -0
- package/build/types-ts3.8/tracing/vercel-ai/index.d.ts +9 -0
- package/build/types-ts3.8/types-hoist/log.d.ts +5 -0
- package/build/types-ts3.8/types-hoist/metric.d.ts +5 -0
- package/build/types-ts3.8/types-hoist/webfetchapi.d.ts +2 -0
- package/build/types-ts3.8/utils/baggage.d.ts +13 -0
- package/build/types-ts3.8/utils/get-default-export.d.ts +22 -0
- package/build/types-ts3.8/utils/request.d.ts +30 -0
- package/build/types-ts3.8/utils/spanUtils.d.ts +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { DEBUG_BUILD } from '../../debug-build.js';
|
|
2
|
+
import { debug } from '../../utils/debug-logger.js';
|
|
3
|
+
|
|
4
|
+
const isOtelWrapped = (fn) =>
|
|
5
|
+
typeof fn.__unwrap === 'function';
|
|
6
|
+
|
|
7
|
+
// exported for tess
|
|
8
|
+
const warning =
|
|
9
|
+
'Double-wrapped http.client detected. Either disable spans in Sentry.httpIntegration, or disable the OpenTelemetry HTTP instrumentation.';
|
|
10
|
+
|
|
11
|
+
let didDoubleWrapWarning = false;
|
|
12
|
+
// no-op in non-debug builds
|
|
13
|
+
const doubleWrapWarning = DEBUG_BUILD
|
|
14
|
+
? (http) => {
|
|
15
|
+
if (!didDoubleWrapWarning) {
|
|
16
|
+
if (isOtelWrapped(http.request) || isOtelWrapped(http.get)) {
|
|
17
|
+
// TODO: add link to documentation
|
|
18
|
+
didDoubleWrapWarning = true;
|
|
19
|
+
debug.warn(warning);
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
: () => {};
|
|
24
|
+
|
|
25
|
+
export { doubleWrapWarning, warning };
|
|
26
|
+
//# sourceMappingURL=double-wrap-warning.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"double-wrap-warning.js","sources":["../../../../src/integrations/http/double-wrap-warning.ts"],"sourcesContent":["import { DEBUG_BUILD } from '../../debug-build';\nimport { debug } from '../../utils/debug-logger';\nimport type { HttpModuleExport } from './types';\n\nconst isOtelWrapped = (fn: Function & { __unwrap?: Function }): fn is Function & { __unwrap: Function } =>\n typeof fn.__unwrap === 'function';\n\n// exported for tess\nexport const warning =\n 'Double-wrapped http.client detected. Either disable spans in Sentry.httpIntegration, or disable the OpenTelemetry HTTP instrumentation.';\n\nlet didDoubleWrapWarning = false;\n// no-op in non-debug builds\nexport const doubleWrapWarning = DEBUG_BUILD\n ? (http: HttpModuleExport) => {\n if (!didDoubleWrapWarning) {\n if (isOtelWrapped(http.request) || isOtelWrapped(http.get)) {\n // TODO: add link to documentation\n didDoubleWrapWarning = true;\n debug.warn(warning);\n }\n }\n }\n : () => {};\n"],"names":[],"mappings":";;;AAIA,MAAM,aAAA,GAAgB,CAAC,EAAE;AACzB,EAAE,OAAO,EAAE,CAAC,QAAA,KAAa,UAAU;;AAEnC;MACa,OAAA;AACb,EAAE;;AAEF,IAAI,oBAAA,GAAuB,KAAK;AAChC;AACO,MAAM,oBAAoB;AACjC,IAAI,CAAC,IAAI,KAAuB;AAChC,MAAM,IAAI,CAAC,oBAAoB,EAAE;AACjC,QAAQ,IAAI,aAAa,CAAC,IAAI,CAAC,OAAO,CAAA,IAAK,aAAa,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE;AACpE;AACA,UAAU,oBAAA,GAAuB,IAAI;AACrC,UAAU,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC;AAC7B,QAAQ;AACR,MAAM;AACN,IAAI;AACJ,IAAI,MAAM,CAAC;;;;"}
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import { SEMANTIC_ATTRIBUTE_SENTRY_OP } from '../../semanticAttributes.js';
|
|
2
|
+
import { getHttpSpanDetailsFromUrlObject, parseStringToURLObject } from '../../utils/url.js';
|
|
3
|
+
import { getRequestUrlFromClientRequest } from './get-request-url.js';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Build the initial span name and attributes for an outgoing HTTP request.
|
|
7
|
+
* This is called before the span is created, to get the initial details.
|
|
8
|
+
*/
|
|
9
|
+
function getOutgoingRequestSpanData(request) {
|
|
10
|
+
const url = getRequestUrlFromClientRequest(request);
|
|
11
|
+
const [name, attributes] = getHttpSpanDetailsFromUrlObject(
|
|
12
|
+
parseStringToURLObject(url),
|
|
13
|
+
'client',
|
|
14
|
+
'auto.http.client',
|
|
15
|
+
request,
|
|
16
|
+
);
|
|
17
|
+
|
|
18
|
+
const userAgent = request.getHeader('user-agent');
|
|
19
|
+
|
|
20
|
+
return {
|
|
21
|
+
name,
|
|
22
|
+
attributes: {
|
|
23
|
+
// TODO(v11): Update these to the Sentry semantic attributes for urls.
|
|
24
|
+
// https://getsentry.github.io/sentry-conventions/attributes/
|
|
25
|
+
[SEMANTIC_ATTRIBUTE_SENTRY_OP]: 'http.client',
|
|
26
|
+
'otel.kind': 'CLIENT',
|
|
27
|
+
'http.url': url,
|
|
28
|
+
'http.method': request.method,
|
|
29
|
+
'http.target': request.path || '/',
|
|
30
|
+
'net.peer.name': request.host,
|
|
31
|
+
'http.host': request.getHeader('host') ,
|
|
32
|
+
...(userAgent ? { 'user_agent.original': userAgent } : {}),
|
|
33
|
+
...attributes,
|
|
34
|
+
},
|
|
35
|
+
onlyIfParent: true,
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Add span attributes once the response is received.
|
|
41
|
+
*/
|
|
42
|
+
function setIncomingResponseSpanData(response, span) {
|
|
43
|
+
const { statusCode, statusMessage, httpVersion, socket } = response;
|
|
44
|
+
const transport = httpVersion?.toUpperCase() !== 'QUIC' ? 'ip_tcp' : 'ip_udp';
|
|
45
|
+
|
|
46
|
+
span.setAttributes({
|
|
47
|
+
'http.response.status_code': statusCode,
|
|
48
|
+
'network.protocol.version': httpVersion,
|
|
49
|
+
// TODO(v11): Update these to the Sentry semantic attributes for urls.
|
|
50
|
+
// https://getsentry.github.io/sentry-conventions/attributes/
|
|
51
|
+
'http.flavor': httpVersion,
|
|
52
|
+
'network.transport': transport,
|
|
53
|
+
'net.transport': transport,
|
|
54
|
+
'http.status_text': statusMessage?.toUpperCase(),
|
|
55
|
+
'http.status_code': statusCode,
|
|
56
|
+
...getResponseContentLengthAttributes(response),
|
|
57
|
+
...getSocketAttrs(socket),
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
function getSocketAttrs(socket) {
|
|
62
|
+
if (!socket) return {};
|
|
63
|
+
const { remoteAddress, remotePort } = socket;
|
|
64
|
+
return {
|
|
65
|
+
'network.peer.address': remoteAddress,
|
|
66
|
+
'network.peer.port': remotePort,
|
|
67
|
+
'net.peer.ip': remoteAddress,
|
|
68
|
+
'net.peer.port': remotePort,
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
function getResponseContentLengthAttributes(response) {
|
|
73
|
+
const { headers } = response;
|
|
74
|
+
const contentLengthHeader = headers['content-length'];
|
|
75
|
+
const length = contentLengthHeader ? parseInt(String(contentLengthHeader), 10) : -1;
|
|
76
|
+
const encoding = headers['content-encoding'];
|
|
77
|
+
return length >= 0
|
|
78
|
+
? encoding && encoding !== 'identity'
|
|
79
|
+
? { 'http.response_content_length': length }
|
|
80
|
+
: { 'http.response_content_length_uncompressed': length }
|
|
81
|
+
: {};
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
export { getOutgoingRequestSpanData, setIncomingResponseSpanData };
|
|
85
|
+
//# sourceMappingURL=get-outgoing-span-data.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"get-outgoing-span-data.js","sources":["../../../../src/integrations/http/get-outgoing-span-data.ts"],"sourcesContent":["import type { Span, SpanAttributes } from '../../types-hoist/span';\nimport { SEMANTIC_ATTRIBUTE_SENTRY_OP } from '../../semanticAttributes';\nimport { getHttpSpanDetailsFromUrlObject, parseStringToURLObject } from '../../utils/url';\nimport type { HttpClientRequest, HttpIncomingMessage } from './types';\nimport { getRequestUrlFromClientRequest } from './get-request-url';\nimport type { StartSpanOptions } from '../../types-hoist/startSpanOptions';\n\n/**\n * Build the initial span name and attributes for an outgoing HTTP request.\n * This is called before the span is created, to get the initial details.\n */\nexport function getOutgoingRequestSpanData(request: HttpClientRequest): StartSpanOptions {\n const url = getRequestUrlFromClientRequest(request);\n const [name, attributes] = getHttpSpanDetailsFromUrlObject(\n parseStringToURLObject(url),\n 'client',\n 'auto.http.client',\n request,\n );\n\n const userAgent = request.getHeader('user-agent');\n\n return {\n name,\n attributes: {\n // TODO(v11): Update these to the Sentry semantic attributes for urls.\n // https://getsentry.github.io/sentry-conventions/attributes/\n [SEMANTIC_ATTRIBUTE_SENTRY_OP]: 'http.client',\n 'otel.kind': 'CLIENT',\n 'http.url': url,\n 'http.method': request.method,\n 'http.target': request.path || '/',\n 'net.peer.name': request.host,\n 'http.host': request.getHeader('host') as string | undefined,\n ...(userAgent ? { 'user_agent.original': userAgent as string } : {}),\n ...attributes,\n },\n onlyIfParent: true,\n };\n}\n\n/**\n * Add span attributes once the response is received.\n */\nexport function setIncomingResponseSpanData(response: HttpIncomingMessage, span: Span): void {\n const { statusCode, statusMessage, httpVersion, socket } = response;\n const transport = httpVersion?.toUpperCase() !== 'QUIC' ? 'ip_tcp' : 'ip_udp';\n\n span.setAttributes({\n 'http.response.status_code': statusCode,\n 'network.protocol.version': httpVersion,\n // TODO(v11): Update these to the Sentry semantic attributes for urls.\n // https://getsentry.github.io/sentry-conventions/attributes/\n 'http.flavor': httpVersion,\n 'network.transport': transport,\n 'net.transport': transport,\n 'http.status_text': statusMessage?.toUpperCase(),\n 'http.status_code': statusCode,\n ...getResponseContentLengthAttributes(response),\n ...getSocketAttrs(socket),\n });\n}\n\nfunction getSocketAttrs(socket: HttpIncomingMessage['socket']): SpanAttributes {\n if (!socket) return {};\n const { remoteAddress, remotePort } = socket;\n return {\n 'network.peer.address': remoteAddress,\n 'network.peer.port': remotePort,\n 'net.peer.ip': remoteAddress,\n 'net.peer.port': remotePort,\n };\n}\n\nfunction getResponseContentLengthAttributes(response: HttpIncomingMessage): SpanAttributes {\n const { headers } = response;\n const contentLengthHeader = headers['content-length'];\n const length = contentLengthHeader ? parseInt(String(contentLengthHeader), 10) : -1;\n const encoding = headers['content-encoding'];\n return length >= 0\n ? encoding && encoding !== 'identity'\n ? { 'http.response_content_length': length }\n : { 'http.response_content_length_uncompressed': length }\n : {};\n}\n"],"names":[],"mappings":";;;;AAOA;AACA;AACA;AACA;AACO,SAAS,0BAA0B,CAAC,OAAO,EAAuC;AACzF,EAAE,MAAM,GAAA,GAAM,8BAA8B,CAAC,OAAO,CAAC;AACrD,EAAE,MAAM,CAAC,IAAI,EAAE,UAAU,CAAA,GAAI,+BAA+B;AAC5D,IAAI,sBAAsB,CAAC,GAAG,CAAC;AAC/B,IAAI,QAAQ;AACZ,IAAI,kBAAkB;AACtB,IAAI,OAAO;AACX,GAAG;;AAEH,EAAE,MAAM,YAAY,OAAO,CAAC,SAAS,CAAC,YAAY,CAAC;;AAEnD,EAAE,OAAO;AACT,IAAI,IAAI;AACR,IAAI,UAAU,EAAE;AAChB;AACA;AACA,MAAM,CAAC,4BAA4B,GAAG,aAAa;AACnD,MAAM,WAAW,EAAE,QAAQ;AAC3B,MAAM,UAAU,EAAE,GAAG;AACrB,MAAM,aAAa,EAAE,OAAO,CAAC,MAAM;AACnC,MAAM,aAAa,EAAE,OAAO,CAAC,IAAA,IAAQ,GAAG;AACxC,MAAM,eAAe,EAAE,OAAO,CAAC,IAAI;AACnC,MAAM,WAAW,EAAE,OAAO,CAAC,SAAS,CAAC,MAAM,CAAA;AAC3C,MAAM,IAAI,SAAA,GAAY,EAAE,qBAAqB,EAAE,SAAA,GAAoB,GAAI,EAAE,CAAC;AAC1E,MAAM,GAAG,UAAU;AACnB,KAAK;AACL,IAAI,YAAY,EAAE,IAAI;AACtB,GAAG;AACH;;AAEA;AACA;AACA;AACO,SAAS,2BAA2B,CAAC,QAAQ,EAAuB,IAAI,EAAc;AAC7F,EAAE,MAAM,EAAE,UAAU,EAAE,aAAa,EAAE,WAAW,EAAE,MAAA,EAAO,GAAI,QAAQ;AACrE,EAAE,MAAM,SAAA,GAAY,WAAW,EAAE,WAAW,EAAC,KAAM,MAAA,GAAS,QAAA,GAAW,QAAQ;;AAE/E,EAAE,IAAI,CAAC,aAAa,CAAC;AACrB,IAAI,2BAA2B,EAAE,UAAU;AAC3C,IAAI,0BAA0B,EAAE,WAAW;AAC3C;AACA;AACA,IAAI,aAAa,EAAE,WAAW;AAC9B,IAAI,mBAAmB,EAAE,SAAS;AAClC,IAAI,eAAe,EAAE,SAAS;AAC9B,IAAI,kBAAkB,EAAE,aAAa,EAAE,WAAW,EAAE;AACpD,IAAI,kBAAkB,EAAE,UAAU;AAClC,IAAI,GAAG,kCAAkC,CAAC,QAAQ,CAAC;AACnD,IAAI,GAAG,cAAc,CAAC,MAAM,CAAC;AAC7B,GAAG,CAAC;AACJ;;AAEA,SAAS,cAAc,CAAC,MAAM,EAAiD;AAC/E,EAAE,IAAI,CAAC,MAAM,EAAE,OAAO,EAAE;AACxB,EAAE,MAAM,EAAE,aAAa,EAAE,UAAA,EAAW,GAAI,MAAM;AAC9C,EAAE,OAAO;AACT,IAAI,sBAAsB,EAAE,aAAa;AACzC,IAAI,mBAAmB,EAAE,UAAU;AACnC,IAAI,aAAa,EAAE,aAAa;AAChC,IAAI,eAAe,EAAE,UAAU;AAC/B,GAAG;AACH;;AAEA,SAAS,kCAAkC,CAAC,QAAQ,EAAuC;AAC3F,EAAE,MAAM,EAAE,OAAA,EAAQ,GAAI,QAAQ;AAC9B,EAAE,MAAM,mBAAA,GAAsB,OAAO,CAAC,gBAAgB,CAAC;AACvD,EAAE,MAAM,MAAA,GAAS,mBAAA,GAAsB,QAAQ,CAAC,MAAM,CAAC,mBAAmB,CAAC,EAAE,EAAE,CAAA,GAAI,EAAE;AACrF,EAAE,MAAM,QAAA,GAAW,OAAO,CAAC,kBAAkB,CAAC;AAC9C,EAAE,OAAO,UAAU;AACnB,MAAM,QAAA,IAAY,QAAA,KAAa;AAC/B,QAAQ,EAAE,8BAA8B,EAAE,MAAA;AAC1C,QAAQ,EAAE,2CAA2C,EAAE,MAAA;AACvD,MAAM,EAAE;AACR;;;;"}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/** Convert an outgoing request to request options. */
|
|
2
|
+
function getRequestOptions(request) {
|
|
3
|
+
// request.host may be 'hostname:port' when the caller passed
|
|
4
|
+
// { host: 'hostname:port' } to http.request(). Split it so that
|
|
5
|
+
// `hostname` is always port-free (matching the http.RequestOptions contract)
|
|
6
|
+
// and the port is not lost when request.port is undefined.
|
|
7
|
+
const hostWithPort = request.host || '';
|
|
8
|
+
const portInHost = /^(.*):(\d+)$/.exec(hostWithPort);
|
|
9
|
+
const hostname = portInHost ? portInHost[1] : hostWithPort;
|
|
10
|
+
const port = request.port ?? (portInHost ? Number(portInHost[2]) : undefined);
|
|
11
|
+
|
|
12
|
+
return {
|
|
13
|
+
method: request.method,
|
|
14
|
+
port,
|
|
15
|
+
protocol: request.protocol,
|
|
16
|
+
host: request.host,
|
|
17
|
+
hostname,
|
|
18
|
+
path: request.path,
|
|
19
|
+
headers: request.getHeaders(),
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
function getRequestUrl(requestOptions) {
|
|
24
|
+
return String(getRequestUrlObject(requestOptions));
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
function getRequestUrlObject(requestOptions) {
|
|
28
|
+
const protocol = requestOptions.protocol || 'http:';
|
|
29
|
+
const hostHeader = requestOptions.headers?.host && String(requestOptions.headers?.host);
|
|
30
|
+
const hostname = hostHeader || requestOptions.hostname || requestOptions.host || '';
|
|
31
|
+
// Don't log standard :80 (http) and :443 (https) ports to reduce the noise
|
|
32
|
+
// Also don't add port if the hostname already includes a port
|
|
33
|
+
const port =
|
|
34
|
+
!requestOptions.port || requestOptions.port === 80 || requestOptions.port === 443 || /^(.*):(\d+)$/.test(hostname)
|
|
35
|
+
? ''
|
|
36
|
+
: `:${requestOptions.port}`;
|
|
37
|
+
const path = requestOptions.path ? requestOptions.path : '/';
|
|
38
|
+
return new URL(path, `${protocol}//${hostname}${port}`);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Build the full URL string from a Node.js ClientRequest.
|
|
43
|
+
*/
|
|
44
|
+
function getRequestUrlFromClientRequest(request) {
|
|
45
|
+
return String(getRequestUrl(getRequestOptions(request)));
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
export { getRequestOptions, getRequestUrl, getRequestUrlFromClientRequest, getRequestUrlObject };
|
|
49
|
+
//# sourceMappingURL=get-request-url.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"get-request-url.js","sources":["../../../../src/integrations/http/get-request-url.ts"],"sourcesContent":["import type { HttpClientRequest, HttpRequestOptions } from './types';\n\n/** Convert an outgoing request to request options. */\nexport function getRequestOptions(request: HttpClientRequest): HttpRequestOptions {\n // request.host may be 'hostname:port' when the caller passed\n // { host: 'hostname:port' } to http.request(). Split it so that\n // `hostname` is always port-free (matching the http.RequestOptions contract)\n // and the port is not lost when request.port is undefined.\n const hostWithPort = request.host || '';\n const portInHost = /^(.*):(\\d+)$/.exec(hostWithPort);\n const hostname = portInHost ? portInHost[1] : hostWithPort;\n const port = request.port ?? (portInHost ? Number(portInHost[2]) : undefined);\n\n return {\n method: request.method,\n port,\n protocol: request.protocol,\n host: request.host,\n hostname,\n path: request.path,\n headers: request.getHeaders(),\n };\n}\n\nexport function getRequestUrl(requestOptions: HttpRequestOptions): string {\n return String(getRequestUrlObject(requestOptions));\n}\n\nexport function getRequestUrlObject(requestOptions: HttpRequestOptions): URL {\n const protocol = requestOptions.protocol || 'http:';\n const hostHeader = requestOptions.headers?.host && String(requestOptions.headers?.host);\n const hostname = hostHeader || requestOptions.hostname || requestOptions.host || '';\n // Don't log standard :80 (http) and :443 (https) ports to reduce the noise\n // Also don't add port if the hostname already includes a port\n const port =\n !requestOptions.port || requestOptions.port === 80 || requestOptions.port === 443 || /^(.*):(\\d+)$/.test(hostname)\n ? ''\n : `:${requestOptions.port}`;\n const path = requestOptions.path ? requestOptions.path : '/';\n return new URL(path, `${protocol}//${hostname}${port}`);\n}\n\n/**\n * Build the full URL string from a Node.js ClientRequest.\n */\nexport function getRequestUrlFromClientRequest(request: HttpClientRequest): string {\n return String(getRequestUrl(getRequestOptions(request)));\n}\n"],"names":[],"mappings":"AAEA;AACO,SAAS,iBAAiB,CAAC,OAAO,EAAyC;AAClF;AACA;AACA;AACA;AACA,EAAE,MAAM,YAAA,GAAe,OAAO,CAAC,IAAA,IAAQ,EAAE;AACzC,EAAE,MAAM,aAAa,cAAc,CAAC,IAAI,CAAC,YAAY,CAAC;AACtD,EAAE,MAAM,QAAA,GAAW,UAAA,GAAa,UAAU,CAAC,CAAC,CAAA,GAAI,YAAY;AAC5D,EAAE,MAAM,IAAA,GAAO,OAAO,CAAC,IAAA,KAAS,UAAA,GAAa,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC,CAAA,GAAI,SAAS,CAAC;;AAE/E,EAAE,OAAO;AACT,IAAI,MAAM,EAAE,OAAO,CAAC,MAAM;AAC1B,IAAI,IAAI;AACR,IAAI,QAAQ,EAAE,OAAO,CAAC,QAAQ;AAC9B,IAAI,IAAI,EAAE,OAAO,CAAC,IAAI;AACtB,IAAI,QAAQ;AACZ,IAAI,IAAI,EAAE,OAAO,CAAC,IAAI;AACtB,IAAI,OAAO,EAAE,OAAO,CAAC,UAAU,EAAE;AACjC,GAAG;AACH;;AAEO,SAAS,aAAa,CAAC,cAAc,EAA8B;AAC1E,EAAE,OAAO,MAAM,CAAC,mBAAmB,CAAC,cAAc,CAAC,CAAC;AACpD;;AAEO,SAAS,mBAAmB,CAAC,cAAc,EAA2B;AAC7E,EAAE,MAAM,QAAA,GAAW,cAAc,CAAC,QAAA,IAAY,OAAO;AACrD,EAAE,MAAM,UAAA,GAAa,cAAc,CAAC,OAAO,EAAE,IAAA,IAAQ,MAAM,CAAC,cAAc,CAAC,OAAO,EAAE,IAAI,CAAC;AACzF,EAAE,MAAM,QAAA,GAAW,UAAA,IAAc,cAAc,CAAC,QAAA,IAAY,cAAc,CAAC,IAAA,IAAQ,EAAE;AACrF;AACA;AACA,EAAE,MAAM,IAAA;AACR,IAAI,CAAC,cAAc,CAAC,IAAA,IAAQ,cAAc,CAAC,SAAS,EAAA,IAAM,cAAc,CAAC,SAAS,GAAA,IAAO,cAAc,CAAC,IAAI,CAAC,QAAQ;AACrH,QAAQ;AACR,QAAQ,CAAC,CAAC,EAAE,cAAc,CAAC,IAAI,CAAC,CAAA;AACA,EAAA,MAAA,IAAA,GAAA,cAAA,CAAA,IAAA,GAAA,cAAA,CAAA,IAAA,GAAA,GAAA;AACA,EAAA,OAAA,IAAA,GAAA,CAAA,IAAA,EAAA,CAAA,EAAA,QAAA,CAAA,EAAA,EAAA,QAAA,CAAA,EAAA,IAAA,CAAA,CAAA,CAAA;AACA;;AAEA;AACA;AACA;AACA,SAAA,8BAAA,CAAA,OAAA,EAAA;AACA,EAAA,OAAA,MAAA,CAAA,aAAA,CAAA,iBAAA,CAAA,OAAA,CAAA,CAAA,CAAA;AACA;;;;"}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import { getClient } from '../../currentScopes.js';
|
|
2
|
+
import { DEBUG_BUILD } from '../../debug-build.js';
|
|
3
|
+
import { debug } from '../../utils/debug-logger.js';
|
|
4
|
+
import { isError } from '../../utils/is.js';
|
|
5
|
+
import { getTraceData } from '../../utils/traceData.js';
|
|
6
|
+
import { shouldPropagateTraceForUrl } from '../../utils/tracePropagationTargets.js';
|
|
7
|
+
import { LOG_PREFIX } from './constants.js';
|
|
8
|
+
import { getRequestUrlFromClientRequest } from './get-request-url.js';
|
|
9
|
+
import { mergeBaggageHeaders } from '../../utils/baggage.js';
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Inject Sentry trace-propagation headers into an outgoing request if the
|
|
13
|
+
* target URL matches the configured `tracePropagationTargets`.
|
|
14
|
+
*
|
|
15
|
+
* Note: this must be called *before* calling `request.end()` (or firing the
|
|
16
|
+
* `http.client.request.start` diagnostics channel), because at that point,
|
|
17
|
+
* the headers have already been sent, and cannot be modified.
|
|
18
|
+
*/
|
|
19
|
+
function injectTracePropagationHeaders(
|
|
20
|
+
request,
|
|
21
|
+
propagationDecisionMap,
|
|
22
|
+
) {
|
|
23
|
+
const url = getRequestUrlFromClientRequest(request);
|
|
24
|
+
const clientOptions = getClient()?.getOptions();
|
|
25
|
+
const { tracePropagationTargets, propagateTraceparent } = clientOptions ?? {};
|
|
26
|
+
|
|
27
|
+
if (!shouldPropagateTraceForUrl(url, tracePropagationTargets, propagationDecisionMap)) {
|
|
28
|
+
return;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
const hasExistingSentryTraceHeader = !!request.getHeader('sentry-trace');
|
|
32
|
+
|
|
33
|
+
if (hasExistingSentryTraceHeader) {
|
|
34
|
+
// add nothing if there's already a sentry-trace header,
|
|
35
|
+
// or else baggage can be sent twice.
|
|
36
|
+
return;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
const traceData = getTraceData({ propagateTraceparent });
|
|
40
|
+
if (!traceData) return;
|
|
41
|
+
|
|
42
|
+
const { 'sentry-trace': sentryTrace, baggage, traceparent } = traceData;
|
|
43
|
+
|
|
44
|
+
if (sentryTrace) {
|
|
45
|
+
try {
|
|
46
|
+
request.setHeader('sentry-trace', sentryTrace);
|
|
47
|
+
DEBUG_BUILD && debug.log(LOG_PREFIX, 'Added sentry-trace header');
|
|
48
|
+
} catch (e) {
|
|
49
|
+
DEBUG_BUILD &&
|
|
50
|
+
debug.error(LOG_PREFIX, 'Failed to set sentry-trace header:', isError(e) ? e.message : 'Unknown error');
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
if (traceparent && !request.getHeader('traceparent')) {
|
|
55
|
+
try {
|
|
56
|
+
request.setHeader('traceparent', traceparent);
|
|
57
|
+
DEBUG_BUILD && debug.log(LOG_PREFIX, 'Added traceparent header');
|
|
58
|
+
} catch (e) {
|
|
59
|
+
DEBUG_BUILD &&
|
|
60
|
+
debug.error(LOG_PREFIX, 'Failed to set traceparent header:', isError(e) ? e.message : 'Unknown error');
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
if (baggage) {
|
|
65
|
+
const merged = mergeBaggageHeaders(request.getHeader('baggage'), baggage);
|
|
66
|
+
if (merged) {
|
|
67
|
+
try {
|
|
68
|
+
request.setHeader('baggage', merged);
|
|
69
|
+
DEBUG_BUILD && debug.log(LOG_PREFIX, 'Added baggage header');
|
|
70
|
+
} catch (e) {
|
|
71
|
+
DEBUG_BUILD &&
|
|
72
|
+
debug.error(LOG_PREFIX, 'Failed to set baggage header:', isError(e) ? e.message : 'Unknown error');
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
export { injectTracePropagationHeaders };
|
|
79
|
+
//# sourceMappingURL=inject-trace-propagation-headers.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"inject-trace-propagation-headers.js","sources":["../../../../src/integrations/http/inject-trace-propagation-headers.ts"],"sourcesContent":["import type { LRUMap } from '../../utils/lru';\nimport { getClient } from '../../currentScopes';\nimport { DEBUG_BUILD } from '../../debug-build';\nimport { debug } from '../../utils/debug-logger';\nimport { isError } from '../../utils/is';\nimport { getTraceData } from '../../utils/traceData';\nimport { shouldPropagateTraceForUrl } from '../../utils/tracePropagationTargets';\nimport { LOG_PREFIX } from './constants';\nimport { getRequestUrlFromClientRequest } from './get-request-url';\nimport type { HttpClientRequest } from './types';\nimport { mergeBaggageHeaders } from '../../utils/baggage';\n\n/**\n * Inject Sentry trace-propagation headers into an outgoing request if the\n * target URL matches the configured `tracePropagationTargets`.\n *\n * Note: this must be called *before* calling `request.end()` (or firing the\n * `http.client.request.start` diagnostics channel), because at that point,\n * the headers have already been sent, and cannot be modified.\n */\nexport function injectTracePropagationHeaders(\n request: HttpClientRequest,\n propagationDecisionMap: LRUMap<string, boolean>,\n): void {\n const url = getRequestUrlFromClientRequest(request);\n const clientOptions = getClient()?.getOptions();\n const { tracePropagationTargets, propagateTraceparent } = clientOptions ?? {};\n\n if (!shouldPropagateTraceForUrl(url, tracePropagationTargets, propagationDecisionMap)) {\n return;\n }\n\n const hasExistingSentryTraceHeader = !!request.getHeader('sentry-trace');\n\n if (hasExistingSentryTraceHeader) {\n // add nothing if there's already a sentry-trace header,\n // or else baggage can be sent twice.\n return;\n }\n\n const traceData = getTraceData({ propagateTraceparent });\n if (!traceData) return;\n\n const { 'sentry-trace': sentryTrace, baggage, traceparent } = traceData;\n\n if (sentryTrace) {\n try {\n request.setHeader('sentry-trace', sentryTrace);\n DEBUG_BUILD && debug.log(LOG_PREFIX, 'Added sentry-trace header');\n } catch (e) {\n DEBUG_BUILD &&\n debug.error(LOG_PREFIX, 'Failed to set sentry-trace header:', isError(e) ? e.message : 'Unknown error');\n }\n }\n\n if (traceparent && !request.getHeader('traceparent')) {\n try {\n request.setHeader('traceparent', traceparent);\n DEBUG_BUILD && debug.log(LOG_PREFIX, 'Added traceparent header');\n } catch (e) {\n DEBUG_BUILD &&\n debug.error(LOG_PREFIX, 'Failed to set traceparent header:', isError(e) ? e.message : 'Unknown error');\n }\n }\n\n if (baggage) {\n const merged = mergeBaggageHeaders(request.getHeader('baggage'), baggage);\n if (merged) {\n try {\n request.setHeader('baggage', merged);\n DEBUG_BUILD && debug.log(LOG_PREFIX, 'Added baggage header');\n } catch (e) {\n DEBUG_BUILD &&\n debug.error(LOG_PREFIX, 'Failed to set baggage header:', isError(e) ? e.message : 'Unknown error');\n }\n }\n }\n}\n"],"names":[],"mappings":";;;;;;;;;;AAYA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACO,SAAS,6BAA6B;AAC7C,EAAE,OAAO;AACT,EAAE,sBAAsB;AACxB,EAAQ;AACR,EAAE,MAAM,GAAA,GAAM,8BAA8B,CAAC,OAAO,CAAC;AACrD,EAAE,MAAM,gBAAgB,SAAS,EAAE,EAAE,UAAU,EAAE;AACjD,EAAE,MAAM,EAAE,uBAAuB,EAAE,oBAAA,KAAyB,aAAA,IAAiB,EAAE;;AAE/E,EAAE,IAAI,CAAC,0BAA0B,CAAC,GAAG,EAAE,uBAAuB,EAAE,sBAAsB,CAAC,EAAE;AACzF,IAAI;AACJ,EAAE;;AAEF,EAAE,MAAM,4BAAA,GAA+B,CAAC,CAAC,OAAO,CAAC,SAAS,CAAC,cAAc,CAAC;;AAE1E,EAAE,IAAI,4BAA4B,EAAE;AACpC;AACA;AACA,IAAI;AACJ,EAAE;;AAEF,EAAE,MAAM,YAAY,YAAY,CAAC,EAAE,oBAAA,EAAsB,CAAC;AAC1D,EAAE,IAAI,CAAC,SAAS,EAAE;;AAElB,EAAE,MAAM,EAAE,cAAc,EAAE,WAAW,EAAE,OAAO,EAAE,WAAA,EAAY,GAAI,SAAS;;AAEzE,EAAE,IAAI,WAAW,EAAE;AACnB,IAAI,IAAI;AACR,MAAM,OAAO,CAAC,SAAS,CAAC,cAAc,EAAE,WAAW,CAAC;AACpD,MAAM,WAAA,IAAe,KAAK,CAAC,GAAG,CAAC,UAAU,EAAE,2BAA2B,CAAC;AACvE,IAAI,CAAA,CAAE,OAAO,CAAC,EAAE;AAChB,MAAM,WAAA;AACN,QAAQ,KAAK,CAAC,KAAK,CAAC,UAAU,EAAE,oCAAoC,EAAE,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,OAAA,GAAU,eAAe,CAAC;AAC/G,IAAI;AACJ,EAAE;;AAEF,EAAE,IAAI,WAAA,IAAe,CAAC,OAAO,CAAC,SAAS,CAAC,aAAa,CAAC,EAAE;AACxD,IAAI,IAAI;AACR,MAAM,OAAO,CAAC,SAAS,CAAC,aAAa,EAAE,WAAW,CAAC;AACnD,MAAM,WAAA,IAAe,KAAK,CAAC,GAAG,CAAC,UAAU,EAAE,0BAA0B,CAAC;AACtE,IAAI,CAAA,CAAE,OAAO,CAAC,EAAE;AAChB,MAAM,WAAA;AACN,QAAQ,KAAK,CAAC,KAAK,CAAC,UAAU,EAAE,mCAAmC,EAAE,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,OAAA,GAAU,eAAe,CAAC;AAC9G,IAAI;AACJ,EAAE;;AAEF,EAAE,IAAI,OAAO,EAAE;AACf,IAAI,MAAM,MAAA,GAAS,mBAAmB,CAAC,OAAO,CAAC,SAAS,CAAC,SAAS,CAAC,EAAE,OAAO,CAAC;AAC7E,IAAI,IAAI,MAAM,EAAE;AAChB,MAAM,IAAI;AACV,QAAQ,OAAO,CAAC,SAAS,CAAC,SAAS,EAAE,MAAM,CAAC;AAC5C,QAAQ,WAAA,IAAe,KAAK,CAAC,GAAG,CAAC,UAAU,EAAE,sBAAsB,CAAC;AACpE,MAAM,CAAA,CAAE,OAAO,CAAC,EAAE;AAClB,QAAQ,WAAA;AACR,UAAU,KAAK,CAAC,KAAK,CAAC,UAAU,EAAE,+BAA+B,EAAE,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,OAAA,GAAU,eAAe,CAAC;AAC5G,MAAM;AACN,IAAI;AACJ,EAAE;AACF;;;;"}
|
|
@@ -1,6 +1,10 @@
|
|
|
1
|
+
import { getIsolationScope } from '../currentScopes.js';
|
|
1
2
|
import { defineIntegration } from '../integration.js';
|
|
3
|
+
import { SEMANTIC_ATTRIBUTE_USER_IP_ADDRESS } from '../semanticAttributes.js';
|
|
2
4
|
import { parseCookie } from '../utils/cookie.js';
|
|
5
|
+
import { httpHeadersToSpanAttributes } from '../utils/request.js';
|
|
3
6
|
import { getClientIPAddress, ipHeaderNames } from '../vendor/getIpAddress.js';
|
|
7
|
+
import { safeSetSpanJSONAttributes } from '../tracing/spans/captureSpan.js';
|
|
4
8
|
|
|
5
9
|
// TODO(v11): Change defaults based on `sendDefaultPii`
|
|
6
10
|
const DEFAULT_INCLUDE = {
|
|
@@ -36,6 +40,22 @@ const _requestDataIntegration = ((options = {}) => {
|
|
|
36
40
|
|
|
37
41
|
return event;
|
|
38
42
|
},
|
|
43
|
+
processSegmentSpan(span, client) {
|
|
44
|
+
const { sdkProcessingMetadata = {} } = getIsolationScope().getScopeData();
|
|
45
|
+
const { normalizedRequest, ipAddress } = sdkProcessingMetadata;
|
|
46
|
+
|
|
47
|
+
if (!normalizedRequest) {
|
|
48
|
+
return;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
const { sendDefaultPii } = client.getOptions();
|
|
52
|
+
const includeWithDefaultPiiApplied = {
|
|
53
|
+
...include,
|
|
54
|
+
ip: include.ip ?? sendDefaultPii,
|
|
55
|
+
};
|
|
56
|
+
|
|
57
|
+
addNormalizedRequestDataToSpan(span, normalizedRequest, ipAddress, includeWithDefaultPiiApplied, sendDefaultPii);
|
|
58
|
+
},
|
|
39
59
|
};
|
|
40
60
|
}) ;
|
|
41
61
|
|
|
@@ -72,6 +92,60 @@ function addNormalizedRequestDataToEvent(
|
|
|
72
92
|
}
|
|
73
93
|
}
|
|
74
94
|
|
|
95
|
+
function addNormalizedRequestDataToSpan(
|
|
96
|
+
span,
|
|
97
|
+
normalizedRequest,
|
|
98
|
+
ipAddress,
|
|
99
|
+
include,
|
|
100
|
+
sendDefaultPii,
|
|
101
|
+
) {
|
|
102
|
+
const requestData = extractNormalizedRequestData(normalizedRequest, include);
|
|
103
|
+
const attributes = {};
|
|
104
|
+
|
|
105
|
+
if (requestData.url) {
|
|
106
|
+
attributes['url.full'] = requestData.url;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
if (requestData.method) {
|
|
110
|
+
attributes['http.request.method'] = requestData.method;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
if (requestData.query_string) {
|
|
114
|
+
attributes['url.query'] = normalizeQueryString(requestData.query_string);
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
safeSetSpanJSONAttributes(span, attributes);
|
|
118
|
+
|
|
119
|
+
// Process cookies before headers so normalizedRequest.cookies takes precedence
|
|
120
|
+
// over the raw cookie header (matching the processEvent path).
|
|
121
|
+
if (requestData.cookies && Object.keys(requestData.cookies).length > 0) {
|
|
122
|
+
const cookieString = Object.entries(requestData.cookies)
|
|
123
|
+
.map(([name, value]) => `${name}=${value}`)
|
|
124
|
+
.join('; ');
|
|
125
|
+
const cookieAttributes = httpHeadersToSpanAttributes({ cookie: cookieString }, sendDefaultPii ?? false, 'request');
|
|
126
|
+
safeSetSpanJSONAttributes(span, cookieAttributes);
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
if (requestData.headers) {
|
|
130
|
+
const headerAttributes = httpHeadersToSpanAttributes(requestData.headers, sendDefaultPii ?? false, 'request');
|
|
131
|
+
safeSetSpanJSONAttributes(span, headerAttributes);
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
if (requestData.data != null) {
|
|
135
|
+
const serialized = typeof requestData.data === 'string' ? requestData.data : JSON.stringify(requestData.data);
|
|
136
|
+
if (serialized) {
|
|
137
|
+
safeSetSpanJSONAttributes(span, { 'http.request.body.data': serialized });
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
if (include.ip) {
|
|
142
|
+
const ip = (normalizedRequest.headers && getClientIPAddress(normalizedRequest.headers)) || ipAddress || undefined;
|
|
143
|
+
if (ip) {
|
|
144
|
+
safeSetSpanJSONAttributes(span, { [SEMANTIC_ATTRIBUTE_USER_IP_ADDRESS]: ip });
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
|
|
75
149
|
function extractNormalizedRequestData(
|
|
76
150
|
normalizedRequest,
|
|
77
151
|
include,
|
|
@@ -82,13 +156,10 @@ function extractNormalizedRequestData(
|
|
|
82
156
|
if (include.headers) {
|
|
83
157
|
requestData.headers = headers;
|
|
84
158
|
|
|
85
|
-
// Remove the Cookie header in case cookie data should not be included in the event
|
|
86
159
|
if (!include.cookies) {
|
|
87
160
|
delete (headers ).cookie;
|
|
88
161
|
}
|
|
89
162
|
|
|
90
|
-
// Remove IP headers in case IP data should not be included in the event.
|
|
91
|
-
// Match case-insensitively — same as getClientIPAddress — so lowercase keys are stripped too.
|
|
92
163
|
if (!include.ip) {
|
|
93
164
|
const ipHeaderNamesLower = new Set(ipHeaderNames.map(name => name.toLowerCase()));
|
|
94
165
|
for (const key of Object.keys(headers)) {
|
|
@@ -122,5 +193,16 @@ function extractNormalizedRequestData(
|
|
|
122
193
|
return requestData;
|
|
123
194
|
}
|
|
124
195
|
|
|
196
|
+
function normalizeQueryString(queryString) {
|
|
197
|
+
if (typeof queryString === 'string') {
|
|
198
|
+
return queryString || undefined;
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
const pairs = Array.isArray(queryString) ? queryString : Object.entries(queryString);
|
|
202
|
+
const result = pairs.map(([key, value]) => `${key}=${value}`).join('&');
|
|
203
|
+
|
|
204
|
+
return result || undefined;
|
|
205
|
+
}
|
|
206
|
+
|
|
125
207
|
export { requestDataIntegration };
|
|
126
208
|
//# sourceMappingURL=requestdata.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"requestdata.js","sources":["../../../src/integrations/requestdata.ts"],"sourcesContent":["import { defineIntegration } from '../integration';\nimport type { Event } from '../types-hoist/event';\nimport type { IntegrationFn } from '../types-hoist/integration';\nimport type { RequestEventData } from '../types-hoist/request';\nimport { parseCookie } from '../utils/cookie';\nimport { getClientIPAddress, ipHeaderNames } from '../vendor/getIpAddress';\n\ninterface RequestDataIncludeOptions {\n cookies?: boolean;\n data?: boolean;\n headers?: boolean;\n ip?: boolean;\n query_string?: boolean;\n url?: boolean;\n}\n\ntype RequestDataIntegrationOptions = {\n /**\n * Controls what data is pulled from the request and added to the event.\n */\n include?: RequestDataIncludeOptions;\n};\n\n// TODO(v11): Change defaults based on `sendDefaultPii`\nconst DEFAULT_INCLUDE: RequestDataIncludeOptions = {\n cookies: true,\n data: true,\n headers: true,\n query_string: true,\n url: true,\n};\n\nconst INTEGRATION_NAME = 'RequestData';\n\nconst _requestDataIntegration = ((options: RequestDataIntegrationOptions = {}) => {\n const include = {\n ...DEFAULT_INCLUDE,\n ...options.include,\n };\n\n return {\n name: INTEGRATION_NAME,\n processEvent(event, _hint, client) {\n const { sdkProcessingMetadata = {} } = event;\n const { normalizedRequest, ipAddress } = sdkProcessingMetadata;\n\n const includeWithDefaultPiiApplied: RequestDataIncludeOptions = {\n ...include,\n ip: include.ip ?? client.getOptions().sendDefaultPii,\n };\n\n if (normalizedRequest) {\n addNormalizedRequestDataToEvent(event, normalizedRequest, { ipAddress }, includeWithDefaultPiiApplied);\n }\n\n return event;\n },\n };\n}) satisfies IntegrationFn;\n\n/**\n * Add data about a request to an event. Primarily for use in Node-based SDKs, but included in `@sentry/core`\n * so it can be used in cross-platform SDKs like `@sentry/nextjs`.\n */\nexport const requestDataIntegration = defineIntegration(_requestDataIntegration);\n\n/**\n * Add already normalized request data to an event.\n * This mutates the passed in event.\n */\nfunction addNormalizedRequestDataToEvent(\n event: Event,\n req: RequestEventData,\n // Data that should not go into `event.request` but is somehow related to requests\n additionalData: { ipAddress?: string },\n include: RequestDataIncludeOptions,\n): void {\n event.request = {\n ...event.request,\n ...extractNormalizedRequestData(req, include),\n };\n\n if (include.ip) {\n const ip = (req.headers && getClientIPAddress(req.headers)) || additionalData.ipAddress;\n if (ip) {\n event.user = {\n ...event.user,\n ip_address: ip,\n };\n }\n }\n}\n\nfunction extractNormalizedRequestData(\n normalizedRequest: RequestEventData,\n include: RequestDataIncludeOptions,\n): RequestEventData {\n const requestData: RequestEventData = {};\n const headers = { ...normalizedRequest.headers };\n\n if (include.headers) {\n requestData.headers = headers;\n\n // Remove the Cookie header in case cookie data should not be included in the event\n if (!include.cookies) {\n delete (headers as { cookie?: string }).cookie;\n }\n\n // Remove IP headers in case IP data should not be included in the event.\n // Match case-insensitively — same as getClientIPAddress — so lowercase keys are stripped too.\n if (!include.ip) {\n const ipHeaderNamesLower = new Set(ipHeaderNames.map(name => name.toLowerCase()));\n for (const key of Object.keys(headers)) {\n if (ipHeaderNamesLower.has(key.toLowerCase())) {\n // eslint-disable-next-line @typescript-eslint/no-dynamic-delete\n delete (headers as Record<string, unknown>)[key];\n }\n }\n }\n }\n\n requestData.method = normalizedRequest.method;\n\n if (include.url) {\n requestData.url = normalizedRequest.url;\n }\n\n if (include.cookies) {\n const cookies = normalizedRequest.cookies || (headers?.cookie ? parseCookie(headers.cookie) : undefined);\n requestData.cookies = cookies || {};\n }\n\n if (include.query_string) {\n requestData.query_string = normalizedRequest.query_string;\n }\n\n if (include.data) {\n requestData.data = normalizedRequest.data;\n }\n\n return requestData;\n}\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"requestdata.js","sources":["../../../src/integrations/requestdata.ts"],"sourcesContent":["import { getIsolationScope } from '../currentScopes';\nimport { defineIntegration } from '../integration';\nimport { SEMANTIC_ATTRIBUTE_USER_IP_ADDRESS } from '../semanticAttributes';\nimport type { Event } from '../types-hoist/event';\nimport type { IntegrationFn } from '../types-hoist/integration';\nimport type { QueryParams, RequestEventData } from '../types-hoist/request';\nimport type { StreamedSpanJSON } from '../types-hoist/span';\nimport { parseCookie } from '../utils/cookie';\nimport { httpHeadersToSpanAttributes } from '../utils/request';\nimport { getClientIPAddress, ipHeaderNames } from '../vendor/getIpAddress';\nimport { safeSetSpanJSONAttributes } from '../tracing/spans/captureSpan';\n\ninterface RequestDataIncludeOptions {\n cookies?: boolean;\n data?: boolean;\n headers?: boolean;\n ip?: boolean;\n query_string?: boolean;\n url?: boolean;\n}\n\ntype RequestDataIntegrationOptions = {\n /**\n * Controls what data is pulled from the request and added to the event.\n */\n include?: RequestDataIncludeOptions;\n};\n\n// TODO(v11): Change defaults based on `sendDefaultPii`\nconst DEFAULT_INCLUDE: RequestDataIncludeOptions = {\n cookies: true,\n data: true,\n headers: true,\n query_string: true,\n url: true,\n};\n\nconst INTEGRATION_NAME = 'RequestData';\n\nconst _requestDataIntegration = ((options: RequestDataIntegrationOptions = {}) => {\n const include = {\n ...DEFAULT_INCLUDE,\n ...options.include,\n };\n\n return {\n name: INTEGRATION_NAME,\n processEvent(event, _hint, client) {\n const { sdkProcessingMetadata = {} } = event;\n const { normalizedRequest, ipAddress } = sdkProcessingMetadata;\n\n const includeWithDefaultPiiApplied: RequestDataIncludeOptions = {\n ...include,\n ip: include.ip ?? client.getOptions().sendDefaultPii,\n };\n\n if (normalizedRequest) {\n addNormalizedRequestDataToEvent(event, normalizedRequest, { ipAddress }, includeWithDefaultPiiApplied);\n }\n\n return event;\n },\n processSegmentSpan(span, client) {\n const { sdkProcessingMetadata = {} } = getIsolationScope().getScopeData();\n const { normalizedRequest, ipAddress } = sdkProcessingMetadata;\n\n if (!normalizedRequest) {\n return;\n }\n\n const { sendDefaultPii } = client.getOptions();\n const includeWithDefaultPiiApplied: RequestDataIncludeOptions = {\n ...include,\n ip: include.ip ?? sendDefaultPii,\n };\n\n addNormalizedRequestDataToSpan(span, normalizedRequest, ipAddress, includeWithDefaultPiiApplied, sendDefaultPii);\n },\n };\n}) satisfies IntegrationFn;\n\n/**\n * Add data about a request to an event. Primarily for use in Node-based SDKs, but included in `@sentry/core`\n * so it can be used in cross-platform SDKs like `@sentry/nextjs`.\n */\nexport const requestDataIntegration = defineIntegration(_requestDataIntegration);\n\n/**\n * Add already normalized request data to an event.\n * This mutates the passed in event.\n */\nfunction addNormalizedRequestDataToEvent(\n event: Event,\n req: RequestEventData,\n // Data that should not go into `event.request` but is somehow related to requests\n additionalData: { ipAddress?: string },\n include: RequestDataIncludeOptions,\n): void {\n event.request = {\n ...event.request,\n ...extractNormalizedRequestData(req, include),\n };\n\n if (include.ip) {\n const ip = (req.headers && getClientIPAddress(req.headers)) || additionalData.ipAddress;\n if (ip) {\n event.user = {\n ...event.user,\n ip_address: ip,\n };\n }\n }\n}\n\nfunction addNormalizedRequestDataToSpan(\n span: StreamedSpanJSON,\n normalizedRequest: RequestEventData,\n ipAddress: string | undefined,\n include: RequestDataIncludeOptions,\n sendDefaultPii: boolean | undefined,\n): void {\n const requestData = extractNormalizedRequestData(normalizedRequest, include);\n const attributes: Record<string, unknown> = {};\n\n if (requestData.url) {\n attributes['url.full'] = requestData.url;\n }\n\n if (requestData.method) {\n attributes['http.request.method'] = requestData.method;\n }\n\n if (requestData.query_string) {\n attributes['url.query'] = normalizeQueryString(requestData.query_string);\n }\n\n safeSetSpanJSONAttributes(span, attributes);\n\n // Process cookies before headers so normalizedRequest.cookies takes precedence\n // over the raw cookie header (matching the processEvent path).\n if (requestData.cookies && Object.keys(requestData.cookies).length > 0) {\n const cookieString = Object.entries(requestData.cookies)\n .map(([name, value]) => `${name}=${value}`)\n .join('; ');\n const cookieAttributes = httpHeadersToSpanAttributes({ cookie: cookieString }, sendDefaultPii ?? false, 'request');\n safeSetSpanJSONAttributes(span, cookieAttributes);\n }\n\n if (requestData.headers) {\n const headerAttributes = httpHeadersToSpanAttributes(requestData.headers, sendDefaultPii ?? false, 'request');\n safeSetSpanJSONAttributes(span, headerAttributes);\n }\n\n if (requestData.data != null) {\n const serialized = typeof requestData.data === 'string' ? requestData.data : JSON.stringify(requestData.data);\n if (serialized) {\n safeSetSpanJSONAttributes(span, { 'http.request.body.data': serialized });\n }\n }\n\n if (include.ip) {\n const ip = (normalizedRequest.headers && getClientIPAddress(normalizedRequest.headers)) || ipAddress || undefined;\n if (ip) {\n safeSetSpanJSONAttributes(span, { [SEMANTIC_ATTRIBUTE_USER_IP_ADDRESS]: ip });\n }\n }\n}\n\nfunction extractNormalizedRequestData(\n normalizedRequest: RequestEventData,\n include: RequestDataIncludeOptions,\n): RequestEventData {\n const requestData: RequestEventData = {};\n const headers = { ...normalizedRequest.headers };\n\n if (include.headers) {\n requestData.headers = headers;\n\n if (!include.cookies) {\n delete (headers as { cookie?: string }).cookie;\n }\n\n if (!include.ip) {\n const ipHeaderNamesLower = new Set(ipHeaderNames.map(name => name.toLowerCase()));\n for (const key of Object.keys(headers)) {\n if (ipHeaderNamesLower.has(key.toLowerCase())) {\n // eslint-disable-next-line @typescript-eslint/no-dynamic-delete\n delete (headers as Record<string, unknown>)[key];\n }\n }\n }\n }\n\n requestData.method = normalizedRequest.method;\n\n if (include.url) {\n requestData.url = normalizedRequest.url;\n }\n\n if (include.cookies) {\n const cookies = normalizedRequest.cookies || (headers?.cookie ? parseCookie(headers.cookie) : undefined);\n requestData.cookies = cookies || {};\n }\n\n if (include.query_string) {\n requestData.query_string = normalizedRequest.query_string;\n }\n\n if (include.data) {\n requestData.data = normalizedRequest.data;\n }\n\n return requestData;\n}\n\nfunction normalizeQueryString(queryString: QueryParams): string | undefined {\n if (typeof queryString === 'string') {\n return queryString || undefined;\n }\n\n const pairs = Array.isArray(queryString) ? queryString : Object.entries(queryString);\n const result = pairs.map(([key, value]) => `${key}=${value}`).join('&');\n\n return result || undefined;\n}\n"],"names":[],"mappings":"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"}
|
|
@@ -1,13 +1,17 @@
|
|
|
1
1
|
import { dsnToString } from '../utils/dsn.js';
|
|
2
2
|
import { createEnvelope } from '../utils/envelope.js';
|
|
3
|
+
import { isBrowser } from '../utils/isBrowser.js';
|
|
3
4
|
|
|
4
5
|
/**
|
|
5
6
|
* Creates a log container envelope item for a list of logs.
|
|
6
7
|
*
|
|
7
8
|
* @param items - The logs to include in the envelope.
|
|
9
|
+
* @param inferUserData - If true, tells Relay to infer the end-user IP and User-Agent from the incoming request.
|
|
10
|
+
* Only emitted as `ingest_settings` in browser environments.
|
|
8
11
|
* @returns The created log container envelope item.
|
|
9
12
|
*/
|
|
10
|
-
function createLogContainerEnvelopeItem(items) {
|
|
13
|
+
function createLogContainerEnvelopeItem(items, inferUserData) {
|
|
14
|
+
const inferSetting = inferUserData ? 'auto' : 'never';
|
|
11
15
|
return [
|
|
12
16
|
{
|
|
13
17
|
type: 'log',
|
|
@@ -15,6 +19,10 @@ function createLogContainerEnvelopeItem(items) {
|
|
|
15
19
|
content_type: 'application/vnd.sentry.items.log+json',
|
|
16
20
|
},
|
|
17
21
|
{
|
|
22
|
+
version: 2,
|
|
23
|
+
...(isBrowser() && {
|
|
24
|
+
ingest_settings: { infer_ip: inferSetting, infer_user_agent: inferSetting },
|
|
25
|
+
}),
|
|
18
26
|
items,
|
|
19
27
|
},
|
|
20
28
|
];
|
|
@@ -29,6 +37,7 @@ function createLogContainerEnvelopeItem(items) {
|
|
|
29
37
|
* @param metadata - The metadata to include in the envelope.
|
|
30
38
|
* @param tunnel - The tunnel to include in the envelope.
|
|
31
39
|
* @param dsn - The DSN to include in the envelope.
|
|
40
|
+
* @param inferUserData - If true, tells Relay to infer the end-user IP and User-Agent from the incoming request.
|
|
32
41
|
* @returns The created envelope.
|
|
33
42
|
*/
|
|
34
43
|
function createLogEnvelope(
|
|
@@ -36,6 +45,7 @@ function createLogEnvelope(
|
|
|
36
45
|
metadata,
|
|
37
46
|
tunnel,
|
|
38
47
|
dsn,
|
|
48
|
+
inferUserData,
|
|
39
49
|
) {
|
|
40
50
|
const headers = {};
|
|
41
51
|
|
|
@@ -50,7 +60,7 @@ function createLogEnvelope(
|
|
|
50
60
|
headers.dsn = dsnToString(dsn);
|
|
51
61
|
}
|
|
52
62
|
|
|
53
|
-
return createEnvelope(headers, [createLogContainerEnvelopeItem(logs)]);
|
|
63
|
+
return createEnvelope(headers, [createLogContainerEnvelopeItem(logs, inferUserData)]);
|
|
54
64
|
}
|
|
55
65
|
|
|
56
66
|
export { createLogContainerEnvelopeItem, createLogEnvelope };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"envelope.js","sources":["../../../src/logs/envelope.ts"],"sourcesContent":["import type { DsnComponents } from '../types-hoist/dsn';\nimport type { LogContainerItem, LogEnvelope } from '../types-hoist/envelope';\nimport type { SerializedLog } from '../types-hoist/log';\nimport type { SdkMetadata } from '../types-hoist/sdkmetadata';\nimport { dsnToString } from '../utils/dsn';\nimport { createEnvelope } from '../utils/envelope';\n\n/**\n * Creates a log container envelope item for a list of logs.\n *\n * @param items - The logs to include in the envelope.\n * @returns The created log container envelope item.\n */\nexport function createLogContainerEnvelopeItem(items: Array<SerializedLog
|
|
1
|
+
{"version":3,"file":"envelope.js","sources":["../../../src/logs/envelope.ts"],"sourcesContent":["import type { DsnComponents } from '../types-hoist/dsn';\nimport type { LogContainerItem, LogEnvelope } from '../types-hoist/envelope';\nimport type { SerializedLog } from '../types-hoist/log';\nimport type { SdkMetadata } from '../types-hoist/sdkmetadata';\nimport { dsnToString } from '../utils/dsn';\nimport { createEnvelope } from '../utils/envelope';\nimport { isBrowser } from '../utils/isBrowser';\n\n/**\n * Creates a log container envelope item for a list of logs.\n *\n * @param items - The logs to include in the envelope.\n * @param inferUserData - If true, tells Relay to infer the end-user IP and User-Agent from the incoming request.\n * Only emitted as `ingest_settings` in browser environments.\n * @returns The created log container envelope item.\n */\nexport function createLogContainerEnvelopeItem(items: Array<SerializedLog>, inferUserData?: boolean): LogContainerItem {\n const inferSetting = inferUserData ? 'auto' : 'never';\n return [\n {\n type: 'log',\n item_count: items.length,\n content_type: 'application/vnd.sentry.items.log+json',\n },\n {\n version: 2,\n ...(isBrowser() && {\n ingest_settings: { infer_ip: inferSetting, infer_user_agent: inferSetting },\n }),\n items,\n },\n ];\n}\n\n/**\n * Creates an envelope for a list of logs.\n *\n * Logs from multiple traces can be included in the same envelope.\n *\n * @param logs - The logs to include in the envelope.\n * @param metadata - The metadata to include in the envelope.\n * @param tunnel - The tunnel to include in the envelope.\n * @param dsn - The DSN to include in the envelope.\n * @param inferUserData - If true, tells Relay to infer the end-user IP and User-Agent from the incoming request.\n * @returns The created envelope.\n */\nexport function createLogEnvelope(\n logs: Array<SerializedLog>,\n metadata?: SdkMetadata,\n tunnel?: string,\n dsn?: DsnComponents,\n inferUserData?: boolean,\n): LogEnvelope {\n const headers: LogEnvelope[0] = {};\n\n if (metadata?.sdk) {\n headers.sdk = {\n name: metadata.sdk.name,\n version: metadata.sdk.version,\n };\n }\n\n if (!!tunnel && !!dsn) {\n headers.dsn = dsnToString(dsn);\n }\n\n return createEnvelope<LogEnvelope>(headers, [createLogContainerEnvelopeItem(logs, inferUserData)]);\n}\n"],"names":[],"mappings":";;;;AAQA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACO,SAAS,8BAA8B,CAAC,KAAK,EAAwB,aAAa,EAA8B;AACvH,EAAE,MAAM,YAAA,GAAe,gBAAgB,MAAA,GAAS,OAAO;AACvD,EAAE,OAAO;AACT,IAAI;AACJ,MAAM,IAAI,EAAE,KAAK;AACjB,MAAM,UAAU,EAAE,KAAK,CAAC,MAAM;AAC9B,MAAM,YAAY,EAAE,uCAAuC;AAC3D,KAAK;AACL,IAAI;AACJ,MAAM,OAAO,EAAE,CAAC;AAChB,MAAM,IAAI,SAAS,MAAM;AACzB,QAAQ,eAAe,EAAE,EAAE,QAAQ,EAAE,YAAY,EAAE,gBAAgB,EAAE,YAAA,EAAc;AACnF,OAAO,CAAC;AACR,MAAM,KAAK;AACX,KAAK;AACL,GAAG;AACH;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACO,SAAS,iBAAiB;AACjC,EAAE,IAAI;AACN,EAAE,QAAQ;AACV,EAAE,MAAM;AACR,EAAE,GAAG;AACL,EAAE,aAAa;AACf,EAAe;AACf,EAAE,MAAM,OAAO,GAAmB,EAAE;;AAEpC,EAAE,IAAI,QAAQ,EAAE,GAAG,EAAE;AACrB,IAAI,OAAO,CAAC,GAAA,GAAM;AAClB,MAAM,IAAI,EAAE,QAAQ,CAAC,GAAG,CAAC,IAAI;AAC7B,MAAM,OAAO,EAAE,QAAQ,CAAC,GAAG,CAAC,OAAO;AACnC,KAAK;AACL,EAAE;;AAEF,EAAE,IAAI,CAAC,CAAC,UAAU,CAAC,CAAC,GAAG,EAAE;AACzB,IAAI,OAAO,CAAC,GAAA,GAAM,WAAW,CAAC,GAAG,CAAC;AAClC,EAAE;;AAEF,EAAE,OAAO,cAAc,CAAc,OAAO,EAAE,CAAC,8BAA8B,CAAC,IAAI,EAAE,aAAa,CAAC,CAAC,CAAC;AACpG;;;;"}
|
|
@@ -186,7 +186,13 @@ function _INTERNAL_flushLogsBuffer(client, maybeLogBuffer) {
|
|
|
186
186
|
}
|
|
187
187
|
|
|
188
188
|
const clientOptions = client.getOptions();
|
|
189
|
-
const envelope = createLogEnvelope(
|
|
189
|
+
const envelope = createLogEnvelope(
|
|
190
|
+
logBuffer,
|
|
191
|
+
clientOptions._metadata,
|
|
192
|
+
clientOptions.tunnel,
|
|
193
|
+
client.getDsn(),
|
|
194
|
+
clientOptions.sendDefaultPii,
|
|
195
|
+
);
|
|
190
196
|
|
|
191
197
|
// Clear the log buffer after envelopes have been constructed.
|
|
192
198
|
_getBufferMap().set(client, []);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"internal.js","sources":["../../../src/logs/internal.ts"],"sourcesContent":["import { serializeAttributes } from '../attributes';\nimport { getGlobalSingleton } from '../carrier';\nimport type { Client } from '../client';\nimport { getClient, getCurrentScope, getIsolationScope } from '../currentScopes';\nimport { DEBUG_BUILD } from '../debug-build';\nimport type { Integration } from '../types-hoist/integration';\nimport type { Log, SerializedLog } from '../types-hoist/log';\nimport { consoleSandbox, debug } from '../utils/debug-logger';\nimport { isParameterizedString } from '../utils/is';\nimport { getCombinedScopeData } from '../utils/scopeData';\nimport { _getSpanForScope } from '../utils/spanOnScope';\nimport { timestampInSeconds } from '../utils/time';\nimport { getSequenceAttribute } from '../utils/timestampSequence';\nimport { _getTraceInfoFromScope } from '../utils/trace-info';\nimport { SEVERITY_TEXT_TO_SEVERITY_NUMBER } from './constants';\nimport { createLogEnvelope } from './envelope';\n\nconst MAX_LOG_BUFFER_SIZE = 100;\n\n/**\n * Sets a log attribute if the value exists and the attribute key is not already present.\n *\n * @param logAttributes - The log attributes object to modify.\n * @param key - The attribute key to set.\n * @param value - The value to set (only sets if truthy and key not present).\n * @param setEvenIfPresent - Whether to set the attribute if it is present. Defaults to true.\n */\nfunction setLogAttribute(\n logAttributes: Record<string, unknown>,\n key: string,\n value: unknown,\n setEvenIfPresent = true,\n): void {\n if (value && (!logAttributes[key] || setEvenIfPresent)) {\n logAttributes[key] = value;\n }\n}\n\n/**\n * Captures a serialized log event and adds it to the log buffer for the given client.\n *\n * @param client - A client. Uses the current client if not provided.\n * @param serializedLog - The serialized log event to capture.\n *\n * @experimental This method will experience breaking changes. This is not yet part of\n * the stable Sentry SDK API and can be changed or removed without warning.\n */\nexport function _INTERNAL_captureSerializedLog(client: Client, serializedLog: SerializedLog): void {\n const bufferMap = _getBufferMap();\n const logBuffer = _INTERNAL_getLogBuffer(client);\n\n if (logBuffer === undefined) {\n bufferMap.set(client, [serializedLog]);\n } else {\n if (logBuffer.length >= MAX_LOG_BUFFER_SIZE) {\n _INTERNAL_flushLogsBuffer(client, logBuffer);\n bufferMap.set(client, [serializedLog]);\n } else {\n bufferMap.set(client, [...logBuffer, serializedLog]);\n }\n }\n}\n\n/**\n * Captures a log event and sends it to Sentry.\n *\n * @param log - The log event to capture.\n * @param scope - A scope. Uses the current scope if not provided.\n * @param client - A client. Uses the current client if not provided.\n * @param captureSerializedLog - A function to capture the serialized log.\n *\n * @experimental This method will experience breaking changes. This is not yet part of\n * the stable Sentry SDK API and can be changed or removed without warning.\n */\nexport function _INTERNAL_captureLog(\n beforeLog: Log,\n currentScope = getCurrentScope(),\n captureSerializedLog: (client: Client, log: SerializedLog) => void = _INTERNAL_captureSerializedLog,\n): void {\n const client = currentScope?.getClient() ?? getClient();\n if (!client) {\n DEBUG_BUILD && debug.warn('No client available to capture log.');\n return;\n }\n\n const { release, environment, enableLogs = false, beforeSendLog } = client.getOptions();\n if (!enableLogs) {\n DEBUG_BUILD && debug.warn('logging option not enabled, log will not be captured.');\n return;\n }\n\n const [, traceContext] = _getTraceInfoFromScope(client, currentScope);\n\n const processedLogAttributes = {\n ...beforeLog.attributes,\n };\n\n const {\n user: { id, email, username },\n attributes: scopeAttributes = {},\n } = getCombinedScopeData(getIsolationScope(), currentScope);\n\n setLogAttribute(processedLogAttributes, 'user.id', id, false);\n setLogAttribute(processedLogAttributes, 'user.email', email, false);\n setLogAttribute(processedLogAttributes, 'user.name', username, false);\n\n setLogAttribute(processedLogAttributes, 'sentry.release', release);\n setLogAttribute(processedLogAttributes, 'sentry.environment', environment);\n\n const { name, version } = client.getSdkMetadata()?.sdk ?? {};\n setLogAttribute(processedLogAttributes, 'sentry.sdk.name', name);\n setLogAttribute(processedLogAttributes, 'sentry.sdk.version', version);\n\n const replay = client.getIntegrationByName<\n Integration & {\n getReplayId: (onlyIfSampled?: boolean) => string;\n getRecordingMode: () => 'session' | 'buffer' | undefined;\n }\n >('Replay');\n\n const replayId = replay?.getReplayId(true);\n setLogAttribute(processedLogAttributes, 'sentry.replay_id', replayId);\n\n if (replayId && replay?.getRecordingMode() === 'buffer') {\n // We send this so we can identify cases where the replayId is attached but the replay itself might not have been sent to Sentry\n setLogAttribute(processedLogAttributes, 'sentry._internal.replay_is_buffering', true);\n }\n\n const beforeLogMessage = beforeLog.message;\n if (isParameterizedString(beforeLogMessage)) {\n const { __sentry_template_string__, __sentry_template_values__ = [] } = beforeLogMessage;\n if (__sentry_template_values__?.length) {\n processedLogAttributes['sentry.message.template'] = __sentry_template_string__;\n }\n __sentry_template_values__.forEach((param, index) => {\n processedLogAttributes[`sentry.message.parameter.${index}`] = param;\n });\n }\n\n const span = _getSpanForScope(currentScope);\n // Add the parent span ID to the log attributes for trace context\n setLogAttribute(processedLogAttributes, 'sentry.trace.parent_span_id', span?.spanContext().spanId);\n\n const processedLog = { ...beforeLog, attributes: processedLogAttributes };\n\n client.emit('beforeCaptureLog', processedLog);\n\n // We need to wrap this in `consoleSandbox` to avoid recursive calls to `beforeSendLog`\n const log = beforeSendLog ? consoleSandbox(() => beforeSendLog(processedLog)) : processedLog;\n if (!log) {\n client.recordDroppedEvent('before_send', 'log_item', 1);\n DEBUG_BUILD && debug.warn('beforeSendLog returned null, log will not be captured.');\n return;\n }\n\n const { level, message, attributes: logAttributes = {}, severityNumber } = log;\n\n const timestamp = timestampInSeconds();\n const sequenceAttr = getSequenceAttribute(timestamp);\n\n const serializedLog: SerializedLog = {\n timestamp,\n level,\n body: message,\n trace_id: traceContext?.trace_id,\n severity_number: severityNumber ?? SEVERITY_TEXT_TO_SEVERITY_NUMBER[level],\n attributes: {\n ...serializeAttributes(scopeAttributes),\n ...serializeAttributes(logAttributes, true),\n [sequenceAttr.key]: sequenceAttr.value,\n },\n };\n\n captureSerializedLog(client, serializedLog);\n\n client.emit('afterCaptureLog', log);\n}\n\n/**\n * Flushes the logs buffer to Sentry.\n *\n * @param client - A client.\n * @param maybeLogBuffer - A log buffer. Uses the log buffer for the given client if not provided.\n *\n * @experimental This method will experience breaking changes. This is not yet part of\n * the stable Sentry SDK API and can be changed or removed without warning.\n */\nexport function _INTERNAL_flushLogsBuffer(client: Client, maybeLogBuffer?: Array<SerializedLog>): void {\n const logBuffer = maybeLogBuffer ?? _INTERNAL_getLogBuffer(client) ?? [];\n if (logBuffer.length === 0) {\n return;\n }\n\n const clientOptions = client.getOptions();\n const envelope = createLogEnvelope(logBuffer, clientOptions._metadata, clientOptions.tunnel, client.getDsn());\n\n // Clear the log buffer after envelopes have been constructed.\n _getBufferMap().set(client, []);\n\n client.emit('flushLogs');\n\n // sendEnvelope should not throw\n // eslint-disable-next-line @typescript-eslint/no-floating-promises\n client.sendEnvelope(envelope);\n}\n\n/**\n * Returns the log buffer for a given client.\n *\n * Exported for testing purposes.\n *\n * @param client - The client to get the log buffer for.\n * @returns The log buffer for the given client.\n */\nexport function _INTERNAL_getLogBuffer(client: Client): Array<SerializedLog> | undefined {\n return _getBufferMap().get(client);\n}\n\nfunction _getBufferMap(): WeakMap<Client, Array<SerializedLog>> {\n // The reference to the Client <> LogBuffer map is stored on the carrier to ensure it's always the same\n return getGlobalSingleton('clientToLogBufferMap', () => new WeakMap<Client, Array<SerializedLog>>());\n}\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"internal.js","sources":["../../../src/logs/internal.ts"],"sourcesContent":["import { serializeAttributes } from '../attributes';\nimport { getGlobalSingleton } from '../carrier';\nimport type { Client } from '../client';\nimport { getClient, getCurrentScope, getIsolationScope } from '../currentScopes';\nimport { DEBUG_BUILD } from '../debug-build';\nimport type { Integration } from '../types-hoist/integration';\nimport type { Log, SerializedLog } from '../types-hoist/log';\nimport { consoleSandbox, debug } from '../utils/debug-logger';\nimport { isParameterizedString } from '../utils/is';\nimport { getCombinedScopeData } from '../utils/scopeData';\nimport { _getSpanForScope } from '../utils/spanOnScope';\nimport { timestampInSeconds } from '../utils/time';\nimport { getSequenceAttribute } from '../utils/timestampSequence';\nimport { _getTraceInfoFromScope } from '../utils/trace-info';\nimport { SEVERITY_TEXT_TO_SEVERITY_NUMBER } from './constants';\nimport { createLogEnvelope } from './envelope';\n\nconst MAX_LOG_BUFFER_SIZE = 100;\n\n/**\n * Sets a log attribute if the value exists and the attribute key is not already present.\n *\n * @param logAttributes - The log attributes object to modify.\n * @param key - The attribute key to set.\n * @param value - The value to set (only sets if truthy and key not present).\n * @param setEvenIfPresent - Whether to set the attribute if it is present. Defaults to true.\n */\nfunction setLogAttribute(\n logAttributes: Record<string, unknown>,\n key: string,\n value: unknown,\n setEvenIfPresent = true,\n): void {\n if (value && (!logAttributes[key] || setEvenIfPresent)) {\n logAttributes[key] = value;\n }\n}\n\n/**\n * Captures a serialized log event and adds it to the log buffer for the given client.\n *\n * @param client - A client. Uses the current client if not provided.\n * @param serializedLog - The serialized log event to capture.\n *\n * @experimental This method will experience breaking changes. This is not yet part of\n * the stable Sentry SDK API and can be changed or removed without warning.\n */\nexport function _INTERNAL_captureSerializedLog(client: Client, serializedLog: SerializedLog): void {\n const bufferMap = _getBufferMap();\n const logBuffer = _INTERNAL_getLogBuffer(client);\n\n if (logBuffer === undefined) {\n bufferMap.set(client, [serializedLog]);\n } else {\n if (logBuffer.length >= MAX_LOG_BUFFER_SIZE) {\n _INTERNAL_flushLogsBuffer(client, logBuffer);\n bufferMap.set(client, [serializedLog]);\n } else {\n bufferMap.set(client, [...logBuffer, serializedLog]);\n }\n }\n}\n\n/**\n * Captures a log event and sends it to Sentry.\n *\n * @param log - The log event to capture.\n * @param scope - A scope. Uses the current scope if not provided.\n * @param client - A client. Uses the current client if not provided.\n * @param captureSerializedLog - A function to capture the serialized log.\n *\n * @experimental This method will experience breaking changes. This is not yet part of\n * the stable Sentry SDK API and can be changed or removed without warning.\n */\nexport function _INTERNAL_captureLog(\n beforeLog: Log,\n currentScope = getCurrentScope(),\n captureSerializedLog: (client: Client, log: SerializedLog) => void = _INTERNAL_captureSerializedLog,\n): void {\n const client = currentScope?.getClient() ?? getClient();\n if (!client) {\n DEBUG_BUILD && debug.warn('No client available to capture log.');\n return;\n }\n\n const { release, environment, enableLogs = false, beforeSendLog } = client.getOptions();\n if (!enableLogs) {\n DEBUG_BUILD && debug.warn('logging option not enabled, log will not be captured.');\n return;\n }\n\n const [, traceContext] = _getTraceInfoFromScope(client, currentScope);\n\n const processedLogAttributes = {\n ...beforeLog.attributes,\n };\n\n const {\n user: { id, email, username },\n attributes: scopeAttributes = {},\n } = getCombinedScopeData(getIsolationScope(), currentScope);\n\n setLogAttribute(processedLogAttributes, 'user.id', id, false);\n setLogAttribute(processedLogAttributes, 'user.email', email, false);\n setLogAttribute(processedLogAttributes, 'user.name', username, false);\n\n setLogAttribute(processedLogAttributes, 'sentry.release', release);\n setLogAttribute(processedLogAttributes, 'sentry.environment', environment);\n\n const { name, version } = client.getSdkMetadata()?.sdk ?? {};\n setLogAttribute(processedLogAttributes, 'sentry.sdk.name', name);\n setLogAttribute(processedLogAttributes, 'sentry.sdk.version', version);\n\n const replay = client.getIntegrationByName<\n Integration & {\n getReplayId: (onlyIfSampled?: boolean) => string;\n getRecordingMode: () => 'session' | 'buffer' | undefined;\n }\n >('Replay');\n\n const replayId = replay?.getReplayId(true);\n setLogAttribute(processedLogAttributes, 'sentry.replay_id', replayId);\n\n if (replayId && replay?.getRecordingMode() === 'buffer') {\n // We send this so we can identify cases where the replayId is attached but the replay itself might not have been sent to Sentry\n setLogAttribute(processedLogAttributes, 'sentry._internal.replay_is_buffering', true);\n }\n\n const beforeLogMessage = beforeLog.message;\n if (isParameterizedString(beforeLogMessage)) {\n const { __sentry_template_string__, __sentry_template_values__ = [] } = beforeLogMessage;\n if (__sentry_template_values__?.length) {\n processedLogAttributes['sentry.message.template'] = __sentry_template_string__;\n }\n __sentry_template_values__.forEach((param, index) => {\n processedLogAttributes[`sentry.message.parameter.${index}`] = param;\n });\n }\n\n const span = _getSpanForScope(currentScope);\n // Add the parent span ID to the log attributes for trace context\n setLogAttribute(processedLogAttributes, 'sentry.trace.parent_span_id', span?.spanContext().spanId);\n\n const processedLog = { ...beforeLog, attributes: processedLogAttributes };\n\n client.emit('beforeCaptureLog', processedLog);\n\n // We need to wrap this in `consoleSandbox` to avoid recursive calls to `beforeSendLog`\n const log = beforeSendLog ? consoleSandbox(() => beforeSendLog(processedLog)) : processedLog;\n if (!log) {\n client.recordDroppedEvent('before_send', 'log_item', 1);\n DEBUG_BUILD && debug.warn('beforeSendLog returned null, log will not be captured.');\n return;\n }\n\n const { level, message, attributes: logAttributes = {}, severityNumber } = log;\n\n const timestamp = timestampInSeconds();\n const sequenceAttr = getSequenceAttribute(timestamp);\n\n const serializedLog: SerializedLog = {\n timestamp,\n level,\n body: message,\n trace_id: traceContext?.trace_id,\n severity_number: severityNumber ?? SEVERITY_TEXT_TO_SEVERITY_NUMBER[level],\n attributes: {\n ...serializeAttributes(scopeAttributes),\n ...serializeAttributes(logAttributes, true),\n [sequenceAttr.key]: sequenceAttr.value,\n },\n };\n\n captureSerializedLog(client, serializedLog);\n\n client.emit('afterCaptureLog', log);\n}\n\n/**\n * Flushes the logs buffer to Sentry.\n *\n * @param client - A client.\n * @param maybeLogBuffer - A log buffer. Uses the log buffer for the given client if not provided.\n *\n * @experimental This method will experience breaking changes. This is not yet part of\n * the stable Sentry SDK API and can be changed or removed without warning.\n */\nexport function _INTERNAL_flushLogsBuffer(client: Client, maybeLogBuffer?: Array<SerializedLog>): void {\n const logBuffer = maybeLogBuffer ?? _INTERNAL_getLogBuffer(client) ?? [];\n if (logBuffer.length === 0) {\n return;\n }\n\n const clientOptions = client.getOptions();\n const envelope = createLogEnvelope(\n logBuffer,\n clientOptions._metadata,\n clientOptions.tunnel,\n client.getDsn(),\n clientOptions.sendDefaultPii,\n );\n\n // Clear the log buffer after envelopes have been constructed.\n _getBufferMap().set(client, []);\n\n client.emit('flushLogs');\n\n // sendEnvelope should not throw\n // eslint-disable-next-line @typescript-eslint/no-floating-promises\n client.sendEnvelope(envelope);\n}\n\n/**\n * Returns the log buffer for a given client.\n *\n * Exported for testing purposes.\n *\n * @param client - The client to get the log buffer for.\n * @returns The log buffer for the given client.\n */\nexport function _INTERNAL_getLogBuffer(client: Client): Array<SerializedLog> | undefined {\n return _getBufferMap().get(client);\n}\n\nfunction _getBufferMap(): WeakMap<Client, Array<SerializedLog>> {\n // The reference to the Client <> LogBuffer map is stored on the carrier to ensure it's always the same\n return getGlobalSingleton('clientToLogBufferMap', () => new WeakMap<Client, Array<SerializedLog>>());\n}\n"],"names":[],"mappings":"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"}
|