Class: NewRelic::Agent::TransactionSampler

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

Overview

This class contains the logic for recording and storing transaction traces (sometimes referred to as ‘transaction samples’).

A transaction trace is a detailed timeline of the events that happened during the processing of a single transaction, including database calls, template rendering calls, and other instrumented method calls.

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initializeTransactionSampler

Returns a new instance of TransactionSampler.



22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
# File 'lib/new_relic/agent/transaction_sampler.rb', line 22

def initialize
  @sample_buffers = []
  @sample_buffers << NewRelic::Agent::Transaction::SlowestSampleBuffer.new
  @sample_buffers << NewRelic::Agent::Transaction::SyntheticsSampleBuffer.new

  # This lock is used to synchronize access to the @last_sample
  # and related variables. It can become necessary on JRuby or
  # any 'honest-to-god'-multithreaded system
  @samples_lock = Mutex.new

  Agent.config.register_callback(:'transaction_tracer.enabled') do |enabled|
    if enabled
      threshold = Agent.config[:'transaction_tracer.transaction_threshold']
      ::NewRelic::Agent.logger.debug("Transaction tracing threshold is #{threshold} seconds.")
    else
      ::NewRelic::Agent.logger.debug('Transaction traces will not be sent to the New Relic service.')
    end
  end

  Agent.config.register_callback(:'transaction_tracer.record_sql') do |config|
    if config == 'raw'
      ::NewRelic::Agent.logger.warn('Agent is configured to send raw SQL to the service')
    end
  end
end

Instance Attribute Details

#last_sampleObject (readonly)



20
21
22
# File 'lib/new_relic/agent/transaction_sampler.rb', line 20

def last_sample
  @last_sample
end

Instance Method Details

#countObject



100
101
102
103
104
105
# File 'lib/new_relic/agent/transaction_sampler.rb', line 100

def count
  @samples_lock.synchronize do
    samples = @sample_buffers.inject([]) { |all, b| all.concat(b.samples) }
    samples.uniq.size
  end
end

#enabled?Boolean

Returns:

  • (Boolean)


48
49
50
# File 'lib/new_relic/agent/transaction_sampler.rb', line 48

def enabled?
  Agent.config[:'transaction_tracer.enabled']
end

#harvest!Object

Gather transaction traces that we’d like to transmit to the server.



69
70
71
72
73
74
75
76
77
# File 'lib/new_relic/agent/transaction_sampler.rb', line 69

def harvest!
  return NewRelic::EMPTY_ARRAY unless enabled?

  samples = @samples_lock.synchronize do
    @last_sample = nil
    harvest_from_sample_buffers
  end
  prepare_samples(samples)
end

#harvest_from_sample_buffersObject



107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
# File 'lib/new_relic/agent/transaction_sampler.rb', line 107

def harvest_from_sample_buffers
  # map + flatten hit mocking issues calling to_ary on 1.9.2.  We only
  # want a single level flatten anyway, but, as you probably already
  # know, Ruby 1.8.6 :/
  result = []
  @sample_buffers.each { |buffer| result.concat(buffer.harvest_samples) }
  result.uniq!
  result.map! do |sample|
    if Transaction === sample
      Transaction::TraceBuilder.build_trace(sample)
    else
      sample
    end
  end
end

#merge!(previous) ⇒ Object



92
93
94
95
96
97
98
# File 'lib/new_relic/agent/transaction_sampler.rb', line 92

def merge!(previous)
  @samples_lock.synchronize do
    @sample_buffers.each do |buffer|
      buffer.store_previous(previous)
    end
  end
end

#on_finishing_transaction(txn) ⇒ Object



52
53
54
55
56
57
58
59
60
# File 'lib/new_relic/agent/transaction_sampler.rb', line 52

def on_finishing_transaction(txn)
  return if !enabled? || txn.ignore_trace?

  @samples_lock.synchronize do
    @last_sample = txn
    store_sample(txn)
    @last_sample
  end
end

#prepare_samples(samples) ⇒ Object



79
80
81
82
83
84
85
86
87
88
89
90
# File 'lib/new_relic/agent/transaction_sampler.rb', line 79

def prepare_samples(samples)
  samples.select do |sample|
    begin
      sample.prepare_to_send!
    rescue => e
      NewRelic::Agent.logger.error('Failed to prepare transaction trace. Error: ', e)
      false
    else
      true
    end
  end
end

#reset!Object

reset samples without rebooting the web server (used by dev mode)



124
125
126
127
128
129
# File 'lib/new_relic/agent/transaction_sampler.rb', line 124

def reset!
  @samples_lock.synchronize do
    @last_sample = nil
    @sample_buffers.each { |sample_buffer| sample_buffer.reset! }
  end
end

#store_sample(sample) ⇒ Object



62
63
64
65
66
# File 'lib/new_relic/agent/transaction_sampler.rb', line 62

def store_sample(sample)
  @sample_buffers.each do |sample_buffer|
    sample_buffer.store(sample)
  end
end