@sentry/core 10.46.0 → 10.48.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/api.js +1 -0
- package/build/cjs/api.js.map +1 -1
- package/build/cjs/attributes.js +43 -0
- package/build/cjs/attributes.js.map +1 -1
- package/build/cjs/client.js +13 -6
- package/build/cjs/client.js.map +1 -1
- package/build/cjs/currentScopes.js +33 -0
- package/build/cjs/currentScopes.js.map +1 -1
- package/build/cjs/envelope.js +4 -3
- package/build/cjs/envelope.js.map +1 -1
- package/build/cjs/index.js +50 -13
- package/build/cjs/index.js.map +1 -1
- package/build/cjs/integration.js +6 -0
- package/build/cjs/integration.js.map +1 -1
- package/build/cjs/integrations/express/index.js +206 -0
- package/build/cjs/integrations/express/index.js.map +1 -0
- package/build/cjs/integrations/express/patch-layer.js +251 -0
- package/build/cjs/integrations/express/patch-layer.js.map +1 -0
- package/build/cjs/integrations/express/request-layer-store.js +25 -0
- package/build/cjs/integrations/express/request-layer-store.js.map +1 -0
- package/build/cjs/integrations/express/set-sdk-processing-metadata.js +17 -0
- package/build/cjs/integrations/express/set-sdk-processing-metadata.js.map +1 -0
- package/build/cjs/integrations/express/types.js +17 -0
- package/build/cjs/integrations/express/types.js.map +1 -0
- package/build/cjs/integrations/express/utils.js +238 -0
- package/build/cjs/integrations/express/utils.js.map +1 -0
- package/build/cjs/integrations/mcp-server/correlation.js +5 -1
- package/build/cjs/integrations/mcp-server/correlation.js.map +1 -1
- package/build/cjs/integrations/mcp-server/handlers.js +18 -10
- package/build/cjs/integrations/mcp-server/handlers.js.map +1 -1
- package/build/cjs/integrations/mcp-server/index.js +2 -1
- package/build/cjs/integrations/mcp-server/index.js.map +1 -1
- package/build/cjs/integrations/mcp-server/transport.js +1 -1
- package/build/cjs/integrations/mcp-server/transport.js.map +1 -1
- package/build/cjs/integrations/mcp-server/validation.js +7 -5
- package/build/cjs/integrations/mcp-server/validation.js.map +1 -1
- package/build/cjs/integrations/spanStreaming.js +48 -0
- package/build/cjs/integrations/spanStreaming.js.map +1 -0
- package/build/cjs/integrations/supabase.js +1 -1
- package/build/cjs/integrations/supabase.js.map +1 -1
- package/build/cjs/semanticAttributes.js +35 -3
- package/build/cjs/semanticAttributes.js.map +1 -1
- package/build/cjs/tracing/ai/gen-ai-attributes.js +9 -79
- package/build/cjs/tracing/ai/gen-ai-attributes.js.map +1 -1
- package/build/cjs/tracing/ai/utils.js +50 -35
- package/build/cjs/tracing/ai/utils.js.map +1 -1
- package/build/cjs/tracing/anthropic-ai/constants.js +10 -10
- package/build/cjs/tracing/anthropic-ai/constants.js.map +1 -1
- package/build/cjs/tracing/anthropic-ai/index.js +18 -20
- package/build/cjs/tracing/anthropic-ai/index.js.map +1 -1
- package/build/cjs/tracing/anthropic-ai/streaming.js +2 -100
- package/build/cjs/tracing/anthropic-ai/streaming.js.map +1 -1
- package/build/cjs/tracing/anthropic-ai/utils.js +0 -9
- package/build/cjs/tracing/anthropic-ai/utils.js.map +1 -1
- package/build/cjs/tracing/dynamicSamplingContext.js +2 -1
- package/build/cjs/tracing/dynamicSamplingContext.js.map +1 -1
- package/build/cjs/tracing/google-genai/constants.js +9 -12
- package/build/cjs/tracing/google-genai/constants.js.map +1 -1
- package/build/cjs/tracing/google-genai/index.js +49 -27
- package/build/cjs/tracing/google-genai/index.js.map +1 -1
- package/build/cjs/tracing/google-genai/streaming.js +2 -23
- package/build/cjs/tracing/google-genai/streaming.js.map +1 -1
- package/build/cjs/tracing/google-genai/utils.js +0 -25
- package/build/cjs/tracing/google-genai/utils.js.map +1 -1
- package/build/cjs/tracing/langchain/embeddings.js +132 -0
- package/build/cjs/tracing/langchain/embeddings.js.map +1 -0
- package/build/cjs/tracing/langchain/index.js.map +1 -1
- package/build/cjs/tracing/openai/constants.js +7 -7
- package/build/cjs/tracing/openai/constants.js.map +1 -1
- package/build/cjs/tracing/openai/index.js +19 -37
- package/build/cjs/tracing/openai/index.js.map +1 -1
- package/build/cjs/tracing/openai/streaming.js +3 -34
- package/build/cjs/tracing/openai/streaming.js.map +1 -1
- package/build/cjs/tracing/openai/utils.js +78 -243
- package/build/cjs/tracing/openai/utils.js.map +1 -1
- package/build/cjs/tracing/sentryNonRecordingSpan.js +7 -0
- package/build/cjs/tracing/sentryNonRecordingSpan.js.map +1 -1
- package/build/cjs/tracing/sentrySpan.js +39 -0
- package/build/cjs/tracing/sentrySpan.js.map +1 -1
- package/build/cjs/tracing/spans/beforeSendSpan.js +43 -0
- package/build/cjs/tracing/spans/beforeSendSpan.js.map +1 -0
- package/build/cjs/tracing/spans/captureSpan.js +126 -0
- package/build/cjs/tracing/spans/captureSpan.js.map +1 -0
- package/build/cjs/tracing/spans/envelope.js +38 -0
- package/build/cjs/tracing/spans/envelope.js.map +1 -0
- package/build/cjs/tracing/spans/estimateSize.js +41 -0
- package/build/cjs/tracing/spans/estimateSize.js.map +1 -0
- package/build/cjs/tracing/spans/hasSpanStreamingEnabled.js +11 -0
- package/build/cjs/tracing/spans/hasSpanStreamingEnabled.js.map +1 -0
- package/build/cjs/tracing/spans/spanBuffer.js +158 -0
- package/build/cjs/tracing/spans/spanBuffer.js.map +1 -0
- package/build/cjs/tracing/trace.js +88 -13
- package/build/cjs/tracing/trace.js.map +1 -1
- package/build/cjs/tracing/vercel-ai/utils.js +1 -4
- package/build/cjs/tracing/vercel-ai/utils.js.map +1 -1
- package/build/cjs/utils/featureFlags.js +6 -0
- package/build/cjs/utils/featureFlags.js.map +1 -1
- package/build/cjs/utils/object.js +33 -0
- package/build/cjs/utils/object.js.map +1 -1
- package/build/cjs/utils/spanUtils.js +116 -13
- package/build/cjs/utils/spanUtils.js.map +1 -1
- package/build/cjs/utils/stacktrace.js +3 -1
- package/build/cjs/utils/stacktrace.js.map +1 -1
- package/build/cjs/utils/string.js +3 -0
- package/build/cjs/utils/string.js.map +1 -1
- package/build/cjs/utils/traceData.js +11 -0
- package/build/cjs/utils/traceData.js.map +1 -1
- package/build/cjs/utils/version.js +1 -1
- package/build/esm/api.js +1 -1
- package/build/esm/api.js.map +1 -1
- package/build/esm/attributes.js +43 -1
- package/build/esm/attributes.js.map +1 -1
- package/build/esm/client.js +8 -1
- package/build/esm/client.js.map +1 -1
- package/build/esm/currentScopes.js +31 -1
- package/build/esm/currentScopes.js.map +1 -1
- package/build/esm/envelope.js +2 -1
- package/build/esm/envelope.js.map +1 -1
- package/build/esm/index.js +13 -4
- package/build/esm/index.js.map +1 -1
- package/build/esm/integration.js +6 -0
- package/build/esm/integration.js.map +1 -1
- package/build/esm/integrations/express/index.js +202 -0
- package/build/esm/integrations/express/index.js.map +1 -0
- package/build/esm/integrations/express/patch-layer.js +249 -0
- package/build/esm/integrations/express/patch-layer.js.map +1 -0
- package/build/esm/integrations/express/request-layer-store.js +22 -0
- package/build/esm/integrations/express/request-layer-store.js.map +1 -0
- package/build/esm/integrations/express/set-sdk-processing-metadata.js +15 -0
- package/build/esm/integrations/express/set-sdk-processing-metadata.js.map +1 -0
- package/build/esm/integrations/express/types.js +10 -0
- package/build/esm/integrations/express/types.js.map +1 -0
- package/build/esm/integrations/express/utils.js +225 -0
- package/build/esm/integrations/express/utils.js.map +1 -0
- package/build/esm/integrations/mcp-server/correlation.js +5 -1
- package/build/esm/integrations/mcp-server/correlation.js.map +1 -1
- package/build/esm/integrations/mcp-server/handlers.js +18 -10
- package/build/esm/integrations/mcp-server/handlers.js.map +1 -1
- package/build/esm/integrations/mcp-server/index.js +2 -1
- package/build/esm/integrations/mcp-server/index.js.map +1 -1
- package/build/esm/integrations/mcp-server/transport.js +1 -1
- package/build/esm/integrations/mcp-server/transport.js.map +1 -1
- package/build/esm/integrations/mcp-server/validation.js +7 -5
- package/build/esm/integrations/mcp-server/validation.js.map +1 -1
- package/build/esm/integrations/spanStreaming.js +46 -0
- package/build/esm/integrations/spanStreaming.js.map +1 -0
- package/build/esm/integrations/supabase.js +1 -1
- package/build/esm/integrations/supabase.js.map +1 -1
- package/build/esm/package.json +1 -1
- package/build/esm/semanticAttributes.js +26 -4
- package/build/esm/semanticAttributes.js.map +1 -1
- package/build/esm/tracing/ai/gen-ai-attributes.js +8 -69
- package/build/esm/tracing/ai/gen-ai-attributes.js.map +1 -1
- package/build/esm/tracing/ai/utils.js +51 -35
- package/build/esm/tracing/ai/utils.js.map +1 -1
- package/build/esm/tracing/anthropic-ai/constants.js +10 -10
- package/build/esm/tracing/anthropic-ai/constants.js.map +1 -1
- package/build/esm/tracing/anthropic-ai/index.js +21 -23
- package/build/esm/tracing/anthropic-ai/index.js.map +1 -1
- package/build/esm/tracing/anthropic-ai/streaming.js +3 -101
- package/build/esm/tracing/anthropic-ai/streaming.js.map +1 -1
- package/build/esm/tracing/anthropic-ai/utils.js +1 -9
- package/build/esm/tracing/anthropic-ai/utils.js.map +1 -1
- package/build/esm/tracing/dynamicSamplingContext.js +2 -1
- package/build/esm/tracing/dynamicSamplingContext.js.map +1 -1
- package/build/esm/tracing/google-genai/constants.js +9 -10
- package/build/esm/tracing/google-genai/constants.js.map +1 -1
- package/build/esm/tracing/google-genai/index.js +53 -31
- package/build/esm/tracing/google-genai/index.js.map +1 -1
- package/build/esm/tracing/google-genai/streaming.js +2 -23
- package/build/esm/tracing/google-genai/streaming.js.map +1 -1
- package/build/esm/tracing/google-genai/utils.js +1 -24
- package/build/esm/tracing/google-genai/utils.js.map +1 -1
- package/build/esm/tracing/langchain/embeddings.js +129 -0
- package/build/esm/tracing/langchain/embeddings.js.map +1 -0
- package/build/esm/tracing/langchain/index.js.map +1 -1
- package/build/esm/tracing/openai/constants.js +7 -7
- package/build/esm/tracing/openai/constants.js.map +1 -1
- package/build/esm/tracing/openai/index.js +21 -39
- package/build/esm/tracing/openai/index.js.map +1 -1
- package/build/esm/tracing/openai/streaming.js +4 -35
- package/build/esm/tracing/openai/streaming.js.map +1 -1
- package/build/esm/tracing/openai/utils.js +79 -232
- package/build/esm/tracing/openai/utils.js.map +1 -1
- package/build/esm/tracing/sentryNonRecordingSpan.js +7 -0
- package/build/esm/tracing/sentryNonRecordingSpan.js.map +1 -1
- package/build/esm/tracing/sentrySpan.js +40 -1
- package/build/esm/tracing/sentrySpan.js.map +1 -1
- package/build/esm/tracing/spans/beforeSendSpan.js +40 -0
- package/build/esm/tracing/spans/beforeSendSpan.js.map +1 -0
- package/build/esm/tracing/spans/captureSpan.js +122 -0
- package/build/esm/tracing/spans/captureSpan.js.map +1 -0
- package/build/esm/tracing/spans/envelope.js +36 -0
- package/build/esm/tracing/spans/envelope.js.map +1 -0
- package/build/esm/tracing/spans/estimateSize.js +39 -0
- package/build/esm/tracing/spans/estimateSize.js.map +1 -0
- package/build/esm/tracing/spans/hasSpanStreamingEnabled.js +9 -0
- package/build/esm/tracing/spans/hasSpanStreamingEnabled.js.map +1 -0
- package/build/esm/tracing/spans/spanBuffer.js +156 -0
- package/build/esm/tracing/spans/spanBuffer.js.map +1 -0
- package/build/esm/tracing/trace.js +89 -14
- package/build/esm/tracing/trace.js.map +1 -1
- package/build/esm/tracing/vercel-ai/utils.js +2 -5
- package/build/esm/tracing/vercel-ai/utils.js.map +1 -1
- package/build/esm/utils/featureFlags.js +6 -0
- package/build/esm/utils/featureFlags.js.map +1 -1
- package/build/esm/utils/object.js +33 -1
- package/build/esm/utils/object.js.map +1 -1
- package/build/esm/utils/spanUtils.js +112 -14
- package/build/esm/utils/spanUtils.js.map +1 -1
- package/build/esm/utils/stacktrace.js +3 -1
- package/build/esm/utils/stacktrace.js.map +1 -1
- package/build/esm/utils/string.js +3 -0
- package/build/esm/utils/string.js.map +1 -1
- package/build/esm/utils/traceData.js +12 -1
- package/build/esm/utils/traceData.js.map +1 -1
- package/build/esm/utils/version.js +1 -1
- package/build/types/api.d.ts +1 -0
- package/build/types/api.d.ts.map +1 -1
- package/build/types/asyncContext/types.d.ts +3 -1
- package/build/types/asyncContext/types.d.ts.map +1 -1
- package/build/types/attributes.d.ts +5 -0
- package/build/types/attributes.d.ts.map +1 -1
- package/build/types/client.d.ts +35 -1
- package/build/types/client.d.ts.map +1 -1
- package/build/types/currentScopes.d.ts +20 -0
- package/build/types/currentScopes.d.ts.map +1 -1
- package/build/types/envelope.d.ts.map +1 -1
- package/build/types/index.d.ts +15 -6
- package/build/types/index.d.ts.map +1 -1
- package/build/types/integration.d.ts.map +1 -1
- package/build/types/integrations/express/index.d.ts +75 -0
- package/build/types/integrations/express/index.d.ts.map +1 -0
- package/build/types/integrations/express/patch-layer.d.ts +32 -0
- package/build/types/integrations/express/patch-layer.d.ts.map +1 -0
- package/build/types/integrations/express/request-layer-store.d.ts +32 -0
- package/build/types/integrations/express/request-layer-store.d.ts.map +1 -0
- package/build/types/integrations/express/set-sdk-processing-metadata.d.ts +35 -0
- package/build/types/integrations/express/set-sdk-processing-metadata.d.ts.map +1 -0
- package/build/types/integrations/express/types.d.ts +154 -0
- package/build/types/integrations/express/types.d.ts.map +1 -0
- package/build/types/integrations/express/utils.d.ts +93 -0
- package/build/types/integrations/express/utils.d.ts.map +1 -0
- package/build/types/integrations/mcp-server/correlation.d.ts +2 -1
- package/build/types/integrations/mcp-server/correlation.d.ts.map +1 -1
- package/build/types/integrations/mcp-server/handlers.d.ts +9 -4
- package/build/types/integrations/mcp-server/handlers.d.ts.map +1 -1
- package/build/types/integrations/mcp-server/index.d.ts +2 -1
- package/build/types/integrations/mcp-server/index.d.ts.map +1 -1
- package/build/types/integrations/mcp-server/types.d.ts +40 -7
- package/build/types/integrations/mcp-server/types.d.ts.map +1 -1
- package/build/types/integrations/mcp-server/validation.d.ts +4 -1
- package/build/types/integrations/mcp-server/validation.d.ts.map +1 -1
- package/build/types/integrations/spanStreaming.d.ts +2 -0
- package/build/types/integrations/spanStreaming.d.ts.map +1 -0
- package/build/types/semanticAttributes.d.ts +23 -3
- package/build/types/semanticAttributes.d.ts.map +1 -1
- package/build/types/tracing/ai/gen-ai-attributes.d.ts +6 -46
- package/build/types/tracing/ai/gen-ai-attributes.d.ts.map +1 -1
- package/build/types/tracing/ai/utils.d.ts +34 -9
- package/build/types/tracing/ai/utils.d.ts.map +1 -1
- package/build/types/tracing/anthropic-ai/constants.d.ts +24 -1
- package/build/types/tracing/anthropic-ai/constants.d.ts.map +1 -1
- package/build/types/tracing/anthropic-ai/index.d.ts.map +1 -1
- package/build/types/tracing/anthropic-ai/streaming.d.ts.map +1 -1
- package/build/types/tracing/anthropic-ai/types.d.ts +5 -2
- package/build/types/tracing/anthropic-ai/types.d.ts.map +1 -1
- package/build/types/tracing/anthropic-ai/utils.d.ts +1 -5
- package/build/types/tracing/anthropic-ai/utils.d.ts.map +1 -1
- package/build/types/tracing/dynamicSamplingContext.d.ts.map +1 -1
- package/build/types/tracing/google-genai/constants.d.ts +22 -3
- package/build/types/tracing/google-genai/constants.d.ts.map +1 -1
- package/build/types/tracing/google-genai/index.d.ts.map +1 -1
- package/build/types/tracing/google-genai/streaming.d.ts.map +1 -1
- package/build/types/tracing/google-genai/types.d.ts +6 -2
- package/build/types/tracing/google-genai/types.d.ts.map +1 -1
- package/build/types/tracing/google-genai/utils.d.ts +0 -9
- package/build/types/tracing/google-genai/utils.d.ts.map +1 -1
- package/build/types/tracing/index.d.ts +1 -0
- package/build/types/tracing/index.d.ts.map +1 -1
- package/build/types/tracing/langchain/embeddings.d.ts +27 -0
- package/build/types/tracing/langchain/embeddings.d.ts.map +1 -0
- package/build/types/tracing/langchain/index.d.ts +1 -0
- package/build/types/tracing/langchain/index.d.ts.map +1 -1
- package/build/types/tracing/openai/constants.d.ts +14 -1
- package/build/types/tracing/openai/constants.d.ts.map +1 -1
- package/build/types/tracing/openai/index.d.ts.map +1 -1
- package/build/types/tracing/openai/streaming.d.ts.map +1 -1
- package/build/types/tracing/openai/types.d.ts +5 -2
- package/build/types/tracing/openai/types.d.ts.map +1 -1
- package/build/types/tracing/openai/utils.d.ts +4 -63
- package/build/types/tracing/openai/utils.d.ts.map +1 -1
- package/build/types/tracing/sentryNonRecordingSpan.d.ts +12 -1
- package/build/types/tracing/sentryNonRecordingSpan.d.ts.map +1 -1
- package/build/types/tracing/sentrySpan.d.ts +10 -1
- package/build/types/tracing/sentrySpan.d.ts.map +1 -1
- package/build/types/tracing/spans/beforeSendSpan.d.ts +35 -0
- package/build/types/tracing/spans/beforeSendSpan.d.ts.map +1 -0
- package/build/types/tracing/spans/captureSpan.d.ts +26 -0
- package/build/types/tracing/spans/captureSpan.d.ts.map +1 -0
- package/build/types/tracing/spans/envelope.d.ts +8 -0
- package/build/types/tracing/spans/envelope.d.ts.map +1 -0
- package/build/types/tracing/spans/estimateSize.d.ts +12 -0
- package/build/types/tracing/spans/estimateSize.d.ts.map +1 -0
- package/build/types/tracing/spans/hasSpanStreamingEnabled.d.ts +6 -0
- package/build/types/tracing/spans/hasSpanStreamingEnabled.d.ts.map +1 -0
- package/build/types/tracing/spans/spanBuffer.d.ts +60 -0
- package/build/types/tracing/spans/spanBuffer.d.ts.map +1 -0
- package/build/types/tracing/trace.d.ts.map +1 -1
- package/build/types/tracing/vercel-ai/utils.d.ts.map +1 -1
- package/build/types/types-hoist/envelope.d.ts +22 -2
- package/build/types/types-hoist/envelope.d.ts.map +1 -1
- package/build/types/types-hoist/integration.d.ts +8 -0
- package/build/types/types-hoist/integration.d.ts.map +1 -1
- package/build/types/types-hoist/link.d.ts +2 -2
- package/build/types/types-hoist/link.d.ts.map +1 -1
- package/build/types/types-hoist/options.d.ts +26 -2
- package/build/types/types-hoist/options.d.ts.map +1 -1
- package/build/types/types-hoist/span.d.ts +35 -0
- package/build/types/types-hoist/span.d.ts.map +1 -1
- package/build/types/utils/featureFlags.d.ts.map +1 -1
- package/build/types/utils/object.d.ts +10 -0
- package/build/types/utils/object.d.ts.map +1 -1
- package/build/types/utils/spanUtils.d.ts +27 -2
- package/build/types/utils/spanUtils.d.ts.map +1 -1
- package/build/types/utils/stacktrace.d.ts.map +1 -1
- package/build/types/utils/string.d.ts +2 -2
- package/build/types/utils/string.d.ts.map +1 -1
- package/build/types/utils/traceData.d.ts +4 -0
- package/build/types/utils/traceData.d.ts.map +1 -1
- package/build/types-ts3.8/api.d.ts +1 -0
- package/build/types-ts3.8/asyncContext/types.d.ts +3 -1
- package/build/types-ts3.8/attributes.d.ts +5 -0
- package/build/types-ts3.8/client.d.ts +35 -1
- package/build/types-ts3.8/currentScopes.d.ts +20 -0
- package/build/types-ts3.8/index.d.ts +15 -6
- package/build/types-ts3.8/integrations/express/index.d.ts +75 -0
- package/build/types-ts3.8/integrations/express/patch-layer.d.ts +32 -0
- package/build/types-ts3.8/integrations/express/request-layer-store.d.ts +32 -0
- package/build/types-ts3.8/integrations/express/set-sdk-processing-metadata.d.ts +35 -0
- package/build/types-ts3.8/integrations/express/types.d.ts +154 -0
- package/build/types-ts3.8/integrations/express/utils.d.ts +96 -0
- package/build/types-ts3.8/integrations/mcp-server/correlation.d.ts +2 -1
- package/build/types-ts3.8/integrations/mcp-server/handlers.d.ts +9 -4
- package/build/types-ts3.8/integrations/mcp-server/index.d.ts +2 -1
- package/build/types-ts3.8/integrations/mcp-server/types.d.ts +40 -7
- package/build/types-ts3.8/integrations/mcp-server/validation.d.ts +4 -1
- package/build/types-ts3.8/integrations/spanStreaming.d.ts +2 -0
- package/build/types-ts3.8/semanticAttributes.d.ts +23 -3
- package/build/types-ts3.8/tracing/ai/gen-ai-attributes.d.ts +6 -46
- package/build/types-ts3.8/tracing/ai/utils.d.ts +34 -9
- package/build/types-ts3.8/tracing/anthropic-ai/constants.d.ts +24 -9
- package/build/types-ts3.8/tracing/anthropic-ai/types.d.ts +5 -2
- package/build/types-ts3.8/tracing/anthropic-ai/utils.d.ts +1 -5
- package/build/types-ts3.8/tracing/google-genai/constants.d.ts +22 -9
- package/build/types-ts3.8/tracing/google-genai/types.d.ts +6 -2
- package/build/types-ts3.8/tracing/google-genai/utils.d.ts +0 -9
- package/build/types-ts3.8/tracing/index.d.ts +1 -0
- package/build/types-ts3.8/tracing/langchain/embeddings.d.ts +27 -0
- package/build/types-ts3.8/tracing/langchain/index.d.ts +1 -0
- package/build/types-ts3.8/tracing/openai/constants.d.ts +14 -6
- package/build/types-ts3.8/tracing/openai/types.d.ts +5 -2
- package/build/types-ts3.8/tracing/openai/utils.d.ts +4 -63
- package/build/types-ts3.8/tracing/sentryNonRecordingSpan.d.ts +12 -1
- package/build/types-ts3.8/tracing/sentrySpan.d.ts +10 -1
- package/build/types-ts3.8/tracing/spans/beforeSendSpan.d.ts +35 -0
- package/build/types-ts3.8/tracing/spans/captureSpan.d.ts +26 -0
- package/build/types-ts3.8/tracing/spans/envelope.d.ts +8 -0
- package/build/types-ts3.8/tracing/spans/estimateSize.d.ts +12 -0
- package/build/types-ts3.8/tracing/spans/hasSpanStreamingEnabled.d.ts +6 -0
- package/build/types-ts3.8/tracing/spans/spanBuffer.d.ts +60 -0
- package/build/types-ts3.8/types-hoist/envelope.d.ts +22 -2
- package/build/types-ts3.8/types-hoist/integration.d.ts +8 -0
- package/build/types-ts3.8/types-hoist/link.d.ts +2 -2
- package/build/types-ts3.8/types-hoist/options.d.ts +26 -2
- package/build/types-ts3.8/types-hoist/span.d.ts +35 -0
- package/build/types-ts3.8/utils/object.d.ts +10 -0
- package/build/types-ts3.8/utils/spanUtils.d.ts +27 -2
- package/build/types-ts3.8/utils/string.d.ts +2 -2
- package/build/types-ts3.8/utils/traceData.d.ts +4 -0
- package/package.json +1 -1
|
@@ -1,92 +1,4 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { INSTRUMENTED_METHODS } from './constants.js';
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* Maps OpenAI method paths to OpenTelemetry semantic convention operation names
|
|
6
|
-
* @see https://opentelemetry.io/docs/specs/semconv/gen-ai/gen-ai-spans/#llm-request-spans
|
|
7
|
-
*/
|
|
8
|
-
function getOperationName(methodPath) {
|
|
9
|
-
if (methodPath.includes('chat.completions')) {
|
|
10
|
-
return OPENAI_OPERATIONS.CHAT;
|
|
11
|
-
}
|
|
12
|
-
if (methodPath.includes('responses')) {
|
|
13
|
-
return OPENAI_OPERATIONS.CHAT;
|
|
14
|
-
}
|
|
15
|
-
if (methodPath.includes('embeddings')) {
|
|
16
|
-
return OPENAI_OPERATIONS.EMBEDDINGS;
|
|
17
|
-
}
|
|
18
|
-
if (methodPath.includes('conversations')) {
|
|
19
|
-
return OPENAI_OPERATIONS.CHAT;
|
|
20
|
-
}
|
|
21
|
-
return methodPath.split('.').pop() || 'unknown';
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
/**
|
|
25
|
-
* Get the span operation for OpenAI methods
|
|
26
|
-
* Following Sentry's convention: "gen_ai.{operation_name}"
|
|
27
|
-
*/
|
|
28
|
-
function getSpanOperation(methodPath) {
|
|
29
|
-
return `gen_ai.${getOperationName(methodPath)}`;
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
/**
|
|
33
|
-
* Check if a method path should be instrumented
|
|
34
|
-
*/
|
|
35
|
-
function shouldInstrument(methodPath) {
|
|
36
|
-
return INSTRUMENTED_METHODS.includes(methodPath );
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
/**
|
|
40
|
-
* Check if response is a Chat Completion object
|
|
41
|
-
*/
|
|
42
|
-
function isChatCompletionResponse(response) {
|
|
43
|
-
return (
|
|
44
|
-
response !== null &&
|
|
45
|
-
typeof response === 'object' &&
|
|
46
|
-
'object' in response &&
|
|
47
|
-
(response ).object === 'chat.completion'
|
|
48
|
-
);
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
/**
|
|
52
|
-
* Check if response is a Responses API object
|
|
53
|
-
*/
|
|
54
|
-
function isResponsesApiResponse(response) {
|
|
55
|
-
return (
|
|
56
|
-
response !== null &&
|
|
57
|
-
typeof response === 'object' &&
|
|
58
|
-
'object' in response &&
|
|
59
|
-
(response ).object === 'response'
|
|
60
|
-
);
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
/**
|
|
64
|
-
* Check if response is an Embeddings API object
|
|
65
|
-
*/
|
|
66
|
-
function isEmbeddingsResponse(response) {
|
|
67
|
-
if (response === null || typeof response !== 'object' || !('object' in response)) {
|
|
68
|
-
return false;
|
|
69
|
-
}
|
|
70
|
-
const responseObject = response ;
|
|
71
|
-
return (
|
|
72
|
-
responseObject.object === 'list' &&
|
|
73
|
-
typeof responseObject.model === 'string' &&
|
|
74
|
-
responseObject.model.toLowerCase().includes('embedding')
|
|
75
|
-
);
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
/**
|
|
79
|
-
* Check if response is a Conversations API object
|
|
80
|
-
* @see https://platform.openai.com/docs/api-reference/conversations
|
|
81
|
-
*/
|
|
82
|
-
function isConversationResponse(response) {
|
|
83
|
-
return (
|
|
84
|
-
response !== null &&
|
|
85
|
-
typeof response === 'object' &&
|
|
86
|
-
'object' in response &&
|
|
87
|
-
(response ).object === 'conversation'
|
|
88
|
-
);
|
|
89
|
-
}
|
|
1
|
+
import { GEN_AI_RESPONSE_FINISH_REASONS_ATTRIBUTE, GEN_AI_RESPONSE_TEXT_ATTRIBUTE, GEN_AI_RESPONSE_TOOL_CALLS_ATTRIBUTE, GEN_AI_REQUEST_MODEL_ATTRIBUTE, GEN_AI_REQUEST_TEMPERATURE_ATTRIBUTE, GEN_AI_REQUEST_TOP_P_ATTRIBUTE, GEN_AI_REQUEST_FREQUENCY_PENALTY_ATTRIBUTE, GEN_AI_REQUEST_PRESENCE_PENALTY_ATTRIBUTE, GEN_AI_REQUEST_STREAM_ATTRIBUTE, GEN_AI_REQUEST_ENCODING_FORMAT_ATTRIBUTE, GEN_AI_REQUEST_DIMENSIONS_ATTRIBUTE, GEN_AI_CONVERSATION_ID_ATTRIBUTE, GEN_AI_RESPONSE_ID_ATTRIBUTE, GEN_AI_RESPONSE_MODEL_ATTRIBUTE, GEN_AI_USAGE_INPUT_TOKENS_ATTRIBUTE, GEN_AI_USAGE_OUTPUT_TOKENS_ATTRIBUTE, GEN_AI_USAGE_TOTAL_TOKENS_ATTRIBUTE } from '../ai/gen-ai-attributes.js';
|
|
90
2
|
|
|
91
3
|
/**
|
|
92
4
|
* Check if streaming event is from the Responses API
|
|
@@ -114,173 +26,108 @@ function isChatCompletionChunk(event) {
|
|
|
114
26
|
}
|
|
115
27
|
|
|
116
28
|
/**
|
|
117
|
-
* Add attributes
|
|
29
|
+
* Add response attributes to a span using duck-typing.
|
|
30
|
+
* Works for Chat Completions, Responses API, Embeddings, and Conversations API responses.
|
|
118
31
|
*/
|
|
119
|
-
function
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
32
|
+
function addResponseAttributes(span, result, recordOutputs) {
|
|
33
|
+
if (!result || typeof result !== 'object') return;
|
|
34
|
+
|
|
35
|
+
const response = result ;
|
|
36
|
+
const attrs = {};
|
|
37
|
+
|
|
38
|
+
// Response ID
|
|
39
|
+
if (typeof response.id === 'string') {
|
|
40
|
+
attrs[GEN_AI_RESPONSE_ID_ATTRIBUTE] = response.id;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
// Response model
|
|
44
|
+
if (typeof response.model === 'string') {
|
|
45
|
+
attrs[GEN_AI_RESPONSE_MODEL_ATTRIBUTE] = response.model;
|
|
132
46
|
}
|
|
47
|
+
|
|
48
|
+
// Conversation ID (conversation objects use id as conversation link)
|
|
49
|
+
if (response.object === 'conversation' && typeof response.id === 'string') {
|
|
50
|
+
attrs[GEN_AI_CONVERSATION_ID_ATTRIBUTE] = response.id;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
// Token usage — supports both naming conventions (chat: prompt_tokens/completion_tokens, responses: input_tokens/output_tokens)
|
|
54
|
+
if (response.usage && typeof response.usage === 'object') {
|
|
55
|
+
const usage = response.usage ;
|
|
56
|
+
|
|
57
|
+
const inputTokens = usage.prompt_tokens ?? usage.input_tokens;
|
|
58
|
+
if (typeof inputTokens === 'number') {
|
|
59
|
+
attrs[GEN_AI_USAGE_INPUT_TOKENS_ATTRIBUTE] = inputTokens;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
const outputTokens = usage.completion_tokens ?? usage.output_tokens;
|
|
63
|
+
if (typeof outputTokens === 'number') {
|
|
64
|
+
attrs[GEN_AI_USAGE_OUTPUT_TOKENS_ATTRIBUTE] = outputTokens;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
if (typeof usage.total_tokens === 'number') {
|
|
68
|
+
attrs[GEN_AI_USAGE_TOTAL_TOKENS_ATTRIBUTE] = usage.total_tokens;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
// Finish reasons from choices (chat completions)
|
|
133
73
|
if (Array.isArray(response.choices)) {
|
|
134
|
-
const
|
|
74
|
+
const choices = response.choices ;
|
|
75
|
+
const finishReasons = choices
|
|
135
76
|
.map(choice => choice.finish_reason)
|
|
136
|
-
.filter((reason) => reason
|
|
77
|
+
.filter((reason) => typeof reason === 'string');
|
|
137
78
|
if (finishReasons.length > 0) {
|
|
138
|
-
|
|
139
|
-
[GEN_AI_RESPONSE_FINISH_REASONS_ATTRIBUTE]: JSON.stringify(finishReasons),
|
|
140
|
-
});
|
|
79
|
+
attrs[GEN_AI_RESPONSE_FINISH_REASONS_ATTRIBUTE] = JSON.stringify(finishReasons);
|
|
141
80
|
}
|
|
142
81
|
|
|
143
|
-
// Extract tool calls from all choices (only if recordOutputs is true)
|
|
144
82
|
if (recordOutputs) {
|
|
145
|
-
|
|
146
|
-
|
|
83
|
+
// Response text from choices
|
|
84
|
+
const responseTexts = choices.map(choice => {
|
|
85
|
+
const message = choice.message ;
|
|
86
|
+
return (message?.content ) || '';
|
|
87
|
+
});
|
|
88
|
+
attrs[GEN_AI_RESPONSE_TEXT_ATTRIBUTE] = JSON.stringify(responseTexts);
|
|
89
|
+
|
|
90
|
+
// Tool calls from choices
|
|
91
|
+
const toolCalls = choices
|
|
92
|
+
.map(choice => {
|
|
93
|
+
const message = choice.message ;
|
|
94
|
+
return message?.tool_calls;
|
|
95
|
+
})
|
|
147
96
|
.filter(calls => Array.isArray(calls) && calls.length > 0)
|
|
148
97
|
.flat();
|
|
149
98
|
|
|
150
99
|
if (toolCalls.length > 0) {
|
|
151
|
-
|
|
152
|
-
[GEN_AI_RESPONSE_TOOL_CALLS_ATTRIBUTE]: JSON.stringify(toolCalls),
|
|
153
|
-
});
|
|
100
|
+
attrs[GEN_AI_RESPONSE_TOOL_CALLS_ATTRIBUTE] = JSON.stringify(toolCalls);
|
|
154
101
|
}
|
|
155
102
|
}
|
|
156
103
|
}
|
|
157
|
-
}
|
|
158
104
|
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
span.setAttributes({
|
|
166
|
-
[GEN_AI_RESPONSE_FINISH_REASONS_ATTRIBUTE]: JSON.stringify([response.status]),
|
|
167
|
-
});
|
|
168
|
-
}
|
|
169
|
-
if (response.usage) {
|
|
170
|
-
setTokenUsageAttributes(
|
|
171
|
-
span,
|
|
172
|
-
response.usage.input_tokens,
|
|
173
|
-
response.usage.output_tokens,
|
|
174
|
-
response.usage.total_tokens,
|
|
175
|
-
);
|
|
105
|
+
// Finish reason from status (responses API)
|
|
106
|
+
if (typeof response.status === 'string') {
|
|
107
|
+
// Only set if not already set from choices
|
|
108
|
+
if (!attrs[GEN_AI_RESPONSE_FINISH_REASONS_ATTRIBUTE]) {
|
|
109
|
+
attrs[GEN_AI_RESPONSE_FINISH_REASONS_ATTRIBUTE] = JSON.stringify([response.status]);
|
|
110
|
+
}
|
|
176
111
|
}
|
|
177
112
|
|
|
178
|
-
// Extract function calls from output (only if recordOutputs is true)
|
|
179
113
|
if (recordOutputs) {
|
|
180
|
-
|
|
181
|
-
if (
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
(item) =>
|
|
185
|
-
// oxlint-disable-next-line typescript/prefer-optional-chain
|
|
186
|
-
typeof item === 'object' && item !== null && (item ).type === 'function_call',
|
|
187
|
-
);
|
|
114
|
+
// Response text from output_text (responses API)
|
|
115
|
+
if (typeof response.output_text === 'string' && !attrs[GEN_AI_RESPONSE_TEXT_ATTRIBUTE]) {
|
|
116
|
+
attrs[GEN_AI_RESPONSE_TEXT_ATTRIBUTE] = response.output_text;
|
|
117
|
+
}
|
|
188
118
|
|
|
119
|
+
// Tool calls from output array (responses API)
|
|
120
|
+
if (Array.isArray(response.output) && response.output.length > 0 && !attrs[GEN_AI_RESPONSE_TOOL_CALLS_ATTRIBUTE]) {
|
|
121
|
+
const functionCalls = (response.output ).filter(
|
|
122
|
+
item => item?.type === 'function_call',
|
|
123
|
+
);
|
|
189
124
|
if (functionCalls.length > 0) {
|
|
190
|
-
|
|
191
|
-
[GEN_AI_RESPONSE_TOOL_CALLS_ATTRIBUTE]: JSON.stringify(functionCalls),
|
|
192
|
-
});
|
|
125
|
+
attrs[GEN_AI_RESPONSE_TOOL_CALLS_ATTRIBUTE] = JSON.stringify(functionCalls);
|
|
193
126
|
}
|
|
194
127
|
}
|
|
195
128
|
}
|
|
196
|
-
}
|
|
197
|
-
|
|
198
|
-
/**
|
|
199
|
-
* Add attributes for Embeddings API responses
|
|
200
|
-
*/
|
|
201
|
-
function addEmbeddingsAttributes(span, response) {
|
|
202
|
-
span.setAttributes({
|
|
203
|
-
[OPENAI_RESPONSE_MODEL_ATTRIBUTE]: response.model,
|
|
204
|
-
[GEN_AI_RESPONSE_MODEL_ATTRIBUTE]: response.model,
|
|
205
|
-
});
|
|
206
|
-
|
|
207
|
-
if (response.usage) {
|
|
208
|
-
setTokenUsageAttributes(span, response.usage.prompt_tokens, undefined, response.usage.total_tokens);
|
|
209
|
-
}
|
|
210
|
-
}
|
|
211
|
-
|
|
212
|
-
/**
|
|
213
|
-
* Add attributes for Conversations API responses
|
|
214
|
-
* @see https://platform.openai.com/docs/api-reference/conversations
|
|
215
|
-
*/
|
|
216
|
-
function addConversationAttributes(span, response) {
|
|
217
|
-
const { id, created_at } = response;
|
|
218
|
-
|
|
219
|
-
span.setAttributes({
|
|
220
|
-
[OPENAI_RESPONSE_ID_ATTRIBUTE]: id,
|
|
221
|
-
[GEN_AI_RESPONSE_ID_ATTRIBUTE]: id,
|
|
222
|
-
// The conversation id is used to link messages across API calls
|
|
223
|
-
[GEN_AI_CONVERSATION_ID_ATTRIBUTE]: id,
|
|
224
|
-
});
|
|
225
|
-
|
|
226
|
-
if (created_at) {
|
|
227
|
-
span.setAttributes({
|
|
228
|
-
[OPENAI_RESPONSE_TIMESTAMP_ATTRIBUTE]: new Date(created_at * 1000).toISOString(),
|
|
229
|
-
});
|
|
230
|
-
}
|
|
231
|
-
}
|
|
232
129
|
|
|
233
|
-
|
|
234
|
-
* Set token usage attributes
|
|
235
|
-
* @param span - The span to add attributes to
|
|
236
|
-
* @param promptTokens - The number of prompt tokens
|
|
237
|
-
* @param completionTokens - The number of completion tokens
|
|
238
|
-
* @param totalTokens - The number of total tokens
|
|
239
|
-
*/
|
|
240
|
-
function setTokenUsageAttributes(
|
|
241
|
-
span,
|
|
242
|
-
promptTokens,
|
|
243
|
-
completionTokens,
|
|
244
|
-
totalTokens,
|
|
245
|
-
) {
|
|
246
|
-
if (promptTokens !== undefined) {
|
|
247
|
-
span.setAttributes({
|
|
248
|
-
[OPENAI_USAGE_PROMPT_TOKENS_ATTRIBUTE]: promptTokens,
|
|
249
|
-
[GEN_AI_USAGE_INPUT_TOKENS_ATTRIBUTE]: promptTokens,
|
|
250
|
-
});
|
|
251
|
-
}
|
|
252
|
-
if (completionTokens !== undefined) {
|
|
253
|
-
span.setAttributes({
|
|
254
|
-
[OPENAI_USAGE_COMPLETION_TOKENS_ATTRIBUTE]: completionTokens,
|
|
255
|
-
[GEN_AI_USAGE_OUTPUT_TOKENS_ATTRIBUTE]: completionTokens,
|
|
256
|
-
});
|
|
257
|
-
}
|
|
258
|
-
if (totalTokens !== undefined) {
|
|
259
|
-
span.setAttributes({
|
|
260
|
-
[GEN_AI_USAGE_TOTAL_TOKENS_ATTRIBUTE]: totalTokens,
|
|
261
|
-
});
|
|
262
|
-
}
|
|
263
|
-
}
|
|
264
|
-
|
|
265
|
-
/**
|
|
266
|
-
* Set common response attributes
|
|
267
|
-
* @param span - The span to add attributes to
|
|
268
|
-
* @param id - The response id
|
|
269
|
-
* @param model - The response model
|
|
270
|
-
* @param timestamp - The response timestamp
|
|
271
|
-
*/
|
|
272
|
-
function setCommonResponseAttributes(span, id, model, timestamp) {
|
|
273
|
-
span.setAttributes({
|
|
274
|
-
[OPENAI_RESPONSE_ID_ATTRIBUTE]: id,
|
|
275
|
-
[GEN_AI_RESPONSE_ID_ATTRIBUTE]: id,
|
|
276
|
-
});
|
|
277
|
-
span.setAttributes({
|
|
278
|
-
[OPENAI_RESPONSE_MODEL_ATTRIBUTE]: model,
|
|
279
|
-
[GEN_AI_RESPONSE_MODEL_ATTRIBUTE]: model,
|
|
280
|
-
});
|
|
281
|
-
span.setAttributes({
|
|
282
|
-
[OPENAI_RESPONSE_TIMESTAMP_ATTRIBUTE]: new Date(timestamp * 1000).toISOString(),
|
|
283
|
-
});
|
|
130
|
+
span.setAttributes(attrs);
|
|
284
131
|
}
|
|
285
132
|
|
|
286
133
|
/**
|
|
@@ -325,5 +172,5 @@ function extractRequestParameters(params) {
|
|
|
325
172
|
return attributes;
|
|
326
173
|
}
|
|
327
174
|
|
|
328
|
-
export {
|
|
175
|
+
export { addResponseAttributes, extractRequestParameters, isChatCompletionChunk, isResponsesApiStreamEvent };
|
|
329
176
|
//# sourceMappingURL=utils.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils.js","sources":["../../../../src/tracing/openai/utils.ts"],"sourcesContent":["import type { Span } from '../../types-hoist/span';\nimport {\n GEN_AI_CONVERSATION_ID_ATTRIBUTE,\n GEN_AI_REQUEST_DIMENSIONS_ATTRIBUTE,\n GEN_AI_REQUEST_ENCODING_FORMAT_ATTRIBUTE,\n GEN_AI_REQUEST_FREQUENCY_PENALTY_ATTRIBUTE,\n GEN_AI_REQUEST_MODEL_ATTRIBUTE,\n GEN_AI_REQUEST_PRESENCE_PENALTY_ATTRIBUTE,\n GEN_AI_REQUEST_STREAM_ATTRIBUTE,\n GEN_AI_REQUEST_TEMPERATURE_ATTRIBUTE,\n GEN_AI_REQUEST_TOP_P_ATTRIBUTE,\n GEN_AI_RESPONSE_FINISH_REASONS_ATTRIBUTE,\n GEN_AI_RESPONSE_ID_ATTRIBUTE,\n GEN_AI_RESPONSE_MODEL_ATTRIBUTE,\n GEN_AI_RESPONSE_TOOL_CALLS_ATTRIBUTE,\n GEN_AI_USAGE_INPUT_TOKENS_ATTRIBUTE,\n GEN_AI_USAGE_OUTPUT_TOKENS_ATTRIBUTE,\n GEN_AI_USAGE_TOTAL_TOKENS_ATTRIBUTE,\n OPENAI_OPERATIONS,\n OPENAI_RESPONSE_ID_ATTRIBUTE,\n OPENAI_RESPONSE_MODEL_ATTRIBUTE,\n OPENAI_RESPONSE_TIMESTAMP_ATTRIBUTE,\n OPENAI_USAGE_COMPLETION_TOKENS_ATTRIBUTE,\n OPENAI_USAGE_PROMPT_TOKENS_ATTRIBUTE,\n} from '../ai/gen-ai-attributes';\nimport { INSTRUMENTED_METHODS } from './constants';\nimport type {\n ChatCompletionChunk,\n InstrumentedMethod,\n OpenAiChatCompletionObject,\n OpenAIConversationObject,\n OpenAICreateEmbeddingsObject,\n OpenAIResponseObject,\n ResponseStreamingEvent,\n} from './types';\n\n/**\n * Maps OpenAI method paths to OpenTelemetry semantic convention operation names\n * @see https://opentelemetry.io/docs/specs/semconv/gen-ai/gen-ai-spans/#llm-request-spans\n */\nexport function getOperationName(methodPath: string): string {\n if (methodPath.includes('chat.completions')) {\n return OPENAI_OPERATIONS.CHAT;\n }\n if (methodPath.includes('responses')) {\n return OPENAI_OPERATIONS.CHAT;\n }\n if (methodPath.includes('embeddings')) {\n return OPENAI_OPERATIONS.EMBEDDINGS;\n }\n if (methodPath.includes('conversations')) {\n return OPENAI_OPERATIONS.CHAT;\n }\n return methodPath.split('.').pop() || 'unknown';\n}\n\n/**\n * Get the span operation for OpenAI methods\n * Following Sentry's convention: \"gen_ai.{operation_name}\"\n */\nexport function getSpanOperation(methodPath: string): string {\n return `gen_ai.${getOperationName(methodPath)}`;\n}\n\n/**\n * Check if a method path should be instrumented\n */\nexport function shouldInstrument(methodPath: string): methodPath is InstrumentedMethod {\n return INSTRUMENTED_METHODS.includes(methodPath as InstrumentedMethod);\n}\n\n/**\n * Check if response is a Chat Completion object\n */\nexport function isChatCompletionResponse(response: unknown): response is OpenAiChatCompletionObject {\n return (\n response !== null &&\n typeof response === 'object' &&\n 'object' in response &&\n (response as Record<string, unknown>).object === 'chat.completion'\n );\n}\n\n/**\n * Check if response is a Responses API object\n */\nexport function isResponsesApiResponse(response: unknown): response is OpenAIResponseObject {\n return (\n response !== null &&\n typeof response === 'object' &&\n 'object' in response &&\n (response as Record<string, unknown>).object === 'response'\n );\n}\n\n/**\n * Check if response is an Embeddings API object\n */\nexport function isEmbeddingsResponse(response: unknown): response is OpenAICreateEmbeddingsObject {\n if (response === null || typeof response !== 'object' || !('object' in response)) {\n return false;\n }\n const responseObject = response as Record<string, unknown>;\n return (\n responseObject.object === 'list' &&\n typeof responseObject.model === 'string' &&\n responseObject.model.toLowerCase().includes('embedding')\n );\n}\n\n/**\n * Check if response is a Conversations API object\n * @see https://platform.openai.com/docs/api-reference/conversations\n */\nexport function isConversationResponse(response: unknown): response is OpenAIConversationObject {\n return (\n response !== null &&\n typeof response === 'object' &&\n 'object' in response &&\n (response as Record<string, unknown>).object === 'conversation'\n );\n}\n\n/**\n * Check if streaming event is from the Responses API\n */\nexport function isResponsesApiStreamEvent(event: unknown): event is ResponseStreamingEvent {\n return (\n event !== null &&\n typeof event === 'object' &&\n 'type' in event &&\n typeof (event as Record<string, unknown>).type === 'string' &&\n ((event as Record<string, unknown>).type as string).startsWith('response.')\n );\n}\n\n/**\n * Check if streaming event is a chat completion chunk\n */\nexport function isChatCompletionChunk(event: unknown): event is ChatCompletionChunk {\n return (\n event !== null &&\n typeof event === 'object' &&\n 'object' in event &&\n (event as Record<string, unknown>).object === 'chat.completion.chunk'\n );\n}\n\n/**\n * Add attributes for Chat Completion responses\n */\nexport function addChatCompletionAttributes(\n span: Span,\n response: OpenAiChatCompletionObject,\n recordOutputs?: boolean,\n): void {\n setCommonResponseAttributes(span, response.id, response.model, response.created);\n if (response.usage) {\n setTokenUsageAttributes(\n span,\n response.usage.prompt_tokens,\n response.usage.completion_tokens,\n response.usage.total_tokens,\n );\n }\n if (Array.isArray(response.choices)) {\n const finishReasons = response.choices\n .map(choice => choice.finish_reason)\n .filter((reason): reason is string => reason !== null);\n if (finishReasons.length > 0) {\n span.setAttributes({\n [GEN_AI_RESPONSE_FINISH_REASONS_ATTRIBUTE]: JSON.stringify(finishReasons),\n });\n }\n\n // Extract tool calls from all choices (only if recordOutputs is true)\n if (recordOutputs) {\n const toolCalls = response.choices\n .map(choice => choice.message?.tool_calls)\n .filter(calls => Array.isArray(calls) && calls.length > 0)\n .flat();\n\n if (toolCalls.length > 0) {\n span.setAttributes({\n [GEN_AI_RESPONSE_TOOL_CALLS_ATTRIBUTE]: JSON.stringify(toolCalls),\n });\n }\n }\n }\n}\n\n/**\n * Add attributes for Responses API responses\n */\nexport function addResponsesApiAttributes(span: Span, response: OpenAIResponseObject, recordOutputs?: boolean): void {\n setCommonResponseAttributes(span, response.id, response.model, response.created_at);\n if (response.status) {\n span.setAttributes({\n [GEN_AI_RESPONSE_FINISH_REASONS_ATTRIBUTE]: JSON.stringify([response.status]),\n });\n }\n if (response.usage) {\n setTokenUsageAttributes(\n span,\n response.usage.input_tokens,\n response.usage.output_tokens,\n response.usage.total_tokens,\n );\n }\n\n // Extract function calls from output (only if recordOutputs is true)\n if (recordOutputs) {\n const responseWithOutput = response as OpenAIResponseObject & { output?: unknown[] };\n if (Array.isArray(responseWithOutput.output) && responseWithOutput.output.length > 0) {\n // Filter for function_call type objects in the output array\n const functionCalls = responseWithOutput.output.filter(\n (item): unknown =>\n // oxlint-disable-next-line typescript/prefer-optional-chain\n typeof item === 'object' && item !== null && (item as Record<string, unknown>).type === 'function_call',\n );\n\n if (functionCalls.length > 0) {\n span.setAttributes({\n [GEN_AI_RESPONSE_TOOL_CALLS_ATTRIBUTE]: JSON.stringify(functionCalls),\n });\n }\n }\n }\n}\n\n/**\n * Add attributes for Embeddings API responses\n */\nexport function addEmbeddingsAttributes(span: Span, response: OpenAICreateEmbeddingsObject): void {\n span.setAttributes({\n [OPENAI_RESPONSE_MODEL_ATTRIBUTE]: response.model,\n [GEN_AI_RESPONSE_MODEL_ATTRIBUTE]: response.model,\n });\n\n if (response.usage) {\n setTokenUsageAttributes(span, response.usage.prompt_tokens, undefined, response.usage.total_tokens);\n }\n}\n\n/**\n * Add attributes for Conversations API responses\n * @see https://platform.openai.com/docs/api-reference/conversations\n */\nexport function addConversationAttributes(span: Span, response: OpenAIConversationObject): void {\n const { id, created_at } = response;\n\n span.setAttributes({\n [OPENAI_RESPONSE_ID_ATTRIBUTE]: id,\n [GEN_AI_RESPONSE_ID_ATTRIBUTE]: id,\n // The conversation id is used to link messages across API calls\n [GEN_AI_CONVERSATION_ID_ATTRIBUTE]: id,\n });\n\n if (created_at) {\n span.setAttributes({\n [OPENAI_RESPONSE_TIMESTAMP_ATTRIBUTE]: new Date(created_at * 1000).toISOString(),\n });\n }\n}\n\n/**\n * Set token usage attributes\n * @param span - The span to add attributes to\n * @param promptTokens - The number of prompt tokens\n * @param completionTokens - The number of completion tokens\n * @param totalTokens - The number of total tokens\n */\nexport function setTokenUsageAttributes(\n span: Span,\n promptTokens?: number,\n completionTokens?: number,\n totalTokens?: number,\n): void {\n if (promptTokens !== undefined) {\n span.setAttributes({\n [OPENAI_USAGE_PROMPT_TOKENS_ATTRIBUTE]: promptTokens,\n [GEN_AI_USAGE_INPUT_TOKENS_ATTRIBUTE]: promptTokens,\n });\n }\n if (completionTokens !== undefined) {\n span.setAttributes({\n [OPENAI_USAGE_COMPLETION_TOKENS_ATTRIBUTE]: completionTokens,\n [GEN_AI_USAGE_OUTPUT_TOKENS_ATTRIBUTE]: completionTokens,\n });\n }\n if (totalTokens !== undefined) {\n span.setAttributes({\n [GEN_AI_USAGE_TOTAL_TOKENS_ATTRIBUTE]: totalTokens,\n });\n }\n}\n\n/**\n * Set common response attributes\n * @param span - The span to add attributes to\n * @param id - The response id\n * @param model - The response model\n * @param timestamp - The response timestamp\n */\nexport function setCommonResponseAttributes(span: Span, id: string, model: string, timestamp: number): void {\n span.setAttributes({\n [OPENAI_RESPONSE_ID_ATTRIBUTE]: id,\n [GEN_AI_RESPONSE_ID_ATTRIBUTE]: id,\n });\n span.setAttributes({\n [OPENAI_RESPONSE_MODEL_ATTRIBUTE]: model,\n [GEN_AI_RESPONSE_MODEL_ATTRIBUTE]: model,\n });\n span.setAttributes({\n [OPENAI_RESPONSE_TIMESTAMP_ATTRIBUTE]: new Date(timestamp * 1000).toISOString(),\n });\n}\n\n/**\n * Extract conversation ID from request parameters\n * Supports both Conversations API and previous_response_id chaining\n * @see https://platform.openai.com/docs/guides/conversation-state\n */\nfunction extractConversationId(params: Record<string, unknown>): string | undefined {\n // Conversations API: conversation parameter (e.g., \"conv_...\")\n if ('conversation' in params && typeof params.conversation === 'string') {\n return params.conversation;\n }\n // Responses chaining: previous_response_id links to parent response\n if ('previous_response_id' in params && typeof params.previous_response_id === 'string') {\n return params.previous_response_id;\n }\n return undefined;\n}\n\n/**\n * Extract request parameters including model settings and conversation context\n */\nexport function extractRequestParameters(params: Record<string, unknown>): Record<string, unknown> {\n const attributes: Record<string, unknown> = {\n [GEN_AI_REQUEST_MODEL_ATTRIBUTE]: params.model ?? 'unknown',\n };\n\n if ('temperature' in params) attributes[GEN_AI_REQUEST_TEMPERATURE_ATTRIBUTE] = params.temperature;\n if ('top_p' in params) attributes[GEN_AI_REQUEST_TOP_P_ATTRIBUTE] = params.top_p;\n if ('frequency_penalty' in params) attributes[GEN_AI_REQUEST_FREQUENCY_PENALTY_ATTRIBUTE] = params.frequency_penalty;\n if ('presence_penalty' in params) attributes[GEN_AI_REQUEST_PRESENCE_PENALTY_ATTRIBUTE] = params.presence_penalty;\n if ('stream' in params) attributes[GEN_AI_REQUEST_STREAM_ATTRIBUTE] = params.stream;\n if ('encoding_format' in params) attributes[GEN_AI_REQUEST_ENCODING_FORMAT_ATTRIBUTE] = params.encoding_format;\n if ('dimensions' in params) attributes[GEN_AI_REQUEST_DIMENSIONS_ATTRIBUTE] = params.dimensions;\n\n // Capture conversation ID for linking messages across API calls\n const conversationId = extractConversationId(params);\n if (conversationId) {\n attributes[GEN_AI_CONVERSATION_ID_ATTRIBUTE] = conversationId;\n }\n\n return attributes;\n}\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"utils.js","sources":["../../../../src/tracing/openai/utils.ts"],"sourcesContent":["import type { Span } from '../../types-hoist/span';\nimport type { SpanAttributeValue } from '../../types-hoist/span';\nimport {\n GEN_AI_CONVERSATION_ID_ATTRIBUTE,\n GEN_AI_REQUEST_DIMENSIONS_ATTRIBUTE,\n GEN_AI_REQUEST_ENCODING_FORMAT_ATTRIBUTE,\n GEN_AI_REQUEST_FREQUENCY_PENALTY_ATTRIBUTE,\n GEN_AI_REQUEST_MODEL_ATTRIBUTE,\n GEN_AI_REQUEST_PRESENCE_PENALTY_ATTRIBUTE,\n GEN_AI_REQUEST_STREAM_ATTRIBUTE,\n GEN_AI_REQUEST_TEMPERATURE_ATTRIBUTE,\n GEN_AI_REQUEST_TOP_P_ATTRIBUTE,\n GEN_AI_RESPONSE_FINISH_REASONS_ATTRIBUTE,\n GEN_AI_RESPONSE_ID_ATTRIBUTE,\n GEN_AI_RESPONSE_MODEL_ATTRIBUTE,\n GEN_AI_RESPONSE_TEXT_ATTRIBUTE,\n GEN_AI_RESPONSE_TOOL_CALLS_ATTRIBUTE,\n GEN_AI_USAGE_INPUT_TOKENS_ATTRIBUTE,\n GEN_AI_USAGE_OUTPUT_TOKENS_ATTRIBUTE,\n GEN_AI_USAGE_TOTAL_TOKENS_ATTRIBUTE,\n} from '../ai/gen-ai-attributes';\nimport type { ChatCompletionChunk, ResponseStreamingEvent } from './types';\n\n/**\n * Check if streaming event is from the Responses API\n */\nexport function isResponsesApiStreamEvent(event: unknown): event is ResponseStreamingEvent {\n return (\n event !== null &&\n typeof event === 'object' &&\n 'type' in event &&\n typeof (event as Record<string, unknown>).type === 'string' &&\n ((event as Record<string, unknown>).type as string).startsWith('response.')\n );\n}\n\n/**\n * Check if streaming event is a chat completion chunk\n */\nexport function isChatCompletionChunk(event: unknown): event is ChatCompletionChunk {\n return (\n event !== null &&\n typeof event === 'object' &&\n 'object' in event &&\n (event as Record<string, unknown>).object === 'chat.completion.chunk'\n );\n}\n\n/**\n * Add response attributes to a span using duck-typing.\n * Works for Chat Completions, Responses API, Embeddings, and Conversations API responses.\n */\nexport function addResponseAttributes(span: Span, result: unknown, recordOutputs?: boolean): void {\n if (!result || typeof result !== 'object') return;\n\n const response = result as Record<string, unknown>;\n const attrs: Record<string, SpanAttributeValue> = {};\n\n // Response ID\n if (typeof response.id === 'string') {\n attrs[GEN_AI_RESPONSE_ID_ATTRIBUTE] = response.id;\n }\n\n // Response model\n if (typeof response.model === 'string') {\n attrs[GEN_AI_RESPONSE_MODEL_ATTRIBUTE] = response.model;\n }\n\n // Conversation ID (conversation objects use id as conversation link)\n if (response.object === 'conversation' && typeof response.id === 'string') {\n attrs[GEN_AI_CONVERSATION_ID_ATTRIBUTE] = response.id;\n }\n\n // Token usage — supports both naming conventions (chat: prompt_tokens/completion_tokens, responses: input_tokens/output_tokens)\n if (response.usage && typeof response.usage === 'object') {\n const usage = response.usage as Record<string, unknown>;\n\n const inputTokens = usage.prompt_tokens ?? usage.input_tokens;\n if (typeof inputTokens === 'number') {\n attrs[GEN_AI_USAGE_INPUT_TOKENS_ATTRIBUTE] = inputTokens;\n }\n\n const outputTokens = usage.completion_tokens ?? usage.output_tokens;\n if (typeof outputTokens === 'number') {\n attrs[GEN_AI_USAGE_OUTPUT_TOKENS_ATTRIBUTE] = outputTokens;\n }\n\n if (typeof usage.total_tokens === 'number') {\n attrs[GEN_AI_USAGE_TOTAL_TOKENS_ATTRIBUTE] = usage.total_tokens;\n }\n }\n\n // Finish reasons from choices (chat completions)\n if (Array.isArray(response.choices)) {\n const choices = response.choices as Array<Record<string, unknown>>;\n const finishReasons = choices\n .map(choice => choice.finish_reason)\n .filter((reason): reason is string => typeof reason === 'string');\n if (finishReasons.length > 0) {\n attrs[GEN_AI_RESPONSE_FINISH_REASONS_ATTRIBUTE] = JSON.stringify(finishReasons);\n }\n\n if (recordOutputs) {\n // Response text from choices\n const responseTexts = choices.map(choice => {\n const message = choice.message as Record<string, unknown> | undefined;\n return (message?.content as string) || '';\n });\n attrs[GEN_AI_RESPONSE_TEXT_ATTRIBUTE] = JSON.stringify(responseTexts);\n\n // Tool calls from choices\n const toolCalls = choices\n .map(choice => {\n const message = choice.message as Record<string, unknown> | undefined;\n return message?.tool_calls;\n })\n .filter(calls => Array.isArray(calls) && calls.length > 0)\n .flat();\n\n if (toolCalls.length > 0) {\n attrs[GEN_AI_RESPONSE_TOOL_CALLS_ATTRIBUTE] = JSON.stringify(toolCalls);\n }\n }\n }\n\n // Finish reason from status (responses API)\n if (typeof response.status === 'string') {\n // Only set if not already set from choices\n if (!attrs[GEN_AI_RESPONSE_FINISH_REASONS_ATTRIBUTE]) {\n attrs[GEN_AI_RESPONSE_FINISH_REASONS_ATTRIBUTE] = JSON.stringify([response.status]);\n }\n }\n\n if (recordOutputs) {\n // Response text from output_text (responses API)\n if (typeof response.output_text === 'string' && !attrs[GEN_AI_RESPONSE_TEXT_ATTRIBUTE]) {\n attrs[GEN_AI_RESPONSE_TEXT_ATTRIBUTE] = response.output_text;\n }\n\n // Tool calls from output array (responses API)\n if (Array.isArray(response.output) && response.output.length > 0 && !attrs[GEN_AI_RESPONSE_TOOL_CALLS_ATTRIBUTE]) {\n const functionCalls = (response.output as Array<Record<string, unknown>>).filter(\n item => item?.type === 'function_call',\n );\n if (functionCalls.length > 0) {\n attrs[GEN_AI_RESPONSE_TOOL_CALLS_ATTRIBUTE] = JSON.stringify(functionCalls);\n }\n }\n }\n\n span.setAttributes(attrs);\n}\n\n/**\n * Extract conversation ID from request parameters\n * Supports both Conversations API and previous_response_id chaining\n * @see https://platform.openai.com/docs/guides/conversation-state\n */\nfunction extractConversationId(params: Record<string, unknown>): string | undefined {\n // Conversations API: conversation parameter (e.g., \"conv_...\")\n if ('conversation' in params && typeof params.conversation === 'string') {\n return params.conversation;\n }\n // Responses chaining: previous_response_id links to parent response\n if ('previous_response_id' in params && typeof params.previous_response_id === 'string') {\n return params.previous_response_id;\n }\n return undefined;\n}\n\n/**\n * Extract request parameters including model settings and conversation context\n */\nexport function extractRequestParameters(params: Record<string, unknown>): Record<string, unknown> {\n const attributes: Record<string, unknown> = {\n [GEN_AI_REQUEST_MODEL_ATTRIBUTE]: params.model ?? 'unknown',\n };\n\n if ('temperature' in params) attributes[GEN_AI_REQUEST_TEMPERATURE_ATTRIBUTE] = params.temperature;\n if ('top_p' in params) attributes[GEN_AI_REQUEST_TOP_P_ATTRIBUTE] = params.top_p;\n if ('frequency_penalty' in params) attributes[GEN_AI_REQUEST_FREQUENCY_PENALTY_ATTRIBUTE] = params.frequency_penalty;\n if ('presence_penalty' in params) attributes[GEN_AI_REQUEST_PRESENCE_PENALTY_ATTRIBUTE] = params.presence_penalty;\n if ('stream' in params) attributes[GEN_AI_REQUEST_STREAM_ATTRIBUTE] = params.stream;\n if ('encoding_format' in params) attributes[GEN_AI_REQUEST_ENCODING_FORMAT_ATTRIBUTE] = params.encoding_format;\n if ('dimensions' in params) attributes[GEN_AI_REQUEST_DIMENSIONS_ATTRIBUTE] = params.dimensions;\n\n // Capture conversation ID for linking messages across API calls\n const conversationId = extractConversationId(params);\n if (conversationId) {\n attributes[GEN_AI_CONVERSATION_ID_ATTRIBUTE] = conversationId;\n }\n\n return attributes;\n}\n"],"names":[],"mappings":"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"}
|
|
@@ -6,9 +6,16 @@ import { TRACE_FLAG_NONE } from '../utils/spanUtils.js';
|
|
|
6
6
|
*/
|
|
7
7
|
class SentryNonRecordingSpan {
|
|
8
8
|
|
|
9
|
+
/**
|
|
10
|
+
* Reason why this span was dropped, if applicable ('ignored' or 'sample_rate').
|
|
11
|
+
* Used to propagate the correct client report outcome to descendant spans
|
|
12
|
+
* when span streaming is enabled.
|
|
13
|
+
*/
|
|
14
|
+
|
|
9
15
|
constructor(spanContext = {}) {
|
|
10
16
|
this._traceId = spanContext.traceId || generateTraceId();
|
|
11
17
|
this._spanId = spanContext.spanId || generateSpanId();
|
|
18
|
+
this.dropReason = spanContext.dropReason;
|
|
12
19
|
}
|
|
13
20
|
|
|
14
21
|
/** @inheritdoc */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sentryNonRecordingSpan.js","sources":["../../../src/tracing/sentryNonRecordingSpan.ts"],"sourcesContent":["import type {\n SentrySpanArguments,\n Span,\n SpanAttributes,\n SpanAttributeValue,\n SpanContextData,\n SpanTimeInput,\n} from '../types-hoist/span';\nimport type { SpanStatus } from '../types-hoist/spanStatus';\nimport { generateSpanId, generateTraceId } from '../utils/propagationContext';\nimport { TRACE_FLAG_NONE } from '../utils/spanUtils';\n\n/**\n * A Sentry Span that is non-recording, meaning it will not be sent to Sentry.\n */\nexport class SentryNonRecordingSpan implements Span {\n private _traceId: string;\n private _spanId: string;\n\n public constructor(spanContext:
|
|
1
|
+
{"version":3,"file":"sentryNonRecordingSpan.js","sources":["../../../src/tracing/sentryNonRecordingSpan.ts"],"sourcesContent":["import type { EventDropReason } from '../types-hoist/clientreport';\nimport type {\n SentrySpanArguments,\n Span,\n SpanAttributes,\n SpanAttributeValue,\n SpanContextData,\n SpanTimeInput,\n} from '../types-hoist/span';\nimport type { SpanStatus } from '../types-hoist/spanStatus';\nimport { generateSpanId, generateTraceId } from '../utils/propagationContext';\nimport { TRACE_FLAG_NONE } from '../utils/spanUtils';\n\ninterface SentryNonRecordingSpanArguments extends SentrySpanArguments {\n dropReason?: EventDropReason;\n}\n\n/**\n * A Sentry Span that is non-recording, meaning it will not be sent to Sentry.\n */\nexport class SentryNonRecordingSpan implements Span {\n private _traceId: string;\n private _spanId: string;\n\n /**\n * Reason why this span was dropped, if applicable ('ignored' or 'sample_rate').\n * Used to propagate the correct client report outcome to descendant spans\n * when span streaming is enabled.\n */\n public dropReason?: EventDropReason;\n\n public constructor(spanContext: SentryNonRecordingSpanArguments = {}) {\n this._traceId = spanContext.traceId || generateTraceId();\n this._spanId = spanContext.spanId || generateSpanId();\n this.dropReason = spanContext.dropReason;\n }\n\n /** @inheritdoc */\n public spanContext(): SpanContextData {\n return {\n spanId: this._spanId,\n traceId: this._traceId,\n traceFlags: TRACE_FLAG_NONE,\n };\n }\n\n /** @inheritdoc */\n public end(_timestamp?: SpanTimeInput): void {}\n\n /** @inheritdoc */\n public setAttribute(_key: string, _value: SpanAttributeValue | undefined): this {\n return this;\n }\n\n /** @inheritdoc */\n public setAttributes(_values: SpanAttributes): this {\n return this;\n }\n\n /** @inheritdoc */\n public setStatus(_status: SpanStatus): this {\n return this;\n }\n\n /** @inheritdoc */\n public updateName(_name: string): this {\n return this;\n }\n\n /** @inheritdoc */\n public isRecording(): boolean {\n return false;\n }\n\n /** @inheritdoc */\n public addEvent(\n _name: string,\n _attributesOrStartTime?: SpanAttributes | SpanTimeInput,\n _startTime?: SpanTimeInput,\n ): this {\n return this;\n }\n\n /** @inheritDoc */\n public addLink(_link: unknown): this {\n return this;\n }\n\n /** @inheritDoc */\n public addLinks(_links: unknown[]): this {\n return this;\n }\n\n /**\n * This should generally not be used,\n * but we need it for being compliant with the OTEL Span interface.\n *\n * @hidden\n * @internal\n */\n public recordException(_exception: unknown, _time?: number | undefined): void {\n // noop\n }\n}\n"],"names":[],"mappings":";;;AAiBA;AACA;AACA;AACO,MAAM,wBAAuC;;AAIpD;AACA;AACA;AACA;AACA;;AAGA,GAAS,WAAW,CAAC,WAAW,GAAoC,EAAE,EAAE;AACxE,IAAI,IAAI,CAAC,QAAA,GAAW,WAAW,CAAC,OAAA,IAAW,eAAe,EAAE;AAC5D,IAAI,IAAI,CAAC,OAAA,GAAU,WAAW,CAAC,MAAA,IAAU,cAAc,EAAE;AACzD,IAAI,IAAI,CAAC,UAAA,GAAa,WAAW,CAAC,UAAU;AAC5C,EAAE;;AAEF;AACA,GAAS,WAAW,GAAoB;AACxC,IAAI,OAAO;AACX,MAAM,MAAM,EAAE,IAAI,CAAC,OAAO;AAC1B,MAAM,OAAO,EAAE,IAAI,CAAC,QAAQ;AAC5B,MAAM,UAAU,EAAE,eAAe;AACjC,KAAK;AACL,EAAE;;AAEF;AACA,GAAS,GAAG,CAAC,UAAU,EAAwB,CAAC;;AAEhD;AACA,GAAS,YAAY,CAAC,IAAI,EAAU,MAAM,EAAwC;AAClF,IAAI,OAAO,IAAI;AACf,EAAE;;AAEF;AACA,GAAS,aAAa,CAAC,OAAO,EAAwB;AACtD,IAAI,OAAO,IAAI;AACf,EAAE;;AAEF;AACA,GAAS,SAAS,CAAC,OAAO,EAAoB;AAC9C,IAAI,OAAO,IAAI;AACf,EAAE;;AAEF;AACA,GAAS,UAAU,CAAC,KAAK,EAAgB;AACzC,IAAI,OAAO,IAAI;AACf,EAAE;;AAEF;AACA,GAAS,WAAW,GAAY;AAChC,IAAI,OAAO,KAAK;AAChB,EAAE;;AAEF;AACA,GAAS,QAAQ;AACjB,IAAI,KAAK;AACT,IAAI,sBAAsB;AAC1B,IAAI,UAAU;AACd,IAAU;AACV,IAAI,OAAO,IAAI;AACf,EAAE;;AAEF;AACA,GAAS,OAAO,CAAC,KAAK,EAAiB;AACvC,IAAI,OAAO,IAAI;AACf,EAAE;;AAEF;AACA,GAAS,QAAQ,CAAC,MAAM,EAAmB;AAC3C,IAAI,OAAO,IAAI;AACf,EAAE;;AAEF;AACA;AACA;AACA;AACA;AACA;AACA;AACA,GAAS,eAAe,CAAC,UAAU,EAAW,KAAK,EAA6B;AAChF;AACA,EAAE;AACF;;;;"}
|
|
@@ -4,13 +4,16 @@ import { createSpanEnvelope } from '../envelope.js';
|
|
|
4
4
|
import { SEMANTIC_ATTRIBUTE_SENTRY_OP, SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, SEMANTIC_ATTRIBUTE_SENTRY_SOURCE, SEMANTIC_ATTRIBUTE_EXCLUSIVE_TIME, SEMANTIC_ATTRIBUTE_PROFILE_ID, SEMANTIC_ATTRIBUTE_SENTRY_CUSTOM_SPAN_NAME } from '../semanticAttributes.js';
|
|
5
5
|
import { debug } from '../utils/debug-logger.js';
|
|
6
6
|
import { generateTraceId, generateSpanId } from '../utils/propagationContext.js';
|
|
7
|
-
import { TRACE_FLAG_SAMPLED, TRACE_FLAG_NONE, spanTimeInputToSeconds, convertSpanLinksForEnvelope, getRootSpan, getStatusMessage, spanToJSON, getSpanDescendants, spanToTransactionTraceContext } from '../utils/spanUtils.js';
|
|
7
|
+
import { TRACE_FLAG_SAMPLED, TRACE_FLAG_NONE, spanTimeInputToSeconds, convertSpanLinksForEnvelope, getRootSpan, getStatusMessage, getStreamedSpanLinks, getSimpleStatusMessage, spanToJSON, getSpanDescendants, spanToTransactionTraceContext } from '../utils/spanUtils.js';
|
|
8
8
|
import { timestampInSeconds } from '../utils/time.js';
|
|
9
9
|
import { getDynamicSamplingContextFromSpan } from './dynamicSamplingContext.js';
|
|
10
10
|
import { logSpanEnd } from './logSpans.js';
|
|
11
11
|
import { timedEventsToMeasurements } from './measurement.js';
|
|
12
|
+
import { hasSpanStreamingEnabled } from './spans/hasSpanStreamingEnabled.js';
|
|
12
13
|
import { getCapturedScopesOnSpan } from './utils.js';
|
|
13
14
|
|
|
15
|
+
/* eslint-disable max-lines */
|
|
16
|
+
|
|
14
17
|
const MAX_SPAN_COUNT = 1000;
|
|
15
18
|
|
|
16
19
|
/**
|
|
@@ -201,6 +204,30 @@ class SentrySpan {
|
|
|
201
204
|
};
|
|
202
205
|
}
|
|
203
206
|
|
|
207
|
+
/**
|
|
208
|
+
* Get {@link StreamedSpanJSON} representation of this span.
|
|
209
|
+
*
|
|
210
|
+
* @hidden
|
|
211
|
+
* @internal This method is purely for internal purposes and should not be used outside
|
|
212
|
+
* of SDK code. If you need to get a JSON representation of a span,
|
|
213
|
+
* use `spanToStreamedSpanJSON(span)` instead.
|
|
214
|
+
*/
|
|
215
|
+
getStreamedSpanJSON() {
|
|
216
|
+
return {
|
|
217
|
+
name: this._name ?? '',
|
|
218
|
+
span_id: this._spanId,
|
|
219
|
+
trace_id: this._traceId,
|
|
220
|
+
parent_span_id: this._parentSpanId,
|
|
221
|
+
start_timestamp: this._startTime,
|
|
222
|
+
// just in case _endTime is not set, we use the start time (i.e. duration 0)
|
|
223
|
+
end_timestamp: this._endTime ?? this._startTime,
|
|
224
|
+
is_segment: this._isStandaloneSpan || this === getRootSpan(this),
|
|
225
|
+
status: getSimpleStatusMessage(this._status),
|
|
226
|
+
attributes: this._attributes,
|
|
227
|
+
links: getStreamedSpanLinks(this._links),
|
|
228
|
+
};
|
|
229
|
+
}
|
|
230
|
+
|
|
204
231
|
/** @inheritdoc */
|
|
205
232
|
isRecording() {
|
|
206
233
|
return !this._endTime && !!this._sampled;
|
|
@@ -247,6 +274,14 @@ class SentrySpan {
|
|
|
247
274
|
const client = getClient();
|
|
248
275
|
if (client) {
|
|
249
276
|
client.emit('spanEnd', this);
|
|
277
|
+
// Guarding sending standalone v1 spans as v2 streamed spans for now.
|
|
278
|
+
// Otherwise they'd be sent once as v1 spans and again as streamed spans.
|
|
279
|
+
// We'll migrate CLS and LCP spans to streamed spans in a later PR and
|
|
280
|
+
// INP spans in the next major of the SDK. At that point, we can fully remove
|
|
281
|
+
// standalone v1 spans <3
|
|
282
|
+
if (!this._isStandaloneSpan) {
|
|
283
|
+
client.emit('afterSpanEnd', this);
|
|
284
|
+
}
|
|
250
285
|
}
|
|
251
286
|
|
|
252
287
|
// A segment span is basically the root span of a local span tree.
|
|
@@ -270,6 +305,10 @@ class SentrySpan {
|
|
|
270
305
|
}
|
|
271
306
|
}
|
|
272
307
|
return;
|
|
308
|
+
} else if (client && hasSpanStreamingEnabled(client)) {
|
|
309
|
+
// TODO (spans): Remove standalone span custom logic in favor of sending simple v2 web vital spans
|
|
310
|
+
client.emit('afterSegmentSpanEnd', this);
|
|
311
|
+
return;
|
|
273
312
|
}
|
|
274
313
|
|
|
275
314
|
const transactionEvent = this._convertSpanToTransaction();
|