Module: Sequel::NewRelicInstrumentation

Includes:
NewRelic::Agent::Instrumentation::ActiveRecordHelper, NewRelic::Agent::MethodTracer
Defined in:
lib/sequel/extensions/newrelic_instrumentation.rb

Overview

New Relic’s Sequel instrumentation is implemented via a plugin for Sequel::Models, and an extension for Sequel::Databases. Every database handle that Sequel knows about when New Relic is loaded will automatically be instrumented, but if you’re using a version of Sequel before 3.47.0, you’ll need to add the extension yourself if you create any after the instrumentation is loaded:

db = Sequel.connect( ... )
db.extension :newrelic_instrumentation

Versions 3.47.0 and later use ‘Database.extension` to automatically install the extension for new connections.

Disabling

If you don’t want your models or database connections to be instrumented, you can disable them by setting ‘disable_database_instrumentation` in your `newrelic.yml` to `true`. It will also honor the `disable_activerecord_instrumentation` setting.

Instance Method Summary collapse

Methods included from NewRelic::Agent::MethodTracer

extended, included, #trace_execution_unscoped, #trace_method_execution, #trace_method_execution_with_scope

Methods included from NewRelic::Agent::MethodTracer::TraceExecutionScoped

#agent_instance, #get_stats_scoped, #get_stats_unscoped, #has_parent?, #log_errors, #metrics_for_current_transaction, #metrics_for_parent_transaction, #pop_flag!, #push_flag!, #set_if_nil, #stat_engine, #trace_disabled?, #trace_execution_scoped, #trace_execution_scoped_footer, #trace_execution_scoped_header, #traced?

Methods included from NewRelic::Agent::Instrumentation::ActiveRecordHelper

metric_for_name, metric_for_sql, remote_service_metric, rollup_metrics_for

Instance Method Details

#log_yield(sql, args = nil) ⇒ Object

Instrument all queries that go through #execute_query.



38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
# File 'lib/sequel/extensions/newrelic_instrumentation.rb', line 38

def log_yield( sql, args=nil )
  return super unless NewRelic::Agent.is_execution_traced?

  t0 = Time.now
  rval = super
  t1 = Time.now

  begin
    duration = t1 - t0
    record_metrics( sql, args, duration )
    notice_sql( sql, args, t0, t1 )
  rescue => err
    NewRelic::Agent.logger.debug "while recording metrics for Sequel", err
  end

  return rval
end

#notice_sql(sql, args, start, finish) ⇒ Object

Record the given sql within a new scope, using the given start and finish times.



73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
# File 'lib/sequel/extensions/newrelic_instrumentation.rb', line 73

def notice_sql( sql, args, start, finish )
  metric   = primary_metric_for( sql, args )
  agent    = NewRelic::Agent.instance
  duration = finish - start

  begin
    scope = agent.stats_engine.push_scope( :sequel, start )
    agent.transaction_sampler.notice_sql( sql, self.opts, duration ) do |*|
      self[ sql ].explain
    end
    agent.sql_sampler.notice_sql( sql, metric, self.opts, duration ) do |*|
      self[ sql ].explain
    end
  ensure
    agent.stats_engine.pop_scope( scope, metric, finish )
  end
end

#primary_metric_for(sql, _) ⇒ Object

Derive a primary database metric for the specified sql.



93
94
95
# File 'lib/sequel/extensions/newrelic_instrumentation.rb', line 93

def primary_metric_for( sql, _ )
  return metric_for_sql(NewRelic::Helper.correctly_encoded(sql))
end

#record_metrics(sql, args, duration) ⇒ Object

Record metrics for the specified sql and args using the specified duration.



58
59
60
61
62
63
64
65
66
67
68
# File 'lib/sequel/extensions/newrelic_instrumentation.rb', line 58

def record_metrics( sql, args, duration)
  primary_metric = primary_metric_for( sql, args )
  engine         = NewRelic::Agent.instance.stats_engine

  engine.record_metrics( primary_metric, duration, :scoped => true )

  metrics = rollup_metrics_for( primary_metric )
  metrics << remote_service_metric( *self.opts.values_at(:adapter, :host) ) if self.opts.key?(:adapter)

  engine.record_metrics( metrics, duration, :scoped => false )
end