class Datadog::PrioritySampler

PrioritySampler

Constants

SAMPLE_RATE_METRIC_KEY

Attributes

pre_sampler[R]
priority_sampler[R]

Public Class Methods

new(opts = {}) click to toggle source
# File lib/ddtrace/sampler.rb, line 200
def initialize(opts = {})
  @pre_sampler = opts[:base_sampler] || AllSampler.new
  @priority_sampler = opts[:post_sampler] || RateByServiceSampler.new
end

Public Instance Methods

sample!(span) click to toggle source
# File lib/ddtrace/sampler.rb, line 209
def sample!(span)
  # If pre-sampling is configured, do it first. (By default, this will sample at 100%.)
  # NOTE: Pre-sampling at rates < 100% may result in partial traces; not recommended.
  span.sampled = pre_sample?(span) ? @pre_sampler.sample!(span) : true

  if span.sampled
    # If priority sampling has already been applied upstream, use that, otherwise...
    unless priority_assigned_upstream?(span)
      # Roll the dice and determine whether how we set the priority.
      priority = priority_sample!(span) ? Datadog::Ext::Priority::AUTO_KEEP : Datadog::Ext::Priority::AUTO_REJECT

      assign_priority!(span, priority)
    end
  else
    # If discarded by pre-sampling, set "reject" priority, so other
    # services for the same trace don't sample needlessly.
    assign_priority!(span, Datadog::Ext::Priority::AUTO_REJECT)
  end

  span.sampled
end
sample?(span) click to toggle source
# File lib/ddtrace/sampler.rb, line 205
def sample?(span)
  @pre_sampler.sample?(span)
end

Private Instance Methods

pre_sample?(span) click to toggle source
# File lib/ddtrace/sampler.rb, line 235
def pre_sample?(span)
  case @pre_sampler
  when RateSampler
    @pre_sampler.sample_rate < 1.0
  when RateByServiceSampler
    @pre_sampler.sample_rate(span) < 1.0
  else
    true
  end
end
preserving_sampling(span) { || ... } click to toggle source

Ensures the span is always propagated to the writer and that the sample rate metric represents the true client-side sampling.

# File lib/ddtrace/sampler.rb, line 258
def preserving_sampling(span)
  pre_sample_rate_metric = span.get_metric(SAMPLE_RATE_METRIC_KEY)

  yield.tap do
    # NOTE: We'll want to leave `span.sampled = true` here; all spans for priority sampling must
    #       be sent to the agent. Otherwise metrics for traces will not be accurate, since the
    #       agent will have an incomplete dataset.
    #
    #       We also ensure that the agent knows we that our `post_sampler` is not performing true sampling,
    #       to avoid erroneous metric upscaling.
    span.sampled = true
    if pre_sample_rate_metric
      # Restore true sampling metric, as only the @pre_sampler can reject traces
      span.set_metric(SAMPLE_RATE_METRIC_KEY, pre_sample_rate_metric)
    else
      # If @pre_sampler is not enable, sending this metric would be misleading
      span.clear_metric(SAMPLE_RATE_METRIC_KEY)
    end
  end
priority_assigned_upstream?(span) click to toggle source
# File lib/ddtrace/sampler.rb, line 246
def priority_assigned_upstream?(span)
  span.context && !span.context.sampling_priority.nil?
end
priority_sample!(span) click to toggle source
# File lib/ddtrace/sampler.rb, line 250
def priority_sample!(span)
  preserving_sampling(span) do
    @priority_sampler.sample!(span)
  end
end