Class: Datadog::Tracing::Sampling::PrioritySampler

Inherits:
Object
  • Object
show all
Defined in:
lib/datadog/tracing/sampling/priority_sampler.rb

Overview

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(opts = {}) ⇒ PrioritySampler

Returns a new instance of PrioritySampler.



22
23
24
25
# File 'lib/datadog/tracing/sampling/priority_sampler.rb', line 22

def initialize(opts = {})
  @pre_sampler = opts[:base_sampler] || AllSampler.new
  @priority_sampler = opts[:post_sampler] || RateByServiceSampler.new(decision: Sampling::Ext::Decision::AGENT_RATE)
end

Instance Attribute Details

#pre_samplerObject (readonly)

NOTE: We do not advise using a pre-sampler. It can save resources, but pre-sampling at rates < 100% may result in partial traces, unless the pre-sampler knows exactly how to drop a span without dropping its ancestors.

Additionally, as service metrics are calculated in the Datadog Agent, the service’s throughput will be underestimated.



20
21
22
# File 'lib/datadog/tracing/sampling/priority_sampler.rb', line 20

def pre_sampler
  @pre_sampler
end

#priority_samplerObject (readonly)

NOTE: We do not advise using a pre-sampler. It can save resources, but pre-sampling at rates < 100% may result in partial traces, unless the pre-sampler knows exactly how to drop a span without dropping its ancestors.

Additionally, as service metrics are calculated in the Datadog Agent, the service’s throughput will be underestimated.



20
21
22
# File 'lib/datadog/tracing/sampling/priority_sampler.rb', line 20

def priority_sampler
  @priority_sampler
end

Class Method Details

.sampled?(priority_sampling) ⇒ Boolean

Check if the Priority Sampling decision is to keep or drop the trace. Other factors can influence the sampling decision; this method is only responsible for interpreting the Sampling Priority decision.

Parameters:

  • priority_sampling (Integer)

    priority sampling number

Returns:

  • (Boolean)

    true if trace is “kept” by priority sampling

  • (Boolean)

    false if trace is “dropped” by priority sampling



95
96
97
# File 'lib/datadog/tracing/sampling/priority_sampler.rb', line 95

def self.sampled?(priority_sampling)
  priority_sampling >= Ext::Priority::AUTO_KEEP
end

Instance Method Details

#sample!(trace) ⇒ Object

DEV-2.0:We should get rid of this complicated interaction between @pre_sampler and @priority_sampler. DEV-2.0:If the user wants to configure a custom sampler, we should only allow them to provide a complete DEV-2.0:sampling suite, not having this convoluted support for mixing arbitrary provided samplers in DEV-2.0:the PrioritySampler. Ideally, the PrioritySampler is only used by Datadog. DEV-2.0:There are too many edge cases and combinations to work around currently in this class.



36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
# File 'lib/datadog/tracing/sampling/priority_sampler.rb', line 36

def sample!(trace)
  # The priority that was set before the sampler ran.
  # This comes from distributed tracing priority propagation.
  distributed_sampling_priority = priority_assigned?(trace)

  # 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.
  trace.sampled = pre_sample?(trace) ? preserving_priority_sampling(trace) { @pre_sampler.sample!(trace) } : true

  if trace.sampled?
    # If priority sampling has already been applied upstream, use that value.
    return true if priority_assigned?(trace)

    # Check with post sampler how we set the priority.
    sample = priority_sample!(trace)

    # Check if post sampler has already assigned a priority.
    return true if priority_assigned?(trace)

    # If not, use agent priority values.
    priority = sample ? Sampling::Ext::Priority::AUTO_KEEP : Sampling::Ext::Priority::AUTO_REJECT
    assign_priority!(trace, priority)
  else
    # If discarded by pre-sampling, set "reject" priority, so other
    # services for the same trace don't sample needlessly.
    assign_priority!(trace, Sampling::Ext::Priority::AUTO_REJECT)
  end

  trace.sampled?
ensure
  if trace.sampling_priority && trace.sampling_priority > 0
    # Don't modify decision if priority was set upstream.
    if !distributed_sampling_priority && !trace.has_tag?(Tracing::Metadata::Ext::Distributed::TAG_DECISION_MAKER)
      # If no sampling priority being assigned at this point, a custom
      # sampler implementation is configured: this means the user has
      # full control over the sampling decision.
      trace.set_tag(
        Tracing::Metadata::Ext::Distributed::TAG_DECISION_MAKER,
        Sampling::Ext::Decision::MANUAL
      )
    end
  else
    # The sampler decided to not keep this span, removing sampling decision.
    trace.clear_tag(Tracing::Metadata::Ext::Distributed::TAG_DECISION_MAKER)
  end
end

#sample?(trace) ⇒ Boolean

Returns:

  • (Boolean)


27
28
29
# File 'lib/datadog/tracing/sampling/priority_sampler.rb', line 27

def sample?(trace)
  @pre_sampler.sample?(trace)
end

#update(rate_by_service, decision: nil) ⇒ Object



84
85
86
# File 'lib/datadog/tracing/sampling/priority_sampler.rb', line 84

def update(rate_by_service, decision: nil)
  @priority_sampler.update(rate_by_service, decision: decision)
end