UNPKG

@sentry/core

Version:
82 lines (79 loc) 3.91 kB
import { DEFAULT_ENVIRONMENT } from '../constants.js'; import { getClient } from '../currentScopes.js'; import { SEMANTIC_ATTRIBUTE_SENTRY_SAMPLE_RATE, SEMANTIC_ATTRIBUTE_SENTRY_PREVIOUS_TRACE_SAMPLE_RATE, SEMANTIC_ATTRIBUTE_SENTRY_SOURCE } from '../semanticAttributes.js'; import { baggageHeaderToDynamicSamplingContext, dynamicSamplingContextToSentryBaggageHeader } from '../utils/baggage.js'; import { extractOrgIdFromClient } from '../utils/dsn.js'; import { hasSpansEnabled } from '../utils/hasSpansEnabled.js'; import { addNonEnumerableProperty } from '../utils/object.js'; import { getRootSpan, spanToJSON, spanIsSampled } from '../utils/spanUtils.js'; import { getCapturedScopesOnSpan } from './utils.js'; const FROZEN_DSC_FIELD = "_frozenDsc"; function freezeDscOnSpan(span, dsc) { const spanWithMaybeDsc = span; addNonEnumerableProperty(spanWithMaybeDsc, FROZEN_DSC_FIELD, dsc); } function getDynamicSamplingContextFromClient(trace_id, client) { const options = client.getOptions(); const { publicKey: public_key } = client.getDsn() || {}; const dsc = { environment: options.environment || DEFAULT_ENVIRONMENT, release: options.release, public_key, trace_id, org_id: extractOrgIdFromClient(client) }; client.emit("createDsc", dsc); return dsc; } function getDynamicSamplingContextFromScope(client, scope) { const propagationContext = scope.getPropagationContext(); return propagationContext.dsc || getDynamicSamplingContextFromClient(propagationContext.traceId, client); } function getDynamicSamplingContextFromSpan(span) { const client = getClient(); if (!client) { return {}; } const rootSpan = getRootSpan(span); const rootSpanJson = spanToJSON(rootSpan); const rootSpanAttributes = rootSpanJson.data; const traceState = rootSpan.spanContext().traceState; const rootSpanSampleRate = traceState?.get("sentry.sample_rate") ?? rootSpanAttributes[SEMANTIC_ATTRIBUTE_SENTRY_SAMPLE_RATE] ?? rootSpanAttributes[SEMANTIC_ATTRIBUTE_SENTRY_PREVIOUS_TRACE_SAMPLE_RATE]; function applyLocalSampleRateToDsc(dsc2) { if (typeof rootSpanSampleRate === "number" || typeof rootSpanSampleRate === "string") { dsc2.sample_rate = `${rootSpanSampleRate}`; } return dsc2; } const frozenDsc = rootSpan[FROZEN_DSC_FIELD]; if (frozenDsc) { return applyLocalSampleRateToDsc(frozenDsc); } const traceStateDsc = traceState?.get("sentry.dsc"); const dscOnTraceState = traceStateDsc && baggageHeaderToDynamicSamplingContext(traceStateDsc); if (dscOnTraceState) { return applyLocalSampleRateToDsc(dscOnTraceState); } const dsc = getDynamicSamplingContextFromClient(span.spanContext().traceId, client); const source = rootSpanAttributes[SEMANTIC_ATTRIBUTE_SENTRY_SOURCE] ?? rootSpanAttributes["sentry.span.source"]; const name = rootSpanJson.description; if (source !== "url" && name) { dsc.transaction = name; } if (hasSpansEnabled()) { dsc.sampled = String(spanIsSampled(rootSpan)); dsc.sample_rand = // In OTEL we store the sample rand on the trace state because we cannot access scopes for NonRecordingSpans // The Sentry OTEL SpanSampler takes care of writing the sample rand on the root span traceState?.get("sentry.sample_rand") ?? // On all other platforms we can actually get the scopes from a root span (we use this as a fallback) getCapturedScopesOnSpan(rootSpan).scope?.getPropagationContext().sampleRand.toString(); } applyLocalSampleRateToDsc(dsc); client.emit("createDsc", dsc, rootSpan); return dsc; } function spanToBaggageHeader(span) { const dsc = getDynamicSamplingContextFromSpan(span); return dynamicSamplingContextToSentryBaggageHeader(dsc); } export { freezeDscOnSpan, getDynamicSamplingContextFromClient, getDynamicSamplingContextFromScope, getDynamicSamplingContextFromSpan, spanToBaggageHeader }; //# sourceMappingURL=dynamicSamplingContext.js.map