@@ -1028,32 +1028,11 @@ function acceptTraceContextPayload(traceparentHeader, tracestateHeader, transpor
10281028 }
10291029 }
10301030
1031- decideSamplingFromW3cData ( { transaction : this , traceparent, tracestate } )
1032- }
1033-
1034- /**
1035- * Updates the transaction with sampling configuration as determined by the
1036- * agent's distributed tracing sampler configuration. In short, updates the
1037- * transaction to always sample, never sample, or let the standard sampling
1038- * algorithm make the decision.
1039- *
1040- * @param {object } params Input parameters.
1041- * @param {Transaction } params.transaction The transaction to update.
1042- * @param {Traceparent } params.traceparent The object representation of a
1043- * traceparent header.
1044- * @param {Tracestate } params.tracestate The object representation of a
1045- * tracestate header.
1046- */
1047- function decideSamplingFromW3cData ( { transaction, traceparent, tracestate } ) {
1048- const agent = transaction . agent
1049- const {
1050- remote_parent_sampled : parentSampled ,
1051- remote_parent_not_sampled : parentNotSampled
1052- } = agent . config . distributed_tracing . sampler
1031+ // Decide sampling from w3c data
10531032 if ( traceparent . isSampled === true ) {
1054- applySamplingStrategy ( { transaction, tracestate, sampler : agent . remoteParentSampledSampler , samplerType : parentSampled } )
1033+ applySamplingStrategy ( { transaction : this , tracestate, sampler : this . agent . remoteParentSampledSampler } )
10551034 } else if ( traceparent . isSampled === false ) {
1056- applySamplingStrategy ( { transaction, tracestate, sampler : agent . remoteParentNotSampledSampler , samplerType : parentNotSampled } )
1035+ applySamplingStrategy ( { transaction : this , tracestate, sampler : this . agent . remoteParentNotSampledSampler } )
10571036 }
10581037}
10591038
@@ -1063,51 +1042,22 @@ function decideSamplingFromW3cData({ transaction, traceparent, tracestate }) {
10631042 *
10641043 * @param {* } params Function parameters.
10651044 * @param {Transaction } params.transaction The transaction to update.
1066- * @param {Tracestate } params.tracestate A tracestate object with embedded New Relic intrinsics.
1067- * @param {object } params.sampler The sampler to use, AdaptiveSampler or TraceIdRatioBasedSampler.
1068- * @param {string|object } params.samplerType A string describing the sampler being used
1069- * ('default', 'always_on', 'always_off'), or an object if 'trace_id_ratio_based'.
1045+ * @param {Tracestate } [params.tracestate] A tracestate object with embedded New Relic intrinsics.
1046+ * @param {object } params.sampler The sampler to use, e.g. AdaptiveSampler or TraceIdRatioBasedSampler.
10701047 */
1071- function applySamplingStrategy ( { transaction, tracestate, sampler, samplerType } ) {
1072- if ( sampler ?. toString ( ) === 'TraceIdRatioBasedSampler' ) {
1073- transaction . sampled = sampler . shouldSample ( transaction . traceId )
1074- // Force calc priority because transaction.sampled likekly has changed
1075- // eslint-disable-next-line sonarjs/pseudo-random
1076- transaction . priority = Math . random ( )
1077- if ( transaction . sampled ) {
1078- transaction . priority += 1
1079- }
1080-
1081- // Truncate the priority after potentially modifying it to avoid floating
1082- // point errors.
1083- transaction . priority = ( ( transaction . priority * 1e6 ) | 0 ) / 1e6
1084- }
1085-
1086- // TODO: Make these their own samplers?
1087- switch ( samplerType ) {
1088- case 'default' : {
1089- // This case is if we're coming from the deprecated newrelic header logic
1090- // where we don't want to override the sampled and priority values
1091- if ( ! tracestate ) {
1092- return
1093- }
1094-
1095- transaction . sampled = tracestate ?. intrinsics ? tracestate . isSampled : null
1096- transaction . priority = tracestate ?. intrinsics ? tracestate . priority : null
1097- break
1098- }
1099-
1100- case 'always_on' : {
1101- transaction . sampled = true
1102- transaction . priority = 2.0
1103- break
1048+ function applySamplingStrategy ( { transaction, tracestate = null , sampler } ) {
1049+ if ( sampler ?. toString ( ) !== 'AdaptiveSampler' ) {
1050+ sampler . applySamplingDecision ( transaction )
1051+ } else {
1052+ // This case is if we're coming from the deprecated newrelic header logic
1053+ // and we don't want to override the sampled and priority values
1054+ if ( ! tracestate ) {
1055+ return
11041056 }
11051057
1106- case 'always_off' : {
1107- transaction . sampled = false
1108- transaction . priority = 0
1109- break
1110- }
1058+ // Explicitly set sampled and priority from tracestate intrinsics if available
1059+ transaction . sampled = tracestate ?. intrinsics ? tracestate . isSampled : null
1060+ transaction . priority = tracestate ?. intrinsics ? tracestate . priority : null
11111061 }
11121062}
11131063
@@ -1209,19 +1159,15 @@ const _dtDefineAttrsFromTraceData = function _dtDefineAttrsFromTraceData(data, t
12091159 this . traceId = data . tr
12101160
12111161 if ( data . pr ) {
1212- // TODO: We need to consider the sampler before blindly accepting this value.
12131162 this . priority = data . pr
12141163 this . sampled = data . sa != null ? data . sa : this . sampled
1215- // we don't have traceparent or tracestate, but this will update
1216- // sampling decision based on our samplers
1217- const {
1218- remote_parent_sampled : parentSampled ,
1219- remote_parent_not_sampled : parentNotSampled
1220- } = this . agent . config . distributed_tracing . sampler
1164+ // Even though New Relic headers are deprecated,
1165+ // we still have to apply our sampling decision on top
1166+ // of the priority and sampled values we receive.
12211167 if ( data ?. sa ) {
1222- applySamplingStrategy ( { transaction : this , sampler : this . agent . remoteParentSampledSampler , samplerType : parentSampled } )
1168+ applySamplingStrategy ( { transaction : this , sampler : this . agent . remoteParentSampledSampler } )
12231169 } else {
1224- applySamplingStrategy ( { transaction : this , sampler : this . agent . remoteParentNotSampledSampler , samplerType : parentNotSampled } )
1170+ applySamplingStrategy ( { transaction : this , sampler : this . agent . remoteParentNotSampledSampler } )
12251171 }
12261172 }
12271173
@@ -1430,48 +1376,15 @@ Transaction.prototype.isSampled = function isSampled() {
14301376}
14311377
14321378/**
1433- * Generates a priority for the transaction if it does not have one already.
1434- * @param {object } sampler The sampler to calculate priority with. Defaults to `this.agent.transactionSampler`.
1379+ * If `priority` does not exist on this transaction already,
1380+ * this.agent.transactionSampler will apply a sampling decision
1381+ * to the transaction, which assigns `priority` and updates `sampled`
1382+ * in respect to this sampling decision.
14351383 */
1436- Transaction . prototype . _calculatePriority = function _calculatePriority ( sampler ) {
1437- if ( ! sampler ) {
1438- sampler = this . agent . transactionSampler
1439- }
1384+ Transaction . prototype . _calculatePriority = function _calculatePriority ( ) {
14401385 if ( this . priority === null ) {
1441- // eslint-disable-next-line sonarjs/pseudo-random
1442- this . priority = Math . random ( )
1443-
1444- // Determine sampling parameter based on type of sampler being used
1445- const shouldSampleParam = sampler . toString ( ) === 'TraceIdRatioBasedSampler'
1446- ? this . traceId
1447- // We want to separate the priority roll from the decision roll to
1448- // avoid biasing the priority range
1449- // eslint-disable-next-line sonarjs/pseudo-random
1450- : Math . random ( )
1451- this . sampled = sampler . shouldSample ( shouldSampleParam )
1452- if ( this . sampled ) {
1453- this . priority += 1
1454- }
1455-
1456- // Truncate the priority after potentially modifying it to avoid floating
1457- // point errors.
1458- this . priority = ( ( this . priority * 1e6 ) | 0 ) / 1e6
1459-
1460- // IGNORE THIS
1461- if ( sampler === this . agent . transactionSampler ) {
1462- const samplerType = this . agent . config . distributed_tracing . sampler . root
1463-
1464- // TODO: have to account if there's no headers
1465- if ( samplerType === 'always_on' ) {
1466- this . sampled = true
1467- this . priority = 2.0
1468- }
1469-
1470- if ( samplerType === 'always_off' ) {
1471- this . sampled = false
1472- this . priority = 0
1473- }
1474- }
1386+ const sampler = this . agent . transactionSampler
1387+ sampler . applySamplingDecision ( this )
14751388 }
14761389}
14771390
0 commit comments