Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 4 additions & 19 deletions lib/agent.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@

'use strict'

const determineSampler = require('./samplers/determine-sampler')
const CollectorAPI = require('./collector/api')
const ServerlessCollector = require('./collector/serverless')
const DESTINATIONS = require('./config/attribute-filter').DESTINATIONS
Expand Down Expand Up @@ -41,6 +40,7 @@ const synthetics = require('./synthetics')
const Harvester = require('./harvester')
const { createFeatureUsageMetrics } = require('./util/application-logging')
const HealthReporter = require('./health-reporter')
const Samplers = require('./samplers')

// Map of valid states to whether or not data collection is valid
const STATES = {
Expand Down Expand Up @@ -288,15 +288,7 @@ function Agent(config) {
this.harvester
)

// Instantiate sampling decisions.
this.sampler = {}
// This is the global adaptive sampler instance used across
// different sampling modes and not intended to be used directly.
this.sampler._globalAdaptiveSampler = null
// The samplers to use for a particular sampler mode.
this.sampler.root = determineSampler({ agent: this, config, sampler: 'root' })
this.sampler.remoteParentSampled = determineSampler({ agent: this, config, sampler: 'remote_parent_sampled' })
this.sampler.remoteParentNotSampled = determineSampler({ agent: this, config, sampler: 'remote_parent_not_sampled' })
this.samplers = new Samplers(this)

this.queries = new QueryTraceAggregator(
{
Expand Down Expand Up @@ -852,17 +844,10 @@ Agent.prototype._listenForConfigChanges = function _listenForConfigChanges() {
self.txSegmentNormalizer.load.apply(self.txSegmentNormalizer, arguments)
})
this.config.on('sampling_target', function updateSamplingTarget(target) {
// Remember config.sampling_target is an alias for
// config.distributed_tracing.sampler.adaptive_sampling_target,
// which is the sampling target for the global adaptive sampler.
if (self.sampler._globalAdaptiveSampler) {
self.sampler._globalAdaptiveSampler.samplingTarget = target
}
self.samplers.updateAdaptiveTarget(target)
})
this.config.on('sampling_target_period_in_seconds', function updateSamplePeriod(period) {
if (self.sampler._globalAdaptiveSampler) {
self.sampler._globalAdaptiveSampler.samplingPeriod = period * 1000
}
self.samplers.updateAdaptivePeriod(period)
})
this.config.on('event_harvest_config', function onHarvestConfigReceived(harvestConfig) {
if (harvestConfig) {
Expand Down
15 changes: 8 additions & 7 deletions lib/samplers/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -64,14 +64,15 @@ distributed_tracing:

There are two sampler modes, each with three sampler sections, resulting in potentially six different sampling decisions that the agent would have to support. We create a new `Sampler` instance (`AdaptiveSampler`, `AlwaysOnSampler`, `AlwaysOffSampler`, or `TraceIdRatioBasedSampler`, defined in this folder) for each of these sampler modes' sections.

`agent.sampler` is defined as:
`agent.samplers` is defined as:

* `agent.sampler.root`
* `agent.sampler.remoteParentSampled`
* `agent.sampler.remoteParentNotSampled`
* `agent.sampler.partialGranularity.root`
* `agent.sampler.partialGranularity.remoteParentSampled`
* `agent.sampler.partialGranularity.remoteParentNotSampled`
* `agent.samplers.root`
* `agent.samplers.remoteParentSampled`
* `agent.samplers.remoteParentNotSampled`
* `agent.samplers.partialRoot`
* `agent.samplers.partialRemoteParentSampled`
* `agent.samplers.partialRemoteParentNotSampled`
* `agent.samplers.adaptiveSampler` (if needed, see below)

These samplers have a `applySamplingDecision({transaction})` function, which `Transaction` calls (in `lib/transaction/index.js`) to update its `sampled` field and therefore its `priority`.

Expand Down
6 changes: 4 additions & 2 deletions lib/samplers/adaptive-sampler.js
Original file line number Diff line number Diff line change
Expand Up @@ -109,8 +109,9 @@ class AdaptiveSampler extends Sampler {
return false
}

applySamplingDecision({ transaction, tracestate = null }) {
applySamplingDecision({ transaction, tracestate, isFullTrace }) {
if (!transaction) return
transaction.isPartialTrace = !isFullTrace
if (tracestate) {
// Explicitly set sampled and priority from tracestate intrinsics if available
transaction.sampled = tracestate?.intrinsics ? tracestate.isSampled : null
Expand All @@ -122,7 +123,8 @@ class AdaptiveSampler extends Sampler {
// eslint-disable-next-line sonarjs/pseudo-random
const initPriority = Math.random()
transaction.sampled = this.shouldSample(initPriority)
transaction.priority = transaction.sampled ? initPriority + 1 : initPriority
// only add 1 to priority when doing a full trace
transaction.priority = transaction.sampled && isFullTrace ? initPriority + 1 : initPriority
// Truncate the priority after potentially modifying it to avoid floating
// point errors.
transaction.priority = ((transaction.priority * 1e6) | 0) / 1e6
Expand Down
4 changes: 2 additions & 2 deletions lib/samplers/always-off-sampler.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,12 @@
* Copyright 2025 New Relic Corporation. All rights reserved.
* SPDX-License-Identifier: Apache-2.0
*/

const Sampler = require('./sampler')

class AlwaysOffSampler extends Sampler {
applySamplingDecision({ transaction }) {
applySamplingDecision({ transaction, isFullTrace }) {
if (!transaction) return
transaction.isPartialTrace = !isFullTrace
transaction.priority = 0
transaction.sampled = false
}
Expand Down
3 changes: 2 additions & 1 deletion lib/samplers/always-on-sampler.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,9 @@
const Sampler = require('./sampler')

class AlwaysOnSampler extends Sampler {
applySamplingDecision({ transaction }) {
applySamplingDecision({ transaction, isFullTrace }) {
if (!transaction) return
transaction.isPartialTrace = !isFullTrace
transaction.priority = 2.0
transaction.sampled = true
}
Expand Down
73 changes: 0 additions & 73 deletions lib/samplers/determine-sampler.js

This file was deleted.

Loading
Loading