Class: ScoutApm::LayerConverters::TraceConverter
- Inherits:
-
ConverterBase
- Object
- ConverterBase
- ScoutApm::LayerConverters::TraceConverter
- Defined in:
- lib/scout_apm/layer_converters/trace_converter.rb
Constant Summary collapse
- MAX_SPANS =
To prevent huge traces from being generated, we stop collecting spans as we go beyond some reasonably large count.
1500
Constants inherited from ConverterBase
Instance Attribute Summary
Attributes inherited from ConverterBase
#context, #layer_finder, #request, #root_layer
Instance Method Summary collapse
-
#backtrace_parser(lines) ⇒ Object
Take an array of ruby backtrace lines and split it into an array of hashes like: [“/Users/cschneid/.rvm/rubies/ruby-2.2.7/lib/ruby/2.2.0/irb/workspace.rb:86:in ‘eval’”, …] turns into: [ { “file”: “app/controllers/users_controller.rb”, “line”: 10, “function”: “index” }, ].
-
#call ⇒ Object
Unconditionally attempts to convert this into a DetailedTrace object.
-
#create_spans(layer, parent_id = nil) ⇒ Object
Returns an array of span objects.
- #limited? ⇒ Boolean
- #log_over_span_limit ⇒ Object
-
#name ⇒ Object
ScoreItemSet API #.
- #over_span_limit?(spans) ⇒ Boolean
- #record! ⇒ Object
- #score ⇒ Object
Methods inherited from ConverterBase
#attach_backtraces, #initialize, #make_meta_options, #make_meta_options_desc_hash, #make_meta_options_scope, #over_metric_limit?, #register_hooks, #scope_layer, #skip_layer?, #store_aggregate_metric, #store_backtrace, #store_specific_metric, #subscope_name, #subscoped?
Constructor Details
This class inherits a constructor from ScoutApm::LayerConverters::ConverterBase
Instance Method Details
#backtrace_parser(lines) ⇒ Object
Take an array of ruby backtrace lines and split it into an array of hashes like:
- “/Users/cschneid/.rvm/rubies/ruby-2.2.7/lib/ruby/2.2.0/irb/workspace.rb:86:in ‘eval’”, …
-
turns into:
[
"file": "app/controllers/users_controller.rb",
"line": 10,
"function": "index"
, ]
142 143 144 145 146 147 148 149 150 151 152 153 154 |
# File 'lib/scout_apm/layer_converters/trace_converter.rb', line 142 def backtrace_parser(lines) bt = ScoutApm::Utils::BacktraceParser.new(lines).call bt.map do |line| match = line.match(/(.*):(\d+):in `(.*)'/) { "file" => match[1], "line" => match[2], "function" => match[3], } end end |
#call ⇒ Object
Unconditionally attempts to convert this into a DetailedTrace object. Can return nil if the request didn’t have any scope_layer or if ‘timeline_traces` aren’t enabled.
27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 |
# File 'lib/scout_apm/layer_converters/trace_converter.rb', line 27 def call return nil unless scope_layer return nil unless context.config.value('timeline_traces') # Since this request is being stored, update the needed counters context.slow_request_policy.stored!(request) # record the change in memory usage mem_delta = ScoutApm::Instruments::Process::ProcessMemory.new(context).rss_to_mb(@request.capture_mem_delta!) transaction_id = request.transaction_id revision = context.environment.git_revision.sha start_instant = request.root_layer.start_time stop_instant = request.root_layer.stop_time type = if request.web? "Web" elsif request.job? "Job" else "Unknown" end # Create request tags # = { :allocations => request.root_layer.total_allocations, :mem_delta => mem_delta, }.merge(request.context.to_flat_hash) host = context.environment.hostname path = request.annotations[:uri] || "" code = "" # User#index for instance spans = create_spans(request.root_layer) if limited? [:"scout.reached_span_cap"] = true end DetailedTrace.new( transaction_id, revision, host, start_instant, stop_instant, type, path, code, spans, # total_score = 0, # percentile_score = 0, # age_score = 0, # memory_delta_score = 0, # memory_allocations_score = 0 ) end |
#create_spans(layer, parent_id = nil) ⇒ Object
Returns an array of span objects. Uses recursion to get all children wired up w/ correct parent_ids
89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 |
# File 'lib/scout_apm/layer_converters/trace_converter.rb', line 89 def create_spans(layer, parent_id = nil) span_id = ScoutApm::Utils::SpanId.new.to_s start_instant = layer.start_time stop_instant = layer.stop_time operation = layer.legacy_metric_name = { :start_allocations => layer.allocations_start, :stop_allocations => layer.allocations_stop, } if layer.desc [:desc] = layer.desc.to_s end if layer.annotations && layer.annotations[:record_count] ["db.record_count"] = layer.annotations[:record_count] end if layer.annotations && layer.annotations[:class_name] ["db.class_name"] = layer.annotations[:class_name] end if layer.backtrace [:backtrace] = backtrace_parser(layer.backtrace) rescue nil end # Collect up self, and all children into result array result = [] result << DetailedTraceSpan.new( span_id.to_s, parent_id.to_s, start_instant, stop_instant, operation, ) layer.children.each do |child| # Don't create spans from limited layers. These don't have start/stop times and our processing can't # handle these yet. unless over_span_limit?(result) || child.is_a?(LimitedLayer) result += create_spans(child, span_id) end end return result end |
#limited? ⇒ Boolean
179 180 181 |
# File 'lib/scout_apm/layer_converters/trace_converter.rb', line 179 def limited? !! @limited end |
#log_over_span_limit ⇒ Object
173 174 175 176 177 |
# File 'lib/scout_apm/layer_converters/trace_converter.rb', line 173 def log_over_span_limit unless limited? context.logger.debug "Not recording additional spans for #{name}. Over the span limit." end end |
#name ⇒ Object
ScoreItemSet API #
22 |
# File 'lib/scout_apm/layer_converters/trace_converter.rb', line 22 def name; request.unique_name; end |
#over_span_limit?(spans) ⇒ Boolean
164 165 166 167 168 169 170 171 |
# File 'lib/scout_apm/layer_converters/trace_converter.rb', line 164 def over_span_limit?(spans) if spans.size > MAX_SPANS log_over_span_limit @limited = true else false end end |
#record! ⇒ Object
9 10 11 12 13 14 15 16 17 |
# File 'lib/scout_apm/layer_converters/trace_converter.rb', line 9 def record! @points = context.slow_request_policy.score(request) # Let the store know we're here, and if it wants our data, it will call # back into #call @store.track_trace!(self) nil # not returning anything in the layer results ... not used end |
#score ⇒ Object
23 |
# File 'lib/scout_apm/layer_converters/trace_converter.rb', line 23 def score; @points; end |