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
-
#allocations_start ⇒ Object
readonly
Returns the value of attribute allocations_start.
-
#allocations_stop ⇒ Object
readonly
Returns the value of attribute allocations_stop.
-
#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
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.
-
#file_name ⇒ Object
The file name associated with the 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.
- #limited? ⇒ Boolean
-
#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.
56 57 58 59 60 61 62 63 64 65 66 67 |
# File 'lib/scout_apm/layer.rb', line 56 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
#allocations_start ⇒ Object (readonly)
Returns the value of attribute allocations_start.
52 53 54 |
# File 'lib/scout_apm/layer.rb', line 52 def allocations_start @allocations_start end |
#allocations_stop ⇒ Object (readonly)
Returns the value of attribute allocations_stop.
52 53 54 |
# File 'lib/scout_apm/layer.rb', line 52 def allocations_stop @allocations_stop end |
#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
50 51 52 |
# File 'lib/scout_apm/layer.rb', line 50 def annotations @annotations end |
#backtrace ⇒ Object
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 |
#file_name ⇒ Object
The file name associated with the layer. Only used for autoinstruments overhead logging.
42 43 44 |
# File 'lib/scout_apm/layer.rb', line 42 def file_name @file_name 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
73 74 75 76 |
# File 'lib/scout_apm/layer.rb', line 73 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.
92 93 94 95 |
# File 'lib/scout_apm/layer.rb', line 92 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.
117 118 119 120 121 122 123 124 |
# File 'lib/scout_apm/layer.rb', line 117 def caller_array # omits the first several callers which are in the ScoutAPM stack. if ScoutApm::Agent.instance.context.environment.ruby_2? || ScoutApm::Agent.instance.context.environment.ruby_3? caller(3...BACKTRACE_CALLER_LIMIT) else caller[3...BACKTRACE_CALLER_LIMIT] end end |
#capture_backtrace! ⇒ Object
112 113 114 |
# File 'lib/scout_apm/layer.rb', line 112 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.
108 109 110 |
# File 'lib/scout_apm/layer.rb', line 108 def legacy_metric_name "#{type}/#{name}" end |
#limited? ⇒ Boolean
69 70 71 |
# File 'lib/scout_apm/layer.rb', line 69 def limited? false end |
#record_allocations! ⇒ Object
Fetch the current number of allocated objects. This will always increment - we fetch when initializing and when stopping the layer.
83 84 85 |
# File 'lib/scout_apm/layer.rb', line 83 def record_allocations! @allocations_stop = ScoutApm::Instruments::Allocations.count end |
#record_stop_time!(stop_time = Time.now) ⇒ Object
78 79 80 |
# File 'lib/scout_apm/layer.rb', line 78 def record_stop_time!(stop_time = Time.now) @stop_time = stop_time end |
#subscopable! ⇒ Object
97 98 99 |
# File 'lib/scout_apm/layer.rb', line 97 def subscopable! @subscopable = true end |
#subscopable? ⇒ Boolean
101 102 103 |
# File 'lib/scout_apm/layer.rb', line 101 def subscopable? @subscopable end |
#to_s ⇒ Object
May not be safe to call in every rails app, relies on Time#iso8601
131 132 133 134 135 136 137 138 139 140 141 142 143 |
# File 'lib/scout_apm/layer.rb', line 131 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.
174 175 176 177 178 179 180 181 |
# File 'lib/scout_apm/layer.rb', line 174 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
149 150 151 152 153 154 155 |
# File 'lib/scout_apm/layer.rb', line 149 def total_call_time if stop_time stop_time - start_time else Time.now - start_time end end |
#total_exclusive_allocations ⇒ Object
183 184 185 |
# File 'lib/scout_apm/layer.rb', line 183 def total_exclusive_allocations total_allocations - child_allocations end |
#total_exclusive_time ⇒ Object
157 158 159 |
# File 'lib/scout_apm/layer.rb', line 157 def total_exclusive_time total_call_time - child_time end |