Module: ScoutApm::Instruments::ActiveRecordInstruments

Defined in:
lib/scout_apm/instruments/active_record.rb

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.prepended(instrumented_class) ⇒ Object



236
237
238
# File 'lib/scout_apm/instruments/active_record.rb', line 236

def self.prepended(instrumented_class)
  ScoutApm::Agent.instance.context.logger.info "Instrumenting #{instrumented_class.inspect}"
end

Instance Method Details

#log(*args, &block) ⇒ Object



240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
# File 'lib/scout_apm/instruments/active_record.rb', line 240

def log(*args, &block)
  # Extract data from the arguments
  sql, name = args
  metric_name = Utils::ActiveRecordMetricName.new(sql, name)
  desc = SqlList.new(sql)

  # Get current ScoutApm context
  req = ScoutApm::RequestManager.lookup
  current_layer = req.current_layer

  # If we call #log, we have a real query to run, and we've already
  # gotten through the cache gatekeeper. Since we want to only trace real
  # queries, and not repeated identical queries that just hit cache, we
  # mark layer as ignorable initially in #find_by_sql, then only when we
  # know it's a real database call do we mark it back as usable.
  #
  # This flag is later used in SlowRequestConverter to skip adding ignorable layers
  current_layer.annotate_layer(:ignorable => false) if current_layer

  # Either: update the current layer and yield, don't start a new one.
  if current_layer && current_layer.type == "ActiveRecord"
    # TODO: Get rid of call .to_s, need to find this without forcing a previous run of the name logic
    if current_layer.name.to_s == Utils::ActiveRecordMetricName::DEFAULT_METRIC
      current_layer.name = metric_name
    end

    if current_layer.desc.nil?
      current_layer.desc = SqlList.new
    end
    current_layer.desc.merge(desc)

    super(*args, &block)

  # OR: Start a new layer, we didn't pick up instrumentation earlier in the stack.
  else
    layer = ScoutApm::Layer.new("ActiveRecord", metric_name)
    layer.desc = desc
    req.start_layer(layer)
    begin
      super(*args, &block)
    ensure
      req.stop_layer
    end
  end
end