ddtrace 0.13.2 → 0.14.0.beta1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (41) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +10 -0
  3. data/Appraisals +12 -0
  4. data/CHANGELOG.md +16 -5
  5. data/Rakefile +18 -1
  6. data/docs/GettingStarted.md +63 -0
  7. data/lib/ddtrace.rb +3 -1
  8. data/lib/ddtrace/configuration.rb +18 -6
  9. data/lib/ddtrace/contrib/active_record/configuration/resolver.rb +46 -0
  10. data/lib/ddtrace/contrib/active_record/configuration/settings.rb +28 -0
  11. data/lib/ddtrace/contrib/active_record/events/sql.rb +11 -7
  12. data/lib/ddtrace/contrib/active_record/integration.rb +44 -0
  13. data/lib/ddtrace/contrib/active_record/patcher.rb +4 -28
  14. data/lib/ddtrace/contrib/active_record/utils.rb +5 -11
  15. data/lib/ddtrace/contrib/base.rb +4 -3
  16. data/lib/ddtrace/contrib/configurable.rb +55 -0
  17. data/lib/ddtrace/contrib/configuration/option.rb +33 -0
  18. data/lib/ddtrace/contrib/configuration/option_definition.rb +29 -0
  19. data/lib/ddtrace/contrib/configuration/option_definition_set.rb +20 -0
  20. data/lib/ddtrace/contrib/configuration/option_set.rb +8 -0
  21. data/lib/ddtrace/contrib/configuration/options.rb +95 -0
  22. data/lib/ddtrace/contrib/configuration/resolver.rb +12 -0
  23. data/lib/ddtrace/contrib/configuration/settings.rb +35 -0
  24. data/lib/ddtrace/contrib/delayed_job/patcher.rb +41 -0
  25. data/lib/ddtrace/contrib/delayed_job/plugin.rb +43 -0
  26. data/lib/ddtrace/contrib/integration.rb +16 -0
  27. data/lib/ddtrace/contrib/patchable.rb +38 -0
  28. data/lib/ddtrace/contrib/patcher.rb +28 -0
  29. data/lib/ddtrace/contrib/rake/instrumentation.rb +3 -15
  30. data/lib/ddtrace/contrib/registerable.rb +33 -0
  31. data/lib/ddtrace/contrib/resque/resque_job.rb +2 -10
  32. data/lib/ddtrace/contrib/sequel/configuration/settings.rb +13 -0
  33. data/lib/ddtrace/contrib/sequel/database.rb +1 -1
  34. data/lib/ddtrace/contrib/sequel/integration.rb +38 -0
  35. data/lib/ddtrace/contrib/sequel/patcher.rb +4 -20
  36. data/lib/ddtrace/patcher.rb +5 -0
  37. data/lib/ddtrace/propagation/http_propagator.rb +0 -6
  38. data/lib/ddtrace/tracer.rb +17 -5
  39. data/lib/ddtrace/vendor/active_record/connection_specification.rb +301 -0
  40. data/lib/ddtrace/version.rb +3 -3
  41. metadata +24 -4
@@ -22,9 +22,13 @@ module Datadog
22
22
  end
23
23
 
24
24
  def process(span, event, _id, payload)
25
- connection_config = Utils.connection_config(payload[:connection_id])
26
- span.name = "#{connection_config[:adapter_name]}.query"
27
- span.service = configuration[:service_name]
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', connection_config[:adapter_name])
37
- span.set_tag('active_record.db.name', connection_config[:database_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', connection_config[:adapter_host])
40
- span.set_tag('out.port', connection_config[:adapter_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/ext/sql'
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 Base
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
- @patched
14
+ done?(:active_record)
36
15
  end
37
16
 
38
17
  def patch
39
- if !@patched && defined?(::ActiveRecord)
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[:adapter_name]
7
+ Datadog::Utils::Database.normalize_vendor(connection_config[:adapter])
8
8
  end
9
9
 
10
10
  def self.database_name
11
- connection_config[:database_name]
11
+ connection_config[:database]
12
12
  end
13
13
 
14
14
  def self.adapter_host
15
- connection_config[:adapter_host]
15
+ connection_config[:host]
16
16
  end
17
17
 
18
18
  def self.adapter_port
19
- connection_config[:adapter_port]
19
+ connection_config[:port]
20
20
  end
21
21
 
22
22
  def self.connection_config(object_id = nil)
23
- config = object_id.nil? ? default_connection_config : connection_config_by_id(object_id)
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.
@@ -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,8 @@
1
+ module Datadog
2
+ module Contrib
3
+ module Configuration
4
+ class OptionSet < Hash
5
+ end
6
+ end
7
+ end
8
+ 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
@@ -0,0 +1,12 @@
1
+ module Datadog
2
+ module Contrib
3
+ module Configuration
4
+ # Resolves a value to a configuration key
5
+ class Resolver
6
+ def resolve(name)
7
+ name
8
+ end
9
+ end
10
+ end
11
+ end
12
+ end