Class: ScoutApm::Layer
- Inherits:
-
Object
- Object
- ScoutApm::Layer
- Defined in:
- lib/scout_apm/layer.rb
Constant Summary collapse
- BACKTRACE_CALLER_LIMIT =
maximum number of lines to send thru for backtrace analysis
50
Instance Attribute Summary collapse
-
#annotations ⇒ Object
readonly
As we go through a part of a request, instrumentation can store additional data Known Keys: :record_count - The number of rows returned by an AR query (From notification instantiation.active_record) :class_name - The ActiveRecord class name (From notification instantiation.active_record).
-
#backtrace ⇒ Object
readonly
If this layer took longer than a fixed amount of time, store the backtrace of where it occurred.
-
#desc ⇒ Object
The description of this layer.
-
#name ⇒ Object
Name: a more specific name of this single item Examples: “Rack::Cache”, “User#find”, “users/index”, “users/index.html.erb”.
-
#start_time ⇒ Object
readonly
Time objects recording the start & stop times of this layer.
-
#stop_time ⇒ Object
readonly
Time objects recording the start & stop times of this layer.
-
#type ⇒ Object
readonly
Type: a general name for the kind of thing being tracked.
Instance Method Summary collapse
- #add_child(child) ⇒ Object
-
#annotate_layer(hsh) ⇒ Object
This data is internal to ScoutApm, to add custom information, use the Context api.
-
#caller_array ⇒ Object
In Ruby 2.0+, we can pass the range directly to the caller to reduce the memory footprint.
- #capture_backtrace! ⇒ Object
-
#children ⇒ Object
An array of children layers For instance, if we are in a middleware, there will likely be only a single child, which is another middleware.
-
#initialize(type, name, start_time = Time.now) ⇒ Layer
constructor
A new instance of Layer.
-
#legacy_metric_name ⇒ Object
This is the old style name.
-
#record_allocations! ⇒ Object
Fetch the current number of allocated objects.
- #record_stop_time!(stop_time = Time.now) ⇒ Object
- #subscopable! ⇒ Object
- #subscopable? ⇒ Boolean
-
#to_s ⇒ Object
May not be safe to call in every rails app, relies on Time#iso8601.
-
#total_allocations ⇒ Object
These are almost identical to the timing metrics.
-
#total_call_time ⇒ Object
Time Calculations.
- #total_exclusive_allocations ⇒ Object
- #total_exclusive_time ⇒ Object
Constructor Details
#initialize(type, name, start_time = Time.now) ⇒ Layer
Returns a new instance of Layer.
51 52 53 54 55 56 57 58 59 60 61 62 |
# File 'lib/scout_apm/layer.rb', line 51 def initialize(type, name, start_time = Time.now) @type = type @name = name @start_time = start_time @allocations_start = ScoutApm::Instruments::Allocations.count @allocations_stop = 0 # initialize these only on first use @children = nil @annotations = nil @desc = nil end |
Instance Attribute Details
#annotations ⇒ Object (readonly)
As we go through a part of a request, instrumentation can store additional data Known Keys:
:record_count - The number of rows returned by an AR query (From notification instantiation.active_record)
:class_name - The ActiveRecord class name (From notification instantiation.active_record)
If no annotations are ever set, this will return nil
47 48 49 |
# File 'lib/scout_apm/layer.rb', line 47 def annotations @annotations end |
#backtrace ⇒ Object (readonly)
If this layer took longer than a fixed amount of time, store the backtrace of where it occurred.
39 40 41 |
# File 'lib/scout_apm/layer.rb', line 39 def backtrace @backtrace end |
#desc ⇒ Object
The description of this layer. Will contain additional details specific to the type of layer. For an ActiveRecord metric, it will contain the SQL run For an outoing HTTP call, it will contain the remote URL accessed Leave blank if there is nothing to note
35 36 37 |
# File 'lib/scout_apm/layer.rb', line 35 def desc @desc end |
#name ⇒ Object
Name: a more specific name of this single item
Examples: "Rack::Cache", "User#find", "users/index", "users/index.html.erb"
Accessor, so we can update a layer if multiple pieces of instrumentation work
together at different layers to fill in the full data. See the ActiveRecord
instrumentation for an example of how this is useful
14 15 16 |
# File 'lib/scout_apm/layer.rb', line 14 def name @name end |
#start_time ⇒ Object (readonly)
Time objects recording the start & stop times of this layer
29 30 31 |
# File 'lib/scout_apm/layer.rb', line 29 def start_time @start_time end |
#stop_time ⇒ Object (readonly)
Time objects recording the start & stop times of this layer
29 30 31 |
# File 'lib/scout_apm/layer.rb', line 29 def stop_time @stop_time end |
#type ⇒ Object (readonly)
Type: a general name for the kind of thing being tracked.
Examples: "Middleware", "ActiveRecord", "Controller", "View"
6 7 8 |
# File 'lib/scout_apm/layer.rb', line 6 def type @type end |
Instance Method Details
#add_child(child) ⇒ Object
64 65 66 67 |
# File 'lib/scout_apm/layer.rb', line 64 def add_child(child) @children ||= LayerChildrenSet.new @children << child end |
#annotate_layer(hsh) ⇒ Object
This data is internal to ScoutApm, to add custom information, use the Context api.
83 84 85 86 |
# File 'lib/scout_apm/layer.rb', line 83 def annotate_layer(hsh) @annotations ||= {} @annotations.merge!(hsh) end |
#caller_array ⇒ Object
In Ruby 2.0+, we can pass the range directly to the caller to reduce the memory footprint.
108 109 110 111 112 113 114 115 |
# File 'lib/scout_apm/layer.rb', line 108 def caller_array # omits the first several callers which are in the ScoutAPM stack. if ScoutApm::Environment.instance.ruby_2? caller(3...BACKTRACE_CALLER_LIMIT) else caller[3...BACKTRACE_CALLER_LIMIT] end end |
#capture_backtrace! ⇒ Object
103 104 105 |
# File 'lib/scout_apm/layer.rb', line 103 def capture_backtrace! @backtrace = caller_array end |
#children ⇒ Object
An array of children layers For instance, if we are in a middleware, there will likely be only a single child, which is another middleware. In a Controller, we may have a handful of children: [ActiveRecord, ActiveRecord, View, HTTP Call].
This useful to get actual time spent in this layer vs. children time
TODO: Check callers for compatibility w/ nil to avoid making an empty array
24 25 26 |
# File 'lib/scout_apm/layer.rb', line 24 def children @children || LayerChildrenSet.new end |
#legacy_metric_name ⇒ Object
This is the old style name. This function is used for now, but should be removed, and the new type & name split should be enforced through the app.
99 100 101 |
# File 'lib/scout_apm/layer.rb', line 99 def legacy_metric_name "#{type}/#{name}" end |
#record_allocations! ⇒ Object
Fetch the current number of allocated objects. This will always increment - we fetch when initializing and when stopping the layer.
74 75 76 |
# File 'lib/scout_apm/layer.rb', line 74 def record_allocations! @allocations_stop = ScoutApm::Instruments::Allocations.count end |
#record_stop_time!(stop_time = Time.now) ⇒ Object
69 70 71 |
# File 'lib/scout_apm/layer.rb', line 69 def record_stop_time!(stop_time = Time.now) @stop_time = stop_time end |
#subscopable! ⇒ Object
88 89 90 |
# File 'lib/scout_apm/layer.rb', line 88 def subscopable! @subscopable = true end |
#subscopable? ⇒ Boolean
92 93 94 |
# File 'lib/scout_apm/layer.rb', line 92 def subscopable? @subscopable end |
#to_s ⇒ Object
May not be safe to call in every rails app, relies on Time#iso8601
122 123 124 125 126 127 128 129 130 131 132 133 134 |
# File 'lib/scout_apm/layer.rb', line 122 def to_s name_clause = "#{type}/#{name}" total_string = total_call_time == 0 ? nil : "Total: #{total_call_time}" self_string = total_exclusive_time == 0 ? nil : "Self: #{total_exclusive_time}" timing_string = [total_string, self_string].compact.join(", ") time_clause = "(Start: #{start_time.iso8601} / Stop: #{stop_time.try(:iso8601)} [#{timing_string}])" desc_clause = "Description: #{desc.inspect}" children_clause = "Children: #{children.length}" "<Layer: #{name_clause} #{time_clause} #{desc_clause} #{children_clause}>" end |
#total_allocations ⇒ Object
These are almost identical to the timing metrics.
165 166 167 168 169 170 171 172 |
# File 'lib/scout_apm/layer.rb', line 165 def total_allocations if @allocations_stop > 0 allocations = (@allocations_stop - @allocations_start) else allocations = (ScoutApm::Instruments::Allocations.count - @allocations_start) end allocations < 0 ? 0 : allocations end |
#total_call_time ⇒ Object
Time Calculations
140 141 142 143 144 145 146 |
# File 'lib/scout_apm/layer.rb', line 140 def total_call_time if stop_time stop_time - start_time else Time.now - start_time end end |
#total_exclusive_allocations ⇒ Object
174 175 176 |
# File 'lib/scout_apm/layer.rb', line 174 def total_exclusive_allocations total_allocations - child_allocations end |
#total_exclusive_time ⇒ Object
148 149 150 |
# File 'lib/scout_apm/layer.rb', line 148 def total_exclusive_time total_call_time - child_time end |