UNPKG

@sentry/core

Version:
1 lines 6.8 kB
{"version":3,"file":"tracing.js","sources":["../../../src/utils/tracing.ts"],"sourcesContent":["import type { DynamicSamplingContext } from '../types-hoist/envelope';\nimport type { PropagationContext } from '../types-hoist/tracing';\nimport type { TraceparentData } from '../types-hoist/transaction';\nimport { baggageHeaderToDynamicSamplingContext } from './baggage';\nimport { parseSampleRate } from './parseSampleRate';\nimport { generateSpanId, generateTraceId } from './propagationContext';\n\n// eslint-disable-next-line @sentry-internal/sdk/no-regexp-constructor -- RegExp is used for readability here\nexport const TRACEPARENT_REGEXP = new RegExp(\n '^[ \\\\t]*' + // whitespace\n '([0-9a-f]{32})?' + // trace_id\n '-?([0-9a-f]{16})?' + // span_id\n '-?([01])?' + // sampled\n '[ \\\\t]*$', // whitespace\n);\n\n/**\n * Extract transaction context data from a `sentry-trace` header.\n *\n * @param traceparent Traceparent string\n *\n * @returns Object containing data from the header, or undefined if traceparent string is malformed\n */\nexport function extractTraceparentData(traceparent?: string): TraceparentData | undefined {\n if (!traceparent) {\n return undefined;\n }\n\n const matches = traceparent.match(TRACEPARENT_REGEXP);\n if (!matches) {\n return undefined;\n }\n\n let parentSampled: boolean | undefined;\n if (matches[3] === '1') {\n parentSampled = true;\n } else if (matches[3] === '0') {\n parentSampled = false;\n }\n\n return {\n traceId: matches[1],\n parentSampled,\n parentSpanId: matches[2],\n };\n}\n\n/**\n * Create a propagation context from incoming headers or\n * creates a minimal new one if the headers are undefined.\n */\nexport function propagationContextFromHeaders(\n sentryTrace: string | undefined,\n baggage: string | number | boolean | string[] | null | undefined,\n): PropagationContext {\n const traceparentData = extractTraceparentData(sentryTrace);\n const dynamicSamplingContext = baggageHeaderToDynamicSamplingContext(baggage);\n\n if (!traceparentData?.traceId) {\n return {\n traceId: generateTraceId(),\n sampleRand: Math.random(),\n };\n }\n\n const sampleRand = getSampleRandFromTraceparentAndDsc(traceparentData, dynamicSamplingContext);\n\n // The sample_rand on the DSC needs to be generated based on traceparent + baggage.\n if (dynamicSamplingContext) {\n dynamicSamplingContext.sample_rand = sampleRand.toString();\n }\n\n const { traceId, parentSpanId, parentSampled } = traceparentData;\n\n return {\n traceId,\n parentSpanId,\n sampled: parentSampled,\n dsc: dynamicSamplingContext || {}, // If we have traceparent data but no DSC it means we are not head of trace and we must freeze it\n sampleRand,\n };\n}\n\n/**\n * Create sentry-trace header from span context values.\n */\nexport function generateSentryTraceHeader(\n traceId: string | undefined = generateTraceId(),\n spanId: string | undefined = generateSpanId(),\n sampled?: boolean,\n): string {\n let sampledString = '';\n if (sampled !== undefined) {\n sampledString = sampled ? '-1' : '-0';\n }\n return `${traceId}-${spanId}${sampledString}`;\n}\n\n/**\n * Given any combination of an incoming trace, generate a sample rand based on its defined semantics.\n *\n * Read more: https://develop.sentry.dev/sdk/telemetry/traces/#propagated-random-value\n */\nfunction getSampleRandFromTraceparentAndDsc(\n traceparentData: TraceparentData | undefined,\n dsc: Partial<DynamicSamplingContext> | undefined,\n): number {\n // When there is an incoming sample rand use it.\n const parsedSampleRand = parseSampleRate(dsc?.sample_rand);\n if (parsedSampleRand !== undefined) {\n return parsedSampleRand;\n }\n\n // Otherwise, if there is an incoming sampling decision + sample rate, generate a sample rand that would lead to the same sampling decision.\n const parsedSampleRate = parseSampleRate(dsc?.sample_rate);\n if (parsedSampleRate && traceparentData?.parentSampled !== undefined) {\n return traceparentData.parentSampled\n ? // Returns a sample rand with positive sampling decision [0, sampleRate)\n Math.random() * parsedSampleRate\n : // Returns a sample rand with negative sampling decision [sampleRate, 1)\n parsedSampleRate + Math.random() * (1 - parsedSampleRate);\n } else {\n // If nothing applies, return a random sample rand.\n return Math.random();\n }\n}\n"],"names":["baggage","baggageHeaderToDynamicSamplingContext","generateTraceId","generateSpanId","parseSampleRate"],"mappings":"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"}