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.
-
#children ⇒ Object
readonly
An array of children layers, in call order.
-
#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
- #child_allocations ⇒ Object
- #child_time ⇒ Object
-
#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.
45 46 47 48 49 50 51 52 53 54 |
# File 'lib/scout_apm/layer.rb', line 45 def initialize(type, name, start_time = Time.now) @type = type @name = name @annotations = {} @start_time = start_time @allocations_start = ScoutApm::Instruments::Allocations.count @allocations_stop = 0 @children = [] # In order of calls @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)
41 42 43 |
# File 'lib/scout_apm/layer.rb', line 41 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.
35 36 37 |
# File 'lib/scout_apm/layer.rb', line 35 def backtrace @backtrace end |
#children ⇒ Object (readonly)
An array of children layers, in call order. 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
22 23 24 |
# File 'lib/scout_apm/layer.rb', line 22 def children @children 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
31 32 33 |
# File 'lib/scout_apm/layer.rb', line 31 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
25 26 27 |
# File 'lib/scout_apm/layer.rb', line 25 def start_time @start_time end |
#stop_time ⇒ Object (readonly)
Time objects recording the start & stop times of this layer
25 26 27 |
# File 'lib/scout_apm/layer.rb', line 25 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
56 57 58 |
# File 'lib/scout_apm/layer.rb', line 56 def add_child(child) @children << child end |
#annotate_layer(hsh) ⇒ Object
This data is internal to ScoutApm, to add custom information, use the Context api.
74 75 76 |
# File 'lib/scout_apm/layer.rb', line 74 def annotate_layer(hsh) @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.
98 99 100 101 102 103 104 105 |
# File 'lib/scout_apm/layer.rb', line 98 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
93 94 95 |
# File 'lib/scout_apm/layer.rb', line 93 def capture_backtrace! @backtrace = caller_array end |
#child_allocations ⇒ Object
167 168 169 170 171 |
# File 'lib/scout_apm/layer.rb', line 167 def child_allocations children. map { |child| child.total_allocations }. inject(0) { |sum, obj| sum + obj } end |
#child_time ⇒ Object
142 143 144 145 146 |
# File 'lib/scout_apm/layer.rb', line 142 def child_time children. map { |child| child.total_call_time }. inject(0) { |sum, time| sum + time } 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.
89 90 91 |
# File 'lib/scout_apm/layer.rb', line 89 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.
65 66 67 |
# File 'lib/scout_apm/layer.rb', line 65 def record_allocations! @allocations_stop = ScoutApm::Instruments::Allocations.count end |
#record_stop_time!(stop_time = Time.now) ⇒ Object
60 61 62 |
# File 'lib/scout_apm/layer.rb', line 60 def record_stop_time!(stop_time = Time.now) @stop_time = stop_time end |
#subscopable! ⇒ Object
78 79 80 |
# File 'lib/scout_apm/layer.rb', line 78 def subscopable! @subscopable = true end |
#subscopable? ⇒ Boolean
82 83 84 |
# File 'lib/scout_apm/layer.rb', line 82 def subscopable? @subscopable end |
#to_s ⇒ Object
May not be safe to call in every rails app, relies on Time#iso8601
112 113 114 115 116 117 118 119 120 121 122 123 124 |
# File 'lib/scout_apm/layer.rb', line 112 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.
154 155 156 157 158 159 160 161 |
# File 'lib/scout_apm/layer.rb', line 154 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
130 131 132 133 134 135 136 |
# File 'lib/scout_apm/layer.rb', line 130 def total_call_time if stop_time stop_time - start_time else Time.now - start_time end end |
#total_exclusive_allocations ⇒ Object
163 164 165 |
# File 'lib/scout_apm/layer.rb', line 163 def total_exclusive_allocations total_allocations - child_allocations end |
#total_exclusive_time ⇒ Object
138 139 140 |
# File 'lib/scout_apm/layer.rb', line 138 def total_exclusive_time total_call_time - child_time end |