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) ⇒ 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:
16 17 18 |
# File 'lib/new_relic/agent/busy_calculator.rb', line 16 def accumulator @accumulator end |
#harvest_start ⇒ Object (readonly)
For testability, add accessors:
16 17 18 |
# File 'lib/new_relic/agent/busy_calculator.rb', line 16 def harvest_start @harvest_start end |
Instance Method Details
#busy_count ⇒ Object
40 41 42 |
# File 'lib/new_relic/agent/busy_calculator.rb', line 40 def busy_count @entrypoint_stack.size end |
#dispatcher_finish(end_time = Time.now) ⇒ Object
27 28 29 30 31 32 33 34 35 36 37 38 |
# File 'lib/new_relic/agent/busy_calculator.rb', line 27 def dispatcher_finish(end_time = Time.now) callers = Thread.current[:busy_entries] -= 1 # Ignore nested calls return if callers > 0 @lock.synchronize do if @entrypoint_stack.empty? NewRelic::Agent.logger.error("Stack underflow tracking dispatcher entry and exit!\n #{caller.join(" \n")}") else @accumulator += (end_time - @entrypoint_stack.pop).to_f end end end |
#dispatcher_start(time) ⇒ Object
18 19 20 21 22 23 24 25 |
# File 'lib/new_relic/agent/busy_calculator.rb', line 18 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.
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 82 |
# File 'lib/new_relic/agent/busy_calculator.rb', line 57 def harvest_busy busy = 0 t0 = Time.now @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]).to_f @entrypoint_stack[frame] = t0 end end busy = 0.0 if busy < 0.0 # don't go below 0% time_window = (t0 - harvest_start).to_f 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.
46 47 48 49 50 51 52 |
# File 'lib/new_relic/agent/busy_calculator.rb', line 46 def reset @entrypoint_stack = [] Thread.current[:busy_entries] = 0 @lock ||= Mutex.new @accumulator = 0 @harvest_start = Time.now end |