Class: NewRelic::Agent::AdaptiveSampler

Inherits:
Object
  • Object
show all
Defined in:
lib/new_relic/agent/adaptive_sampler.rb

Instance Method Summary collapse

Constructor Details

#initialize(target_samples = 10, period_duration = 60) ⇒ AdaptiveSampler



8
9
10
11
12
13
14
15
16
17
18
# File 'lib/new_relic/agent/adaptive_sampler.rb', line 8

def initialize(target_samples = 10, period_duration = 60)
  @target = target_samples
  @seen = 0
  @seen_last = 0
  @sampled_count = 0
  @period_duration = period_duration
  @first_period = true
  @period_start = Process.clock_gettime(Process::CLOCK_MONOTONIC)
  @lock = Mutex.new
  register_config_callbacks
end

Instance Method Details

#exponential_backoffObject



42
43
44
# File 'lib/new_relic/agent/adaptive_sampler.rb', line 42

def exponential_backoff
  @target**(@target.to_f / @sampled_count) - @target**0.5
end

#sampled?Boolean

Called at the beginning of each transaction, increments seen and returns a boolean indicating if we should mark the transaction as sampled. This uses the adaptive sampling algorithm.



23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
# File 'lib/new_relic/agent/adaptive_sampler.rb', line 23

def sampled?
  @lock.synchronize do
    reset_if_period_expired!
    sampled = if @first_period
      @sampled_count < 10
    elsif @sampled_count < @target
      rand(@seen_last) < @target
    else
      # you've met the target and need to exponentially back off
      rand(@seen) < exponential_backoff
    end

    @sampled_count += 1 if sampled
    @seen += 1

    sampled
  end
end

#statsObject



46
47
48
49
50
51
52
53
54
55
# File 'lib/new_relic/agent/adaptive_sampler.rb', line 46

def stats
  @lock.synchronize do
    {
      target: @target,
      seen: @seen,
      seen_last: @seen_last,
      sampled_count: @sampled_count
    }
  end
end