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
this returns the size of the entry point stack, which determines how many transactions are running.
-
#dispatcher_finish(end_time = nil) ⇒ Object
called when a transaction finishes, to add time to the instance variable accumulator.
-
#dispatcher_start(time) ⇒ Object
sets up busy calculations based on the start and end of transactions - used for a rough estimate of what percentage of wall clock time is spent processing requests.
-
#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:
20 21 22 |
# File 'lib/new_relic/agent/busy_calculator.rb', line 20 def accumulator @accumulator end |
#harvest_start ⇒ Object (readonly)
For testability, add accessors:
20 21 22 |
# File 'lib/new_relic/agent/busy_calculator.rb', line 20 def harvest_start @harvest_start end |
Instance Method Details
#busy_count ⇒ Object
this returns the size of the entry point stack, which determines how many transactions are running
58 59 60 |
# File 'lib/new_relic/agent/busy_calculator.rb', line 58 def busy_count @entrypoint_stack.size end |
#dispatcher_finish(end_time = nil) ⇒ Object
called when a transaction finishes, to add time to the instance variable accumulator. this is harvested when we send data to the server
37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 |
# File 'lib/new_relic/agent/busy_calculator.rb', line 37 def dispatcher_finish(end_time = nil) # If #dispatcher_start hasn't been called at least once, abort early return unless Thread.current[:busy_entries] 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.warn("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
sets up busy calculations based on the start and end of transactions - used for a rough estimate of what percentage of wall clock time is spent processing requests
25 26 27 28 29 30 31 32 |
# File 'lib/new_relic/agent/busy_calculator.rb', line 25 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.
74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 |
# File 'lib/new_relic/agent/busy_calculator.rb', line 74 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 if Agent.config[:report_instance_busy] NewRelic::Agent.record_metric('Instance/Busy', busy) end @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.
64 65 66 67 68 69 70 |
# File 'lib/new_relic/agent/busy_calculator.rb', line 64 def reset @entrypoint_stack = [] Thread.current[:busy_entries] = 0 @lock ||= Mutex.new @accumulator = 0 @harvest_start = time_now end |