ddtrace 0.32.0 → 0.33.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (65) hide show
  1. checksums.yaml +5 -5
  2. data/.env +2 -0
  3. data/Appraisals +9 -6
  4. data/CHANGELOG.md +32 -1
  5. data/Rakefile +3 -2
  6. data/ddtrace.gemspec +2 -1
  7. data/docker-compose.yml +9 -0
  8. data/docs/GettingStarted.md +69 -6
  9. data/lib/ddtrace.rb +1 -0
  10. data/lib/ddtrace/configuration/option.rb +3 -2
  11. data/lib/ddtrace/configuration/option_definition.rb +1 -1
  12. data/lib/ddtrace/configuration/options.rb +5 -0
  13. data/lib/ddtrace/contrib/action_cable/integration.rb +2 -2
  14. data/lib/ddtrace/contrib/action_pack/integration.rb +2 -2
  15. data/lib/ddtrace/contrib/action_view/integration.rb +2 -2
  16. data/lib/ddtrace/contrib/active_model_serializers/integration.rb +3 -5
  17. data/lib/ddtrace/contrib/active_record/configuration/resolver.rb +4 -5
  18. data/lib/ddtrace/contrib/active_record/integration.rb +2 -2
  19. data/lib/ddtrace/contrib/active_support/integration.rb +2 -2
  20. data/lib/ddtrace/contrib/aws/integration.rb +6 -2
  21. data/lib/ddtrace/contrib/aws/patcher.rb +8 -2
  22. data/lib/ddtrace/contrib/concurrent_ruby/integration.rb +6 -2
  23. data/lib/ddtrace/contrib/configurable.rb +30 -13
  24. data/lib/ddtrace/contrib/configuration/resolver.rb +7 -3
  25. data/lib/ddtrace/contrib/dalli/integration.rb +2 -2
  26. data/lib/ddtrace/contrib/delayed_job/integration.rb +6 -2
  27. data/lib/ddtrace/contrib/elasticsearch/integration.rb +2 -2
  28. data/lib/ddtrace/contrib/ethon/integration.rb +6 -2
  29. data/lib/ddtrace/contrib/excon/integration.rb +6 -2
  30. data/lib/ddtrace/contrib/faraday/integration.rb +2 -2
  31. data/lib/ddtrace/contrib/grape/integration.rb +3 -3
  32. data/lib/ddtrace/contrib/graphql/integration.rb +3 -5
  33. data/lib/ddtrace/contrib/grpc/integration.rb +2 -2
  34. data/lib/ddtrace/contrib/http/integration.rb +4 -0
  35. data/lib/ddtrace/contrib/mongodb/integration.rb +2 -2
  36. data/lib/ddtrace/contrib/mysql2/integration.rb +6 -2
  37. data/lib/ddtrace/contrib/patchable.rb +21 -4
  38. data/lib/ddtrace/contrib/presto/configuration/settings.rb +23 -0
  39. data/lib/ddtrace/contrib/presto/ext.rb +25 -0
  40. data/lib/ddtrace/contrib/presto/instrumentation.rb +107 -0
  41. data/lib/ddtrace/contrib/presto/integration.rb +36 -0
  42. data/lib/ddtrace/contrib/presto/patcher.rb +30 -0
  43. data/lib/ddtrace/contrib/racecar/integration.rb +3 -3
  44. data/lib/ddtrace/contrib/rack/integration.rb +6 -2
  45. data/lib/ddtrace/contrib/rails/integration.rb +6 -3
  46. data/lib/ddtrace/contrib/rake/integration.rb +6 -2
  47. data/lib/ddtrace/contrib/redis/configuration/resolver.rb +36 -0
  48. data/lib/ddtrace/contrib/redis/integration.rb +7 -3
  49. data/lib/ddtrace/contrib/redis/patcher.rb +11 -2
  50. data/lib/ddtrace/contrib/redis/vendor/resolver.rb +159 -0
  51. data/lib/ddtrace/contrib/resque/integration.rb +8 -2
  52. data/lib/ddtrace/contrib/rest_client/integration.rb +6 -2
  53. data/lib/ddtrace/contrib/sequel/integration.rb +6 -2
  54. data/lib/ddtrace/contrib/shoryuken/integration.rb +9 -7
  55. data/lib/ddtrace/contrib/sidekiq/configuration/settings.rb +5 -0
  56. data/lib/ddtrace/contrib/sidekiq/ext.rb +2 -0
  57. data/lib/ddtrace/contrib/sidekiq/integration.rb +2 -2
  58. data/lib/ddtrace/contrib/sidekiq/server_tracer.rb +7 -3
  59. data/lib/ddtrace/contrib/sidekiq/tracing.rb +19 -2
  60. data/lib/ddtrace/contrib/sinatra/integration.rb +2 -2
  61. data/lib/ddtrace/contrib/sucker_punch/integration.rb +3 -3
  62. data/lib/ddtrace/runtime/metrics.rb +2 -2
  63. data/lib/ddtrace/sampling/rule_sampler.rb +16 -2
  64. data/lib/ddtrace/version.rb +1 -1
  65. metadata +12 -18
@@ -0,0 +1,36 @@
1
+ require 'ddtrace/contrib/integration'
2
+ require 'ddtrace/contrib/presto/configuration/settings'
3
+ require 'ddtrace/contrib/presto/patcher'
4
+
5
+ module Datadog
6
+ module Contrib
7
+ module Presto
8
+ # Description of Presto integration
9
+ class Integration
10
+ include Contrib::Integration
11
+
12
+ register_as :presto
13
+
14
+ def self.version
15
+ Gem.loaded_specs['presto-client'] && Gem.loaded_specs['presto-client'].version
16
+ end
17
+
18
+ def self.loaded?
19
+ defined?(::Presto::Client::Client)
20
+ end
21
+
22
+ def self.compatible?
23
+ super && version >= Gem::Version.new('0.5.14')
24
+ end
25
+
26
+ def default_configuration
27
+ Configuration::Settings.new
28
+ end
29
+
30
+ def patcher
31
+ Patcher
32
+ end
33
+ end
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,30 @@
1
+ require 'ddtrace/contrib/patcher'
2
+ require 'ddtrace/contrib/presto/ext'
3
+ require 'ddtrace/contrib/presto/instrumentation'
4
+
5
+ module Datadog
6
+ module Contrib
7
+ module Presto
8
+ # Patcher enables patching of 'presto-client' module.
9
+ module Patcher
10
+ include Contrib::Patcher
11
+
12
+ module_function
13
+
14
+ def patched?
15
+ done?(:presto)
16
+ end
17
+
18
+ def patch
19
+ do_once(:presto) do
20
+ begin
21
+ ::Presto::Client::Client.send(:include, Instrumentation::Client)
22
+ rescue StandardError => e
23
+ Datadog::Logger.log.error("Unable to apply Presto integration: #{e}")
24
+ end
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
30
+ end
@@ -15,12 +15,12 @@ module Datadog
15
15
  Gem.loaded_specs['racecar'] && Gem.loaded_specs['racecar'].version
16
16
  end
17
17
 
18
- def self.present?
19
- super && defined?(::Racecar)
18
+ def self.loaded?
19
+ defined?(::Racecar) && defined?(::ActiveSupport::Notifications)
20
20
  end
21
21
 
22
22
  def self.compatible?
23
- super && defined?(::ActiveSupport::Notifications)
23
+ super && version >= Gem::Version.new('0.3.5')
24
24
  end
25
25
 
26
26
  def default_configuration
@@ -15,8 +15,12 @@ module Datadog
15
15
  Gem.loaded_specs['rack'] && Gem.loaded_specs['rack'].version
16
16
  end
17
17
 
18
- def self.present?
19
- super && defined?(::Rack)
18
+ def self.loaded?
19
+ defined?(::Rack)
20
+ end
21
+
22
+ def self.compatible?
23
+ super && version >= Gem::Version.new('1.1.0')
20
24
  end
21
25
 
22
26
  def default_configuration
@@ -15,13 +15,16 @@ module Datadog
15
15
  Gem.loaded_specs['rails'] && Gem.loaded_specs['rails'].version
16
16
  end
17
17
 
18
- def self.present?
18
+ def self.loaded?
19
19
  defined?(::Rails)
20
20
  end
21
21
 
22
22
  def self.compatible?
23
- return false if ENV['DISABLE_DATADOG_RAILS']
24
- super && defined?(::Rails::VERSION) && ::Rails::VERSION::MAJOR.to_i >= 3
23
+ super && version >= Gem::Version.new('3.0')
24
+ end
25
+
26
+ def self.patchable?
27
+ super && !ENV.key?('DISABLE_DATADOG_RAILS')
25
28
  end
26
29
 
27
30
  def default_configuration
@@ -15,8 +15,12 @@ module Datadog
15
15
  Gem.loaded_specs['rake'] && Gem.loaded_specs['rake'].version
16
16
  end
17
17
 
18
- def self.present?
19
- super && defined?(::Rake)
18
+ def self.loaded?
19
+ defined?(::Rake)
20
+ end
21
+
22
+ def self.compatible?
23
+ super && version >= Gem::Version.new('12.0')
20
24
  end
21
25
 
22
26
  def default_configuration
@@ -0,0 +1,36 @@
1
+ require 'ddtrace/contrib/redis/vendor/resolver'
2
+
3
+ module Datadog
4
+ module Contrib
5
+ module Redis
6
+ module Configuration
7
+ # Converts Symbols, Strings, and Hashes to a normalized connection settings Hash.
8
+ class Resolver < Contrib::Configuration::Resolver
9
+ def resolve(key_or_hash)
10
+ return :default if key_or_hash == :default
11
+
12
+ normalize(connection_resolver.resolve(key_or_hash))
13
+ end
14
+
15
+ def normalize(hash)
16
+ return { url: hash[:url] } if hash[:scheme] == 'unix'
17
+
18
+ # Connexion strings are always converted to host, port, db and scheme
19
+ # but the host, port, db and scheme will generate the :url only after
20
+ # establishing a first connexion
21
+ {
22
+ host: hash[:host],
23
+ port: hash[:port],
24
+ db: hash[:db],
25
+ scheme: hash[:scheme]
26
+ }
27
+ end
28
+
29
+ def connection_resolver
30
+ @connection_resolver ||= ::Datadog::Contrib::Redis::Vendor::Resolver.new
31
+ end
32
+ end
33
+ end
34
+ end
35
+ end
36
+ end
@@ -15,12 +15,12 @@ module Datadog
15
15
  Gem.loaded_specs['redis'] && Gem.loaded_specs['redis'].version
16
16
  end
17
17
 
18
- def self.present?
19
- super && defined?(::Redis)
18
+ def self.loaded?
19
+ defined?(::Redis)
20
20
  end
21
21
 
22
22
  def self.compatible?
23
- !version.nil? && version >= Gem::Version.new('3.0.0')
23
+ super && version >= Gem::Version.new('3.2')
24
24
  end
25
25
 
26
26
  def default_configuration
@@ -30,6 +30,10 @@ module Datadog
30
30
  def patcher
31
31
  Patcher
32
32
  end
33
+
34
+ def resolver
35
+ @resolver ||= Configuration::Resolver.new
36
+ end
33
37
  end
34
38
  end
35
39
  end
@@ -1,5 +1,6 @@
1
1
  require 'ddtrace/contrib/patcher'
2
2
  require 'ddtrace/contrib/redis/ext'
3
+ require 'ddtrace/contrib/redis/configuration/resolver'
3
4
 
4
5
  module Datadog
5
6
  module Contrib
@@ -72,16 +73,24 @@ module Datadog
72
73
  def datadog_pin
73
74
  @datadog_pin ||= begin
74
75
  pin = Datadog::Pin.new(
75
- Datadog.configuration[:redis][:service_name],
76
+ datadog_configuration[:service_name],
76
77
  app: Ext::APP,
77
78
  app_type: Datadog::Ext::AppTypes::DB,
78
- tracer: Datadog.configuration[:redis][:tracer]
79
+ tracer: datadog_configuration[:tracer]
79
80
  )
80
81
  pin.onto(self)
81
82
  end
82
83
  end
84
+
85
+ private
86
+
87
+ def datadog_configuration
88
+ Datadog.configuration[:redis, options]
89
+ end
83
90
  end
84
91
  end
92
+ # rubocop:enable Metrics/MethodLength
93
+ # rubocop:enable Metrics/BlockLength
85
94
  end
86
95
  end
87
96
  end
@@ -0,0 +1,159 @@
1
+ require 'uri'
2
+
3
+ # NOTE: This code is copied directly from Redis.
4
+ # Its purpose is to resolve connection information.
5
+ # It exists here only because it doesn't exist in the redis
6
+ # library as a separated module and it allows to avoid
7
+ # instantiating a new Redis::Client for resolving the connection
8
+ module Datadog
9
+ module Contrib
10
+ module Redis
11
+ module Vendor
12
+ class Resolver # :nodoc:
13
+ # Connection DEFAULTS for a Redis::Client are unchanged for
14
+ # the integration supported options.
15
+ # https://github.com/redis/redis-rb/blob/v3.0.0/lib/redis/client.rb#L6-L14
16
+ # https://github.com/redis/redis-rb/blob/v4.1.3/lib/redis/client.rb#L10-L26
17
+ # Since the integration takes in consideration only few attributes, all
18
+ # versions are compatible for :url, :scheme, :host, :port, :db
19
+ DEFAULTS = {
20
+ url: -> { ENV['REDIS_URL'] },
21
+ scheme: 'redis',
22
+ host: '127.0.0.1',
23
+ port: 6379,
24
+ path: nil,
25
+ # :timeout => 5.0,
26
+ password: nil,
27
+ db: 0 # ,
28
+ # :driver => nil,
29
+ # :id => nil,
30
+ # :tcp_keepalive => 0,
31
+ # :reconnect_attempts => 1,
32
+ # :reconnect_delay => 0,
33
+ # :reconnect_delay_max => 0.5,
34
+ # :inherit_socket => false
35
+ }.freeze
36
+
37
+ def resolve(options)
38
+ _parse_options(options)
39
+ end
40
+
41
+ # rubocop:disable Metrics/AbcSize
42
+ # rubocop:disable Metrics/MethodLength
43
+ # rubocop:disable Metrics/PerceivedComplexity
44
+ #
45
+ # This method is a subset of the implementation provided in v3.0.0
46
+ # https://github.com/redis/redis-rb/blob/v3.0.0/lib/redis/client.rb
47
+ # https://github.com/redis/redis-rb/blob/v4.1.3/lib/redis/client.rb
48
+ #
49
+ # Since it has been backported from the original gem, some linting
50
+ # cops have been disabled
51
+ def _parse_options(options)
52
+ # https://github.com/redis/redis-rb/blob/v4.1.3/lib/redis/client.rb#L404
53
+ # Early return for modern client options
54
+ return options if options[:_parsed]
55
+
56
+ defaults = DEFAULTS.dup
57
+ options = options.dup
58
+
59
+ defaults.keys.each do |key|
60
+ # Fill in defaults if needed
61
+ if defaults[key].respond_to?(:call)
62
+ defaults[key] = defaults[key].call
63
+ end
64
+
65
+ # Symbolize only keys that are needed
66
+ options[key] = options[key.to_s] if options.key?(key.to_s)
67
+ end
68
+
69
+ url = options[:url]
70
+ url = defaults[:url] if url.nil?
71
+
72
+ # Override defaults from URL if given
73
+ if url
74
+ uri = URI(url)
75
+
76
+ if uri.scheme == 'unix'
77
+ defaults[:path] = uri.path
78
+ elsif uri.scheme == 'redis' || uri.scheme == 'rediss'
79
+ defaults[:scheme] = uri.scheme
80
+ defaults[:host] = uri.host if uri.host
81
+ defaults[:port] = uri.port if uri.port
82
+ defaults[:password] = CGI.unescape(uri.password) if uri.password
83
+ defaults[:db] = uri.path[1..-1].to_i if uri.path
84
+ defaults[:role] = :master
85
+ else
86
+ raise ArgumentError, "invalid uri scheme '#{uri.scheme}'"
87
+ end
88
+
89
+ # defaults[:ssl] = true if uri.scheme == "rediss"
90
+ end
91
+
92
+ # Use default when option is not specified or nil
93
+ defaults.keys.each do |key|
94
+ options[key] = defaults[key] if options[key].nil?
95
+ end
96
+
97
+ if options[:path]
98
+ # Unix socket
99
+ options[:scheme] = 'unix'
100
+ options.delete(:host)
101
+ options.delete(:port)
102
+ else
103
+ # TCP socket
104
+ options[:host] = options[:host].to_s
105
+ options[:port] = options[:port].to_i
106
+ end
107
+
108
+ # Options ignored by the integration
109
+ #
110
+ # if options.has_key?(:timeout)
111
+ # options[:connect_timeout] ||= options[:timeout]
112
+ # options[:read_timeout] ||= options[:timeout]
113
+ # options[:write_timeout] ||= options[:timeout]
114
+ # end
115
+
116
+ # options[:connect_timeout] = Float(options[:connect_timeout])
117
+ # options[:read_timeout] = Float(options[:read_timeout])
118
+ # options[:write_timeout] = Float(options[:write_timeout])
119
+
120
+ # options[:reconnect_attempts] = options[:reconnect_attempts].to_i
121
+ # options[:reconnect_delay] = options[:reconnect_delay].to_f
122
+ # options[:reconnect_delay_max] = options[:reconnect_delay_max].to_f
123
+
124
+ options[:db] = options[:db].to_i
125
+ # options[:driver] = _parse_driver(options[:driver]) || Connection.drivers.last
126
+
127
+ # case options[:tcp_keepalive]
128
+ # when Hash
129
+ # [:time, :intvl, :probes].each do |key|
130
+ # unless options[:tcp_keepalive][key].is_a?(Integer)
131
+ # raise "Expected the #{key.inspect} key in :tcp_keepalive to be an Integer"
132
+ # end
133
+ # end
134
+
135
+ # when Integer
136
+ # if options[:tcp_keepalive] >= 60
137
+ # options[:tcp_keepalive] = {:time => options[:tcp_keepalive] - 20, :intvl => 10, :probes => 2}
138
+
139
+ # elsif options[:tcp_keepalive] >= 30
140
+ # options[:tcp_keepalive] = {:time => options[:tcp_keepalive] - 10, :intvl => 5, :probes => 2}
141
+
142
+ # elsif options[:tcp_keepalive] >= 5
143
+ # options[:tcp_keepalive] = {:time => options[:tcp_keepalive] - 2, :intvl => 2, :probes => 1}
144
+ # end
145
+ # end
146
+
147
+ options[:_parsed] = true
148
+
149
+ options
150
+ end
151
+
152
+ # rubocop:enable Metrics/AbcSize
153
+ # rubocop:enable Metrics/MethodLength
154
+ # rubocop:enable Metrics/PerceivedComplexity
155
+ end
156
+ end
157
+ end
158
+ end
159
+ end
@@ -15,8 +15,14 @@ module Datadog
15
15
  Gem.loaded_specs['resque'] && Gem.loaded_specs['resque'].version
16
16
  end
17
17
 
18
- def self.present?
19
- super && defined?(::Resque)
18
+ def self.loaded?
19
+ defined?(::Resque)
20
+ end
21
+
22
+ def self.compatible?
23
+ super \
24
+ && version >= Gem::Version.new('1.0') \
25
+ && version < Gem::Version.new('2.0')
20
26
  end
21
27
 
22
28
  def default_configuration
@@ -14,8 +14,12 @@ module Datadog
14
14
  Gem.loaded_specs['rest-client'] && Gem.loaded_specs['rest-client'].version
15
15
  end
16
16
 
17
- def self.present?
18
- super && defined?(::RestClient::Request)
17
+ def self.loaded?
18
+ defined?(::RestClient::Request)
19
+ end
20
+
21
+ def self.compatible?
22
+ super && version >= Gem::Version.new('1.8')
19
23
  end
20
24
 
21
25
  def default_configuration
@@ -15,8 +15,12 @@ module Datadog
15
15
  Gem.loaded_specs['sequel'] && Gem.loaded_specs['sequel'].version
16
16
  end
17
17
 
18
- def self.present?
19
- super && defined?(::Sequel)
18
+ def self.loaded?
19
+ defined?(::Sequel)
20
+ end
21
+
22
+ def self.compatible?
23
+ super && version >= Gem::Version.new('3.41')
20
24
  end
21
25
 
22
26
  def default_configuration
@@ -12,14 +12,16 @@ module Datadog
12
12
 
13
13
  register_as :shoryuken
14
14
 
15
- class << self
16
- def version
17
- Gem.loaded_specs['shoryuken'] && Gem.loaded_specs['shoryuken'].version
18
- end
15
+ def self.version
16
+ Gem.loaded_specs['shoryuken'] && Gem.loaded_specs['shoryuken'].version
17
+ end
18
+
19
+ def self.loaded?
20
+ defined?(::Shoryuken)
21
+ end
19
22
 
20
- def present?
21
- super && defined?(::Shoryuken)
22
- end
23
+ def self.compatible?
24
+ super && version >= Gem::Version.new('4.0.2')
23
25
  end
24
26
 
25
27
  def default_configuration