Class: NewRelic::Agent::TransactionSampler
- Inherits:
-
Object
- Object
- NewRelic::Agent::TransactionSampler
- Defined in:
- lib/new_relic/agent/transaction_sampler.rb
Defined Under Namespace
Modules: Shim
Constant Summary collapse
- BUILDER_KEY =
:transaction_sample_builder
- MAX_DATA_LENGTH =
16384
- MAX_SQL_LENGTH =
some statements (particularly INSERTS with large BLOBS may be very large; we should trim them to a maximum usable length config is the driver configuration for the connection duration is seconds, float value.
16384
Instance Attribute Summary collapse
-
#disabled ⇒ Object
readonly
Returns the value of attribute disabled.
-
#last_sample ⇒ Object
readonly
Returns the value of attribute last_sample.
-
#random_sampling ⇒ Object
Returns the value of attribute random_sampling.
-
#samples ⇒ Object
readonly
Returns the value of attribute samples.
-
#sampling_rate ⇒ Object
Returns the value of attribute sampling_rate.
-
#stack_trace_threshold ⇒ Object
Returns the value of attribute stack_trace_threshold.
Instance Method Summary collapse
- #current_sample_id ⇒ Object
- #disable ⇒ Object
- #enable ⇒ Object
-
#harvest(previous = nil, slow_threshold = 2.0) ⇒ Object
get the set of collected samples, merging into previous samples, and clear the collected sample list.
- #ignore_transaction ⇒ Object
-
#initialize ⇒ TransactionSampler
constructor
A new instance of TransactionSampler.
- #notice_first_scope_push(time) ⇒ Object
-
#notice_nosql(key, duration) ⇒ Object
duration is seconds, float value.
- #notice_pop_scope(scope, time = Time.now) ⇒ Object
- #notice_profile(profile) ⇒ Object
- #notice_push_scope(scope, time = Time.now) ⇒ Object
-
#notice_scope_empty(time = Time.now) ⇒ Object
This is called when we are done with the transaction.
- #notice_sql(sql, config, duration) ⇒ Object
- #notice_transaction(path, uri = nil, params = {}) ⇒ Object
- #notice_transaction_cpu_time(cpu_time) ⇒ Object
-
#reset! ⇒ Object
reset samples without rebooting the web server.
- #scope_depth ⇒ Object
Constructor Details
#initialize ⇒ TransactionSampler
Returns a new instance of TransactionSampler.
19 20 21 22 23 24 25 26 27 28 29 |
# File 'lib/new_relic/agent/transaction_sampler.rb', line 19 def initialize @samples = [] @harvest_count = 0 @max_samples = 100 @random_sample = nil config = NewRelic::Control.instance sampler_config = config.fetch('transaction_tracer', {}) @segment_limit = sampler_config.fetch('limit_segments', 4000) @stack_trace_threshold = sampler_config.fetch('stack_trace_threshold', 0.500).to_f @samples_lock = Mutex.new end |
Instance Attribute Details
#disabled ⇒ Object (readonly)
Returns the value of attribute disabled.
17 18 19 |
# File 'lib/new_relic/agent/transaction_sampler.rb', line 17 def disabled @disabled end |
#last_sample ⇒ Object (readonly)
Returns the value of attribute last_sample.
17 18 19 |
# File 'lib/new_relic/agent/transaction_sampler.rb', line 17 def last_sample @last_sample end |
#random_sampling ⇒ Object
Returns the value of attribute random_sampling.
16 17 18 |
# File 'lib/new_relic/agent/transaction_sampler.rb', line 16 def random_sampling @random_sampling end |
#samples ⇒ Object (readonly)
Returns the value of attribute samples.
17 18 19 |
# File 'lib/new_relic/agent/transaction_sampler.rb', line 17 def samples @samples end |
#sampling_rate ⇒ Object
Returns the value of attribute sampling_rate.
16 17 18 |
# File 'lib/new_relic/agent/transaction_sampler.rb', line 16 def sampling_rate @sampling_rate end |
#stack_trace_threshold ⇒ Object
Returns the value of attribute stack_trace_threshold.
16 17 18 |
# File 'lib/new_relic/agent/transaction_sampler.rb', line 16 def stack_trace_threshold @stack_trace_threshold end |
Instance Method Details
#current_sample_id ⇒ Object
31 32 33 34 |
# File 'lib/new_relic/agent/transaction_sampler.rb', line 31 def current_sample_id b=builder b and b.sample_id end |
#disable ⇒ Object
41 42 43 44 |
# File 'lib/new_relic/agent/transaction_sampler.rb', line 41 def disable @disabled = true NewRelic::Agent.instance.stats_engine.remove_transaction_sampler self end |
#enable ⇒ Object
36 37 38 39 |
# File 'lib/new_relic/agent/transaction_sampler.rb', line 36 def enable @disabled = false NewRelic::Agent.instance.stats_engine.transaction_sampler = self end |
#harvest(previous = nil, slow_threshold = 2.0) ⇒ Object
get the set of collected samples, merging into previous samples, and clear the collected sample list.
171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 |
# File 'lib/new_relic/agent/transaction_sampler.rb', line 171 def harvest(previous = nil, slow_threshold = 2.0) return [] if disabled result = [] previous ||= [] previous = [previous] unless previous.is_a?(Array) previous_slowest = previous.inject(nil) {|a,ts| (a) ? ((a.duration > ts.duration) ? a : ts) : ts} @samples_lock.synchronize do if @random_sampling @harvest_count += 1 if (@harvest_count % @sampling_rate) == 0 result << @random_sample if @random_sample else @random_sample = nil # if we don't nil this out, then we won't send the slowest if slowest == @random_sample end end slowest = @slowest_sample @slowest_sample = nil if slowest && slowest != @random_sample && slowest.duration >= slow_threshold if previous_slowest.nil? || previous_slowest.duration < slowest.duration result << slowest else result << previous_slowest end end @random_sample = nil @last_sample = nil end # Truncate the samples at 2100 segments. The UI will clamp them at 2000 segments anyway. # This will save us memory and bandwidth. result.each { |sample| sample.truncate(@segment_limit) } result end |
#ignore_transaction ⇒ Object
121 122 123 |
# File 'lib/new_relic/agent/transaction_sampler.rb', line 121 def ignore_transaction builder.ignore_transaction if builder end |
#notice_first_scope_push(time) ⇒ Object
51 52 53 |
# File 'lib/new_relic/agent/transaction_sampler.rb', line 51 def notice_first_scope_push(time) start_builder(time.to_f) unless disabled end |
#notice_nosql(key, duration) ⇒ Object
duration is seconds, float value.
164 165 166 |
# File 'lib/new_relic/agent/transaction_sampler.rb', line 164 def notice_nosql(key, duration) notice_extra_data(key, duration, :key) end |
#notice_pop_scope(scope, time = Time.now) ⇒ Object
85 86 87 88 89 |
# File 'lib/new_relic/agent/transaction_sampler.rb', line 85 def notice_pop_scope(scope, time = Time.now) return unless builder raise "frozen already???" if builder.sample.frozen? builder.trace_exit(scope, time.to_f) end |
#notice_profile(profile) ⇒ Object
124 125 126 |
# File 'lib/new_relic/agent/transaction_sampler.rb', line 124 def notice_profile(profile) builder.set_profile(profile) if builder end |
#notice_push_scope(scope, time = Time.now) ⇒ Object
55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 |
# File 'lib/new_relic/agent/transaction_sampler.rb', line 55 def notice_push_scope(scope, time=Time.now) return unless builder builder.trace_entry(scope, time.to_f) # in developer mode, capture the stack trace with the segment. # this is cpu and memory expensive and therefore should not be # turned on in production mode if NewRelic::Control.instance.developer_mode? segment = builder.current_segment if segment # Strip stack frames off the top that match /new_relic/agent/ trace = caller while trace.first =~/\/lib\/new_relic\/agent\// trace.shift end trace = trace[0..39] if trace.length > 40 segment[:backtrace] = trace end end end |
#notice_scope_empty(time = Time.now) ⇒ Object
This is called when we are done with the transaction. We’ve unwound the stack to the top level.
93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 |
# File 'lib/new_relic/agent/transaction_sampler.rb', line 93 def notice_scope_empty(time=Time.now) last_builder = builder return unless last_builder last_builder.finish_trace(time.to_f) clear_builder return if last_builder.ignored? @samples_lock.synchronize do @last_sample = last_builder.sample @random_sample = @last_sample if @random_sampling # ensure we don't collect more than a specified number of samples in memory @samples << @last_sample if NewRelic::Control.instance.developer_mode? @samples.shift while @samples.length > @max_samples if @slowest_sample.nil? || @slowest_sample.duration < @last_sample.duration @slowest_sample = @last_sample end end end |
#notice_sql(sql, config, duration) ⇒ Object
157 158 159 160 161 |
# File 'lib/new_relic/agent/transaction_sampler.rb', line 157 def notice_sql(sql, config, duration) if Thread::current[:record_sql] != false notice_extra_data(sql, duration, :sql, config, :connection_config) end end |
#notice_transaction(path, uri = nil, params = {}) ⇒ Object
117 118 119 |
# File 'lib/new_relic/agent/transaction_sampler.rb', line 117 def notice_transaction(path, uri=nil, params={}) builder.set_transaction_info(path, uri, params) if !disabled && builder end |
#notice_transaction_cpu_time(cpu_time) ⇒ Object
128 129 130 |
# File 'lib/new_relic/agent/transaction_sampler.rb', line 128 def notice_transaction_cpu_time(cpu_time) builder.set_transaction_cpu_time(cpu_time) if builder end |
#reset! ⇒ Object
reset samples without rebooting the web server
213 214 215 216 |
# File 'lib/new_relic/agent/transaction_sampler.rb', line 213 def reset! @samples = [] @last_sample = nil end |
#scope_depth ⇒ Object
79 80 81 82 83 |
# File 'lib/new_relic/agent/transaction_sampler.rb', line 79 def scope_depth return 0 unless builder builder.scope_depth end |