Module: Datadog::Contrib::ActiveRecord::Patcher

Defined in:
lib/ddtrace/contrib/active_record/patcher.rb

Overview

Patcher enables patching of ‘active_record’ module. This is used in monkey.rb to manually apply patches

Class Method Summary collapse

Class Method Details

.adapter_nameObject



47
48
49
50
51
# File 'lib/ddtrace/contrib/active_record/patcher.rb', line 47

def self.adapter_name
  @adapter_name ||= Datadog::Contrib::Rails::Utils.normalize_vendor(
    ::ActiveRecord::Base.connection_config[:adapter]
  )
end

.database_serviceObject



58
59
60
61
62
63
64
65
66
67
68
69
# File 'lib/ddtrace/contrib/active_record/patcher.rb', line 58

def self.database_service
  @database_service ||= if defined?(::Sinatra)
                          datadog_trace.fetch(:default_database_service, adapter_name())
                        else
                          adapter_name()
                        end
  if @database_service
    tracer().set_service_info(@database_service, 'sinatra',
                              Datadog::Ext::AppTypes::DB)
  end
  @database_service
end

.datadog_traceObject



41
42
43
44
45
# File 'lib/ddtrace/contrib/active_record/patcher.rb', line 41

def self.datadog_trace
  # TODO: Consider using patcher for Rails as well.
  # @tracer ||= defined?(::Rails) && ::Rails.configuration.datadog_trace
  @datadog_trace ||= defined?(::Sinatra) && ::Sinatra::Application.settings.datadog_tracer.cfg
end

.patchObject



16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
# File 'lib/ddtrace/contrib/active_record/patcher.rb', line 16

def patch
  if !@patched && defined?(::ActiveRecord)
    begin
      require 'ddtrace/contrib/rails/utils'
      require 'ddtrace/ext/sql'
      require 'ddtrace/ext/app_types'

      patch_active_record()

      @patched = true
    rescue StandardError => e
      Datadog::Tracer.log.error("Unable to apply Active Record integration: #{e}")
    end
  end

  @patched
end

.patch_active_recordObject



34
35
36
37
38
39
# File 'lib/ddtrace/contrib/active_record/patcher.rb', line 34

def patch_active_record
  # subscribe when the active record query has been processed
  ::ActiveSupport::Notifications.subscribe('sql.active_record') do |*args|
    sql(*args)
  end
end

.patched?Boolean

patched? tells whether patch has been successfully applied

Returns:

  • (Boolean)


12
13
14
# File 'lib/ddtrace/contrib/active_record/patcher.rb', line 12

def patched?
  @patched
end

.sql(_name, start, finish, _id, payload) ⇒ Object



71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
# File 'lib/ddtrace/contrib/active_record/patcher.rb', line 71

def self.sql(_name, start, finish, _id, payload)
  span_type = Datadog::Ext::SQL::TYPE

  span = tracer.trace(
    "#{adapter_name}.query",
    resource: payload.fetch(:sql),
    service: database_service,
    span_type: span_type
  )

  # the span should have the query ONLY in the Resource attribute,
  # so that the ``sql.query`` tag will be set in the agent with an
  # obfuscated version
  span.span_type = Datadog::Ext::SQL::TYPE
  span.set_tag('active_record.db.vendor', adapter_name)
  span.start_time = start
  span.finish(finish)
rescue StandardError => e
  Datadog::Tracer.log.error(e.message)
end

.tracerObject



53
54
55
56
# File 'lib/ddtrace/contrib/active_record/patcher.rb', line 53

def self.tracer
  return Datadog.tracer unless datadog_trace
  @tracer ||= datadog_trace.fetch(:tracer)
end