@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
|
@@ -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":["defineIntegration","getClientIPAddress","ipHeaderNames","parseCookie"],"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":["getIsolationScope","defineIntegration","getClientIPAddress","safeSetSpanJSONAttributes","httpHeadersToSpanAttributes","SEMANTIC_ATTRIBUTE_USER_IP_ADDRESS","ipHeaderNames","parseCookie"],"mappings":"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"}
|
|
@@ -2,14 +2,18 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
|
2
2
|
|
|
3
3
|
const dsn = require('../utils/dsn.js');
|
|
4
4
|
const envelope = require('../utils/envelope.js');
|
|
5
|
+
const isBrowser = require('../utils/isBrowser.js');
|
|
5
6
|
|
|
6
7
|
/**
|
|
7
8
|
* Creates a log container envelope item for a list of logs.
|
|
8
9
|
*
|
|
9
10
|
* @param items - The logs to include in the envelope.
|
|
11
|
+
* @param inferUserData - If true, tells Relay to infer the end-user IP and User-Agent from the incoming request.
|
|
12
|
+
* Only emitted as `ingest_settings` in browser environments.
|
|
10
13
|
* @returns The created log container envelope item.
|
|
11
14
|
*/
|
|
12
|
-
function createLogContainerEnvelopeItem(items) {
|
|
15
|
+
function createLogContainerEnvelopeItem(items, inferUserData) {
|
|
16
|
+
const inferSetting = inferUserData ? 'auto' : 'never';
|
|
13
17
|
return [
|
|
14
18
|
{
|
|
15
19
|
type: 'log',
|
|
@@ -17,6 +21,10 @@ function createLogContainerEnvelopeItem(items) {
|
|
|
17
21
|
content_type: 'application/vnd.sentry.items.log+json',
|
|
18
22
|
},
|
|
19
23
|
{
|
|
24
|
+
version: 2,
|
|
25
|
+
...(isBrowser.isBrowser() && {
|
|
26
|
+
ingest_settings: { infer_ip: inferSetting, infer_user_agent: inferSetting },
|
|
27
|
+
}),
|
|
20
28
|
items,
|
|
21
29
|
},
|
|
22
30
|
];
|
|
@@ -31,6 +39,7 @@ function createLogContainerEnvelopeItem(items) {
|
|
|
31
39
|
* @param metadata - The metadata to include in the envelope.
|
|
32
40
|
* @param tunnel - The tunnel to include in the envelope.
|
|
33
41
|
* @param dsn - The DSN to include in the envelope.
|
|
42
|
+
* @param inferUserData - If true, tells Relay to infer the end-user IP and User-Agent from the incoming request.
|
|
34
43
|
* @returns The created envelope.
|
|
35
44
|
*/
|
|
36
45
|
function createLogEnvelope(
|
|
@@ -38,6 +47,7 @@ function createLogEnvelope(
|
|
|
38
47
|
metadata,
|
|
39
48
|
tunnel,
|
|
40
49
|
dsn$1,
|
|
50
|
+
inferUserData,
|
|
41
51
|
) {
|
|
42
52
|
const headers = {};
|
|
43
53
|
|
|
@@ -52,7 +62,7 @@ function createLogEnvelope(
|
|
|
52
62
|
headers.dsn = dsn.dsnToString(dsn$1);
|
|
53
63
|
}
|
|
54
64
|
|
|
55
|
-
return envelope.createEnvelope(headers, [createLogContainerEnvelopeItem(logs)]);
|
|
65
|
+
return envelope.createEnvelope(headers, [createLogContainerEnvelopeItem(logs, inferUserData)]);
|
|
56
66
|
}
|
|
57
67
|
|
|
58
68
|
exports.createLogContainerEnvelopeItem = createLogContainerEnvelopeItem;
|
|
@@ -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":["isBrowser","dsn","dsnToString","createEnvelope"],"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,IAAIA,mBAAS,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,EAAEC,KAAG;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,CAACA,KAAG,EAAE;AACzB,IAAI,OAAO,CAAC,GAAA,GAAMC,eAAW,CAACD,KAAG,CAAC;AAClC,EAAE;;AAEF,EAAE,OAAOE,uBAAc,CAAc,OAAO,EAAE,CAAC,8BAA8B,CAAC,IAAI,EAAE,aAAa,CAAC,CAAC,CAAC;AACpG;;;;;"}
|
|
@@ -188,7 +188,13 @@ function _INTERNAL_flushLogsBuffer(client, maybeLogBuffer) {
|
|
|
188
188
|
}
|
|
189
189
|
|
|
190
190
|
const clientOptions = client.getOptions();
|
|
191
|
-
const envelope$1 = envelope.createLogEnvelope(
|
|
191
|
+
const envelope$1 = envelope.createLogEnvelope(
|
|
192
|
+
logBuffer,
|
|
193
|
+
clientOptions._metadata,
|
|
194
|
+
clientOptions.tunnel,
|
|
195
|
+
client.getDsn(),
|
|
196
|
+
clientOptions.sendDefaultPii,
|
|
197
|
+
);
|
|
192
198
|
|
|
193
199
|
// Clear the log buffer after envelopes have been constructed.
|
|
194
200
|
_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":["getCurrentScope","getClient","DEBUG_BUILD","debug","_getTraceInfoFromScope","getCombinedScopeData","getIsolationScope","isParameterizedString","_getSpanForScope","consoleSandbox","timestampInSeconds","getSequenceAttribute","SEVERITY_TEXT_TO_SEVERITY_NUMBER","serializeAttributes","envelope","createLogEnvelope","getGlobalSingleton"],"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":["getCurrentScope","getClient","DEBUG_BUILD","debug","_getTraceInfoFromScope","getCombinedScopeData","getIsolationScope","isParameterizedString","_getSpanForScope","consoleSandbox","timestampInSeconds","getSequenceAttribute","SEVERITY_TEXT_TO_SEVERITY_NUMBER","serializeAttributes","envelope","createLogEnvelope","getGlobalSingleton"],"mappings":"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"}
|
|
@@ -2,14 +2,21 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
|
2
2
|
|
|
3
3
|
const dsn = require('../utils/dsn.js');
|
|
4
4
|
const envelope = require('../utils/envelope.js');
|
|
5
|
+
const isBrowser = require('../utils/isBrowser.js');
|
|
5
6
|
|
|
6
7
|
/**
|
|
7
8
|
* Creates a metric container envelope item for a list of metrics.
|
|
8
9
|
*
|
|
9
10
|
* @param items - The metrics to include in the envelope.
|
|
11
|
+
* @param inferUserData - If true, tells Relay to infer the end-user IP and User-Agent from the incoming request.
|
|
12
|
+
* Only emitted as `ingest_settings` in browser environments.
|
|
10
13
|
* @returns The created metric container envelope item.
|
|
11
14
|
*/
|
|
12
|
-
function createMetricContainerEnvelopeItem(
|
|
15
|
+
function createMetricContainerEnvelopeItem(
|
|
16
|
+
items,
|
|
17
|
+
inferUserData,
|
|
18
|
+
) {
|
|
19
|
+
const inferSetting = inferUserData ? 'auto' : 'never';
|
|
13
20
|
return [
|
|
14
21
|
{
|
|
15
22
|
type: 'trace_metric',
|
|
@@ -17,6 +24,10 @@ function createMetricContainerEnvelopeItem(items) {
|
|
|
17
24
|
content_type: 'application/vnd.sentry.items.trace-metric+json',
|
|
18
25
|
} ,
|
|
19
26
|
{
|
|
27
|
+
version: 2,
|
|
28
|
+
...(isBrowser.isBrowser() && {
|
|
29
|
+
ingest_settings: { infer_ip: inferSetting, infer_user_agent: inferSetting },
|
|
30
|
+
}),
|
|
20
31
|
items,
|
|
21
32
|
},
|
|
22
33
|
];
|
|
@@ -31,6 +42,7 @@ function createMetricContainerEnvelopeItem(items) {
|
|
|
31
42
|
* @param metadata - The metadata to include in the envelope.
|
|
32
43
|
* @param tunnel - The tunnel to include in the envelope.
|
|
33
44
|
* @param dsn - The DSN to include in the envelope.
|
|
45
|
+
* @param inferUserData - If true, tells Relay to infer the end-user IP and User-Agent from the incoming request.
|
|
34
46
|
* @returns The created envelope.
|
|
35
47
|
*/
|
|
36
48
|
function createMetricEnvelope(
|
|
@@ -38,6 +50,7 @@ function createMetricEnvelope(
|
|
|
38
50
|
metadata,
|
|
39
51
|
tunnel,
|
|
40
52
|
dsn$1,
|
|
53
|
+
inferUserData,
|
|
41
54
|
) {
|
|
42
55
|
const headers = {};
|
|
43
56
|
|
|
@@ -52,7 +65,7 @@ function createMetricEnvelope(
|
|
|
52
65
|
headers.dsn = dsn.dsnToString(dsn$1);
|
|
53
66
|
}
|
|
54
67
|
|
|
55
|
-
return envelope.createEnvelope(headers, [createMetricContainerEnvelopeItem(metrics)]);
|
|
68
|
+
return envelope.createEnvelope(headers, [createMetricContainerEnvelopeItem(metrics, inferUserData)]);
|
|
56
69
|
}
|
|
57
70
|
|
|
58
71
|
exports.createMetricContainerEnvelopeItem = createMetricContainerEnvelopeItem;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"envelope.js","sources":["../../../src/metrics/envelope.ts"],"sourcesContent":["import type { DsnComponents } from '../types-hoist/dsn';\nimport type { MetricContainerItem, MetricEnvelope } from '../types-hoist/envelope';\nimport type { SerializedMetric } from '../types-hoist/metric';\nimport type { SdkMetadata } from '../types-hoist/sdkmetadata';\nimport { dsnToString } from '../utils/dsn';\nimport { createEnvelope } from '../utils/envelope';\n\n/**\n * Creates a metric container envelope item for a list of metrics.\n *\n * @param items - The metrics to include in the envelope.\n * @returns The created metric container envelope item.\n */\nexport function createMetricContainerEnvelopeItem(items: Array<SerializedMetric
|
|
1
|
+
{"version":3,"file":"envelope.js","sources":["../../../src/metrics/envelope.ts"],"sourcesContent":["import type { DsnComponents } from '../types-hoist/dsn';\nimport type { MetricContainerItem, MetricEnvelope } from '../types-hoist/envelope';\nimport type { SerializedMetric } from '../types-hoist/metric';\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 metric container envelope item for a list of metrics.\n *\n * @param items - The metrics 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 metric container envelope item.\n */\nexport function createMetricContainerEnvelopeItem(\n items: Array<SerializedMetric>,\n inferUserData?: boolean,\n): MetricContainerItem {\n const inferSetting = inferUserData ? 'auto' : 'never';\n return [\n {\n type: 'trace_metric',\n item_count: items.length,\n content_type: 'application/vnd.sentry.items.trace-metric+json',\n } as MetricContainerItem[0],\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 metrics.\n *\n * Metrics from multiple traces can be included in the same envelope.\n *\n * @param metrics - The metrics 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 createMetricEnvelope(\n metrics: Array<SerializedMetric>,\n metadata?: SdkMetadata,\n tunnel?: string,\n dsn?: DsnComponents,\n inferUserData?: boolean,\n): MetricEnvelope {\n const headers: MetricEnvelope[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<MetricEnvelope>(headers, [createMetricContainerEnvelopeItem(metrics, inferUserData)]);\n}\n"],"names":["isBrowser","dsn","dsnToString","createEnvelope"],"mappings":";;;;;;AAQA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACO,SAAS,iCAAiC;AACjD,EAAE,KAAK;AACP,EAAE,aAAa;AACf,EAAuB;AACvB,EAAE,MAAM,YAAA,GAAe,gBAAgB,MAAA,GAAS,OAAO;AACvD,EAAE,OAAO;AACT,IAAI;AACJ,MAAM,IAAI,EAAE,cAAc;AAC1B,MAAM,UAAU,EAAE,KAAK,CAAC,MAAM;AAC9B,MAAM,YAAY,EAAE,gDAAgD;AACpE,KAAI;AACJ,IAAI;AACJ,MAAM,OAAO,EAAE,CAAC;AAChB,MAAM,IAAIA,mBAAS,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,oBAAoB;AACpC,EAAE,OAAO;AACT,EAAE,QAAQ;AACV,EAAE,MAAM;AACR,EAAEC,KAAG;AACL,EAAE,aAAa;AACf,EAAkB;AAClB,EAAE,MAAM,OAAO,GAAsB,EAAE;;AAEvC,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,CAACA,KAAG,EAAE;AACzB,IAAI,OAAO,CAAC,GAAA,GAAMC,eAAW,CAACD,KAAG,CAAC;AAClC,EAAE;;AAEF,EAAE,OAAOE,uBAAc,CAAiB,OAAO,EAAE,CAAC,iCAAiC,CAAC,OAAO,EAAE,aAAa,CAAC,CAAC,CAAC;AAC7G;;;;;"}
|
|
@@ -208,7 +208,13 @@ function _INTERNAL_flushMetricsBuffer(client, maybeMetricBuffer) {
|
|
|
208
208
|
}
|
|
209
209
|
|
|
210
210
|
const clientOptions = client.getOptions();
|
|
211
|
-
const envelope$1 = envelope.createMetricEnvelope(
|
|
211
|
+
const envelope$1 = envelope.createMetricEnvelope(
|
|
212
|
+
metricBuffer,
|
|
213
|
+
clientOptions._metadata,
|
|
214
|
+
clientOptions.tunnel,
|
|
215
|
+
client.getDsn(),
|
|
216
|
+
clientOptions.sendDefaultPii,
|
|
217
|
+
);
|
|
212
218
|
|
|
213
219
|
// Clear the metric buffer after envelopes have been constructed.
|
|
214
220
|
_getBufferMap().set(client, []);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"internal.js","sources":["../../../src/metrics/internal.ts"],"sourcesContent":["import { type RawAttributes, 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 { Scope } from '../scope';\nimport type { Integration } from '../types-hoist/integration';\nimport type { Metric, SerializedMetric } from '../types-hoist/metric';\nimport type { User } from '../types-hoist/user';\nimport { debug } from '../utils/debug-logger';\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 { createMetricEnvelope } from './envelope';\n\nconst MAX_METRIC_BUFFER_SIZE = 1000;\n\n/**\n * Sets a metric attribute if the value exists and the attribute key is not already present.\n *\n * @param metricAttributes - The metric 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 setMetricAttribute(\n metricAttributes: Record<string, unknown>,\n key: string,\n value: unknown,\n setEvenIfPresent = true,\n): void {\n if (value && (setEvenIfPresent || !(key in metricAttributes))) {\n metricAttributes[key] = value;\n }\n}\n\n/**\n * Captures a serialized metric event and adds it to the metric buffer for the given client.\n *\n * @param client - A client. Uses the current client if not provided.\n * @param serializedMetric - The serialized metric 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_captureSerializedMetric(client: Client, serializedMetric: SerializedMetric): void {\n const bufferMap = _getBufferMap();\n const metricBuffer = _INTERNAL_getMetricBuffer(client);\n\n if (metricBuffer === undefined) {\n bufferMap.set(client, [serializedMetric]);\n } else {\n if (metricBuffer.length >= MAX_METRIC_BUFFER_SIZE) {\n _INTERNAL_flushMetricsBuffer(client, metricBuffer);\n bufferMap.set(client, [serializedMetric]);\n } else {\n bufferMap.set(client, [...metricBuffer, serializedMetric]);\n }\n }\n}\n\n/**\n * Options for capturing a metric internally.\n */\nexport interface InternalCaptureMetricOptions {\n /**\n * The scope to capture the metric with.\n */\n scope?: Scope;\n\n /**\n * A function to capture the serialized metric.\n */\n captureSerializedMetric?: (client: Client, metric: SerializedMetric) => void;\n}\n\n/**\n * Enriches metric with all contextual attributes (user, SDK metadata, replay, etc.)\n */\nfunction _enrichMetricAttributes(beforeMetric: Metric, client: Client, user: User): Metric {\n const { release, environment } = client.getOptions();\n\n const processedMetricAttributes = {\n ...beforeMetric.attributes,\n };\n\n // Add user attributes\n setMetricAttribute(processedMetricAttributes, 'user.id', user.id, false);\n setMetricAttribute(processedMetricAttributes, 'user.email', user.email, false);\n setMetricAttribute(processedMetricAttributes, 'user.name', user.username, false);\n\n // Add Sentry metadata\n setMetricAttribute(processedMetricAttributes, 'sentry.release', release);\n setMetricAttribute(processedMetricAttributes, 'sentry.environment', environment);\n\n // Add SDK metadata\n const { name, version } = client.getSdkMetadata()?.sdk ?? {};\n setMetricAttribute(processedMetricAttributes, 'sentry.sdk.name', name);\n setMetricAttribute(processedMetricAttributes, 'sentry.sdk.version', version);\n\n // Add replay metadata\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 setMetricAttribute(processedMetricAttributes, 'sentry.replay_id', replayId);\n\n if (replayId && replay?.getRecordingMode() === 'buffer') {\n setMetricAttribute(processedMetricAttributes, 'sentry._internal.replay_is_buffering', true);\n }\n\n return {\n ...beforeMetric,\n attributes: processedMetricAttributes,\n };\n}\n\n/**\n * Creates a serialized metric ready to be sent to Sentry.\n */\nfunction _buildSerializedMetric(\n metric: Metric,\n client: Client,\n currentScope: Scope,\n scopeAttributes: RawAttributes<Record<string, unknown>> | undefined,\n): SerializedMetric {\n // Get trace context\n const [, traceContext] = _getTraceInfoFromScope(client, currentScope);\n const span = _getSpanForScope(currentScope);\n const traceId = span ? span.spanContext().traceId : traceContext?.trace_id;\n const spanId = span ? span.spanContext().spanId : undefined;\n\n const timestamp = timestampInSeconds();\n const sequenceAttr = getSequenceAttribute(timestamp);\n\n return {\n timestamp,\n trace_id: traceId ?? '',\n span_id: spanId,\n name: metric.name,\n type: metric.type,\n unit: metric.unit,\n value: metric.value,\n attributes: {\n ...serializeAttributes(scopeAttributes),\n ...serializeAttributes(metric.attributes, 'skip-undefined'),\n [sequenceAttr.key]: sequenceAttr.value,\n },\n };\n}\n\n/**\n * Captures a metric event and sends it to Sentry.\n *\n * @param metric - The metric event to capture.\n * @param options - Options for capturing the metric.\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_captureMetric(beforeMetric: Metric, options?: InternalCaptureMetricOptions): void {\n const currentScope = options?.scope ?? getCurrentScope();\n const captureSerializedMetric = options?.captureSerializedMetric ?? _INTERNAL_captureSerializedMetric;\n const client = currentScope?.getClient() ?? getClient();\n if (!client) {\n DEBUG_BUILD && debug.warn('No client available to capture metric.');\n return;\n }\n\n const { _experiments, enableMetrics, beforeSendMetric } = client.getOptions();\n\n // todo(v11): Remove the experimental flag\n // eslint-disable-next-line deprecation/deprecation\n const metricsEnabled = enableMetrics ?? _experiments?.enableMetrics ?? true;\n\n if (!metricsEnabled) {\n DEBUG_BUILD && debug.warn('metrics option not enabled, metric will not be captured.');\n return;\n }\n\n // Enrich metric with contextual attributes\n const { user, attributes: scopeAttributes } = getCombinedScopeData(getIsolationScope(), currentScope);\n const enrichedMetric = _enrichMetricAttributes(beforeMetric, client, user);\n\n client.emit('processMetric', enrichedMetric);\n\n // todo(v11): Remove the experimental `beforeSendMetric`\n // eslint-disable-next-line deprecation/deprecation\n const beforeSendCallback = beforeSendMetric || _experiments?.beforeSendMetric;\n const processedMetric = beforeSendCallback ? beforeSendCallback(enrichedMetric) : enrichedMetric;\n\n if (!processedMetric) {\n DEBUG_BUILD && debug.log('`beforeSendMetric` returned `null`, will not send metric.');\n return;\n }\n\n const serializedMetric = _buildSerializedMetric(processedMetric, client, currentScope, scopeAttributes);\n\n DEBUG_BUILD && debug.log('[Metric]', serializedMetric);\n\n captureSerializedMetric(client, serializedMetric);\n\n client.emit('afterCaptureMetric', processedMetric);\n}\n\n/**\n * Flushes the metrics buffer to Sentry.\n *\n * @param client - A client.\n * @param maybeMetricBuffer - A metric buffer. Uses the metric 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_flushMetricsBuffer(client: Client, maybeMetricBuffer?: Array<SerializedMetric>): void {\n const metricBuffer = maybeMetricBuffer ?? _INTERNAL_getMetricBuffer(client) ?? [];\n if (metricBuffer.length === 0) {\n return;\n }\n\n const clientOptions = client.getOptions();\n const envelope = createMetricEnvelope(metricBuffer, clientOptions._metadata, clientOptions.tunnel, client.getDsn());\n\n // Clear the metric buffer after envelopes have been constructed.\n _getBufferMap().set(client, []);\n\n client.emit('flushMetrics');\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 metric buffer for a given client.\n *\n * Exported for testing purposes.\n *\n * @param client - The client to get the metric buffer for.\n * @returns The metric buffer for the given client.\n */\nexport function _INTERNAL_getMetricBuffer(client: Client): Array<SerializedMetric> | undefined {\n return _getBufferMap().get(client);\n}\n\nfunction _getBufferMap(): WeakMap<Client, Array<SerializedMetric>> {\n // The reference to the Client <> MetricBuffer map is stored on the carrier to ensure it's always the same\n return getGlobalSingleton('clientToMetricBufferMap', () => new WeakMap<Client, Array<SerializedMetric>>());\n}\n"],"names":["_getTraceInfoFromScope","_getSpanForScope","timestampInSeconds","getSequenceAttribute","serializeAttributes","getCurrentScope","getClient","DEBUG_BUILD","debug","getCombinedScopeData","getIsolationScope","envelope","createMetricEnvelope","getGlobalSingleton"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"internal.js","sources":["../../../src/metrics/internal.ts"],"sourcesContent":["import { type RawAttributes, 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 { Scope } from '../scope';\nimport type { Integration } from '../types-hoist/integration';\nimport type { Metric, SerializedMetric } from '../types-hoist/metric';\nimport type { User } from '../types-hoist/user';\nimport { debug } from '../utils/debug-logger';\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 { createMetricEnvelope } from './envelope';\n\nconst MAX_METRIC_BUFFER_SIZE = 1000;\n\n/**\n * Sets a metric attribute if the value exists and the attribute key is not already present.\n *\n * @param metricAttributes - The metric 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 setMetricAttribute(\n metricAttributes: Record<string, unknown>,\n key: string,\n value: unknown,\n setEvenIfPresent = true,\n): void {\n if (value && (setEvenIfPresent || !(key in metricAttributes))) {\n metricAttributes[key] = value;\n }\n}\n\n/**\n * Captures a serialized metric event and adds it to the metric buffer for the given client.\n *\n * @param client - A client. Uses the current client if not provided.\n * @param serializedMetric - The serialized metric 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_captureSerializedMetric(client: Client, serializedMetric: SerializedMetric): void {\n const bufferMap = _getBufferMap();\n const metricBuffer = _INTERNAL_getMetricBuffer(client);\n\n if (metricBuffer === undefined) {\n bufferMap.set(client, [serializedMetric]);\n } else {\n if (metricBuffer.length >= MAX_METRIC_BUFFER_SIZE) {\n _INTERNAL_flushMetricsBuffer(client, metricBuffer);\n bufferMap.set(client, [serializedMetric]);\n } else {\n bufferMap.set(client, [...metricBuffer, serializedMetric]);\n }\n }\n}\n\n/**\n * Options for capturing a metric internally.\n */\nexport interface InternalCaptureMetricOptions {\n /**\n * The scope to capture the metric with.\n */\n scope?: Scope;\n\n /**\n * A function to capture the serialized metric.\n */\n captureSerializedMetric?: (client: Client, metric: SerializedMetric) => void;\n}\n\n/**\n * Enriches metric with all contextual attributes (user, SDK metadata, replay, etc.)\n */\nfunction _enrichMetricAttributes(beforeMetric: Metric, client: Client, user: User): Metric {\n const { release, environment } = client.getOptions();\n\n const processedMetricAttributes = {\n ...beforeMetric.attributes,\n };\n\n // Add user attributes\n setMetricAttribute(processedMetricAttributes, 'user.id', user.id, false);\n setMetricAttribute(processedMetricAttributes, 'user.email', user.email, false);\n setMetricAttribute(processedMetricAttributes, 'user.name', user.username, false);\n\n // Add Sentry metadata\n setMetricAttribute(processedMetricAttributes, 'sentry.release', release);\n setMetricAttribute(processedMetricAttributes, 'sentry.environment', environment);\n\n // Add SDK metadata\n const { name, version } = client.getSdkMetadata()?.sdk ?? {};\n setMetricAttribute(processedMetricAttributes, 'sentry.sdk.name', name);\n setMetricAttribute(processedMetricAttributes, 'sentry.sdk.version', version);\n\n // Add replay metadata\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 setMetricAttribute(processedMetricAttributes, 'sentry.replay_id', replayId);\n\n if (replayId && replay?.getRecordingMode() === 'buffer') {\n setMetricAttribute(processedMetricAttributes, 'sentry._internal.replay_is_buffering', true);\n }\n\n return {\n ...beforeMetric,\n attributes: processedMetricAttributes,\n };\n}\n\n/**\n * Creates a serialized metric ready to be sent to Sentry.\n */\nfunction _buildSerializedMetric(\n metric: Metric,\n client: Client,\n currentScope: Scope,\n scopeAttributes: RawAttributes<Record<string, unknown>> | undefined,\n): SerializedMetric {\n // Get trace context\n const [, traceContext] = _getTraceInfoFromScope(client, currentScope);\n const span = _getSpanForScope(currentScope);\n const traceId = span ? span.spanContext().traceId : traceContext?.trace_id;\n const spanId = span ? span.spanContext().spanId : undefined;\n\n const timestamp = timestampInSeconds();\n const sequenceAttr = getSequenceAttribute(timestamp);\n\n return {\n timestamp,\n trace_id: traceId ?? '',\n span_id: spanId,\n name: metric.name,\n type: metric.type,\n unit: metric.unit,\n value: metric.value,\n attributes: {\n ...serializeAttributes(scopeAttributes),\n ...serializeAttributes(metric.attributes, 'skip-undefined'),\n [sequenceAttr.key]: sequenceAttr.value,\n },\n };\n}\n\n/**\n * Captures a metric event and sends it to Sentry.\n *\n * @param metric - The metric event to capture.\n * @param options - Options for capturing the metric.\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_captureMetric(beforeMetric: Metric, options?: InternalCaptureMetricOptions): void {\n const currentScope = options?.scope ?? getCurrentScope();\n const captureSerializedMetric = options?.captureSerializedMetric ?? _INTERNAL_captureSerializedMetric;\n const client = currentScope?.getClient() ?? getClient();\n if (!client) {\n DEBUG_BUILD && debug.warn('No client available to capture metric.');\n return;\n }\n\n const { _experiments, enableMetrics, beforeSendMetric } = client.getOptions();\n\n // todo(v11): Remove the experimental flag\n // eslint-disable-next-line deprecation/deprecation\n const metricsEnabled = enableMetrics ?? _experiments?.enableMetrics ?? true;\n\n if (!metricsEnabled) {\n DEBUG_BUILD && debug.warn('metrics option not enabled, metric will not be captured.');\n return;\n }\n\n // Enrich metric with contextual attributes\n const { user, attributes: scopeAttributes } = getCombinedScopeData(getIsolationScope(), currentScope);\n const enrichedMetric = _enrichMetricAttributes(beforeMetric, client, user);\n\n client.emit('processMetric', enrichedMetric);\n\n // todo(v11): Remove the experimental `beforeSendMetric`\n // eslint-disable-next-line deprecation/deprecation\n const beforeSendCallback = beforeSendMetric || _experiments?.beforeSendMetric;\n const processedMetric = beforeSendCallback ? beforeSendCallback(enrichedMetric) : enrichedMetric;\n\n if (!processedMetric) {\n DEBUG_BUILD && debug.log('`beforeSendMetric` returned `null`, will not send metric.');\n return;\n }\n\n const serializedMetric = _buildSerializedMetric(processedMetric, client, currentScope, scopeAttributes);\n\n DEBUG_BUILD && debug.log('[Metric]', serializedMetric);\n\n captureSerializedMetric(client, serializedMetric);\n\n client.emit('afterCaptureMetric', processedMetric);\n}\n\n/**\n * Flushes the metrics buffer to Sentry.\n *\n * @param client - A client.\n * @param maybeMetricBuffer - A metric buffer. Uses the metric 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_flushMetricsBuffer(client: Client, maybeMetricBuffer?: Array<SerializedMetric>): void {\n const metricBuffer = maybeMetricBuffer ?? _INTERNAL_getMetricBuffer(client) ?? [];\n if (metricBuffer.length === 0) {\n return;\n }\n\n const clientOptions = client.getOptions();\n const envelope = createMetricEnvelope(\n metricBuffer,\n clientOptions._metadata,\n clientOptions.tunnel,\n client.getDsn(),\n clientOptions.sendDefaultPii,\n );\n\n // Clear the metric buffer after envelopes have been constructed.\n _getBufferMap().set(client, []);\n\n client.emit('flushMetrics');\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 metric buffer for a given client.\n *\n * Exported for testing purposes.\n *\n * @param client - The client to get the metric buffer for.\n * @returns The metric buffer for the given client.\n */\nexport function _INTERNAL_getMetricBuffer(client: Client): Array<SerializedMetric> | undefined {\n return _getBufferMap().get(client);\n}\n\nfunction _getBufferMap(): WeakMap<Client, Array<SerializedMetric>> {\n // The reference to the Client <> MetricBuffer map is stored on the carrier to ensure it's always the same\n return getGlobalSingleton('clientToMetricBufferMap', () => new WeakMap<Client, Array<SerializedMetric>>());\n}\n"],"names":["_getTraceInfoFromScope","_getSpanForScope","timestampInSeconds","getSequenceAttribute","serializeAttributes","getCurrentScope","getClient","DEBUG_BUILD","debug","getCombinedScopeData","getIsolationScope","envelope","createMetricEnvelope","getGlobalSingleton"],"mappings":"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"}
|
|
@@ -2,6 +2,7 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
|
2
2
|
|
|
3
3
|
const semanticAttributes = require('../../semanticAttributes.js');
|
|
4
4
|
const scopeData = require('../../utils/scopeData.js');
|
|
5
|
+
const url = require('../../utils/url.js');
|
|
5
6
|
const spanUtils = require('../../utils/spanUtils.js');
|
|
6
7
|
const utils = require('../utils.js');
|
|
7
8
|
const beforeSendSpan = require('./beforeSendSpan.js');
|
|
@@ -69,6 +70,23 @@ function captureSpan(span, client) {
|
|
|
69
70
|
};
|
|
70
71
|
}
|
|
71
72
|
|
|
73
|
+
/**
|
|
74
|
+
* Safely set attributes on a span JSON.
|
|
75
|
+
* If an attribute already exists, it will not be overwritten.
|
|
76
|
+
*/
|
|
77
|
+
function safeSetSpanJSONAttributes(
|
|
78
|
+
spanJSON,
|
|
79
|
+
newAttributes,
|
|
80
|
+
) {
|
|
81
|
+
const originalAttributes = spanJSON.attributes ?? (spanJSON.attributes = {});
|
|
82
|
+
|
|
83
|
+
Object.entries(newAttributes).forEach(([key, value]) => {
|
|
84
|
+
if (value != null && !(key in originalAttributes)) {
|
|
85
|
+
originalAttributes[key] = value;
|
|
86
|
+
}
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
|
|
72
90
|
function applyCommonSpanAttributes(
|
|
73
91
|
spanJSON,
|
|
74
92
|
serializedSegmentSpan,
|
|
@@ -113,23 +131,6 @@ function applyBeforeSendSpanCallback(
|
|
|
113
131
|
return modifedSpan;
|
|
114
132
|
}
|
|
115
133
|
|
|
116
|
-
/**
|
|
117
|
-
* Safely set attributes on a span JSON.
|
|
118
|
-
* If an attribute already exists, it will not be overwritten.
|
|
119
|
-
*/
|
|
120
|
-
function safeSetSpanJSONAttributes(
|
|
121
|
-
spanJSON,
|
|
122
|
-
newAttributes,
|
|
123
|
-
) {
|
|
124
|
-
const originalAttributes = spanJSON.attributes ?? (spanJSON.attributes = {});
|
|
125
|
-
|
|
126
|
-
Object.entries(newAttributes).forEach(([key, value]) => {
|
|
127
|
-
if (value != null && !(key in originalAttributes)) {
|
|
128
|
-
originalAttributes[key] = value;
|
|
129
|
-
}
|
|
130
|
-
});
|
|
131
|
-
}
|
|
132
|
-
|
|
133
134
|
// OTel SpanKind values (numeric to avoid importing from @opentelemetry/api)
|
|
134
135
|
const SPAN_KIND_SERVER = 1;
|
|
135
136
|
const SPAN_KIND_CLIENT = 2;
|
|
@@ -210,21 +211,55 @@ function inferHttpSpanData(
|
|
|
210
211
|
return;
|
|
211
212
|
}
|
|
212
213
|
|
|
213
|
-
// Only overwrite the span name when we have an explicit http.route — it's more specific than
|
|
214
|
-
// what OTel instrumentation sets as the span name. For all other cases (url.full, http.target),
|
|
215
|
-
// the OTel-set name is already good enough and we'd risk producing a worse name (e.g. full URL).
|
|
216
214
|
const httpRoute = attributes['http.route'];
|
|
217
215
|
if (typeof httpRoute === 'string') {
|
|
218
216
|
spanJSON.name = `${httpMethod} ${httpRoute}`;
|
|
219
217
|
safeSetSpanJSONAttributes(spanJSON, { [semanticAttributes.SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: 'route' });
|
|
220
218
|
} else {
|
|
221
|
-
//
|
|
222
|
-
//
|
|
223
|
-
|
|
219
|
+
// Infer span name from URL attributes, matching the non-streamed exporter's behavior.
|
|
220
|
+
// Only overwrite the name for OTel spans (known spanKind)
|
|
221
|
+
if (spanKind === SPAN_KIND_CLIENT || spanKind === SPAN_KIND_SERVER) {
|
|
222
|
+
const urlPath = getUrlPath(attributes, spanKind);
|
|
223
|
+
if (urlPath) {
|
|
224
|
+
spanJSON.name = `${httpMethod} ${urlPath}`;
|
|
225
|
+
}
|
|
226
|
+
}
|
|
224
227
|
safeSetSpanJSONAttributes(spanJSON, { [semanticAttributes.SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: 'url' });
|
|
225
228
|
}
|
|
226
229
|
}
|
|
227
230
|
|
|
231
|
+
/**
|
|
232
|
+
* Extract a URL path from span attributes for use in the span name.
|
|
233
|
+
* Mirrors the logic in the non-streamed exporter's `getSanitizedUrl`.
|
|
234
|
+
*/
|
|
235
|
+
function getUrlPath(
|
|
236
|
+
attributes,
|
|
237
|
+
spanKind,
|
|
238
|
+
) {
|
|
239
|
+
const httpUrl = attributes['http.url'] || attributes['url.full'];
|
|
240
|
+
const httpTarget = attributes['http.target'];
|
|
241
|
+
|
|
242
|
+
const parsedUrl = typeof httpUrl === 'string' ? url.parseUrl(httpUrl) : undefined;
|
|
243
|
+
const sanitizedUrl = parsedUrl ? url.getSanitizedUrlString(parsedUrl) : undefined;
|
|
244
|
+
|
|
245
|
+
// For server spans, prefer the relative target path
|
|
246
|
+
if (spanKind === SPAN_KIND_SERVER && typeof httpTarget === 'string') {
|
|
247
|
+
return url.stripUrlQueryAndFragment(httpTarget);
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
// For client spans (and others), use the full sanitized URL
|
|
251
|
+
if (sanitizedUrl) {
|
|
252
|
+
return sanitizedUrl;
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
// Fall back to target if no full URL is available
|
|
256
|
+
if (typeof httpTarget === 'string') {
|
|
257
|
+
return url.stripUrlQueryAndFragment(httpTarget);
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
return undefined;
|
|
261
|
+
}
|
|
262
|
+
|
|
228
263
|
function inferDbSpanData(spanJSON, attributes) {
|
|
229
264
|
safeSetSpanJSONAttributes(spanJSON, { [semanticAttributes.SEMANTIC_ATTRIBUTE_SENTRY_OP]: 'db' });
|
|
230
265
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"captureSpan.js","sources":["../../../../src/tracing/spans/captureSpan.ts"],"sourcesContent":["import type { RawAttributes } from '../../attributes';\nimport type { Client } from '../../client';\nimport type { ScopeData } from '../../scope';\nimport {\n SEMANTIC_ATTRIBUTE_SENTRY_CUSTOM_SPAN_NAME,\n SEMANTIC_ATTRIBUTE_SENTRY_ENVIRONMENT,\n SEMANTIC_ATTRIBUTE_SENTRY_OP,\n SEMANTIC_ATTRIBUTE_SENTRY_RELEASE,\n SEMANTIC_ATTRIBUTE_SENTRY_SDK_NAME,\n SEMANTIC_ATTRIBUTE_SENTRY_SDK_VERSION,\n SEMANTIC_ATTRIBUTE_SENTRY_SEGMENT_ID,\n SEMANTIC_ATTRIBUTE_SENTRY_SEGMENT_NAME,\n SEMANTIC_ATTRIBUTE_SENTRY_SOURCE,\n SEMANTIC_ATTRIBUTE_USER_EMAIL,\n SEMANTIC_ATTRIBUTE_USER_ID,\n SEMANTIC_ATTRIBUTE_USER_IP_ADDRESS,\n SEMANTIC_ATTRIBUTE_USER_USERNAME,\n} from '../../semanticAttributes';\nimport type { SerializedStreamedSpan, Span, StreamedSpanJSON } from '../../types-hoist/span';\nimport { getCombinedScopeData } from '../../utils/scopeData';\nimport {\n INTERNAL_getSegmentSpan,\n showSpanDropWarning,\n spanToStreamedSpanJSON,\n streamedSpanJsonToSerializedSpan,\n} from '../../utils/spanUtils';\nimport { getCapturedScopesOnSpan } from '../utils';\nimport { isStreamedBeforeSendSpanCallback } from './beforeSendSpan';\n\nexport type SerializedStreamedSpanWithSegmentSpan = SerializedStreamedSpan & {\n _segmentSpan: Span;\n};\n\n/**\n * Captures a span and returns a JSON representation to be enqueued for sending.\n *\n * IMPORTANT: This function converts the span to JSON immediately to avoid writing\n * to an already-ended OTel span instance (which is blocked by the OTel Span class).\n *\n * @returns the final serialized span with a reference to its segment span. This reference\n * is needed later on to compute the DSC for the span envelope.\n */\nexport function captureSpan(span: Span, client: Client): SerializedStreamedSpanWithSegmentSpan {\n // Convert to JSON FIRST - we cannot write to an already-ended span\n const spanJSON = spanToStreamedSpanJSON(span);\n\n const segmentSpan = INTERNAL_getSegmentSpan(span);\n const serializedSegmentSpan = spanToStreamedSpanJSON(segmentSpan);\n\n const { isolationScope: spanIsolationScope, scope: spanScope } = getCapturedScopesOnSpan(span);\n\n const finalScopeData = getCombinedScopeData(spanIsolationScope, spanScope);\n\n applyCommonSpanAttributes(spanJSON, serializedSegmentSpan, client, finalScopeData);\n\n // Backfill span data from OTel semantic conventions when not explicitly set.\n // OTel-originated spans don't have sentry.op, description, etc. — the non-streamed path\n // infers these in the SentrySpanExporter, but streamed spans skip the exporter entirely.\n // Access `kind` via duck-typing — OTel span objects have this property but it's not on Sentry's Span type.\n // This must run before all hooks and beforeSendSpan so that user callbacks can see and override inferred values.\n const spanKind = (span as { kind?: number }).kind;\n inferSpanDataFromOtelAttributes(spanJSON, spanKind);\n\n if (spanJSON.is_segment) {\n applyScopeToSegmentSpan(spanJSON, finalScopeData);\n // Allow hook subscribers to mutate the segment span JSON\n // This also invokes the `processSegmentSpan` hook of all integrations\n client.emit('processSegmentSpan', spanJSON);\n }\n\n // This allows hook subscribers to mutate the span JSON\n // This also invokes the `processSpan` hook of all integrations\n client.emit('processSpan', spanJSON);\n\n const { beforeSendSpan } = client.getOptions();\n const processedSpan =\n beforeSendSpan && isStreamedBeforeSendSpanCallback(beforeSendSpan)\n ? applyBeforeSendSpanCallback(spanJSON, beforeSendSpan)\n : spanJSON;\n\n // Backfill sentry.span.source from sentry.source. Only `sentry.span.source` is respected by Sentry.\n // TODO(v11): Remove this backfill once we renamed SEMANTIC_ATTRIBUTE_SENTRY_SOURCE to sentry.span.source\n const spanNameSource = processedSpan.attributes?.[SEMANTIC_ATTRIBUTE_SENTRY_SOURCE];\n if (spanNameSource) {\n safeSetSpanJSONAttributes(processedSpan, {\n // Purposefully not using a constant defined here like in other attributes:\n // This will be the name for SEMANTIC_ATTRIBUTE_SENTRY_SOURCE in v11\n 'sentry.span.source': spanNameSource,\n });\n }\n\n return {\n ...streamedSpanJsonToSerializedSpan(processedSpan),\n _segmentSpan: segmentSpan,\n };\n}\n\nfunction applyScopeToSegmentSpan(_segmentSpanJSON: StreamedSpanJSON, _scopeData: ScopeData): void {\n // TODO: Apply all scope and request data from auto instrumentation (contexts, request) to segment span\n // This will follow in a separate PR\n}\n\nfunction applyCommonSpanAttributes(\n spanJSON: StreamedSpanJSON,\n serializedSegmentSpan: StreamedSpanJSON,\n client: Client,\n scopeData: ScopeData,\n): void {\n const sdk = client.getSdkMetadata();\n const { release, environment, sendDefaultPii } = client.getOptions();\n\n // avoid overwriting any previously set attributes (from users or potentially our SDK instrumentation)\n safeSetSpanJSONAttributes(spanJSON, {\n [SEMANTIC_ATTRIBUTE_SENTRY_RELEASE]: release,\n [SEMANTIC_ATTRIBUTE_SENTRY_ENVIRONMENT]: environment,\n [SEMANTIC_ATTRIBUTE_SENTRY_SEGMENT_NAME]: serializedSegmentSpan.name,\n [SEMANTIC_ATTRIBUTE_SENTRY_SEGMENT_ID]: serializedSegmentSpan.span_id,\n [SEMANTIC_ATTRIBUTE_SENTRY_SDK_NAME]: sdk?.sdk?.name,\n [SEMANTIC_ATTRIBUTE_SENTRY_SDK_VERSION]: sdk?.sdk?.version,\n ...(sendDefaultPii\n ? {\n [SEMANTIC_ATTRIBUTE_USER_ID]: scopeData.user?.id,\n [SEMANTIC_ATTRIBUTE_USER_EMAIL]: scopeData.user?.email,\n [SEMANTIC_ATTRIBUTE_USER_IP_ADDRESS]: scopeData.user?.ip_address,\n [SEMANTIC_ATTRIBUTE_USER_USERNAME]: scopeData.user?.username,\n }\n : {}),\n ...scopeData.attributes,\n });\n}\n\n/**\n * Apply a user-provided beforeSendSpan callback to a span JSON.\n */\nexport function applyBeforeSendSpanCallback(\n span: StreamedSpanJSON,\n beforeSendSpan: (span: StreamedSpanJSON) => StreamedSpanJSON,\n): StreamedSpanJSON {\n const modifedSpan = beforeSendSpan(span);\n if (!modifedSpan) {\n showSpanDropWarning();\n return span;\n }\n return modifedSpan;\n}\n\n/**\n * Safely set attributes on a span JSON.\n * If an attribute already exists, it will not be overwritten.\n */\nexport function safeSetSpanJSONAttributes(\n spanJSON: StreamedSpanJSON,\n newAttributes: RawAttributes<Record<string, unknown>>,\n): void {\n const originalAttributes = spanJSON.attributes ?? (spanJSON.attributes = {});\n\n Object.entries(newAttributes).forEach(([key, value]) => {\n if (value != null && !(key in originalAttributes)) {\n originalAttributes[key] = value;\n }\n });\n}\n\n// OTel SpanKind values (numeric to avoid importing from @opentelemetry/api)\nconst SPAN_KIND_SERVER = 1;\nconst SPAN_KIND_CLIENT = 2;\n\n/**\n * Infer and backfill span data from OTel semantic conventions.\n * This mirrors what the `SentrySpanExporter` does for non-streamed spans via `getSpanData`/`inferSpanData`.\n * Streamed spans skip the exporter, so we do the inference here during capture.\n *\n * Backfills: `sentry.op`, `sentry.source`, and `name` (description).\n * Uses `safeSetSpanJSONAttributes` so explicitly set attributes are never overwritten.\n */\n/** Exported only for tests. */\nexport function inferSpanDataFromOtelAttributes(spanJSON: StreamedSpanJSON, spanKind?: number): void {\n const attributes = spanJSON.attributes;\n if (!attributes) {\n return;\n }\n\n const httpMethod = attributes['http.request.method'] || attributes['http.method'];\n if (httpMethod) {\n inferHttpSpanData(spanJSON, attributes, spanKind, httpMethod);\n return;\n }\n\n const dbSystem = attributes['db.system.name'] || attributes['db.system'];\n const opIsCache =\n typeof attributes[SEMANTIC_ATTRIBUTE_SENTRY_OP] === 'string' &&\n `${attributes[SEMANTIC_ATTRIBUTE_SENTRY_OP]}`.startsWith('cache.');\n if (dbSystem && !opIsCache) {\n inferDbSpanData(spanJSON, attributes);\n return;\n }\n\n if (attributes['rpc.service']) {\n safeSetSpanJSONAttributes(spanJSON, { [SEMANTIC_ATTRIBUTE_SENTRY_OP]: 'rpc' });\n return;\n }\n\n if (attributes['messaging.system']) {\n safeSetSpanJSONAttributes(spanJSON, { [SEMANTIC_ATTRIBUTE_SENTRY_OP]: 'message' });\n return;\n }\n\n const faasTrigger = attributes['faas.trigger'];\n if (faasTrigger) {\n safeSetSpanJSONAttributes(spanJSON, { [SEMANTIC_ATTRIBUTE_SENTRY_OP]: `${faasTrigger}` });\n }\n}\n\nfunction inferHttpSpanData(\n spanJSON: StreamedSpanJSON,\n attributes: RawAttributes<Record<string, unknown>>,\n spanKind: number | undefined,\n httpMethod: unknown,\n): void {\n // Infer op: http.client, http.server, or just http\n const opParts = ['http'];\n if (spanKind === SPAN_KIND_CLIENT) {\n opParts.push('client');\n } else if (spanKind === SPAN_KIND_SERVER) {\n opParts.push('server');\n }\n if (attributes['sentry.http.prefetch']) {\n opParts.push('prefetch');\n }\n safeSetSpanJSONAttributes(spanJSON, { [SEMANTIC_ATTRIBUTE_SENTRY_OP]: opParts.join('.') });\n\n // If the user set a custom span name via updateSpanName(), apply it — OTel instrumentation\n // may have overwritten span.name after the user set it, so we restore from the attribute.\n const customName = attributes[SEMANTIC_ATTRIBUTE_SENTRY_CUSTOM_SPAN_NAME];\n if (typeof customName === 'string') {\n spanJSON.name = customName;\n return;\n }\n\n if (attributes[SEMANTIC_ATTRIBUTE_SENTRY_SOURCE] === 'custom') {\n return;\n }\n\n // Only overwrite the span name when we have an explicit http.route — it's more specific than\n // what OTel instrumentation sets as the span name. For all other cases (url.full, http.target),\n // the OTel-set name is already good enough and we'd risk producing a worse name (e.g. full URL).\n const httpRoute = attributes['http.route'];\n if (typeof httpRoute === 'string') {\n spanJSON.name = `${httpMethod} ${httpRoute}`;\n safeSetSpanJSONAttributes(spanJSON, { [SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: 'route' });\n } else {\n // Fallback: set source to 'url' for HTTP spans without a route.\n // The spec requires sentry.span.source on segment spans, and the non-streamed exporter\n // always sets this — so we need to ensure it's present for streamed spans too.\n safeSetSpanJSONAttributes(spanJSON, { [SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: 'url' });\n }\n}\n\nfunction inferDbSpanData(spanJSON: StreamedSpanJSON, attributes: RawAttributes<Record<string, unknown>>): void {\n safeSetSpanJSONAttributes(spanJSON, { [SEMANTIC_ATTRIBUTE_SENTRY_OP]: 'db' });\n\n // If the user set a custom span name via updateSpanName(), apply it.\n const customName = attributes[SEMANTIC_ATTRIBUTE_SENTRY_CUSTOM_SPAN_NAME];\n if (typeof customName === 'string') {\n spanJSON.name = customName;\n return;\n }\n\n if (attributes[SEMANTIC_ATTRIBUTE_SENTRY_SOURCE] === 'custom') {\n return;\n }\n\n const statement = attributes['db.statement'];\n if (statement) {\n spanJSON.name = `${statement}`;\n safeSetSpanJSONAttributes(spanJSON, { [SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: 'task' });\n }\n}\n"],"names":["spanToStreamedSpanJSON","INTERNAL_getSegmentSpan","getCapturedScopesOnSpan","getCombinedScopeData","beforeSendSpan","isStreamedBeforeSendSpanCallback","SEMANTIC_ATTRIBUTE_SENTRY_SOURCE","streamedSpanJsonToSerializedSpan","SEMANTIC_ATTRIBUTE_SENTRY_RELEASE","SEMANTIC_ATTRIBUTE_SENTRY_ENVIRONMENT","SEMANTIC_ATTRIBUTE_SENTRY_SEGMENT_NAME","SEMANTIC_ATTRIBUTE_SENTRY_SEGMENT_ID","SEMANTIC_ATTRIBUTE_SENTRY_SDK_NAME","SEMANTIC_ATTRIBUTE_SENTRY_SDK_VERSION","SEMANTIC_ATTRIBUTE_USER_ID","SEMANTIC_ATTRIBUTE_USER_EMAIL","SEMANTIC_ATTRIBUTE_USER_IP_ADDRESS","SEMANTIC_ATTRIBUTE_USER_USERNAME","showSpanDropWarning","SEMANTIC_ATTRIBUTE_SENTRY_OP","SEMANTIC_ATTRIBUTE_SENTRY_CUSTOM_SPAN_NAME"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"captureSpan.js","sources":["../../../../src/tracing/spans/captureSpan.ts"],"sourcesContent":["import type { RawAttributes } from '../../attributes';\nimport type { Client } from '../../client';\nimport type { ScopeData } from '../../scope';\nimport {\n SEMANTIC_ATTRIBUTE_SENTRY_CUSTOM_SPAN_NAME,\n SEMANTIC_ATTRIBUTE_SENTRY_ENVIRONMENT,\n SEMANTIC_ATTRIBUTE_SENTRY_OP,\n SEMANTIC_ATTRIBUTE_SENTRY_RELEASE,\n SEMANTIC_ATTRIBUTE_SENTRY_SDK_NAME,\n SEMANTIC_ATTRIBUTE_SENTRY_SDK_VERSION,\n SEMANTIC_ATTRIBUTE_SENTRY_SEGMENT_ID,\n SEMANTIC_ATTRIBUTE_SENTRY_SEGMENT_NAME,\n SEMANTIC_ATTRIBUTE_SENTRY_SOURCE,\n SEMANTIC_ATTRIBUTE_USER_EMAIL,\n SEMANTIC_ATTRIBUTE_USER_ID,\n SEMANTIC_ATTRIBUTE_USER_IP_ADDRESS,\n SEMANTIC_ATTRIBUTE_USER_USERNAME,\n} from '../../semanticAttributes';\nimport type { SerializedStreamedSpan, Span, StreamedSpanJSON } from '../../types-hoist/span';\nimport { getCombinedScopeData } from '../../utils/scopeData';\nimport { getSanitizedUrlString, parseUrl, stripUrlQueryAndFragment } from '../../utils/url';\nimport {\n INTERNAL_getSegmentSpan,\n showSpanDropWarning,\n spanToStreamedSpanJSON,\n streamedSpanJsonToSerializedSpan,\n} from '../../utils/spanUtils';\nimport { getCapturedScopesOnSpan } from '../utils';\nimport { isStreamedBeforeSendSpanCallback } from './beforeSendSpan';\n\nexport type SerializedStreamedSpanWithSegmentSpan = SerializedStreamedSpan & {\n _segmentSpan: Span;\n};\n\n/**\n * Captures a span and returns a JSON representation to be enqueued for sending.\n *\n * IMPORTANT: This function converts the span to JSON immediately to avoid writing\n * to an already-ended OTel span instance (which is blocked by the OTel Span class).\n *\n * @returns the final serialized span with a reference to its segment span. This reference\n * is needed later on to compute the DSC for the span envelope.\n */\nexport function captureSpan(span: Span, client: Client): SerializedStreamedSpanWithSegmentSpan {\n // Convert to JSON FIRST - we cannot write to an already-ended span\n const spanJSON = spanToStreamedSpanJSON(span);\n\n const segmentSpan = INTERNAL_getSegmentSpan(span);\n const serializedSegmentSpan = spanToStreamedSpanJSON(segmentSpan);\n\n const { isolationScope: spanIsolationScope, scope: spanScope } = getCapturedScopesOnSpan(span);\n\n const finalScopeData = getCombinedScopeData(spanIsolationScope, spanScope);\n\n applyCommonSpanAttributes(spanJSON, serializedSegmentSpan, client, finalScopeData);\n\n // Backfill span data from OTel semantic conventions when not explicitly set.\n // OTel-originated spans don't have sentry.op, description, etc. — the non-streamed path\n // infers these in the SentrySpanExporter, but streamed spans skip the exporter entirely.\n // Access `kind` via duck-typing — OTel span objects have this property but it's not on Sentry's Span type.\n // This must run before all hooks and beforeSendSpan so that user callbacks can see and override inferred values.\n const spanKind = (span as { kind?: number }).kind;\n inferSpanDataFromOtelAttributes(spanJSON, spanKind);\n\n if (spanJSON.is_segment) {\n applyScopeToSegmentSpan(spanJSON, finalScopeData);\n // Allow hook subscribers to mutate the segment span JSON\n // This also invokes the `processSegmentSpan` hook of all integrations\n client.emit('processSegmentSpan', spanJSON);\n }\n\n // This allows hook subscribers to mutate the span JSON\n // This also invokes the `processSpan` hook of all integrations\n client.emit('processSpan', spanJSON);\n\n const { beforeSendSpan } = client.getOptions();\n const processedSpan =\n beforeSendSpan && isStreamedBeforeSendSpanCallback(beforeSendSpan)\n ? applyBeforeSendSpanCallback(spanJSON, beforeSendSpan)\n : spanJSON;\n\n // Backfill sentry.span.source from sentry.source. Only `sentry.span.source` is respected by Sentry.\n // TODO(v11): Remove this backfill once we renamed SEMANTIC_ATTRIBUTE_SENTRY_SOURCE to sentry.span.source\n const spanNameSource = processedSpan.attributes?.[SEMANTIC_ATTRIBUTE_SENTRY_SOURCE];\n if (spanNameSource) {\n safeSetSpanJSONAttributes(processedSpan, {\n // Purposefully not using a constant defined here like in other attributes:\n // This will be the name for SEMANTIC_ATTRIBUTE_SENTRY_SOURCE in v11\n 'sentry.span.source': spanNameSource,\n });\n }\n\n return {\n ...streamedSpanJsonToSerializedSpan(processedSpan),\n _segmentSpan: segmentSpan,\n };\n}\n\nfunction applyScopeToSegmentSpan(_segmentSpanJSON: StreamedSpanJSON, _scopeData: ScopeData): void {\n // TODO: Apply contexts data from auto instrumentation to segment span\n // This will follow in a separate PR\n}\n\n/**\n * Safely set attributes on a span JSON.\n * If an attribute already exists, it will not be overwritten.\n */\nexport function safeSetSpanJSONAttributes(\n spanJSON: StreamedSpanJSON,\n newAttributes: RawAttributes<Record<string, unknown>>,\n): void {\n const originalAttributes = spanJSON.attributes ?? (spanJSON.attributes = {});\n\n Object.entries(newAttributes).forEach(([key, value]) => {\n if (value != null && !(key in originalAttributes)) {\n originalAttributes[key] = value;\n }\n });\n}\n\nfunction applyCommonSpanAttributes(\n spanJSON: StreamedSpanJSON,\n serializedSegmentSpan: StreamedSpanJSON,\n client: Client,\n scopeData: ScopeData,\n): void {\n const sdk = client.getSdkMetadata();\n const { release, environment, sendDefaultPii } = client.getOptions();\n\n // avoid overwriting any previously set attributes (from users or potentially our SDK instrumentation)\n safeSetSpanJSONAttributes(spanJSON, {\n [SEMANTIC_ATTRIBUTE_SENTRY_RELEASE]: release,\n [SEMANTIC_ATTRIBUTE_SENTRY_ENVIRONMENT]: environment,\n [SEMANTIC_ATTRIBUTE_SENTRY_SEGMENT_NAME]: serializedSegmentSpan.name,\n [SEMANTIC_ATTRIBUTE_SENTRY_SEGMENT_ID]: serializedSegmentSpan.span_id,\n [SEMANTIC_ATTRIBUTE_SENTRY_SDK_NAME]: sdk?.sdk?.name,\n [SEMANTIC_ATTRIBUTE_SENTRY_SDK_VERSION]: sdk?.sdk?.version,\n ...(sendDefaultPii\n ? {\n [SEMANTIC_ATTRIBUTE_USER_ID]: scopeData.user?.id,\n [SEMANTIC_ATTRIBUTE_USER_EMAIL]: scopeData.user?.email,\n [SEMANTIC_ATTRIBUTE_USER_IP_ADDRESS]: scopeData.user?.ip_address,\n [SEMANTIC_ATTRIBUTE_USER_USERNAME]: scopeData.user?.username,\n }\n : {}),\n ...scopeData.attributes,\n });\n}\n\n/**\n * Apply a user-provided beforeSendSpan callback to a span JSON.\n */\nexport function applyBeforeSendSpanCallback(\n span: StreamedSpanJSON,\n beforeSendSpan: (span: StreamedSpanJSON) => StreamedSpanJSON,\n): StreamedSpanJSON {\n const modifedSpan = beforeSendSpan(span);\n if (!modifedSpan) {\n showSpanDropWarning();\n return span;\n }\n return modifedSpan;\n}\n\n// OTel SpanKind values (numeric to avoid importing from @opentelemetry/api)\nconst SPAN_KIND_SERVER = 1;\nconst SPAN_KIND_CLIENT = 2;\n\n/**\n * Infer and backfill span data from OTel semantic conventions.\n * This mirrors what the `SentrySpanExporter` does for non-streamed spans via `getSpanData`/`inferSpanData`.\n * Streamed spans skip the exporter, so we do the inference here during capture.\n *\n * Backfills: `sentry.op`, `sentry.source`, and `name` (description).\n * Uses `safeSetSpanJSONAttributes` so explicitly set attributes are never overwritten.\n */\n/** Exported only for tests. */\nexport function inferSpanDataFromOtelAttributes(spanJSON: StreamedSpanJSON, spanKind?: number): void {\n const attributes = spanJSON.attributes;\n if (!attributes) {\n return;\n }\n\n const httpMethod = attributes['http.request.method'] || attributes['http.method'];\n if (httpMethod) {\n inferHttpSpanData(spanJSON, attributes, spanKind, httpMethod);\n return;\n }\n\n const dbSystem = attributes['db.system.name'] || attributes['db.system'];\n const opIsCache =\n typeof attributes[SEMANTIC_ATTRIBUTE_SENTRY_OP] === 'string' &&\n `${attributes[SEMANTIC_ATTRIBUTE_SENTRY_OP]}`.startsWith('cache.');\n if (dbSystem && !opIsCache) {\n inferDbSpanData(spanJSON, attributes);\n return;\n }\n\n if (attributes['rpc.service']) {\n safeSetSpanJSONAttributes(spanJSON, { [SEMANTIC_ATTRIBUTE_SENTRY_OP]: 'rpc' });\n return;\n }\n\n if (attributes['messaging.system']) {\n safeSetSpanJSONAttributes(spanJSON, { [SEMANTIC_ATTRIBUTE_SENTRY_OP]: 'message' });\n return;\n }\n\n const faasTrigger = attributes['faas.trigger'];\n if (faasTrigger) {\n safeSetSpanJSONAttributes(spanJSON, { [SEMANTIC_ATTRIBUTE_SENTRY_OP]: `${faasTrigger}` });\n }\n}\n\nfunction inferHttpSpanData(\n spanJSON: StreamedSpanJSON,\n attributes: RawAttributes<Record<string, unknown>>,\n spanKind: number | undefined,\n httpMethod: unknown,\n): void {\n // Infer op: http.client, http.server, or just http\n const opParts = ['http'];\n if (spanKind === SPAN_KIND_CLIENT) {\n opParts.push('client');\n } else if (spanKind === SPAN_KIND_SERVER) {\n opParts.push('server');\n }\n if (attributes['sentry.http.prefetch']) {\n opParts.push('prefetch');\n }\n safeSetSpanJSONAttributes(spanJSON, { [SEMANTIC_ATTRIBUTE_SENTRY_OP]: opParts.join('.') });\n\n // If the user set a custom span name via updateSpanName(), apply it — OTel instrumentation\n // may have overwritten span.name after the user set it, so we restore from the attribute.\n const customName = attributes[SEMANTIC_ATTRIBUTE_SENTRY_CUSTOM_SPAN_NAME];\n if (typeof customName === 'string') {\n spanJSON.name = customName;\n return;\n }\n\n if (attributes[SEMANTIC_ATTRIBUTE_SENTRY_SOURCE] === 'custom') {\n return;\n }\n\n const httpRoute = attributes['http.route'];\n if (typeof httpRoute === 'string') {\n spanJSON.name = `${httpMethod} ${httpRoute}`;\n safeSetSpanJSONAttributes(spanJSON, { [SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: 'route' });\n } else {\n // Infer span name from URL attributes, matching the non-streamed exporter's behavior.\n // Only overwrite the name for OTel spans (known spanKind)\n if (spanKind === SPAN_KIND_CLIENT || spanKind === SPAN_KIND_SERVER) {\n const urlPath = getUrlPath(attributes, spanKind);\n if (urlPath) {\n spanJSON.name = `${httpMethod} ${urlPath}`;\n }\n }\n safeSetSpanJSONAttributes(spanJSON, { [SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: 'url' });\n }\n}\n\n/**\n * Extract a URL path from span attributes for use in the span name.\n * Mirrors the logic in the non-streamed exporter's `getSanitizedUrl`.\n */\nfunction getUrlPath(\n attributes: RawAttributes<Record<string, unknown>>,\n spanKind: number | undefined,\n): string | undefined {\n const httpUrl = attributes['http.url'] || attributes['url.full'];\n const httpTarget = attributes['http.target'];\n\n const parsedUrl = typeof httpUrl === 'string' ? parseUrl(httpUrl) : undefined;\n const sanitizedUrl = parsedUrl ? getSanitizedUrlString(parsedUrl) : undefined;\n\n // For server spans, prefer the relative target path\n if (spanKind === SPAN_KIND_SERVER && typeof httpTarget === 'string') {\n return stripUrlQueryAndFragment(httpTarget);\n }\n\n // For client spans (and others), use the full sanitized URL\n if (sanitizedUrl) {\n return sanitizedUrl;\n }\n\n // Fall back to target if no full URL is available\n if (typeof httpTarget === 'string') {\n return stripUrlQueryAndFragment(httpTarget);\n }\n\n return undefined;\n}\n\nfunction inferDbSpanData(spanJSON: StreamedSpanJSON, attributes: RawAttributes<Record<string, unknown>>): void {\n safeSetSpanJSONAttributes(spanJSON, { [SEMANTIC_ATTRIBUTE_SENTRY_OP]: 'db' });\n\n // If the user set a custom span name via updateSpanName(), apply it.\n const customName = attributes[SEMANTIC_ATTRIBUTE_SENTRY_CUSTOM_SPAN_NAME];\n if (typeof customName === 'string') {\n spanJSON.name = customName;\n return;\n }\n\n if (attributes[SEMANTIC_ATTRIBUTE_SENTRY_SOURCE] === 'custom') {\n return;\n }\n\n const statement = attributes['db.statement'];\n if (statement) {\n spanJSON.name = `${statement}`;\n safeSetSpanJSONAttributes(spanJSON, { [SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: 'task' });\n }\n}\n"],"names":["spanToStreamedSpanJSON","INTERNAL_getSegmentSpan","getCapturedScopesOnSpan","getCombinedScopeData","beforeSendSpan","isStreamedBeforeSendSpanCallback","SEMANTIC_ATTRIBUTE_SENTRY_SOURCE","streamedSpanJsonToSerializedSpan","SEMANTIC_ATTRIBUTE_SENTRY_RELEASE","SEMANTIC_ATTRIBUTE_SENTRY_ENVIRONMENT","SEMANTIC_ATTRIBUTE_SENTRY_SEGMENT_NAME","SEMANTIC_ATTRIBUTE_SENTRY_SEGMENT_ID","SEMANTIC_ATTRIBUTE_SENTRY_SDK_NAME","SEMANTIC_ATTRIBUTE_SENTRY_SDK_VERSION","SEMANTIC_ATTRIBUTE_USER_ID","SEMANTIC_ATTRIBUTE_USER_EMAIL","SEMANTIC_ATTRIBUTE_USER_IP_ADDRESS","SEMANTIC_ATTRIBUTE_USER_USERNAME","showSpanDropWarning","SEMANTIC_ATTRIBUTE_SENTRY_OP","SEMANTIC_ATTRIBUTE_SENTRY_CUSTOM_SPAN_NAME","parseUrl","getSanitizedUrlString","stripUrlQueryAndFragment"],"mappings":"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"}
|
|
@@ -612,6 +612,7 @@ function _isTracingSuppressed(scope) {
|
|
|
612
612
|
return scope.getScopeData().sdkProcessingMetadata[SUPPRESS_TRACING_KEY] === true;
|
|
613
613
|
}
|
|
614
614
|
|
|
615
|
+
exports.SUPPRESS_TRACING_KEY = SUPPRESS_TRACING_KEY;
|
|
615
616
|
exports.continueTrace = continueTrace;
|
|
616
617
|
exports.startInactiveSpan = startInactiveSpan;
|
|
617
618
|
exports.startNewTrace = startNewTrace;
|