Module: Datadog::Tracing::Contrib::ActiveRecord::Utils

Defined in:
lib/datadog/tracing/contrib/active_record/utils.rb

Overview

Common utilities for Rails

Constant Summary collapse

EMPTY_CONFIG =
{}.freeze

Class Method Summary collapse

Class Method Details

.adapter_hostObject



20
21
22
# File 'lib/datadog/tracing/contrib/active_record/utils.rb', line 20

def self.adapter_host
  connection_config[:host]
end

.adapter_nameObject



12
13
14
# File 'lib/datadog/tracing/contrib/active_record/utils.rb', line 12

def self.adapter_name
  Contrib::Utils::Database.normalize_vendor(connection_config[:adapter])
end

.adapter_portObject



24
25
26
# File 'lib/datadog/tracing/contrib/active_record/utils.rb', line 24

def self.adapter_port
  connection_config[:port]
end

.connection_config(connection = nil, connection_id = nil) ⇒ Object

Returns the connection configuration hash from the current connection

Since Rails 6.0, we have direct access to the object, while older versions of Rails only provide us the connection id.



36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
# File 'lib/datadog/tracing/contrib/active_record/utils.rb', line 36

def self.connection_config(connection = nil, connection_id = nil)
  return default_connection_config if connection.nil? && connection_id.nil?

  conn = if !connection.nil?
           # Since Rails 6.0, the connection object
           # is directly available.
           connection
         else
           # For Rails < 6.0, only the `connection_id`
           # is available. We have to find the connection
           # object from it.
           connection_from_id(connection_id)
         end

  if conn && conn.instance_variable_defined?(:@config)
    conn.instance_variable_get(:@config)
  else
    EMPTY_CONFIG
  end
end

.connection_from_id(connection_id) ⇒ Object

JRuby does not enable ObjectSpace._id2ref by default, as it has large performance impact: github.com/jruby/jruby/wiki/PerformanceTuning/cf155dd9#dont-enable-objectspace

This fallback code does not support the makara gem, as its connections don’t live in the ActiveRecord connection pool.



62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
# File 'lib/datadog/tracing/contrib/active_record/utils.rb', line 62

def self.connection_from_id(connection_id)
  # `connection_id` is the `#object_id` of the
  # connection. We can perform an ObjectSpace
  # lookup to find it.
  #
  # This works not only for ActiveRecord, but for
  # extensions that might have their own connection
  # pool (e.g. https://rubygems.org/gems/makara).
  ObjectSpace._id2ref(connection_id)
rescue => e
  # Because `connection_id` references a live connection
  # present in the current stack, it is very unlikely that
  # `_id2ref` will fail, but we add this safeguard just
  # in case.
  Datadog.logger.debug(
    "connection_id #{connection_id} does not represent a valid object. " \
            "Cause: #{e.class.name} #{e.message} Source: #{Array(e.backtrace).first}"
  )
end

.database_nameObject



16
17
18
# File 'lib/datadog/tracing/contrib/active_record/utils.rb', line 16

def self.database_name
  connection_config[:database]
end

.db_config(connection_pool) ⇒ Hash

Returns:

  • (Hash)


115
116
117
118
119
120
121
# File 'lib/datadog/tracing/contrib/active_record/utils.rb', line 115

def self.db_config(connection_pool)
  if connection_pool.respond_to? :db_config
    connection_pool.db_config.configuration_hash
  else
    connection_pool.spec.config
  end
end

.default_connection_configHash

Returns:

  • (Hash)


99
100
101
102
103
104
105
106
107
108
109
110
111
112
# File 'lib/datadog/tracing/contrib/active_record/utils.rb', line 99

def self.default_connection_config
  return @default_connection_config if instance_variable_defined?(:@default_connection_config)

  current_connection_name = if ::ActiveRecord::Base.respond_to?(:connection_specification_name)
                              ::ActiveRecord::Base.connection_specification_name
                            else
                              ::ActiveRecord::Base
                            end

  connection_pool = ::ActiveRecord::Base.connection_handler.retrieve_connection_pool(current_connection_name)
  connection_pool.nil? ? EMPTY_CONFIG : (@default_connection_config = db_config(connection_pool))
rescue StandardError
  EMPTY_CONFIG
end