ddtrace 0.13.2 → 0.14.0.beta1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.rubocop.yml +10 -0
- data/Appraisals +12 -0
- data/CHANGELOG.md +16 -5
- data/Rakefile +18 -1
- data/docs/GettingStarted.md +63 -0
- data/lib/ddtrace.rb +3 -1
- data/lib/ddtrace/configuration.rb +18 -6
- data/lib/ddtrace/contrib/active_record/configuration/resolver.rb +46 -0
- data/lib/ddtrace/contrib/active_record/configuration/settings.rb +28 -0
- data/lib/ddtrace/contrib/active_record/events/sql.rb +11 -7
- data/lib/ddtrace/contrib/active_record/integration.rb +44 -0
- data/lib/ddtrace/contrib/active_record/patcher.rb +4 -28
- data/lib/ddtrace/contrib/active_record/utils.rb +5 -11
- data/lib/ddtrace/contrib/base.rb +4 -3
- data/lib/ddtrace/contrib/configurable.rb +55 -0
- data/lib/ddtrace/contrib/configuration/option.rb +33 -0
- data/lib/ddtrace/contrib/configuration/option_definition.rb +29 -0
- data/lib/ddtrace/contrib/configuration/option_definition_set.rb +20 -0
- data/lib/ddtrace/contrib/configuration/option_set.rb +8 -0
- data/lib/ddtrace/contrib/configuration/options.rb +95 -0
- data/lib/ddtrace/contrib/configuration/resolver.rb +12 -0
- data/lib/ddtrace/contrib/configuration/settings.rb +35 -0
- data/lib/ddtrace/contrib/delayed_job/patcher.rb +41 -0
- data/lib/ddtrace/contrib/delayed_job/plugin.rb +43 -0
- data/lib/ddtrace/contrib/integration.rb +16 -0
- data/lib/ddtrace/contrib/patchable.rb +38 -0
- data/lib/ddtrace/contrib/patcher.rb +28 -0
- data/lib/ddtrace/contrib/rake/instrumentation.rb +3 -15
- data/lib/ddtrace/contrib/registerable.rb +33 -0
- data/lib/ddtrace/contrib/resque/resque_job.rb +2 -10
- data/lib/ddtrace/contrib/sequel/configuration/settings.rb +13 -0
- data/lib/ddtrace/contrib/sequel/database.rb +1 -1
- data/lib/ddtrace/contrib/sequel/integration.rb +38 -0
- data/lib/ddtrace/contrib/sequel/patcher.rb +4 -20
- data/lib/ddtrace/patcher.rb +5 -0
- data/lib/ddtrace/propagation/http_propagator.rb +0 -6
- data/lib/ddtrace/tracer.rb +17 -5
- data/lib/ddtrace/vendor/active_record/connection_specification.rb +301 -0
- data/lib/ddtrace/version.rb +3 -3
- metadata +24 -4
@@ -22,9 +22,13 @@ module Datadog
|
|
22
22
|
end
|
23
23
|
|
24
24
|
def process(span, event, _id, payload)
|
25
|
-
|
26
|
-
|
27
|
-
|
25
|
+
config = Utils.connection_config(payload[:connection_id])
|
26
|
+
settings = Datadog.configuration[:active_record, config]
|
27
|
+
adapter_name = Datadog::Utils::Database.normalize_vendor(config[:adapter])
|
28
|
+
service_name = !settings.nil? ? settings.service_name : configuration[:service_name]
|
29
|
+
|
30
|
+
span.name = "#{adapter_name}.query"
|
31
|
+
span.service = service_name
|
28
32
|
span.resource = payload.fetch(:sql)
|
29
33
|
span.span_type = Datadog::Ext::SQL::TYPE
|
30
34
|
|
@@ -33,11 +37,11 @@ module Datadog
|
|
33
37
|
# is simply cached from memory, so the notification is fired with start == finish.
|
34
38
|
cached = payload[:cached] || (payload[:name] == 'CACHE')
|
35
39
|
|
36
|
-
span.set_tag('active_record.db.vendor',
|
37
|
-
span.set_tag('active_record.db.name',
|
40
|
+
span.set_tag('active_record.db.vendor', adapter_name)
|
41
|
+
span.set_tag('active_record.db.name', config[:database])
|
38
42
|
span.set_tag('active_record.db.cached', cached) if cached
|
39
|
-
span.set_tag('out.host',
|
40
|
-
span.set_tag('out.port',
|
43
|
+
span.set_tag('out.host', config[:host]) if config[:host]
|
44
|
+
span.set_tag('out.port', config[:port]) if config[:port]
|
41
45
|
rescue StandardError => e
|
42
46
|
Datadog::Tracer.log.debug(e.message)
|
43
47
|
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
require 'ddtrace/ext/sql'
|
2
|
+
require 'ddtrace/ext/app_types'
|
3
|
+
require 'ddtrace/contrib/integration'
|
4
|
+
require 'ddtrace/contrib/active_record/events'
|
5
|
+
require 'ddtrace/contrib/active_record/configuration/resolver'
|
6
|
+
require 'ddtrace/contrib/active_record/configuration/settings'
|
7
|
+
require 'ddtrace/contrib/active_record/patcher'
|
8
|
+
|
9
|
+
module Datadog
|
10
|
+
module Contrib
|
11
|
+
module ActiveRecord
|
12
|
+
# Describes the ActiveRecord integration
|
13
|
+
class Integration
|
14
|
+
include Contrib::Integration
|
15
|
+
|
16
|
+
register_as :active_record, auto_patch: false
|
17
|
+
|
18
|
+
def self.version
|
19
|
+
Gem.loaded_specs['activerecord'] && Gem.loaded_specs['activerecord'].version
|
20
|
+
end
|
21
|
+
|
22
|
+
def self.present?
|
23
|
+
super && defined?(::ActiveRecord)
|
24
|
+
end
|
25
|
+
|
26
|
+
def self.compatible?
|
27
|
+
super && version >= Gem::Version.new('3.0')
|
28
|
+
end
|
29
|
+
|
30
|
+
def default_configuration
|
31
|
+
Configuration::Settings.new
|
32
|
+
end
|
33
|
+
|
34
|
+
def patcher
|
35
|
+
ActiveRecord::Patcher
|
36
|
+
end
|
37
|
+
|
38
|
+
def resolver
|
39
|
+
@resolver ||= Configuration::Resolver.new
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -1,6 +1,4 @@
|
|
1
|
-
require 'ddtrace/
|
2
|
-
require 'ddtrace/ext/app_types'
|
3
|
-
require 'ddtrace/contrib/active_record/utils'
|
1
|
+
require 'ddtrace/contrib/patcher'
|
4
2
|
require 'ddtrace/contrib/active_record/events'
|
5
3
|
|
6
4
|
module Datadog
|
@@ -8,44 +6,22 @@ module Datadog
|
|
8
6
|
module ActiveRecord
|
9
7
|
# Patcher enables patching of 'active_record' module.
|
10
8
|
module Patcher
|
11
|
-
include
|
12
|
-
|
13
|
-
register_as :active_record, auto_patch: false
|
14
|
-
option :service_name, depends_on: [:tracer] do |value|
|
15
|
-
(value || Utils.adapter_name).tap do |v|
|
16
|
-
get_option(:tracer).set_service_info(v, 'active_record', Ext::AppTypes::DB)
|
17
|
-
end
|
18
|
-
end
|
19
|
-
option :orm_service_name
|
20
|
-
option :tracer, default: Datadog.tracer do |value|
|
21
|
-
(value || Datadog.tracer).tap do |v|
|
22
|
-
# Make sure to update tracers of all subscriptions
|
23
|
-
Events.subscriptions.each do |subscription|
|
24
|
-
subscription.tracer = v
|
25
|
-
end
|
26
|
-
end
|
27
|
-
end
|
28
|
-
|
29
|
-
@patched = false
|
9
|
+
include Contrib::Patcher
|
30
10
|
|
31
11
|
module_function
|
32
12
|
|
33
|
-
# patched? tells whether patch has been successfully applied
|
34
13
|
def patched?
|
35
|
-
|
14
|
+
done?(:active_record)
|
36
15
|
end
|
37
16
|
|
38
17
|
def patch
|
39
|
-
|
18
|
+
do_once(:active_record) do
|
40
19
|
begin
|
41
20
|
Events.subscribe!
|
42
|
-
@patched = true
|
43
21
|
rescue StandardError => e
|
44
22
|
Datadog::Tracer.log.error("Unable to apply Active Record integration: #{e}")
|
45
23
|
end
|
46
24
|
end
|
47
|
-
|
48
|
-
@patched
|
49
25
|
end
|
50
26
|
end
|
51
27
|
end
|
@@ -4,29 +4,23 @@ module Datadog
|
|
4
4
|
# Common utilities for Rails
|
5
5
|
module Utils
|
6
6
|
def self.adapter_name
|
7
|
-
connection_config[:
|
7
|
+
Datadog::Utils::Database.normalize_vendor(connection_config[:adapter])
|
8
8
|
end
|
9
9
|
|
10
10
|
def self.database_name
|
11
|
-
connection_config[:
|
11
|
+
connection_config[:database]
|
12
12
|
end
|
13
13
|
|
14
14
|
def self.adapter_host
|
15
|
-
connection_config[:
|
15
|
+
connection_config[:host]
|
16
16
|
end
|
17
17
|
|
18
18
|
def self.adapter_port
|
19
|
-
connection_config[:
|
19
|
+
connection_config[:port]
|
20
20
|
end
|
21
21
|
|
22
22
|
def self.connection_config(object_id = nil)
|
23
|
-
|
24
|
-
{
|
25
|
-
adapter_name: Datadog::Utils::Database.normalize_vendor(config[:adapter]),
|
26
|
-
adapter_host: config[:host],
|
27
|
-
adapter_port: config[:port],
|
28
|
-
database_name: config[:database]
|
29
|
-
}
|
23
|
+
object_id.nil? ? default_connection_config : connection_config_by_id(object_id)
|
30
24
|
end
|
31
25
|
|
32
26
|
# Attempt to retrieve the connection from an object ID.
|
data/lib/ddtrace/contrib/base.rb
CHANGED
@@ -1,5 +1,6 @@
|
|
1
|
-
require 'ddtrace/registry'
|
2
1
|
require 'ddtrace/configurable'
|
2
|
+
require 'ddtrace/patcher'
|
3
|
+
require 'ddtrace/registry/registerable'
|
3
4
|
|
4
5
|
module Datadog
|
5
6
|
module Contrib
|
@@ -7,8 +8,8 @@ module Datadog
|
|
7
8
|
module Base
|
8
9
|
def self.included(base)
|
9
10
|
base.send(:include, Registry::Registerable)
|
10
|
-
base.send(:include, Configurable)
|
11
|
-
base.send(:include, Patcher)
|
11
|
+
base.send(:include, Datadog::Configurable)
|
12
|
+
base.send(:include, Datadog::Patcher)
|
12
13
|
end
|
13
14
|
end
|
14
15
|
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
require 'ddtrace/contrib/configuration/resolver'
|
2
|
+
require 'ddtrace/contrib/configuration/settings'
|
3
|
+
|
4
|
+
module Datadog
|
5
|
+
module Contrib
|
6
|
+
# Defines configurable behavior for integrations
|
7
|
+
module Configurable
|
8
|
+
def self.included(base)
|
9
|
+
base.send(:include, InstanceMethods)
|
10
|
+
end
|
11
|
+
|
12
|
+
# Configurable instance behavior for integrations
|
13
|
+
module InstanceMethods
|
14
|
+
def default_configuration
|
15
|
+
Configuration::Settings.new
|
16
|
+
end
|
17
|
+
|
18
|
+
def reset_configuration!
|
19
|
+
@configurations = nil
|
20
|
+
@resolver = nil
|
21
|
+
end
|
22
|
+
|
23
|
+
def configuration(name = :default)
|
24
|
+
name = :default if name.nil?
|
25
|
+
name = resolver.resolve(name)
|
26
|
+
return nil unless configurations.key?(name)
|
27
|
+
configurations[name]
|
28
|
+
end
|
29
|
+
|
30
|
+
def configurations
|
31
|
+
@configurations ||= Hash.new { default_configuration }.tap do |configs|
|
32
|
+
configs[:default] = default_configuration
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
def configure(name, options = {}, &block)
|
37
|
+
name = resolver.resolve(name || :default)
|
38
|
+
|
39
|
+
configurations[name].tap do |settings|
|
40
|
+
settings.configure(options, &block)
|
41
|
+
configurations[name] = settings
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
protected
|
46
|
+
|
47
|
+
attr_writer :resolver
|
48
|
+
|
49
|
+
def resolver
|
50
|
+
@resolver ||= Configuration::Resolver.new
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
module Datadog
|
2
|
+
module Contrib
|
3
|
+
module Configuration
|
4
|
+
# Represents an instance of an integration configuration option
|
5
|
+
class Option
|
6
|
+
attr_reader \
|
7
|
+
:definition
|
8
|
+
|
9
|
+
def initialize(definition, context)
|
10
|
+
@definition = definition
|
11
|
+
@context = context
|
12
|
+
@value = nil
|
13
|
+
@is_set = false
|
14
|
+
end
|
15
|
+
|
16
|
+
def set(value)
|
17
|
+
@value = @context.instance_exec(value, &definition.setter).tap do
|
18
|
+
@is_set = true
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
def get
|
23
|
+
return definition.default_value unless @is_set
|
24
|
+
@value
|
25
|
+
end
|
26
|
+
|
27
|
+
def reset
|
28
|
+
set(definition.default_value)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
module Datadog
|
2
|
+
module Contrib
|
3
|
+
module Configuration
|
4
|
+
# Represents a definition for an integration configuration option
|
5
|
+
class OptionDefinition
|
6
|
+
IDENTITY = ->(x) { x }
|
7
|
+
|
8
|
+
attr_reader \
|
9
|
+
:default,
|
10
|
+
:depends_on,
|
11
|
+
:lazy,
|
12
|
+
:name,
|
13
|
+
:setter
|
14
|
+
|
15
|
+
def initialize(name, meta = {}, &block)
|
16
|
+
@default = meta[:default]
|
17
|
+
@depends_on = meta[:depends_on] || []
|
18
|
+
@lazy = meta[:lazy] || false
|
19
|
+
@name = name.to_sym
|
20
|
+
@setter = meta[:setter] || block || IDENTITY
|
21
|
+
end
|
22
|
+
|
23
|
+
def default_value
|
24
|
+
lazy ? @default.call : @default
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
require 'ddtrace/configuration/resolver'
|
2
|
+
|
3
|
+
module Datadog
|
4
|
+
module Contrib
|
5
|
+
module Configuration
|
6
|
+
# Represents a set of configuration option definitions for an integration
|
7
|
+
class OptionDefinitionSet < Hash
|
8
|
+
def dependency_order
|
9
|
+
Datadog::Configuration::Resolver.new(dependency_graph).call
|
10
|
+
end
|
11
|
+
|
12
|
+
def dependency_graph
|
13
|
+
each_with_object({}) do |(name, option), graph|
|
14
|
+
graph[name] = option.depends_on
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,95 @@
|
|
1
|
+
require 'ddtrace/contrib/configuration/option'
|
2
|
+
require 'ddtrace/contrib/configuration/option_set'
|
3
|
+
require 'ddtrace/contrib/configuration/option_definition'
|
4
|
+
require 'ddtrace/contrib/configuration/option_definition_set'
|
5
|
+
|
6
|
+
module Datadog
|
7
|
+
module Contrib
|
8
|
+
module Configuration
|
9
|
+
# Behavior for a configuration object that has options
|
10
|
+
module Options
|
11
|
+
def self.included(base)
|
12
|
+
base.send(:extend, ClassMethods)
|
13
|
+
base.send(:include, InstanceMethods)
|
14
|
+
end
|
15
|
+
|
16
|
+
# Class behavior for a configuration object with options
|
17
|
+
module ClassMethods
|
18
|
+
def options
|
19
|
+
@options ||= begin
|
20
|
+
# Allows for class inheritance of option definitions
|
21
|
+
superclass <= Options ? superclass.options.dup : OptionDefinitionSet.new
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
protected
|
26
|
+
|
27
|
+
def option(name, meta = {}, &block)
|
28
|
+
options[name] = OptionDefinition.new(name, meta, &block).tap do
|
29
|
+
define_option_accessors(name)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
private
|
34
|
+
|
35
|
+
def define_option_accessors(name)
|
36
|
+
option_name = name
|
37
|
+
|
38
|
+
define_method(option_name) do
|
39
|
+
get_option(option_name)
|
40
|
+
end
|
41
|
+
|
42
|
+
define_method("#{option_name}=") do |value|
|
43
|
+
set_option(option_name, value)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
# Instance behavior for a configuration object with options
|
49
|
+
module InstanceMethods
|
50
|
+
def options
|
51
|
+
@options ||= OptionSet.new
|
52
|
+
end
|
53
|
+
|
54
|
+
def set_option(name, value)
|
55
|
+
add_option(name) unless options.key?(name)
|
56
|
+
options[name].set(value)
|
57
|
+
end
|
58
|
+
|
59
|
+
def get_option(name)
|
60
|
+
add_option(name) unless options.key?(name)
|
61
|
+
options[name].get
|
62
|
+
end
|
63
|
+
|
64
|
+
def to_h
|
65
|
+
options.each_with_object({}) do |(key, _), hash|
|
66
|
+
hash[key] = get_option(key)
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
def reset_options!
|
71
|
+
options.values.each(&:reset)
|
72
|
+
end
|
73
|
+
|
74
|
+
private
|
75
|
+
|
76
|
+
def add_option(name)
|
77
|
+
assert_valid_option!(name)
|
78
|
+
definition = self.class.options[name]
|
79
|
+
Option.new(definition, self).tap do |option|
|
80
|
+
options[name] = option
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
def assert_valid_option!(name)
|
85
|
+
unless self.class.options.key?(name)
|
86
|
+
raise(InvalidOptionError, "#{self.class.name} doesn't define the option: #{name}")
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
InvalidOptionError = Class.new(StandardError)
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|