@sentry/core 10.51.0 → 10.53.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/browser.js +3 -0
- package/build/cjs/browser.js +529 -0
- package/build/cjs/browser.js.map +1 -0
- package/build/cjs/client.js +15 -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 +82 -62
- package/build/cjs/index.js.map +1 -1
- package/build/cjs/instrument/console.js +43 -3
- package/build/cjs/instrument/console.js.map +1 -1
- package/build/cjs/integrations/captureconsole.js +2 -2
- package/build/cjs/integrations/captureconsole.js.map +1 -1
- package/build/cjs/integrations/console.js +5 -1
- package/build/cjs/integrations/console.js.map +1 -1
- package/build/cjs/integrations/express/index.js +4 -6
- 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/mcp-server/errorCapture.js +2 -2
- package/build/cjs/integrations/mcp-server/errorCapture.js.map +1 -1
- package/build/cjs/integrations/mcp-server/handlers.js +72 -0
- package/build/cjs/integrations/mcp-server/handlers.js.map +1 -1
- package/build/cjs/integrations/mcp-server/index.js +10 -1
- package/build/cjs/integrations/mcp-server/index.js.map +1 -1
- package/build/cjs/integrations/requestdata.js +85 -3
- package/build/cjs/integrations/requestdata.js.map +1 -1
- package/build/cjs/integrations/supabase.js +4 -4
- package/build/cjs/integrations/supabase.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/server.js +563 -0
- package/build/cjs/server.js.map +1 -0
- package/build/cjs/tracing/ai/utils.js +2 -2
- package/build/cjs/tracing/ai/utils.js.map +1 -1
- package/build/cjs/tracing/anthropic-ai/index.js +3 -3
- package/build/cjs/tracing/anthropic-ai/index.js.map +1 -1
- package/build/cjs/tracing/anthropic-ai/streaming.js +3 -3
- package/build/cjs/tracing/anthropic-ai/streaming.js.map +1 -1
- package/build/cjs/tracing/anthropic-ai/utils.js +2 -2
- package/build/cjs/tracing/anthropic-ai/utils.js.map +1 -1
- package/build/cjs/tracing/google-genai/index.js +3 -3
- package/build/cjs/tracing/google-genai/index.js.map +1 -1
- package/build/cjs/tracing/google-genai/streaming.js +2 -2
- package/build/cjs/tracing/google-genai/streaming.js.map +1 -1
- package/build/cjs/tracing/langchain/embeddings.js +2 -2
- package/build/cjs/tracing/langchain/embeddings.js.map +1 -1
- package/build/cjs/tracing/langchain/index.js +4 -4
- package/build/cjs/tracing/langchain/index.js.map +1 -1
- package/build/cjs/tracing/langgraph/index.js +3 -3
- package/build/cjs/tracing/langgraph/index.js.map +1 -1
- package/build/cjs/tracing/langgraph/utils.js +2 -2
- package/build/cjs/tracing/langgraph/utils.js.map +1 -1
- package/build/cjs/tracing/openai/index.js +3 -3
- package/build/cjs/tracing/openai/index.js.map +1 -1
- package/build/cjs/tracing/openai/streaming.js +2 -2
- package/build/cjs/tracing/openai/streaming.js.map +1 -1
- package/build/cjs/tracing/sentrySpan.js +5 -0
- package/build/cjs/tracing/sentrySpan.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/spans/extractGenAiSpans.js +60 -0
- package/build/cjs/tracing/spans/extractGenAiSpans.js.map +1 -0
- package/build/cjs/tracing/spans/spanJsonToStreamedSpan.js +26 -0
- package/build/cjs/tracing/spans/spanJsonToStreamedSpan.js.map +1 -0
- 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 +99 -15
- package/build/cjs/tracing/vercel-ai/index.js.map +1 -1
- package/build/cjs/trpc.js +3 -3
- package/build/cjs/trpc.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/exports.js +7 -7
- package/build/cjs/utils/exports.js.map +1 -1
- package/build/cjs/utils/flushIfServerless.js +2 -2
- package/build/cjs/utils/flushIfServerless.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/string.js +9 -2
- package/build/cjs/utils/string.js.map +1 -1
- package/build/cjs/utils/traceData.js +2 -2
- package/build/cjs/utils/traceData.js.map +1 -1
- package/build/cjs/utils/version.js +1 -1
- package/build/esm/browser.js +142 -0
- package/build/esm/browser.js.map +1 -0
- package/build/esm/client.js +15 -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 +20 -15
- package/build/esm/index.js.map +1 -1
- package/build/esm/instrument/console.js +44 -5
- package/build/esm/instrument/console.js.map +1 -1
- package/build/esm/integrations/console.js +6 -2
- package/build/esm/integrations/console.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/mcp-server/handlers.js +72 -1
- package/build/esm/integrations/mcp-server/handlers.js.map +1 -1
- package/build/esm/integrations/mcp-server/index.js +11 -2
- package/build/esm/integrations/mcp-server/index.js.map +1 -1
- 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/server.js +157 -0
- package/build/esm/server.js.map +1 -0
- package/build/esm/tracing/sentrySpan.js +5 -0
- package/build/esm/tracing/sentrySpan.js.map +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/spans/extractGenAiSpans.js +58 -0
- package/build/esm/tracing/spans/extractGenAiSpans.js.map +1 -0
- package/build/esm/tracing/spans/spanJsonToStreamedSpan.js +24 -0
- package/build/esm/tracing/spans/spanJsonToStreamedSpan.js.map +1 -0
- 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 +101 -18
- 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/exports.js +7 -7
- package/build/esm/utils/exports.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/string.js +9 -2
- package/build/esm/utils/string.js.map +1 -1
- package/build/esm/utils/version.js +1 -1
- package/build/types/browser-exports.d.ts +11 -0
- package/build/types/browser-exports.d.ts.map +1 -0
- package/build/types/browser.d.ts +3 -0
- package/build/types/browser.d.ts.map +1 -0
- package/build/types/build-time-plugins/buildTimeOptionsBase.d.ts +8 -0
- package/build/types/build-time-plugins/buildTimeOptionsBase.d.ts.map +1 -1
- package/build/types/carrier.d.ts +1 -1
- package/build/types/carrier.d.ts.map +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 +3 -223
- package/build/types/index.d.ts.map +1 -1
- package/build/types/instrument/console.d.ts +7 -0
- package/build/types/instrument/console.d.ts.map +1 -1
- package/build/types/integrations/captureconsole.d.ts +1 -1
- package/build/types/integrations/captureconsole.d.ts.map +1 -1
- package/build/types/integrations/console.d.ts +5 -0
- package/build/types/integrations/console.d.ts.map +1 -1
- package/build/types/integrations/conversationId.d.ts +1 -1
- package/build/types/integrations/conversationId.d.ts.map +1 -1
- package/build/types/integrations/dedupe.d.ts +1 -1
- package/build/types/integrations/dedupe.d.ts.map +1 -1
- package/build/types/integrations/eventFilters.d.ts +2 -2
- package/build/types/integrations/eventFilters.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/extraerrordata.d.ts +1 -1
- package/build/types/integrations/extraerrordata.d.ts.map +1 -1
- package/build/types/integrations/functiontostring.d.ts +1 -1
- package/build/types/integrations/functiontostring.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/linkederrors.d.ts +1 -1
- package/build/types/integrations/linkederrors.d.ts.map +1 -1
- package/build/types/integrations/mcp-server/handlers.d.ts +18 -0
- package/build/types/integrations/mcp-server/handlers.d.ts.map +1 -1
- package/build/types/integrations/mcp-server/index.d.ts +8 -1
- package/build/types/integrations/mcp-server/index.d.ts.map +1 -1
- package/build/types/integrations/requestdata.d.ts +1 -1
- package/build/types/integrations/requestdata.d.ts.map +1 -1
- package/build/types/integrations/spanStreaming.d.ts +1 -1
- package/build/types/integrations/spanStreaming.d.ts.map +1 -1
- package/build/types/integrations/supabase.d.ts +1 -1
- package/build/types/integrations/supabase.d.ts.map +1 -1
- package/build/types/integrations/zoderrors.d.ts +1 -1
- package/build/types/integrations/zoderrors.d.ts.map +1 -1
- package/build/types/logs/console-integration.d.ts +1 -1
- package/build/types/logs/console-integration.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/server-exports.d.ts +26 -0
- package/build/types/server-exports.d.ts.map +1 -0
- package/build/types/server.d.ts +10 -0
- package/build/types/server.d.ts.map +1 -0
- package/build/types/shared-exports.d.ts +215 -0
- package/build/types/shared-exports.d.ts.map +1 -0
- package/build/types/tracing/index.d.ts +1 -1
- package/build/types/tracing/index.d.ts.map +1 -1
- package/build/types/tracing/sentrySpan.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/spans/extractGenAiSpans.d.ts +15 -0
- package/build/types/tracing/spans/extractGenAiSpans.d.ts.map +1 -0
- package/build/types/tracing/spans/spanJsonToStreamedSpan.d.ts +6 -0
- package/build/types/tracing/spans/spanJsonToStreamedSpan.d.ts.map +1 -0
- 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/envelope.d.ts +1 -1
- package/build/types/types-hoist/envelope.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/options.d.ts +8 -0
- package/build/types/types-hoist/options.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/utils/string.d.ts +1 -1
- package/build/types/utils/string.d.ts.map +1 -1
- package/build/types-ts3.8/browser-exports.d.ts +11 -0
- package/build/types-ts3.8/browser.d.ts +3 -0
- package/build/types-ts3.8/build-time-plugins/buildTimeOptionsBase.d.ts +8 -0
- package/build/types-ts3.8/carrier.d.ts +1 -1
- package/build/types-ts3.8/index.d.ts +3 -225
- package/build/types-ts3.8/instrument/console.d.ts +7 -0
- package/build/types-ts3.8/integrations/captureconsole.d.ts +1 -1
- package/build/types-ts3.8/integrations/console.d.ts +5 -0
- package/build/types-ts3.8/integrations/conversationId.d.ts +1 -1
- package/build/types-ts3.8/integrations/dedupe.d.ts +1 -1
- package/build/types-ts3.8/integrations/eventFilters.d.ts +2 -2
- package/build/types-ts3.8/integrations/express/utils.d.ts +1 -5
- package/build/types-ts3.8/integrations/extraerrordata.d.ts +1 -1
- package/build/types-ts3.8/integrations/functiontostring.d.ts +1 -1
- 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/integrations/linkederrors.d.ts +1 -1
- package/build/types-ts3.8/integrations/mcp-server/handlers.d.ts +18 -0
- package/build/types-ts3.8/integrations/mcp-server/index.d.ts +8 -1
- package/build/types-ts3.8/integrations/requestdata.d.ts +1 -1
- package/build/types-ts3.8/integrations/spanStreaming.d.ts +1 -1
- package/build/types-ts3.8/integrations/supabase.d.ts +1 -1
- package/build/types-ts3.8/integrations/zoderrors.d.ts +1 -1
- package/build/types-ts3.8/logs/console-integration.d.ts +1 -1
- 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/server-exports.d.ts +21 -0
- package/build/types-ts3.8/server.d.ts +10 -0
- package/build/types-ts3.8/shared-exports.d.ts +214 -0
- 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/spans/extractGenAiSpans.d.ts +15 -0
- package/build/types-ts3.8/tracing/spans/spanJsonToStreamedSpan.d.ts +6 -0
- 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/envelope.d.ts +1 -1
- 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/options.d.ts +8 -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/build/types-ts3.8/utils/string.d.ts +1 -1
- package/package.json +24 -2
- package/server.js +3 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client-patch.js","sources":["../../../../src/integrations/http/client-patch.ts"],"sourcesContent":["/**\n * Platform-portable HTTP(S) outgoing-request patching integration\n *\n * Patches the `http` and `https` Node.js built-in module exports to create\n * Sentry spans for outgoing requests and optionally inject distributed trace\n * propagation headers.\n *\n * @module\n *\n * This Sentry integration is a derivative work based on the OpenTelemetry\n * HTTP instrumentation.\n *\n * <https://github.com/open-telemetry/opentelemetry-js/tree/main/experimental/packages/opentelemetry-instrumentation-http>\n *\n * Extended under the terms of the Apache 2.0 license linked below:\n *\n * ----\n *\n * Copyright The OpenTelemetry Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * https://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { getDefaultExport } from '../../utils/get-default-export';\nimport { HTTP_ON_CLIENT_REQUEST } from './constants';\nimport type { HttpExport, HttpModuleExport, HttpInstrumentationOptions, HttpClientRequest } from './types';\nimport { getOriginalFunction, wrapMethod } from '../../utils/object';\nimport { getHttpClientSubscriptions } from './client-subscriptions';\n\nfunction patchHttpRequest(httpModule: HttpExport, options: HttpInstrumentationOptions): void {\n // avoid double-wrap\n if (!getOriginalFunction(httpModule.request)) {\n const { [HTTP_ON_CLIENT_REQUEST]: onHttpClientRequestCreated } = getHttpClientSubscriptions({\n ...options,\n http: httpModule,\n });\n\n const originalRequest = httpModule.request;\n wrapMethod(httpModule, 'request', function patchedRequest(this: HttpExport, ...args: unknown[]) {\n const request = originalRequest.apply(this, args) as HttpClientRequest;\n onHttpClientRequestCreated({ request }, HTTP_ON_CLIENT_REQUEST);\n return request;\n });\n }\n}\n\n// This simply ensures that http.get calls http.request, which we patched.\n// Call it from the object each time, to ensure that any subsequent patches\n// or other mutations are also respected.\nfunction patchHttpGet(httpModule: HttpExport) {\n if (!getOriginalFunction(httpModule.get)) {\n // match node's normalization to exactly 3 arguments.\n wrapMethod(httpModule, 'get', function patchedGet(this: HttpExport, input: unknown, options: unknown, cb: unknown) {\n // http.get is like http.request but automatically calls .end()\n const request = httpModule.request.call(this, input, options, cb) as HttpClientRequest;\n request.end();\n return request;\n });\n }\n}\n\nfunction patchModule(httpModuleExport: HttpModuleExport, options: HttpInstrumentationOptions = {}): HttpModuleExport {\n const httpDefault = getDefaultExport(httpModuleExport);\n const httpModule = httpModuleExport as HttpExport;\n // if we have a default, patch that, and copy to the import container\n if (httpDefault !== httpModuleExport) {\n patchModule(httpDefault, options);\n // copy with defineProperty because these might be configured oddly\n for (const method of ['get', 'request']) {\n const desc = Object.getOwnPropertyDescriptor(httpDefault, method);\n /* v8 ignore start - will always be set at this point */\n if (desc) {\n Object.defineProperty(httpModule, method, desc);\n }\n /* v8 ignore stop */\n }\n return httpModule;\n }\n patchHttpRequest(httpModule, options);\n patchHttpGet(httpModule);\n return httpModuleExport;\n}\n\n/**\n * Patch an `node:http` or `node:https` module-shaped export so that every\n * outgoing request is tracked by Sentry.\n *\n * @example\n * ```javascript\n * import http from 'http';\n * import { patchHttpModule } from '@sentry/core';\n * patchHttpModule(http, { propagateTrace: true });\n * ```\n */\nexport const patchHttpModuleClient = (\n httpModuleExport: HttpModuleExport,\n options: HttpInstrumentationOptions = {},\n): HttpModuleExport => patchModule(httpModuleExport, options);\n"],"names":[],"mappings":";;;;;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;AAQA,SAAS,gBAAgB,CAAC,UAAU,EAAc,OAAO,EAAoC;AAC7F;AACA,EAAE,IAAI,CAAC,mBAAmB,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE;AAChD,IAAI,MAAM,EAAE,CAAC,sBAAsB,GAAG,0BAAA,EAA2B,GAAI,0BAA0B,CAAC;AAChG,MAAM,GAAG,OAAO;AAChB,MAAM,IAAI,EAAE,UAAU;AACtB,KAAK,CAAC;;AAEN,IAAI,MAAM,eAAA,GAAkB,UAAU,CAAC,OAAO;AAC9C,IAAI,UAAU,CAAC,UAAU,EAAE,SAAS,EAAE,SAAS,cAAc,EAAmB,GAAG,IAAI,EAAa;AACpG,MAAM,MAAM,OAAA,GAAU,eAAe,CAAC,KAAK,CAAC,IAAI,EAAE,IAAI,CAAA;AACtD,MAAM,0BAA0B,CAAC,EAAE,SAAS,EAAE,sBAAsB,CAAC;AACrE,MAAM,OAAO,OAAO;AACpB,IAAI,CAAC,CAAC;AACN,EAAE;AACF;;AAEA;AACA;AACA;AACA,SAAS,YAAY,CAAC,UAAU,EAAc;AAC9C,EAAE,IAAI,CAAC,mBAAmB,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE;AAC5C;AACA,IAAI,UAAU,CAAC,UAAU,EAAE,KAAK,EAAE,SAAS,UAAU,EAAmB,KAAK,EAAW,OAAO,EAAW,EAAE,EAAW;AACvH;AACA,MAAM,MAAM,OAAA,GAAU,UAAU,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,EAAE,KAAK,EAAE,OAAO,EAAE,EAAE,CAAA;AACtE,MAAM,OAAO,CAAC,GAAG,EAAE;AACnB,MAAM,OAAO,OAAO;AACpB,IAAI,CAAC,CAAC;AACN,EAAE;AACF;;AAEA,SAAS,WAAW,CAAC,gBAAgB,EAAoB,OAAO,GAA+B,EAAE,EAAoB;AACrH,EAAE,MAAM,WAAA,GAAc,gBAAgB,CAAC,gBAAgB,CAAC;AACxD,EAAE,MAAM,UAAA,GAAa,gBAAA;AACrB;AACA,EAAE,IAAI,WAAA,KAAgB,gBAAgB,EAAE;AACxC,IAAI,WAAW,CAAC,WAAW,EAAE,OAAO,CAAC;AACrC;AACA,IAAI,KAAK,MAAM,MAAA,IAAU,CAAC,KAAK,EAAE,SAAS,CAAC,EAAE;AAC7C,MAAM,MAAM,IAAA,GAAO,MAAM,CAAC,wBAAwB,CAAC,WAAW,EAAE,MAAM,CAAC;AACvE;AACA,MAAM,IAAI,IAAI,EAAE;AAChB,QAAQ,MAAM,CAAC,cAAc,CAAC,UAAU,EAAE,MAAM,EAAE,IAAI,CAAC;AACvD,MAAM;AACN;AACA,IAAI;AACJ,IAAI,OAAO,UAAU;AACrB,EAAE;AACF,EAAE,gBAAgB,CAAC,UAAU,EAAE,OAAO,CAAC;AACvC,EAAE,YAAY,CAAC,UAAU,CAAC;AAC1B,EAAE,OAAO,gBAAgB;AACzB;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACO,MAAM,wBAAwB;AACrC,EAAE,gBAAgB;AAClB,EAAE,OAAO,GAA+B,EAAE;AAC1C,KAAuB,WAAW,CAAC,gBAAgB,EAAE,OAAO;;;;"}
|
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
import { addOutgoingRequestBreadcrumb } from './add-outgoing-request-breadcrumb.js';
|
|
2
|
+
import { DEBUG_BUILD } from '../../debug-build.js';
|
|
3
|
+
import { debug } from '../../utils/debug-logger.js';
|
|
4
|
+
import { getCurrentScope, getClient } from '../../currentScopes.js';
|
|
5
|
+
import { getSpanStatusFromHttpCode, SPAN_STATUS_ERROR, SPAN_STATUS_UNSET } from '../../tracing/spanstatus.js';
|
|
6
|
+
import { hasSpansEnabled } from '../../utils/hasSpansEnabled.js';
|
|
7
|
+
import { SUPPRESS_TRACING_KEY, startInactiveSpan, withActiveSpan } from '../../tracing/trace.js';
|
|
8
|
+
import { LRUMap } from '../../utils/lru.js';
|
|
9
|
+
import { getOutgoingRequestSpanData, setIncomingResponseSpanData } from './get-outgoing-span-data.js';
|
|
10
|
+
import { getRequestUrlFromClientRequest } from './get-request-url.js';
|
|
11
|
+
import { injectTracePropagationHeaders } from './inject-trace-propagation-headers.js';
|
|
12
|
+
import { HTTP_ON_CLIENT_REQUEST, LOG_PREFIX } from './constants.js';
|
|
13
|
+
import { doubleWrapWarning } from './double-wrap-warning.js';
|
|
14
|
+
|
|
15
|
+
function getHttpClientSubscriptions(options) {
|
|
16
|
+
const propagationDecisionMap = new LRUMap(100);
|
|
17
|
+
const getConfig = () => getClient()?.getOptions();
|
|
18
|
+
|
|
19
|
+
const onHttpClientRequestCreated = (data) => {
|
|
20
|
+
// Skip all instrumentation if tracing is suppressed
|
|
21
|
+
// (e.g., Sentry's own transport uses this to avoid self-instrumentation)
|
|
22
|
+
if (getCurrentScope().getScopeData().sdkProcessingMetadata[SUPPRESS_TRACING_KEY] === true) {
|
|
23
|
+
return;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
const clientOptions = getConfig();
|
|
27
|
+
const {
|
|
28
|
+
errorMonitor = 'error',
|
|
29
|
+
spans: createSpans = clientOptions ? hasSpansEnabled(clientOptions) : true,
|
|
30
|
+
propagateTrace = false,
|
|
31
|
+
breadcrumbs = true,
|
|
32
|
+
http,
|
|
33
|
+
https,
|
|
34
|
+
suppressOtelWarning = false,
|
|
35
|
+
} = options;
|
|
36
|
+
|
|
37
|
+
const { request } = data ;
|
|
38
|
+
|
|
39
|
+
// check if request is ignored. if so, we do nothing at all.
|
|
40
|
+
if (options.ignoreOutgoingRequests?.(getRequestUrlFromClientRequest(request), request)) {
|
|
41
|
+
return;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
// guard against adding breadcrumbs multiple times, or when not enabled
|
|
45
|
+
let addedBreadcrumbs = false;
|
|
46
|
+
function addBreadcrumbs(request, response) {
|
|
47
|
+
if (!addedBreadcrumbs) {
|
|
48
|
+
addedBreadcrumbs = true;
|
|
49
|
+
addOutgoingRequestBreadcrumb(request, response);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
// called if spans and/or trace propagation are disabled
|
|
54
|
+
function breadcrumbsOnly(request) {
|
|
55
|
+
request.on(errorMonitor, () => addBreadcrumbs(request, undefined));
|
|
56
|
+
request.prependListener('response', response => {
|
|
57
|
+
if (request.listenerCount('response') <= 1) {
|
|
58
|
+
response.resume();
|
|
59
|
+
}
|
|
60
|
+
response.on('end', () => addBreadcrumbs(request, response));
|
|
61
|
+
response.on(errorMonitor, () => addBreadcrumbs(request, response));
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
if (!createSpans) {
|
|
66
|
+
// no spans, but maybe tracing and/or breadcrumbs
|
|
67
|
+
if (breadcrumbs) {
|
|
68
|
+
breadcrumbsOnly(request);
|
|
69
|
+
}
|
|
70
|
+
if (propagateTrace) {
|
|
71
|
+
injectTracePropagationHeaders(request, propagationDecisionMap);
|
|
72
|
+
}
|
|
73
|
+
return;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
// guard against OTel wrapping the same module and emitting double-spans
|
|
77
|
+
// this doesn't prevent it, just prints a debug warning for the user.
|
|
78
|
+
if (!suppressOtelWarning) {
|
|
79
|
+
if (http) doubleWrapWarning(http);
|
|
80
|
+
if (https) doubleWrapWarning(https);
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
// spans are enabled
|
|
84
|
+
const span = startInactiveSpan(getOutgoingRequestSpanData(request));
|
|
85
|
+
options.outgoingRequestHook?.(span, request);
|
|
86
|
+
|
|
87
|
+
// Inject trace headers after span creation so sentry-trace contains the
|
|
88
|
+
// outgoing span's ID (not the parent's), enabling downstream services to
|
|
89
|
+
// link to this span.
|
|
90
|
+
if (propagateTrace) {
|
|
91
|
+
if (span.isRecording()) {
|
|
92
|
+
withActiveSpan(span, () => {
|
|
93
|
+
injectTracePropagationHeaders(request, propagationDecisionMap);
|
|
94
|
+
});
|
|
95
|
+
} else {
|
|
96
|
+
injectTracePropagationHeaders(request, propagationDecisionMap);
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
let spanEnded = false;
|
|
101
|
+
function endSpan(status) {
|
|
102
|
+
if (!spanEnded) {
|
|
103
|
+
spanEnded = true;
|
|
104
|
+
span.setStatus(status);
|
|
105
|
+
span.end();
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
// Fallback: end span if the connection closes before any response.
|
|
110
|
+
// This is removed if we do get a response, because in that case
|
|
111
|
+
// we want to only end the span when the response is finished.
|
|
112
|
+
const requestOnClose = () => endSpan({ code: SPAN_STATUS_UNSET });
|
|
113
|
+
request.on('close', requestOnClose);
|
|
114
|
+
|
|
115
|
+
request.on(errorMonitor, error => {
|
|
116
|
+
DEBUG_BUILD && debug.log(LOG_PREFIX, 'outgoingRequest on request error()', error);
|
|
117
|
+
if (breadcrumbs) {
|
|
118
|
+
addBreadcrumbs(request, undefined);
|
|
119
|
+
}
|
|
120
|
+
endSpan({ code: SPAN_STATUS_ERROR });
|
|
121
|
+
});
|
|
122
|
+
|
|
123
|
+
request.prependListener('response', response => {
|
|
124
|
+
// no longer need this, listen on response now.
|
|
125
|
+
// do not end the span until the response finishes
|
|
126
|
+
request.removeListener('close', requestOnClose);
|
|
127
|
+
if (request.listenerCount('response') <= 1) {
|
|
128
|
+
response.resume();
|
|
129
|
+
}
|
|
130
|
+
setIncomingResponseSpanData(response, span);
|
|
131
|
+
options.outgoingResponseHook?.(span, response);
|
|
132
|
+
|
|
133
|
+
let finished = false;
|
|
134
|
+
function finishWithResponse(error) {
|
|
135
|
+
if (!finished) {
|
|
136
|
+
finished = true;
|
|
137
|
+
if (error) {
|
|
138
|
+
DEBUG_BUILD && debug.log(LOG_PREFIX, 'outgoingRequest on response error()', error);
|
|
139
|
+
}
|
|
140
|
+
if (breadcrumbs) {
|
|
141
|
+
addBreadcrumbs(request, response);
|
|
142
|
+
}
|
|
143
|
+
const aborted = response.aborted && !response.complete;
|
|
144
|
+
const status =
|
|
145
|
+
error || typeof response.statusCode !== 'number' || aborted
|
|
146
|
+
? { code: SPAN_STATUS_ERROR }
|
|
147
|
+
: getSpanStatusFromHttpCode(response.statusCode);
|
|
148
|
+
options.applyCustomAttributesOnSpan?.(span, request, response);
|
|
149
|
+
endSpan(status);
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
response.on('end', () => finishWithResponse());
|
|
154
|
+
response.on(errorMonitor, finishWithResponse);
|
|
155
|
+
});
|
|
156
|
+
};
|
|
157
|
+
|
|
158
|
+
return {
|
|
159
|
+
[HTTP_ON_CLIENT_REQUEST]: onHttpClientRequestCreated,
|
|
160
|
+
};
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
export { getHttpClientSubscriptions };
|
|
164
|
+
//# sourceMappingURL=client-subscriptions.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client-subscriptions.js","sources":["../../../../src/integrations/http/client-subscriptions.ts"],"sourcesContent":["/**\n * Define the channels and subscription methods to subscribe to in order to\n * instrument the `node:http` module. Note that this does *not* actually\n * register the subscriptions, it simply returns a data object with the\n * channel names and the subscription handlers. Attach these to diagnostic\n * channels on Node versions where they are supported (ie, >=22.12.0).\n *\n * If any other platforms that do support diagnostic channels eventually add\n * channel coverage for the `node:http` client, then these methods can be\n * used on those platforms as well.\n *\n * This implementation is used in the client-patch strategy, by simply\n * calling the handlers with the relevant data at the appropriate time.\n */\n\nimport type { SpanStatus } from '../../types-hoist/spanStatus';\nimport { addOutgoingRequestBreadcrumb } from './add-outgoing-request-breadcrumb';\nimport {\n getSpanStatusFromHttpCode,\n SPAN_STATUS_ERROR,\n SPAN_STATUS_UNSET,\n startInactiveSpan,\n SUPPRESS_TRACING_KEY,\n withActiveSpan,\n} from '../../tracing';\nimport { debug } from '../../utils/debug-logger';\nimport { LRUMap } from '../../utils/lru';\nimport { getOutgoingRequestSpanData, setIncomingResponseSpanData } from './get-outgoing-span-data';\nimport { getRequestUrlFromClientRequest } from './get-request-url';\nimport { injectTracePropagationHeaders } from './inject-trace-propagation-headers';\nimport type { HttpInstrumentationOptions, HttpClientRequest, HttpIncomingMessage } from './types';\nimport { DEBUG_BUILD } from '../../debug-build';\nimport { LOG_PREFIX, HTTP_ON_CLIENT_REQUEST } from './constants';\nimport type { ClientSubscriptionName } from './constants';\nimport { getClient, getCurrentScope } from '../../currentScopes';\nimport { hasSpansEnabled } from '../../utils/hasSpansEnabled';\nimport { doubleWrapWarning } from './double-wrap-warning';\n\ntype ChannelListener = (message: unknown, name: string | symbol) => void;\n\nexport type HttpClientSubscriptions = Record<ClientSubscriptionName, ChannelListener>;\n\nexport function getHttpClientSubscriptions(options: HttpInstrumentationOptions): HttpClientSubscriptions {\n const propagationDecisionMap = new LRUMap<string, boolean>(100);\n const getConfig = () => getClient()?.getOptions();\n\n const onHttpClientRequestCreated: ChannelListener = (data: unknown): void => {\n // Skip all instrumentation if tracing is suppressed\n // (e.g., Sentry's own transport uses this to avoid self-instrumentation)\n if (getCurrentScope().getScopeData().sdkProcessingMetadata[SUPPRESS_TRACING_KEY] === true) {\n return;\n }\n\n const clientOptions = getConfig();\n const {\n errorMonitor = 'error',\n spans: createSpans = clientOptions ? hasSpansEnabled(clientOptions) : true,\n propagateTrace = false,\n breadcrumbs = true,\n http,\n https,\n suppressOtelWarning = false,\n } = options;\n\n const { request } = data as { request: HttpClientRequest };\n\n // check if request is ignored. if so, we do nothing at all.\n if (options.ignoreOutgoingRequests?.(getRequestUrlFromClientRequest(request), request)) {\n return;\n }\n\n // guard against adding breadcrumbs multiple times, or when not enabled\n let addedBreadcrumbs = false;\n function addBreadcrumbs(request: HttpClientRequest, response: HttpIncomingMessage | undefined) {\n if (!addedBreadcrumbs) {\n addedBreadcrumbs = true;\n addOutgoingRequestBreadcrumb(request, response);\n }\n }\n\n // called if spans and/or trace propagation are disabled\n function breadcrumbsOnly(request: HttpClientRequest) {\n request.on(errorMonitor, () => addBreadcrumbs(request, undefined));\n request.prependListener('response', response => {\n if (request.listenerCount('response') <= 1) {\n response.resume();\n }\n response.on('end', () => addBreadcrumbs(request, response));\n response.on(errorMonitor, () => addBreadcrumbs(request, response));\n });\n }\n\n if (!createSpans) {\n // no spans, but maybe tracing and/or breadcrumbs\n if (breadcrumbs) {\n breadcrumbsOnly(request);\n }\n if (propagateTrace) {\n injectTracePropagationHeaders(request, propagationDecisionMap);\n }\n return;\n }\n\n // guard against OTel wrapping the same module and emitting double-spans\n // this doesn't prevent it, just prints a debug warning for the user.\n if (!suppressOtelWarning) {\n if (http) doubleWrapWarning(http);\n if (https) doubleWrapWarning(https);\n }\n\n // spans are enabled\n const span = startInactiveSpan(getOutgoingRequestSpanData(request));\n options.outgoingRequestHook?.(span, request);\n\n // Inject trace headers after span creation so sentry-trace contains the\n // outgoing span's ID (not the parent's), enabling downstream services to\n // link to this span.\n if (propagateTrace) {\n if (span.isRecording()) {\n withActiveSpan(span, () => {\n injectTracePropagationHeaders(request, propagationDecisionMap);\n });\n } else {\n injectTracePropagationHeaders(request, propagationDecisionMap);\n }\n }\n\n let spanEnded = false;\n function endSpan(status: SpanStatus): void {\n if (!spanEnded) {\n spanEnded = true;\n span.setStatus(status);\n span.end();\n }\n }\n\n // Fallback: end span if the connection closes before any response.\n // This is removed if we do get a response, because in that case\n // we want to only end the span when the response is finished.\n const requestOnClose = () => endSpan({ code: SPAN_STATUS_UNSET });\n request.on('close', requestOnClose);\n\n request.on(errorMonitor, error => {\n DEBUG_BUILD && debug.log(LOG_PREFIX, 'outgoingRequest on request error()', error);\n if (breadcrumbs) {\n addBreadcrumbs(request, undefined);\n }\n endSpan({ code: SPAN_STATUS_ERROR });\n });\n\n request.prependListener('response', response => {\n // no longer need this, listen on response now.\n // do not end the span until the response finishes\n request.removeListener('close', requestOnClose);\n if (request.listenerCount('response') <= 1) {\n response.resume();\n }\n setIncomingResponseSpanData(response, span);\n options.outgoingResponseHook?.(span, response);\n\n let finished = false;\n function finishWithResponse(error?: unknown): void {\n if (!finished) {\n finished = true;\n if (error) {\n DEBUG_BUILD && debug.log(LOG_PREFIX, 'outgoingRequest on response error()', error);\n }\n if (breadcrumbs) {\n addBreadcrumbs(request, response);\n }\n const aborted = response.aborted && !response.complete;\n const status: SpanStatus =\n error || typeof response.statusCode !== 'number' || aborted\n ? { code: SPAN_STATUS_ERROR }\n : getSpanStatusFromHttpCode(response.statusCode);\n options.applyCustomAttributesOnSpan?.(span, request, response);\n endSpan(status);\n }\n }\n\n response.on('end', () => finishWithResponse());\n response.on(errorMonitor, finishWithResponse);\n });\n };\n\n return {\n [HTTP_ON_CLIENT_REQUEST]: onHttpClientRequestCreated,\n };\n}\n"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
const LOG_PREFIX = '@sentry/instrumentation-http';
|
|
2
|
+
const HTTP_ON_CLIENT_REQUEST = 'http.client.request.created';
|
|
3
|
+
const HTTP_ON_SERVER_REQUEST = 'http.server.request.start';
|
|
4
|
+
|
|
5
|
+
export { HTTP_ON_CLIENT_REQUEST, HTTP_ON_SERVER_REQUEST, LOG_PREFIX };
|
|
6
|
+
//# sourceMappingURL=constants.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"constants.js","sources":["../../../../src/integrations/http/constants.ts"],"sourcesContent":["export const LOG_PREFIX = '@sentry/instrumentation-http';\nexport const HTTP_ON_CLIENT_REQUEST = 'http.client.request.created';\nexport const HTTP_ON_SERVER_REQUEST = 'http.server.request.start';\nexport type ClientSubscriptionName = typeof HTTP_ON_CLIENT_REQUEST;\nexport type ServerSubscriptionName = typeof HTTP_ON_SERVER_REQUEST;\n"],"names":[],"mappings":"AAAO,MAAM,UAAA,GAAa;AACnB,MAAM,sBAAA,GAAyB;AAC/B,MAAM,sBAAA,GAAyB;;;;"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { DEBUG_BUILD } from '../../debug-build.js';
|
|
2
|
+
import { debug } from '../../utils/debug-logger.js';
|
|
3
|
+
|
|
4
|
+
const isOtelWrapped = (fn) =>
|
|
5
|
+
typeof fn.__unwrap === 'function';
|
|
6
|
+
|
|
7
|
+
// exported for tess
|
|
8
|
+
const warning =
|
|
9
|
+
'Double-wrapped http.client detected. Either disable spans in Sentry.httpIntegration, or disable the OpenTelemetry HTTP instrumentation.';
|
|
10
|
+
|
|
11
|
+
let didDoubleWrapWarning = false;
|
|
12
|
+
// no-op in non-debug builds
|
|
13
|
+
const doubleWrapWarning = DEBUG_BUILD
|
|
14
|
+
? (http) => {
|
|
15
|
+
if (!didDoubleWrapWarning) {
|
|
16
|
+
if (isOtelWrapped(http.request) || isOtelWrapped(http.get)) {
|
|
17
|
+
// TODO: add link to documentation
|
|
18
|
+
didDoubleWrapWarning = true;
|
|
19
|
+
debug.warn(warning);
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
: () => {};
|
|
24
|
+
|
|
25
|
+
export { doubleWrapWarning, warning };
|
|
26
|
+
//# sourceMappingURL=double-wrap-warning.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"double-wrap-warning.js","sources":["../../../../src/integrations/http/double-wrap-warning.ts"],"sourcesContent":["import { DEBUG_BUILD } from '../../debug-build';\nimport { debug } from '../../utils/debug-logger';\nimport type { HttpModuleExport } from './types';\n\nconst isOtelWrapped = (fn: Function & { __unwrap?: Function }): fn is Function & { __unwrap: Function } =>\n typeof fn.__unwrap === 'function';\n\n// exported for tess\nexport const warning =\n 'Double-wrapped http.client detected. Either disable spans in Sentry.httpIntegration, or disable the OpenTelemetry HTTP instrumentation.';\n\nlet didDoubleWrapWarning = false;\n// no-op in non-debug builds\nexport const doubleWrapWarning = DEBUG_BUILD\n ? (http: HttpModuleExport) => {\n if (!didDoubleWrapWarning) {\n if (isOtelWrapped(http.request) || isOtelWrapped(http.get)) {\n // TODO: add link to documentation\n didDoubleWrapWarning = true;\n debug.warn(warning);\n }\n }\n }\n : () => {};\n"],"names":[],"mappings":";;;AAIA,MAAM,aAAA,GAAgB,CAAC,EAAE;AACzB,EAAE,OAAO,EAAE,CAAC,QAAA,KAAa,UAAU;;AAEnC;MACa,OAAA;AACb,EAAE;;AAEF,IAAI,oBAAA,GAAuB,KAAK;AAChC;AACO,MAAM,oBAAoB;AACjC,IAAI,CAAC,IAAI,KAAuB;AAChC,MAAM,IAAI,CAAC,oBAAoB,EAAE;AACjC,QAAQ,IAAI,aAAa,CAAC,IAAI,CAAC,OAAO,CAAA,IAAK,aAAa,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE;AACpE;AACA,UAAU,oBAAA,GAAuB,IAAI;AACrC,UAAU,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC;AAC7B,QAAQ;AACR,MAAM;AACN,IAAI;AACJ,IAAI,MAAM,CAAC;;;;"}
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import { SEMANTIC_ATTRIBUTE_SENTRY_OP } from '../../semanticAttributes.js';
|
|
2
|
+
import { getHttpSpanDetailsFromUrlObject, parseStringToURLObject } from '../../utils/url.js';
|
|
3
|
+
import { getRequestUrlFromClientRequest } from './get-request-url.js';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Build the initial span name and attributes for an outgoing HTTP request.
|
|
7
|
+
* This is called before the span is created, to get the initial details.
|
|
8
|
+
*/
|
|
9
|
+
function getOutgoingRequestSpanData(request) {
|
|
10
|
+
const url = getRequestUrlFromClientRequest(request);
|
|
11
|
+
const [name, attributes] = getHttpSpanDetailsFromUrlObject(
|
|
12
|
+
parseStringToURLObject(url),
|
|
13
|
+
'client',
|
|
14
|
+
'auto.http.client',
|
|
15
|
+
request,
|
|
16
|
+
);
|
|
17
|
+
|
|
18
|
+
const userAgent = request.getHeader('user-agent');
|
|
19
|
+
|
|
20
|
+
return {
|
|
21
|
+
name,
|
|
22
|
+
attributes: {
|
|
23
|
+
// TODO(v11): Update these to the Sentry semantic attributes for urls.
|
|
24
|
+
// https://getsentry.github.io/sentry-conventions/attributes/
|
|
25
|
+
[SEMANTIC_ATTRIBUTE_SENTRY_OP]: 'http.client',
|
|
26
|
+
'otel.kind': 'CLIENT',
|
|
27
|
+
'http.url': url,
|
|
28
|
+
'http.method': request.method,
|
|
29
|
+
'http.target': request.path || '/',
|
|
30
|
+
'net.peer.name': request.host,
|
|
31
|
+
'http.host': request.getHeader('host') ,
|
|
32
|
+
...(userAgent ? { 'user_agent.original': userAgent } : {}),
|
|
33
|
+
...attributes,
|
|
34
|
+
},
|
|
35
|
+
onlyIfParent: true,
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Add span attributes once the response is received.
|
|
41
|
+
*/
|
|
42
|
+
function setIncomingResponseSpanData(response, span) {
|
|
43
|
+
const { statusCode, statusMessage, httpVersion, socket } = response;
|
|
44
|
+
const transport = httpVersion?.toUpperCase() !== 'QUIC' ? 'ip_tcp' : 'ip_udp';
|
|
45
|
+
|
|
46
|
+
span.setAttributes({
|
|
47
|
+
'http.response.status_code': statusCode,
|
|
48
|
+
'network.protocol.version': httpVersion,
|
|
49
|
+
// TODO(v11): Update these to the Sentry semantic attributes for urls.
|
|
50
|
+
// https://getsentry.github.io/sentry-conventions/attributes/
|
|
51
|
+
'http.flavor': httpVersion,
|
|
52
|
+
'network.transport': transport,
|
|
53
|
+
'net.transport': transport,
|
|
54
|
+
'http.status_text': statusMessage?.toUpperCase(),
|
|
55
|
+
'http.status_code': statusCode,
|
|
56
|
+
...getResponseContentLengthAttributes(response),
|
|
57
|
+
...getSocketAttrs(socket),
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
function getSocketAttrs(socket) {
|
|
62
|
+
if (!socket) return {};
|
|
63
|
+
const { remoteAddress, remotePort } = socket;
|
|
64
|
+
return {
|
|
65
|
+
'network.peer.address': remoteAddress,
|
|
66
|
+
'network.peer.port': remotePort,
|
|
67
|
+
'net.peer.ip': remoteAddress,
|
|
68
|
+
'net.peer.port': remotePort,
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
function getResponseContentLengthAttributes(response) {
|
|
73
|
+
const { headers } = response;
|
|
74
|
+
const contentLengthHeader = headers['content-length'];
|
|
75
|
+
const length = contentLengthHeader ? parseInt(String(contentLengthHeader), 10) : -1;
|
|
76
|
+
const encoding = headers['content-encoding'];
|
|
77
|
+
return length >= 0
|
|
78
|
+
? encoding && encoding !== 'identity'
|
|
79
|
+
? { 'http.response_content_length': length }
|
|
80
|
+
: { 'http.response_content_length_uncompressed': length }
|
|
81
|
+
: {};
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
export { getOutgoingRequestSpanData, setIncomingResponseSpanData };
|
|
85
|
+
//# sourceMappingURL=get-outgoing-span-data.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"get-outgoing-span-data.js","sources":["../../../../src/integrations/http/get-outgoing-span-data.ts"],"sourcesContent":["import type { Span, SpanAttributes } from '../../types-hoist/span';\nimport { SEMANTIC_ATTRIBUTE_SENTRY_OP } from '../../semanticAttributes';\nimport { getHttpSpanDetailsFromUrlObject, parseStringToURLObject } from '../../utils/url';\nimport type { HttpClientRequest, HttpIncomingMessage } from './types';\nimport { getRequestUrlFromClientRequest } from './get-request-url';\nimport type { StartSpanOptions } from '../../types-hoist/startSpanOptions';\n\n/**\n * Build the initial span name and attributes for an outgoing HTTP request.\n * This is called before the span is created, to get the initial details.\n */\nexport function getOutgoingRequestSpanData(request: HttpClientRequest): StartSpanOptions {\n const url = getRequestUrlFromClientRequest(request);\n const [name, attributes] = getHttpSpanDetailsFromUrlObject(\n parseStringToURLObject(url),\n 'client',\n 'auto.http.client',\n request,\n );\n\n const userAgent = request.getHeader('user-agent');\n\n return {\n name,\n attributes: {\n // TODO(v11): Update these to the Sentry semantic attributes for urls.\n // https://getsentry.github.io/sentry-conventions/attributes/\n [SEMANTIC_ATTRIBUTE_SENTRY_OP]: 'http.client',\n 'otel.kind': 'CLIENT',\n 'http.url': url,\n 'http.method': request.method,\n 'http.target': request.path || '/',\n 'net.peer.name': request.host,\n 'http.host': request.getHeader('host') as string | undefined,\n ...(userAgent ? { 'user_agent.original': userAgent as string } : {}),\n ...attributes,\n },\n onlyIfParent: true,\n };\n}\n\n/**\n * Add span attributes once the response is received.\n */\nexport function setIncomingResponseSpanData(response: HttpIncomingMessage, span: Span): void {\n const { statusCode, statusMessage, httpVersion, socket } = response;\n const transport = httpVersion?.toUpperCase() !== 'QUIC' ? 'ip_tcp' : 'ip_udp';\n\n span.setAttributes({\n 'http.response.status_code': statusCode,\n 'network.protocol.version': httpVersion,\n // TODO(v11): Update these to the Sentry semantic attributes for urls.\n // https://getsentry.github.io/sentry-conventions/attributes/\n 'http.flavor': httpVersion,\n 'network.transport': transport,\n 'net.transport': transport,\n 'http.status_text': statusMessage?.toUpperCase(),\n 'http.status_code': statusCode,\n ...getResponseContentLengthAttributes(response),\n ...getSocketAttrs(socket),\n });\n}\n\nfunction getSocketAttrs(socket: HttpIncomingMessage['socket']): SpanAttributes {\n if (!socket) return {};\n const { remoteAddress, remotePort } = socket;\n return {\n 'network.peer.address': remoteAddress,\n 'network.peer.port': remotePort,\n 'net.peer.ip': remoteAddress,\n 'net.peer.port': remotePort,\n };\n}\n\nfunction getResponseContentLengthAttributes(response: HttpIncomingMessage): SpanAttributes {\n const { headers } = response;\n const contentLengthHeader = headers['content-length'];\n const length = contentLengthHeader ? parseInt(String(contentLengthHeader), 10) : -1;\n const encoding = headers['content-encoding'];\n return length >= 0\n ? encoding && encoding !== 'identity'\n ? { 'http.response_content_length': length }\n : { 'http.response_content_length_uncompressed': length }\n : {};\n}\n"],"names":[],"mappings":";;;;AAOA;AACA;AACA;AACA;AACO,SAAS,0BAA0B,CAAC,OAAO,EAAuC;AACzF,EAAE,MAAM,GAAA,GAAM,8BAA8B,CAAC,OAAO,CAAC;AACrD,EAAE,MAAM,CAAC,IAAI,EAAE,UAAU,CAAA,GAAI,+BAA+B;AAC5D,IAAI,sBAAsB,CAAC,GAAG,CAAC;AAC/B,IAAI,QAAQ;AACZ,IAAI,kBAAkB;AACtB,IAAI,OAAO;AACX,GAAG;;AAEH,EAAE,MAAM,YAAY,OAAO,CAAC,SAAS,CAAC,YAAY,CAAC;;AAEnD,EAAE,OAAO;AACT,IAAI,IAAI;AACR,IAAI,UAAU,EAAE;AAChB;AACA;AACA,MAAM,CAAC,4BAA4B,GAAG,aAAa;AACnD,MAAM,WAAW,EAAE,QAAQ;AAC3B,MAAM,UAAU,EAAE,GAAG;AACrB,MAAM,aAAa,EAAE,OAAO,CAAC,MAAM;AACnC,MAAM,aAAa,EAAE,OAAO,CAAC,IAAA,IAAQ,GAAG;AACxC,MAAM,eAAe,EAAE,OAAO,CAAC,IAAI;AACnC,MAAM,WAAW,EAAE,OAAO,CAAC,SAAS,CAAC,MAAM,CAAA;AAC3C,MAAM,IAAI,SAAA,GAAY,EAAE,qBAAqB,EAAE,SAAA,GAAoB,GAAI,EAAE,CAAC;AAC1E,MAAM,GAAG,UAAU;AACnB,KAAK;AACL,IAAI,YAAY,EAAE,IAAI;AACtB,GAAG;AACH;;AAEA;AACA;AACA;AACO,SAAS,2BAA2B,CAAC,QAAQ,EAAuB,IAAI,EAAc;AAC7F,EAAE,MAAM,EAAE,UAAU,EAAE,aAAa,EAAE,WAAW,EAAE,MAAA,EAAO,GAAI,QAAQ;AACrE,EAAE,MAAM,SAAA,GAAY,WAAW,EAAE,WAAW,EAAC,KAAM,MAAA,GAAS,QAAA,GAAW,QAAQ;;AAE/E,EAAE,IAAI,CAAC,aAAa,CAAC;AACrB,IAAI,2BAA2B,EAAE,UAAU;AAC3C,IAAI,0BAA0B,EAAE,WAAW;AAC3C;AACA;AACA,IAAI,aAAa,EAAE,WAAW;AAC9B,IAAI,mBAAmB,EAAE,SAAS;AAClC,IAAI,eAAe,EAAE,SAAS;AAC9B,IAAI,kBAAkB,EAAE,aAAa,EAAE,WAAW,EAAE;AACpD,IAAI,kBAAkB,EAAE,UAAU;AAClC,IAAI,GAAG,kCAAkC,CAAC,QAAQ,CAAC;AACnD,IAAI,GAAG,cAAc,CAAC,MAAM,CAAC;AAC7B,GAAG,CAAC;AACJ;;AAEA,SAAS,cAAc,CAAC,MAAM,EAAiD;AAC/E,EAAE,IAAI,CAAC,MAAM,EAAE,OAAO,EAAE;AACxB,EAAE,MAAM,EAAE,aAAa,EAAE,UAAA,EAAW,GAAI,MAAM;AAC9C,EAAE,OAAO;AACT,IAAI,sBAAsB,EAAE,aAAa;AACzC,IAAI,mBAAmB,EAAE,UAAU;AACnC,IAAI,aAAa,EAAE,aAAa;AAChC,IAAI,eAAe,EAAE,UAAU;AAC/B,GAAG;AACH;;AAEA,SAAS,kCAAkC,CAAC,QAAQ,EAAuC;AAC3F,EAAE,MAAM,EAAE,OAAA,EAAQ,GAAI,QAAQ;AAC9B,EAAE,MAAM,mBAAA,GAAsB,OAAO,CAAC,gBAAgB,CAAC;AACvD,EAAE,MAAM,MAAA,GAAS,mBAAA,GAAsB,QAAQ,CAAC,MAAM,CAAC,mBAAmB,CAAC,EAAE,EAAE,CAAA,GAAI,EAAE;AACrF,EAAE,MAAM,QAAA,GAAW,OAAO,CAAC,kBAAkB,CAAC;AAC9C,EAAE,OAAO,UAAU;AACnB,MAAM,QAAA,IAAY,QAAA,KAAa;AAC/B,QAAQ,EAAE,8BAA8B,EAAE,MAAA;AAC1C,QAAQ,EAAE,2CAA2C,EAAE,MAAA;AACvD,MAAM,EAAE;AACR;;;;"}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/** Convert an outgoing request to request options. */
|
|
2
|
+
function getRequestOptions(request) {
|
|
3
|
+
// request.host may be 'hostname:port' when the caller passed
|
|
4
|
+
// { host: 'hostname:port' } to http.request(). Split it so that
|
|
5
|
+
// `hostname` is always port-free (matching the http.RequestOptions contract)
|
|
6
|
+
// and the port is not lost when request.port is undefined.
|
|
7
|
+
const hostWithPort = request.host || '';
|
|
8
|
+
const portInHost = /^(.*):(\d+)$/.exec(hostWithPort);
|
|
9
|
+
const hostname = portInHost ? portInHost[1] : hostWithPort;
|
|
10
|
+
const port = request.port ?? (portInHost ? Number(portInHost[2]) : undefined);
|
|
11
|
+
|
|
12
|
+
return {
|
|
13
|
+
method: request.method,
|
|
14
|
+
port,
|
|
15
|
+
protocol: request.protocol,
|
|
16
|
+
host: request.host,
|
|
17
|
+
hostname,
|
|
18
|
+
path: request.path,
|
|
19
|
+
headers: request.getHeaders(),
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
function getRequestUrl(requestOptions) {
|
|
24
|
+
return String(getRequestUrlObject(requestOptions));
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
function getRequestUrlObject(requestOptions) {
|
|
28
|
+
const protocol = requestOptions.protocol || 'http:';
|
|
29
|
+
const hostHeader = requestOptions.headers?.host && String(requestOptions.headers?.host);
|
|
30
|
+
const hostname = hostHeader || requestOptions.hostname || requestOptions.host || '';
|
|
31
|
+
// Don't log standard :80 (http) and :443 (https) ports to reduce the noise
|
|
32
|
+
// Also don't add port if the hostname already includes a port
|
|
33
|
+
const port =
|
|
34
|
+
!requestOptions.port || requestOptions.port === 80 || requestOptions.port === 443 || /^(.*):(\d+)$/.test(hostname)
|
|
35
|
+
? ''
|
|
36
|
+
: `:${requestOptions.port}`;
|
|
37
|
+
const path = requestOptions.path ? requestOptions.path : '/';
|
|
38
|
+
return new URL(path, `${protocol}//${hostname}${port}`);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Build the full URL string from a Node.js ClientRequest.
|
|
43
|
+
*/
|
|
44
|
+
function getRequestUrlFromClientRequest(request) {
|
|
45
|
+
return String(getRequestUrl(getRequestOptions(request)));
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
export { getRequestOptions, getRequestUrl, getRequestUrlFromClientRequest, getRequestUrlObject };
|
|
49
|
+
//# sourceMappingURL=get-request-url.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"get-request-url.js","sources":["../../../../src/integrations/http/get-request-url.ts"],"sourcesContent":["import type { HttpClientRequest, HttpRequestOptions } from './types';\n\n/** Convert an outgoing request to request options. */\nexport function getRequestOptions(request: HttpClientRequest): HttpRequestOptions {\n // request.host may be 'hostname:port' when the caller passed\n // { host: 'hostname:port' } to http.request(). Split it so that\n // `hostname` is always port-free (matching the http.RequestOptions contract)\n // and the port is not lost when request.port is undefined.\n const hostWithPort = request.host || '';\n const portInHost = /^(.*):(\\d+)$/.exec(hostWithPort);\n const hostname = portInHost ? portInHost[1] : hostWithPort;\n const port = request.port ?? (portInHost ? Number(portInHost[2]) : undefined);\n\n return {\n method: request.method,\n port,\n protocol: request.protocol,\n host: request.host,\n hostname,\n path: request.path,\n headers: request.getHeaders(),\n };\n}\n\nexport function getRequestUrl(requestOptions: HttpRequestOptions): string {\n return String(getRequestUrlObject(requestOptions));\n}\n\nexport function getRequestUrlObject(requestOptions: HttpRequestOptions): URL {\n const protocol = requestOptions.protocol || 'http:';\n const hostHeader = requestOptions.headers?.host && String(requestOptions.headers?.host);\n const hostname = hostHeader || requestOptions.hostname || requestOptions.host || '';\n // Don't log standard :80 (http) and :443 (https) ports to reduce the noise\n // Also don't add port if the hostname already includes a port\n const port =\n !requestOptions.port || requestOptions.port === 80 || requestOptions.port === 443 || /^(.*):(\\d+)$/.test(hostname)\n ? ''\n : `:${requestOptions.port}`;\n const path = requestOptions.path ? requestOptions.path : '/';\n return new URL(path, `${protocol}//${hostname}${port}`);\n}\n\n/**\n * Build the full URL string from a Node.js ClientRequest.\n */\nexport function getRequestUrlFromClientRequest(request: HttpClientRequest): string {\n return String(getRequestUrl(getRequestOptions(request)));\n}\n"],"names":[],"mappings":"AAEA;AACO,SAAS,iBAAiB,CAAC,OAAO,EAAyC;AAClF;AACA;AACA;AACA;AACA,EAAE,MAAM,YAAA,GAAe,OAAO,CAAC,IAAA,IAAQ,EAAE;AACzC,EAAE,MAAM,aAAa,cAAc,CAAC,IAAI,CAAC,YAAY,CAAC;AACtD,EAAE,MAAM,QAAA,GAAW,UAAA,GAAa,UAAU,CAAC,CAAC,CAAA,GAAI,YAAY;AAC5D,EAAE,MAAM,IAAA,GAAO,OAAO,CAAC,IAAA,KAAS,UAAA,GAAa,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC,CAAA,GAAI,SAAS,CAAC;;AAE/E,EAAE,OAAO;AACT,IAAI,MAAM,EAAE,OAAO,CAAC,MAAM;AAC1B,IAAI,IAAI;AACR,IAAI,QAAQ,EAAE,OAAO,CAAC,QAAQ;AAC9B,IAAI,IAAI,EAAE,OAAO,CAAC,IAAI;AACtB,IAAI,QAAQ;AACZ,IAAI,IAAI,EAAE,OAAO,CAAC,IAAI;AACtB,IAAI,OAAO,EAAE,OAAO,CAAC,UAAU,EAAE;AACjC,GAAG;AACH;;AAEO,SAAS,aAAa,CAAC,cAAc,EAA8B;AAC1E,EAAE,OAAO,MAAM,CAAC,mBAAmB,CAAC,cAAc,CAAC,CAAC;AACpD;;AAEO,SAAS,mBAAmB,CAAC,cAAc,EAA2B;AAC7E,EAAE,MAAM,QAAA,GAAW,cAAc,CAAC,QAAA,IAAY,OAAO;AACrD,EAAE,MAAM,UAAA,GAAa,cAAc,CAAC,OAAO,EAAE,IAAA,IAAQ,MAAM,CAAC,cAAc,CAAC,OAAO,EAAE,IAAI,CAAC;AACzF,EAAE,MAAM,QAAA,GAAW,UAAA,IAAc,cAAc,CAAC,QAAA,IAAY,cAAc,CAAC,IAAA,IAAQ,EAAE;AACrF;AACA;AACA,EAAE,MAAM,IAAA;AACR,IAAI,CAAC,cAAc,CAAC,IAAA,IAAQ,cAAc,CAAC,SAAS,EAAA,IAAM,cAAc,CAAC,SAAS,GAAA,IAAO,cAAc,CAAC,IAAI,CAAC,QAAQ;AACrH,QAAQ;AACR,QAAQ,CAAC,CAAC,EAAE,cAAc,CAAC,IAAI,CAAC,CAAA;AACA,EAAA,MAAA,IAAA,GAAA,cAAA,CAAA,IAAA,GAAA,cAAA,CAAA,IAAA,GAAA,GAAA;AACA,EAAA,OAAA,IAAA,GAAA,CAAA,IAAA,EAAA,CAAA,EAAA,QAAA,CAAA,EAAA,EAAA,QAAA,CAAA,EAAA,IAAA,CAAA,CAAA,CAAA;AACA;;AAEA;AACA;AACA;AACA,SAAA,8BAAA,CAAA,OAAA,EAAA;AACA,EAAA,OAAA,MAAA,CAAA,aAAA,CAAA,iBAAA,CAAA,OAAA,CAAA,CAAA,CAAA;AACA;;;;"}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import { getClient } from '../../currentScopes.js';
|
|
2
|
+
import { DEBUG_BUILD } from '../../debug-build.js';
|
|
3
|
+
import { debug } from '../../utils/debug-logger.js';
|
|
4
|
+
import { isError } from '../../utils/is.js';
|
|
5
|
+
import { getTraceData } from '../../utils/traceData.js';
|
|
6
|
+
import { shouldPropagateTraceForUrl } from '../../utils/tracePropagationTargets.js';
|
|
7
|
+
import { LOG_PREFIX } from './constants.js';
|
|
8
|
+
import { getRequestUrlFromClientRequest } from './get-request-url.js';
|
|
9
|
+
import { mergeBaggageHeaders } from '../../utils/baggage.js';
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Inject Sentry trace-propagation headers into an outgoing request if the
|
|
13
|
+
* target URL matches the configured `tracePropagationTargets`.
|
|
14
|
+
*
|
|
15
|
+
* Note: this must be called *before* calling `request.end()` (or firing the
|
|
16
|
+
* `http.client.request.start` diagnostics channel), because at that point,
|
|
17
|
+
* the headers have already been sent, and cannot be modified.
|
|
18
|
+
*/
|
|
19
|
+
function injectTracePropagationHeaders(
|
|
20
|
+
request,
|
|
21
|
+
propagationDecisionMap,
|
|
22
|
+
) {
|
|
23
|
+
const url = getRequestUrlFromClientRequest(request);
|
|
24
|
+
const clientOptions = getClient()?.getOptions();
|
|
25
|
+
const { tracePropagationTargets, propagateTraceparent } = clientOptions ?? {};
|
|
26
|
+
|
|
27
|
+
if (!shouldPropagateTraceForUrl(url, tracePropagationTargets, propagationDecisionMap)) {
|
|
28
|
+
return;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
const hasExistingSentryTraceHeader = !!request.getHeader('sentry-trace');
|
|
32
|
+
|
|
33
|
+
if (hasExistingSentryTraceHeader) {
|
|
34
|
+
// add nothing if there's already a sentry-trace header,
|
|
35
|
+
// or else baggage can be sent twice.
|
|
36
|
+
return;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
const traceData = getTraceData({ propagateTraceparent });
|
|
40
|
+
if (!traceData) return;
|
|
41
|
+
|
|
42
|
+
const { 'sentry-trace': sentryTrace, baggage, traceparent } = traceData;
|
|
43
|
+
|
|
44
|
+
if (sentryTrace) {
|
|
45
|
+
try {
|
|
46
|
+
request.setHeader('sentry-trace', sentryTrace);
|
|
47
|
+
DEBUG_BUILD && debug.log(LOG_PREFIX, 'Added sentry-trace header');
|
|
48
|
+
} catch (e) {
|
|
49
|
+
DEBUG_BUILD &&
|
|
50
|
+
debug.error(LOG_PREFIX, 'Failed to set sentry-trace header:', isError(e) ? e.message : 'Unknown error');
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
if (traceparent && !request.getHeader('traceparent')) {
|
|
55
|
+
try {
|
|
56
|
+
request.setHeader('traceparent', traceparent);
|
|
57
|
+
DEBUG_BUILD && debug.log(LOG_PREFIX, 'Added traceparent header');
|
|
58
|
+
} catch (e) {
|
|
59
|
+
DEBUG_BUILD &&
|
|
60
|
+
debug.error(LOG_PREFIX, 'Failed to set traceparent header:', isError(e) ? e.message : 'Unknown error');
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
if (baggage) {
|
|
65
|
+
const merged = mergeBaggageHeaders(request.getHeader('baggage'), baggage);
|
|
66
|
+
if (merged) {
|
|
67
|
+
try {
|
|
68
|
+
request.setHeader('baggage', merged);
|
|
69
|
+
DEBUG_BUILD && debug.log(LOG_PREFIX, 'Added baggage header');
|
|
70
|
+
} catch (e) {
|
|
71
|
+
DEBUG_BUILD &&
|
|
72
|
+
debug.error(LOG_PREFIX, 'Failed to set baggage header:', isError(e) ? e.message : 'Unknown error');
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
export { injectTracePropagationHeaders };
|
|
79
|
+
//# sourceMappingURL=inject-trace-propagation-headers.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"inject-trace-propagation-headers.js","sources":["../../../../src/integrations/http/inject-trace-propagation-headers.ts"],"sourcesContent":["import type { LRUMap } from '../../utils/lru';\nimport { getClient } from '../../currentScopes';\nimport { DEBUG_BUILD } from '../../debug-build';\nimport { debug } from '../../utils/debug-logger';\nimport { isError } from '../../utils/is';\nimport { getTraceData } from '../../utils/traceData';\nimport { shouldPropagateTraceForUrl } from '../../utils/tracePropagationTargets';\nimport { LOG_PREFIX } from './constants';\nimport { getRequestUrlFromClientRequest } from './get-request-url';\nimport type { HttpClientRequest } from './types';\nimport { mergeBaggageHeaders } from '../../utils/baggage';\n\n/**\n * Inject Sentry trace-propagation headers into an outgoing request if the\n * target URL matches the configured `tracePropagationTargets`.\n *\n * Note: this must be called *before* calling `request.end()` (or firing the\n * `http.client.request.start` diagnostics channel), because at that point,\n * the headers have already been sent, and cannot be modified.\n */\nexport function injectTracePropagationHeaders(\n request: HttpClientRequest,\n propagationDecisionMap: LRUMap<string, boolean>,\n): void {\n const url = getRequestUrlFromClientRequest(request);\n const clientOptions = getClient()?.getOptions();\n const { tracePropagationTargets, propagateTraceparent } = clientOptions ?? {};\n\n if (!shouldPropagateTraceForUrl(url, tracePropagationTargets, propagationDecisionMap)) {\n return;\n }\n\n const hasExistingSentryTraceHeader = !!request.getHeader('sentry-trace');\n\n if (hasExistingSentryTraceHeader) {\n // add nothing if there's already a sentry-trace header,\n // or else baggage can be sent twice.\n return;\n }\n\n const traceData = getTraceData({ propagateTraceparent });\n if (!traceData) return;\n\n const { 'sentry-trace': sentryTrace, baggage, traceparent } = traceData;\n\n if (sentryTrace) {\n try {\n request.setHeader('sentry-trace', sentryTrace);\n DEBUG_BUILD && debug.log(LOG_PREFIX, 'Added sentry-trace header');\n } catch (e) {\n DEBUG_BUILD &&\n debug.error(LOG_PREFIX, 'Failed to set sentry-trace header:', isError(e) ? e.message : 'Unknown error');\n }\n }\n\n if (traceparent && !request.getHeader('traceparent')) {\n try {\n request.setHeader('traceparent', traceparent);\n DEBUG_BUILD && debug.log(LOG_PREFIX, 'Added traceparent header');\n } catch (e) {\n DEBUG_BUILD &&\n debug.error(LOG_PREFIX, 'Failed to set traceparent header:', isError(e) ? e.message : 'Unknown error');\n }\n }\n\n if (baggage) {\n const merged = mergeBaggageHeaders(request.getHeader('baggage'), baggage);\n if (merged) {\n try {\n request.setHeader('baggage', merged);\n DEBUG_BUILD && debug.log(LOG_PREFIX, 'Added baggage header');\n } catch (e) {\n DEBUG_BUILD &&\n debug.error(LOG_PREFIX, 'Failed to set baggage header:', isError(e) ? e.message : 'Unknown error');\n }\n }\n }\n}\n"],"names":[],"mappings":";;;;;;;;;;AAYA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACO,SAAS,6BAA6B;AAC7C,EAAE,OAAO;AACT,EAAE,sBAAsB;AACxB,EAAQ;AACR,EAAE,MAAM,GAAA,GAAM,8BAA8B,CAAC,OAAO,CAAC;AACrD,EAAE,MAAM,gBAAgB,SAAS,EAAE,EAAE,UAAU,EAAE;AACjD,EAAE,MAAM,EAAE,uBAAuB,EAAE,oBAAA,KAAyB,aAAA,IAAiB,EAAE;;AAE/E,EAAE,IAAI,CAAC,0BAA0B,CAAC,GAAG,EAAE,uBAAuB,EAAE,sBAAsB,CAAC,EAAE;AACzF,IAAI;AACJ,EAAE;;AAEF,EAAE,MAAM,4BAAA,GAA+B,CAAC,CAAC,OAAO,CAAC,SAAS,CAAC,cAAc,CAAC;;AAE1E,EAAE,IAAI,4BAA4B,EAAE;AACpC;AACA;AACA,IAAI;AACJ,EAAE;;AAEF,EAAE,MAAM,YAAY,YAAY,CAAC,EAAE,oBAAA,EAAsB,CAAC;AAC1D,EAAE,IAAI,CAAC,SAAS,EAAE;;AAElB,EAAE,MAAM,EAAE,cAAc,EAAE,WAAW,EAAE,OAAO,EAAE,WAAA,EAAY,GAAI,SAAS;;AAEzE,EAAE,IAAI,WAAW,EAAE;AACnB,IAAI,IAAI;AACR,MAAM,OAAO,CAAC,SAAS,CAAC,cAAc,EAAE,WAAW,CAAC;AACpD,MAAM,WAAA,IAAe,KAAK,CAAC,GAAG,CAAC,UAAU,EAAE,2BAA2B,CAAC;AACvE,IAAI,CAAA,CAAE,OAAO,CAAC,EAAE;AAChB,MAAM,WAAA;AACN,QAAQ,KAAK,CAAC,KAAK,CAAC,UAAU,EAAE,oCAAoC,EAAE,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,OAAA,GAAU,eAAe,CAAC;AAC/G,IAAI;AACJ,EAAE;;AAEF,EAAE,IAAI,WAAA,IAAe,CAAC,OAAO,CAAC,SAAS,CAAC,aAAa,CAAC,EAAE;AACxD,IAAI,IAAI;AACR,MAAM,OAAO,CAAC,SAAS,CAAC,aAAa,EAAE,WAAW,CAAC;AACnD,MAAM,WAAA,IAAe,KAAK,CAAC,GAAG,CAAC,UAAU,EAAE,0BAA0B,CAAC;AACtE,IAAI,CAAA,CAAE,OAAO,CAAC,EAAE;AAChB,MAAM,WAAA;AACN,QAAQ,KAAK,CAAC,KAAK,CAAC,UAAU,EAAE,mCAAmC,EAAE,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,OAAA,GAAU,eAAe,CAAC;AAC9G,IAAI;AACJ,EAAE;;AAEF,EAAE,IAAI,OAAO,EAAE;AACf,IAAI,MAAM,MAAA,GAAS,mBAAmB,CAAC,OAAO,CAAC,SAAS,CAAC,SAAS,CAAC,EAAE,OAAO,CAAC;AAC7E,IAAI,IAAI,MAAM,EAAE;AAChB,MAAM,IAAI;AACV,QAAQ,OAAO,CAAC,SAAS,CAAC,SAAS,EAAE,MAAM,CAAC;AAC5C,QAAQ,WAAA,IAAe,KAAK,CAAC,GAAG,CAAC,UAAU,EAAE,sBAAsB,CAAC;AACpE,MAAM,CAAA,CAAE,OAAO,CAAC,EAAE;AAClB,QAAQ,WAAA;AACR,UAAU,KAAK,CAAC,KAAK,CAAC,UAAU,EAAE,+BAA+B,EAAE,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,OAAA,GAAU,eAAe,CAAC;AAC5G,MAAM;AACN,IAAI;AACJ,EAAE;AACF;;;;"}
|
|
@@ -168,5 +168,76 @@ function wrapAllMCPHandlers(serverInstance) {
|
|
|
168
168
|
wrapPromptHandlers(serverInstance);
|
|
169
169
|
}
|
|
170
170
|
|
|
171
|
-
|
|
171
|
+
/**
|
|
172
|
+
* Retroactively wraps handlers on tools, resources, and prompts that were registered
|
|
173
|
+
* before `wrapMcpServerWithSentry` was called.
|
|
174
|
+
*
|
|
175
|
+
* The MCP SDK stores registered entries in private maps and invokes them via the entry's
|
|
176
|
+
* own property at call time — `executor` for tools, `readCallback` for resources, and
|
|
177
|
+
* `handler` for prompts. Replacing those properties
|
|
178
|
+
* in-place is therefore equivalent to having wrapped the original registration call.
|
|
179
|
+
*
|
|
180
|
+
* NOTE: This intentionally accesses private MCP SDK internals (`_registeredTools` etc.).
|
|
181
|
+
* The properties and their shapes are verified against @modelcontextprotocol/sdk source:
|
|
182
|
+
* https://github.com/modelcontextprotocol/typescript-sdk/blob/2c0c481cb9dbfd15c8613f765c940a5f5bace94d/packages/server/src/server/mcp.ts#L304
|
|
183
|
+
* When upgrading the MCP SDK, re-verify that these internal maps and their callable
|
|
184
|
+
* properties still exist and are invoked directly (not captured by closure at registration).
|
|
185
|
+
* All access is defensive — if a property is absent or not a function we skip silently.
|
|
186
|
+
* @internal
|
|
187
|
+
*/
|
|
188
|
+
function wrapExistingHandlers(serverInstance) {
|
|
189
|
+
const server = serverInstance ;
|
|
190
|
+
|
|
191
|
+
// Tools: MCP SDK calls registeredTool.executor (generated from handler at registration time)
|
|
192
|
+
const registeredTools = server['_registeredTools'];
|
|
193
|
+
if (registeredTools && typeof registeredTools === 'object') {
|
|
194
|
+
for (const [name, tool] of Object.entries(registeredTools )) {
|
|
195
|
+
if (typeof tool['executor'] === 'function') {
|
|
196
|
+
tool['executor'] = createWrappedHandler(tool['executor'] , 'registerTool', name);
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
// Resources: MCP SDK calls registeredResource.readCallback
|
|
202
|
+
const registeredResources = server['_registeredResources'];
|
|
203
|
+
if (registeredResources && typeof registeredResources === 'object') {
|
|
204
|
+
for (const [name, resource] of Object.entries(registeredResources )) {
|
|
205
|
+
if (typeof resource['readCallback'] === 'function') {
|
|
206
|
+
resource['readCallback'] = createWrappedHandler(
|
|
207
|
+
resource['readCallback'] ,
|
|
208
|
+
'registerResource',
|
|
209
|
+
name,
|
|
210
|
+
);
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
// Resource templates: MCP SDK calls registeredResourceTemplate.readCallback
|
|
216
|
+
const registeredResourceTemplates = server['_registeredResourceTemplates'];
|
|
217
|
+
if (registeredResourceTemplates && typeof registeredResourceTemplates === 'object') {
|
|
218
|
+
for (const [name, template] of Object.entries(
|
|
219
|
+
registeredResourceTemplates ,
|
|
220
|
+
)) {
|
|
221
|
+
if (typeof template['readCallback'] === 'function') {
|
|
222
|
+
template['readCallback'] = createWrappedHandler(
|
|
223
|
+
template['readCallback'] ,
|
|
224
|
+
'registerResource',
|
|
225
|
+
name,
|
|
226
|
+
);
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
// Prompts: MCP SDK calls registeredPrompt.handler
|
|
232
|
+
const registeredPrompts = server['_registeredPrompts'];
|
|
233
|
+
if (registeredPrompts && typeof registeredPrompts === 'object') {
|
|
234
|
+
for (const [name, prompt] of Object.entries(registeredPrompts )) {
|
|
235
|
+
if (typeof prompt['handler'] === 'function') {
|
|
236
|
+
prompt['handler'] = createWrappedHandler(prompt['handler'] , 'registerPrompt', name);
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
export { wrapAllMCPHandlers, wrapExistingHandlers, wrapPromptHandlers, wrapResourceHandlers, wrapToolHandlers };
|
|
172
243
|
//# sourceMappingURL=handlers.js.map
|