package.build.cjs.tracing.dynamicSamplingContext.js Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of core Show documentation
Show all versions of core Show documentation
Base implementation for all Sentry JavaScript SDKs
Object.defineProperty(exports, '__esModule', { value: true });
const utils = require('@sentry/utils');
const constants = require('../constants.js');
const currentScopes = require('../currentScopes.js');
const semanticAttributes = require('../semanticAttributes.js');
const hasTracingEnabled = require('../utils/hasTracingEnabled.js');
const spanUtils = require('../utils/spanUtils.js');
/**
* If you change this value, also update the terser plugin config to
* avoid minification of the object property!
*/
const FROZEN_DSC_FIELD = '_frozenDsc';
/**
* Freeze the given DSC on the given span.
*/
function freezeDscOnSpan(span, dsc) {
const spanWithMaybeDsc = span ;
utils.addNonEnumerableProperty(spanWithMaybeDsc, FROZEN_DSC_FIELD, dsc);
}
/**
* Creates a dynamic sampling context from a client.
*
* Dispatches the `createDsc` lifecycle hook as a side effect.
*/
function getDynamicSamplingContextFromClient(trace_id, client) {
const options = client.getOptions();
const { publicKey: public_key } = client.getDsn() || {};
const dsc = utils.dropUndefinedKeys({
environment: options.environment || constants.DEFAULT_ENVIRONMENT,
release: options.release,
public_key,
trace_id,
}) ;
client.emit('createDsc', dsc);
return dsc;
}
/**
* Creates a dynamic sampling context from a span (and client and scope)
*
* @param span the span from which a few values like the root span name and sample rate are extracted.
*
* @returns a dynamic sampling context
*/
function getDynamicSamplingContextFromSpan(span) {
const client = currentScopes.getClient();
if (!client) {
return {};
}
const dsc = getDynamicSamplingContextFromClient(spanUtils.spanToJSON(span).trace_id || '', client);
const rootSpan = spanUtils.getRootSpan(span);
// For core implementation, we freeze the DSC onto the span as a non-enumerable property
const frozenDsc = (rootSpan )[FROZEN_DSC_FIELD];
if (frozenDsc) {
return frozenDsc;
}
// For OpenTelemetry, we freeze the DSC on the trace state
const traceState = rootSpan.spanContext().traceState;
const traceStateDsc = traceState && traceState.get('sentry.dsc');
// If the span has a DSC, we want it to take precedence
const dscOnTraceState = traceStateDsc && utils.baggageHeaderToDynamicSamplingContext(traceStateDsc);
if (dscOnTraceState) {
return dscOnTraceState;
}
// Else, we generate it from the span
const jsonSpan = spanUtils.spanToJSON(rootSpan);
const attributes = jsonSpan.data || {};
const maybeSampleRate = attributes[semanticAttributes.SEMANTIC_ATTRIBUTE_SENTRY_SAMPLE_RATE];
if (maybeSampleRate != null) {
dsc.sample_rate = `${maybeSampleRate}`;
}
// We don't want to have a transaction name in the DSC if the source is "url" because URLs might contain PII
const source = attributes[semanticAttributes.SEMANTIC_ATTRIBUTE_SENTRY_SOURCE];
// after JSON conversion, txn.name becomes jsonSpan.description
const name = jsonSpan.description;
if (source !== 'url' && name) {
dsc.transaction = name;
}
// How can we even land here with hasTracingEnabled() returning false?
// Otel creates a Non-recording span in Tracing Without Performance mode when handling incoming requests
// So we end up with an active span that is not sampled (neither positively nor negatively)
if (hasTracingEnabled.hasTracingEnabled()) {
dsc.sampled = String(spanUtils.spanIsSampled(rootSpan));
}
client.emit('createDsc', dsc, rootSpan);
return dsc;
}
/**
* Convert a Span to a baggage header.
*/
function spanToBaggageHeader(span) {
const dsc = getDynamicSamplingContextFromSpan(span);
return utils.dynamicSamplingContextToSentryBaggageHeader(dsc);
}
exports.freezeDscOnSpan = freezeDscOnSpan;
exports.getDynamicSamplingContextFromClient = getDynamicSamplingContextFromClient;
exports.getDynamicSamplingContextFromSpan = getDynamicSamplingContextFromSpan;
exports.spanToBaggageHeader = spanToBaggageHeader;
//# sourceMappingURL=dynamicSamplingContext.js.map