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:
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
this returns the size of the entry point stack, which determines how many transactions are running
54 55 56 |
# File 'lib/new_relic/agent/busy_calculator.rb', line 54 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
33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 |
# File 'lib/new_relic/agent/busy_calculator.rb', line 33 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
21 22 23 24 25 26 27 28 |
# File 'lib/new_relic/agent/busy_calculator.rb', line 21 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.
70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 |
# File 'lib/new_relic/agent/busy_calculator.rb', line 70 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 if Agent.config[:report_instance_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.
60 61 62 63 64 65 66 |
# File 'lib/new_relic/agent/busy_calculator.rb', line 60 def reset @entrypoint_stack = [] Thread.current[:busy_entries] = 0 @lock ||= Mutex.new @accumulator = 0 @harvest_start = time_now end |