Module: NewRelic::Agent::BusyCalculator
- Extended by:
- BusyCalculator
- Included in:
- BusyCalculator
- Defined in:
- lib/new_relic/agent/busy_calculator.rb
Overview
This module supports calculation of actual time spent processing requests over the course of one harvest period. It’s similar to what you would get if you just added up all the execution times of controller calls, however that will be inaccurate when requests span the minute boundaries. This module manages accounting of requests not yet completed.
Calls are re-entrant. All start calls must be paired with finish calls, or a reset call.
Instance Attribute Summary collapse
-
#accumulator ⇒ Object
readonly
For testability, add accessors:.
-
#harvest_start ⇒ Object
readonly
For testability, add accessors:.
Instance Method Summary collapse
- #busy_count ⇒ Object
- #dispatcher_finish(end_time = Time.now.to_f) ⇒ Object
- #dispatcher_start(time) ⇒ Object
-
#harvest_busy ⇒ Object
Called before uploading to to the server to collect current busy stats.
-
#reset ⇒ Object
Reset the state of the information accumulated by all threads, but only reset the recursion counter for this thread.
Instance Attribute Details
#accumulator ⇒ Object (readonly)
For testability, add accessors:
13 14 15 |
# File 'lib/new_relic/agent/busy_calculator.rb', line 13 def accumulator @accumulator end |
#harvest_start ⇒ Object (readonly)
For testability, add accessors:
13 14 15 |
# File 'lib/new_relic/agent/busy_calculator.rb', line 13 def harvest_start @harvest_start end |
Instance Method Details
#busy_count ⇒ Object
37 38 39 |
# File 'lib/new_relic/agent/busy_calculator.rb', line 37 def busy_count @entrypoint_stack.size end |
#dispatcher_finish(end_time = Time.now.to_f) ⇒ Object
24 25 26 27 28 29 30 31 32 33 34 35 |
# File 'lib/new_relic/agent/busy_calculator.rb', line 24 def dispatcher_finish(end_time = Time.now.to_f) callers = Thread.current[:busy_entries] -= 1 # Ignore nested calls return if callers > 0 @lock.synchronize do if @entrypoint_stack.empty? NewRelic::Control.instance.log.error("Stack underflow tracking dispatcher entry and exit!\n #{caller.join(" \n")}") else @accumulator += (end_time - @entrypoint_stack.pop) end end end |
#dispatcher_start(time) ⇒ Object
15 16 17 18 19 20 21 22 |
# File 'lib/new_relic/agent/busy_calculator.rb', line 15 def dispatcher_start(time) Thread.current[:busy_entries] ||= 0 callers = Thread.current[:busy_entries] += 1 return if callers > 1 @lock.synchronize do @entrypoint_stack.push time end end |
#harvest_busy ⇒ Object
Called before uploading to to the server to collect current busy stats.
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 |
# File 'lib/new_relic/agent/busy_calculator.rb', line 54 def harvest_busy busy = 0 t0 = Time.now.to_f @lock.synchronize do busy = accumulator @accumulator = 0 # Walk through the stack and capture all times up to # now for entrypoints @entrypoint_stack.size.times do |frame| busy += (t0 - @entrypoint_stack[frame]) @entrypoint_stack[frame] = t0 end end busy = 0.0 if busy < 0.0 # don't go below 0% time_window = (t0 - harvest_start) time_window = 1.0 if time_window == 0.0 # protect against divide by zero busy = busy / time_window instance_busy_stats.record_data_point busy @harvest_start = t0 end |
#reset ⇒ Object
Reset the state of the information accumulated by all threads, but only reset the recursion counter for this thread.
43 44 45 46 47 48 49 |
# File 'lib/new_relic/agent/busy_calculator.rb', line 43 def reset @entrypoint_stack = [] Thread.current[:busy_entries] = 0 @lock ||= Mutex.new @accumulator = 0 @harvest_start = Time.now.to_f end |