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



22
23
24
# File 'lib/datadog/tracing/contrib/active_record/utils.rb', line 22

def self.adapter_host
  connection_config[:host]
end

.adapter_nameObject



14
15
16
# File 'lib/datadog/tracing/contrib/active_record/utils.rb', line 14

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

.adapter_portObject



26
27
28
# File 'lib/datadog/tracing/contrib/active_record/utils.rb', line 26

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.



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

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.



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

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



18
19
20
# File 'lib/datadog/tracing/contrib/active_record/utils.rb', line 18

def self.database_name
  connection_config[:database]
end

.db_config(connection_pool) ⇒ Hash

Returns:

  • (Hash)


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

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)


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

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