Class: ScoutApm::TrackedRequest
- Inherits:
-
Object
- Object
- ScoutApm::TrackedRequest
- Defined in:
- lib/scout_apm/tracked_request.rb
Instance Attribute Summary collapse
-
#annotations ⇒ Object
readonly
As we go through a request, instrumentation can mark more general data into the Request Known Keys: :uri - the full URI requested by the user.
-
#context ⇒ Object
readonly
Context is application defined extra information.
-
#headers ⇒ Object
readonly
Headers as recorded by rails Can be nil if we never reach a Rails Controller.
-
#root_layer ⇒ Object
readonly
The first layer registered with this request.
-
#stackprof ⇒ Object
readonly
Nil until the request is finalized, at which point it will hold the entire raw stackprof output for this request.
Instance Method Summary collapse
- #acknowledge_children! ⇒ Object
-
#annotate_request(hsh) ⇒ Object
As we learn things about this request, we can add data here.
-
#error! ⇒ Object
This request had an exception.
- #error? ⇒ Boolean
-
#finalized? ⇒ Boolean
Are we finished with this request? We’re done if we have no layers left after popping one off.
-
#ignore_children! ⇒ Object
Enable this when you would otherwise double track something interesting.
-
#initialize ⇒ TrackedRequest
constructor
A new instance of TrackedRequest.
-
#record! ⇒ Object
Convert this request to the appropriate structure, then report it into the peristent Store object.
-
#recorded? ⇒ Boolean
Have we already persisted this request? Used to know when we should just create a new one (don’t attempt to add data to an already-recorded request).
- #set_headers(headers) ⇒ Object
- #start_layer(layer) ⇒ Object
-
#start_request(layer) ⇒ Object
Run at the beginning of the whole request.
- #stop_layer ⇒ Object
-
#stop_request ⇒ Object
Run at the end of the whole request.
Constructor Details
#initialize ⇒ TrackedRequest
Returns a new instance of TrackedRequest.
32 33 34 35 36 37 38 39 40 |
# File 'lib/scout_apm/tracked_request.rb', line 32 def initialize @layers = [] @annotations = {} @ignoring_children = false @context = Context.new @root_layer = nil @stackprof = nil @error = false end |
Instance Attribute Details
#annotations ⇒ Object (readonly)
As we go through a request, instrumentation can mark more general data into the Request Known Keys:
:uri - the full URI requested by the user
22 23 24 |
# File 'lib/scout_apm/tracked_request.rb', line 22 def annotations @annotations end |
#context ⇒ Object (readonly)
Context is application defined extra information. (ie, which user, what is their email/ip, what plan are they on, what locale are they using, etc) See documentation for examples on how to set this from a before_filter
13 14 15 |
# File 'lib/scout_apm/tracked_request.rb', line 13 def context @context end |
#headers ⇒ Object (readonly)
Headers as recorded by rails Can be nil if we never reach a Rails Controller
30 31 32 |
# File 'lib/scout_apm/tracked_request.rb', line 30 def headers @headers end |
#root_layer ⇒ Object (readonly)
The first layer registered with this request. All other layers will be children of this layer.
17 18 19 |
# File 'lib/scout_apm/tracked_request.rb', line 17 def root_layer @root_layer end |
#stackprof ⇒ Object (readonly)
Nil until the request is finalized, at which point it will hold the entire raw stackprof output for this request
26 27 28 |
# File 'lib/scout_apm/tracked_request.rb', line 26 def stackprof @stackprof end |
Instance Method Details
#acknowledge_children! ⇒ Object
168 169 170 |
# File 'lib/scout_apm/tracked_request.rb', line 168 def acknowledge_children! @ignoring_children = false end |
#annotate_request(hsh) ⇒ Object
As we learn things about this request, we can add data here. For instance, when we know where Rails routed this request to, we can store that scope info. Or as soon as we know which URI it was directed at, we can store that.
This data is internal to ScoutApm, to add custom information, use the Context api.
104 105 106 |
# File 'lib/scout_apm/tracked_request.rb', line 104 def annotate_request(hsh) @annotations.merge!(hsh) end |
#error! ⇒ Object
This request had an exception. Mark it down as an error
109 110 111 |
# File 'lib/scout_apm/tracked_request.rb', line 109 def error! @error = true end |
#error? ⇒ Boolean
113 114 115 |
# File 'lib/scout_apm/tracked_request.rb', line 113 def error? @error end |
#finalized? ⇒ Boolean
Are we finished with this request? We’re done if we have no layers left after popping one off
70 71 72 |
# File 'lib/scout_apm/tracked_request.rb', line 70 def finalized? @layers.none? end |
#ignore_children! ⇒ Object
Enable this when you would otherwise double track something interesting. This came up when we implemented InfluxDB instrumentation, which is more specific, and useful than the fact that InfluxDB happens to use Net::HTTP internally
When enabled, new layers won’t be added to the current Request.
164 165 166 |
# File 'lib/scout_apm/tracked_request.rb', line 164 def ignore_children! @ignoring_children = true end |
#record! ⇒ Object
Convert this request to the appropriate structure, then report it into the peristent Store object
127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 |
# File 'lib/scout_apm/tracked_request.rb', line 127 def record! @recorded = true metrics = LayerMetricConverter.new(self).call ScoutApm::Agent.instance.store.track!(metrics) slow, slow_metrics = LayerSlowTransactionConverter.new(self).call ScoutApm::Agent.instance.store.track_slow_transaction!(slow) ScoutApm::Agent.instance.store.track!(slow_metrics) error_metrics = LayerErrorConverter.new(self).call ScoutApm::Agent.instance.store.track!(error_metrics) queue_time_metrics = RequestQueueTime.new(self).call ScoutApm::Agent.instance.store.track!(queue_time_metrics) # ScoutApm::Agent.instance.logger.debug("Finished recording request") if metrics.any? end |
#recorded? ⇒ Boolean
Have we already persisted this request? Used to know when we should just create a new one (don’t attempt to add data to an already-recorded request). See RequestManager
149 150 151 |
# File 'lib/scout_apm/tracked_request.rb', line 149 def recorded? @recorded end |
#set_headers(headers) ⇒ Object
117 118 119 |
# File 'lib/scout_apm/tracked_request.rb', line 117 def set_headers(headers) @headers = headers end |
#start_layer(layer) ⇒ Object
42 43 44 45 46 47 48 |
# File 'lib/scout_apm/tracked_request.rb', line 42 def start_layer(layer) start_request(layer) unless @root_layer # ScoutApm::Agent.instance.logger.info("Starting Layer: #{layer.to_s}") @layers[-1].add_child(layer) if @layers.any? @layers.push(layer) end |
#start_request(layer) ⇒ Object
Run at the beginning of the whole request
-
Capture the first layer as the root_layer
-
Start Stackprof (disabling to avoid conflicts if stackprof is included as middleware since we aren’t sending this up to server now)
78 79 80 81 |
# File 'lib/scout_apm/tracked_request.rb', line 78 def start_request(layer) @root_layer = layer unless @root_layer # capture root layer #StackProf.start(:mode => :wall, :interval => ScoutApm::Agent.instance.config.value("stackprof_interval")) end |
#stop_layer ⇒ Object
50 51 52 53 54 55 56 57 58 59 60 61 62 |
# File 'lib/scout_apm/tracked_request.rb', line 50 def stop_layer layer = @layers.pop layer.record_stop_time! # Do this here, rather than in the layer because we need this caller. Maybe able to move it? if layer.total_exclusive_time > ScoutApm::SlowTransaction::BACKTRACE_THRESHOLD layer.store_backtrace(caller) end if finalized? stop_request end end |
#stop_request ⇒ Object
Run at the end of the whole request
-
Collect stackprof info
-
Send the request off to be stored
87 88 89 90 91 92 93 |
# File 'lib/scout_apm/tracked_request.rb', line 87 def stop_request # ScoutApm::Agent.instance.logger.debug("stop_request: #{annotations[:uri]}" ) #StackProf.stop # disabling to avoid conflicts if stackprof is included as middleware since we aren't sending this up to server now #@stackprof = StackProf.results record! end |