ddtrace 0.42.0 → 0.43.0

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.
Files changed (70) hide show
  1. checksums.yaml +5 -5
  2. data/.github/workflows/add-milestone-to-pull-requests.yml +42 -0
  3. data/.github/workflows/create-next-milestone.yml +20 -0
  4. data/.simplecov +1 -1
  5. data/Appraisals +160 -132
  6. data/CHANGELOG.md +36 -0
  7. data/CONTRIBUTING.md +1 -1
  8. data/Rakefile +39 -0
  9. data/docs/DevelopmentGuide.md +2 -2
  10. data/docs/GettingStarted.md +71 -1
  11. data/lib/ddtrace.rb +2 -0
  12. data/lib/ddtrace/configuration.rb +20 -4
  13. data/lib/ddtrace/configuration/settings.rb +4 -2
  14. data/lib/ddtrace/context.rb +18 -0
  15. data/lib/ddtrace/context_provider.rb +12 -1
  16. data/lib/ddtrace/contrib/active_support/cache/instrumentation.rb +104 -3
  17. data/lib/ddtrace/contrib/active_support/cache/patcher.rb +21 -0
  18. data/lib/ddtrace/contrib/active_support/ext.rb +3 -0
  19. data/lib/ddtrace/contrib/active_support/notifications/event.rb +10 -0
  20. data/lib/ddtrace/contrib/aws/instrumentation.rb +2 -1
  21. data/lib/ddtrace/contrib/aws/patcher.rb +0 -1
  22. data/lib/ddtrace/contrib/configurable.rb +2 -0
  23. data/lib/ddtrace/contrib/configuration/resolvers/pattern_resolver.rb +4 -5
  24. data/lib/ddtrace/contrib/cucumber/configuration/settings.rb +38 -0
  25. data/lib/ddtrace/contrib/cucumber/ext.rb +19 -0
  26. data/lib/ddtrace/contrib/cucumber/formatter.rb +104 -0
  27. data/lib/ddtrace/contrib/cucumber/instrumentation.rb +24 -0
  28. data/lib/ddtrace/contrib/cucumber/integration.rb +40 -0
  29. data/lib/ddtrace/contrib/cucumber/patcher.rb +23 -0
  30. data/lib/ddtrace/contrib/delayed_job/configuration/settings.rb +1 -0
  31. data/lib/ddtrace/contrib/delayed_job/plugin.rb +3 -1
  32. data/lib/ddtrace/contrib/excon/middleware.rb +7 -1
  33. data/lib/ddtrace/contrib/faraday/patcher.rb +1 -1
  34. data/lib/ddtrace/contrib/grape/configuration/settings.rb +7 -0
  35. data/lib/ddtrace/contrib/grape/endpoint.rb +19 -4
  36. data/lib/ddtrace/contrib/http/instrumentation.rb +2 -2
  37. data/lib/ddtrace/contrib/httprb/instrumentation.rb +2 -2
  38. data/lib/ddtrace/contrib/kafka/event.rb +1 -1
  39. data/lib/ddtrace/contrib/que/configuration/settings.rb +1 -0
  40. data/lib/ddtrace/contrib/que/tracer.rb +2 -1
  41. data/lib/ddtrace/contrib/rails/patcher.rb +5 -2
  42. data/lib/ddtrace/contrib/resque/configuration/settings.rb +1 -0
  43. data/lib/ddtrace/contrib/resque/resque_job.rb +1 -1
  44. data/lib/ddtrace/contrib/rspec/configuration/settings.rb +38 -0
  45. data/lib/ddtrace/contrib/rspec/example.rb +61 -0
  46. data/lib/ddtrace/contrib/rspec/example_group.rb +61 -0
  47. data/lib/ddtrace/contrib/rspec/ext.rb +19 -0
  48. data/lib/ddtrace/contrib/rspec/integration.rb +41 -0
  49. data/lib/ddtrace/contrib/rspec/patcher.rb +25 -0
  50. data/lib/ddtrace/contrib/shoryuken/configuration/settings.rb +1 -0
  51. data/lib/ddtrace/contrib/shoryuken/tracer.rb +4 -1
  52. data/lib/ddtrace/contrib/sidekiq/configuration/settings.rb +1 -0
  53. data/lib/ddtrace/contrib/sidekiq/server_tracer.rb +4 -1
  54. data/lib/ddtrace/contrib/sneakers/configuration/settings.rb +1 -0
  55. data/lib/ddtrace/contrib/sneakers/tracer.rb +17 -20
  56. data/lib/ddtrace/contrib/status_code_matcher.rb +67 -0
  57. data/lib/ddtrace/ext/app_types.rb +1 -0
  58. data/lib/ddtrace/ext/ci.rb +265 -0
  59. data/lib/ddtrace/ext/distributed.rb +8 -2
  60. data/lib/ddtrace/ext/git.rb +12 -0
  61. data/lib/ddtrace/ext/runtime.rb +1 -0
  62. data/lib/ddtrace/ext/test.rb +24 -0
  63. data/lib/ddtrace/runtime/identity.rb +4 -5
  64. data/lib/ddtrace/sampling/rate_limiter.rb +65 -16
  65. data/lib/ddtrace/tracer.rb +14 -1
  66. data/lib/ddtrace/utils.rb +10 -11
  67. data/lib/ddtrace/utils/forking.rb +52 -0
  68. data/lib/ddtrace/version.rb +1 -1
  69. data/lib/ddtrace/writer.rb +19 -1
  70. metadata +23 -31
@@ -0,0 +1,24 @@
1
+ require 'ddtrace/contrib/cucumber/formatter'
2
+
3
+ module Datadog
4
+ module Contrib
5
+ module Cucumber
6
+ # Instrumentation for Cucumber
7
+ module Instrumentation
8
+ def self.included(base)
9
+ base.send(:prepend, InstanceMethods)
10
+ end
11
+
12
+ # Instance methods for configuration
13
+ module InstanceMethods
14
+ attr_reader :datadog_formatter
15
+
16
+ def formatters
17
+ @datadog_formatter ||= Datadog::Contrib::Cucumber::Formatter.new(@configuration)
18
+ [@datadog_formatter] + super
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,40 @@
1
+ require 'ddtrace/contrib/integration'
2
+ require 'ddtrace/contrib/cucumber/configuration/settings'
3
+ require 'ddtrace/contrib/cucumber/patcher'
4
+ require 'ddtrace/contrib/integration'
5
+
6
+ module Datadog
7
+ module Contrib
8
+ module Cucumber
9
+ # Description of Cucumber integration
10
+ class Integration
11
+ include Contrib::Integration
12
+
13
+ MINIMUM_VERSION = Gem::Version.new('3.0.0')
14
+
15
+ register_as :cucumber, auto_patch: true
16
+
17
+ def self.version
18
+ Gem.loaded_specs['cucumber'] \
19
+ && Gem.loaded_specs['cucumber'].version
20
+ end
21
+
22
+ def self.loaded?
23
+ !defined?(::Cucumber).nil? && !defined?(::Cucumber::Runtime).nil?
24
+ end
25
+
26
+ def self.compatible?
27
+ super && version >= MINIMUM_VERSION
28
+ end
29
+
30
+ def default_configuration
31
+ Configuration::Settings.new
32
+ end
33
+
34
+ def patcher
35
+ Patcher
36
+ end
37
+ end
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,23 @@
1
+ require 'ddtrace/contrib/patcher'
2
+ require 'ddtrace/contrib/cucumber/instrumentation'
3
+
4
+ module Datadog
5
+ module Contrib
6
+ module Cucumber
7
+ # Patcher enables patching of 'cucumber' module.
8
+ module Patcher
9
+ include Contrib::Patcher
10
+
11
+ module_function
12
+
13
+ def target_version
14
+ Integration.version
15
+ end
16
+
17
+ def patch
18
+ ::Cucumber::Runtime.send(:include, Instrumentation)
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
@@ -24,6 +24,7 @@ module Datadog
24
24
 
25
25
  option :service_name, default: Ext::SERVICE_NAME
26
26
  option :client_service_name, default: Ext::CLIENT_SERVICE_NAME
27
+ option :error_handler, default: Datadog::Tracer::DEFAULT_ON_ERROR
27
28
  end
28
29
  end
29
30
  end
@@ -10,7 +10,9 @@ module Datadog
10
10
  def self.instrument_invoke(job, &block)
11
11
  return block.call(job) unless tracer && tracer.enabled
12
12
 
13
- tracer.trace(Ext::SPAN_JOB, service: configuration[:service_name], resource: job_name(job)) do |span|
13
+ tracer.trace(Ext::SPAN_JOB, service: configuration[:service_name], resource: job_name(job),
14
+ on_error: configuration[:error_handler]) do |span|
15
+
14
16
  set_sample_rate(span)
15
17
 
16
18
  # Measure service stats
@@ -63,6 +63,12 @@ module Datadog
63
63
  @options
64
64
  end
65
65
 
66
+ # default_options in this case contains our specific middleware options
67
+ # so we want it to take precedence in build_request_options
68
+ def build_request_options!(datum)
69
+ datadog_configuration(datum[:host]).options_hash.merge(@default_options)
70
+ end
71
+
66
72
  def initialize(stack)
67
73
  super(stack, self.class.options)
68
74
  end
@@ -149,7 +155,7 @@ module Datadog
149
155
  end
150
156
 
151
157
  def build_request_options!(datum)
152
- datadog_configuration(datum[:host]).options_hash.merge(@default_options)
158
+ @default_options.merge(datadog_configuration(datum[:host]).options_hash)
153
159
  end
154
160
 
155
161
  def datadog_configuration(host = :default)
@@ -30,7 +30,7 @@ module Datadog
30
30
  .new(
31
31
  get_option(:service_name),
32
32
  app: Ext::APP,
33
- app_type: Datadog::Ext::AppTypes::WEB,
33
+ app_type: Datadog::Ext::HTTP::TYPE_OUTBOUND,
34
34
  tracer: -> { get_option(:tracer) }
35
35
  ).onto(::Faraday)
36
36
  end
@@ -1,6 +1,7 @@
1
1
  require 'ddtrace/contrib/configuration/settings'
2
2
  require 'ddtrace/ext/http'
3
3
  require 'ddtrace/contrib/grape/ext'
4
+ require 'ddtrace/contrib/status_code_matcher'
4
5
 
5
6
  module Datadog
6
7
  module Contrib
@@ -24,6 +25,12 @@ module Datadog
24
25
  end
25
26
 
26
27
  option :service_name, default: Ext::SERVICE_NAME
28
+
29
+ option :error_statuses, default: nil do |o|
30
+ o.setter do |new_value, _old_value|
31
+ Datadog::Contrib::StatusCodeMatcher.new(new_value) unless new_value.nil?
32
+ end
33
+ end
27
34
  end
28
35
  end
29
36
  end
@@ -1,4 +1,3 @@
1
-
2
1
  require 'ddtrace/ext/http'
3
2
  require 'ddtrace/ext/errors'
4
3
  require 'ddtrace/contrib/analytics'
@@ -90,7 +89,10 @@ module Datadog
90
89
  Contrib::Analytics.set_measured(span)
91
90
 
92
91
  # catch thrown exceptions
93
- span.set_error(payload[:exception_object]) unless payload[:exception_object].nil?
92
+
93
+ if exception_is_error?(payload[:exception_object])
94
+ span.set_error(payload[:exception_object])
95
+ end
94
96
 
95
97
  # override the current span with this notification values
96
98
  span.set_tag(Ext::TAG_ROUTE_ENDPOINT, api_view) unless api_view.nil?
@@ -133,7 +135,9 @@ module Datadog
133
135
  # Measure service stats
134
136
  Contrib::Analytics.set_measured(span)
135
137
 
136
- span.set_error(payload[:exception_object]) unless payload[:exception_object].nil?
138
+ if exception_is_error?(payload[:exception_object])
139
+ span.set_error(payload[:exception_object])
140
+ end
137
141
  ensure
138
142
  span.start(start)
139
143
  span.finish(finish)
@@ -168,7 +172,10 @@ module Datadog
168
172
  Contrib::Analytics.set_measured(span)
169
173
 
170
174
  # catch thrown exceptions
171
- span.set_error(payload[:exception_object]) unless payload[:exception_object].nil?
175
+ if exception_is_error?(payload[:exception_object])
176
+ span.set_error(payload[:exception_object])
177
+ end
178
+
172
179
  span.set_tag(Ext::TAG_FILTER_TYPE, type.to_s)
173
180
  ensure
174
181
  span.start(start)
@@ -196,6 +203,14 @@ module Datadog
196
203
  datadog_configuration[:analytics_sample_rate]
197
204
  end
198
205
 
206
+ def exception_is_error?(exception)
207
+ matcher = datadog_configuration[:error_statuses]
208
+ return false unless exception
209
+ return true unless matcher
210
+ return true unless exception.respond_to?('status')
211
+ matcher.include?(exception.status)
212
+ end
213
+
199
214
  def enabled?
200
215
  datadog_configuration[:enabled] == true
201
216
  end
@@ -118,7 +118,7 @@ module Datadog
118
118
  @datadog_pin ||= Datadog::Pin.new(
119
119
  service,
120
120
  app: Ext::APP,
121
- app_type: Datadog::Ext::AppTypes::WEB,
121
+ app_type: Datadog::Ext::HTTP::TYPE_OUTBOUND,
122
122
  tracer: -> { config[:tracer] }
123
123
  )
124
124
 
@@ -146,7 +146,7 @@ module Datadog
146
146
  @default_datadog_pin ||= Datadog::Pin.new(
147
147
  service,
148
148
  app: Ext::APP,
149
- app_type: Datadog::Ext::AppTypes::WEB,
149
+ app_type: Datadog::Ext::HTTP::TYPE_OUTBOUND,
150
150
  tracer: -> { config[:tracer] }
151
151
  )
152
152
  end
@@ -103,7 +103,7 @@ module Datadog
103
103
  Datadog::Pin.new(
104
104
  service,
105
105
  app: Ext::APP,
106
- app_type: Datadog::Ext::AppTypes::WEB,
106
+ app_type: Datadog::Ext::HTTP::TYPE_OUTBOUND,
107
107
  tracer: -> { config[:tracer] }
108
108
  )
109
109
  end
@@ -126,7 +126,7 @@ module Datadog
126
126
  Datadog::Pin.new(
127
127
  service,
128
128
  app: Ext::APP,
129
- app_type: Datadog::Ext::AppTypes::WEB,
129
+ app_type: Datadog::Ext::HTTP::TYPE_OUTBOUND,
130
130
  tracer: -> { config[:tracer] }
131
131
  )
132
132
  end
@@ -42,7 +42,7 @@ module Datadog
42
42
  # Measure service stats
43
43
  Contrib::Analytics.set_measured(span)
44
44
 
45
- span.set_error(payload[:exception_object]) if payload[:exception_object]
45
+ report_if_exception(span, payload)
46
46
  end
47
47
  end
48
48
  end
@@ -35,6 +35,7 @@ module Datadog
35
35
  o.default { env_to_bool(Ext::ENV_TAG_DATA_ENABLED, false) }
36
36
  o.lazy
37
37
  end
38
+ option :error_handler, default: Datadog::Tracer::DEFAULT_ON_ERROR
38
39
  end
39
40
  end
40
41
  end
@@ -10,7 +10,8 @@ module Datadog
10
10
  def call(job)
11
11
  trace_options = {
12
12
  service: configuration[:service_name],
13
- span_type: Datadog::Ext::AppTypes::WORKER
13
+ span_type: Datadog::Ext::AppTypes::WORKER,
14
+ on_error: configuration[:error_handler]
14
15
  }
15
16
 
16
17
  tracer.trace(Ext::SPAN_JOB, trace_options) do |request_span|
@@ -53,6 +53,7 @@ module Datadog
53
53
  end
54
54
 
55
55
  def add_logger(app)
56
+ should_warn = true
56
57
  # check if lograge key exists
57
58
  # Note: Rails executes initializers sequentially based on alphabetical order,
58
59
  # and lograge config could occur after dd config.
@@ -62,6 +63,7 @@ module Datadog
62
63
  # See: https://github.com/roidrage/lograge/blob/1729eab7956bb95c5992e4adab251e4f93ff9280/lib/lograge/railtie.rb#L7-L12
63
64
  if app.config.respond_to?(:lograge)
64
65
  Datadog::Contrib::Rails::LogInjection.add_lograge_logger(app)
66
+ should_warn = false
65
67
  end
66
68
 
67
69
  # if lograge isn't set, check if tagged logged is enabled.
@@ -71,9 +73,10 @@ module Datadog
71
73
  logger.is_a?(::ActiveSupport::TaggedLogging)
72
74
 
73
75
  Datadog::Contrib::Rails::LogInjection.add_as_tagged_logging_logger(app)
74
- else
75
- Datadog.logger.warn("Unable to enable Datadog Trace context, Logger #{logger} is not supported")
76
+ should_warn = false
76
77
  end
78
+
79
+ Datadog.logger.warn("Unable to enable Datadog Trace context, Logger #{logger} is not supported") if should_warn
77
80
  end
78
81
 
79
82
  def patch_after_intialize
@@ -24,6 +24,7 @@ module Datadog
24
24
 
25
25
  option :service_name, default: Ext::SERVICE_NAME
26
26
  option :workers, default: []
27
+ option :error_handler, default: Datadog::Tracer::DEFAULT_ON_ERROR
27
28
  end
28
29
  end
29
30
  end
@@ -48,7 +48,7 @@ module Datadog
48
48
  end
49
49
 
50
50
  def span_options
51
- { service: datadog_configuration[:service_name] }
51
+ { service: datadog_configuration[:service_name], on_error: datadog_configuration[:error_handler] }
52
52
  end
53
53
 
54
54
  def tracer
@@ -0,0 +1,38 @@
1
+ require 'ddtrace/contrib/configuration/settings'
2
+ require 'ddtrace/contrib/rspec/ext'
3
+
4
+ module Datadog
5
+ module Contrib
6
+ module RSpec
7
+ module Configuration
8
+ # Custom settings for the RSpec integration
9
+ class Settings < Contrib::Configuration::Settings
10
+ option :enabled do |o|
11
+ o.default { env_to_bool(Ext::ENV_ENABLED, true) }
12
+ o.lazy
13
+ end
14
+
15
+ option :analytics_enabled do |o|
16
+ o.default { env_to_bool(Ext::ENV_ANALYTICS_ENABLED, true) }
17
+ o.lazy
18
+ end
19
+
20
+ option :analytics_sample_rate do |o|
21
+ o.default { env_to_float(Ext::ENV_ANALYTICS_SAMPLE_RATE, 1.0) }
22
+ o.lazy
23
+ end
24
+
25
+ option :service_name do |o|
26
+ o.default { Datadog.configuration.service || Ext::SERVICE_NAME }
27
+ o.lazy
28
+ end
29
+
30
+ option :operation_name do |o|
31
+ o.default { ENV.key?(Ext::ENV_OPERATION_NAME) ? ENV[Ext::ENV_OPERATION_NAME] : Ext::OPERATION_NAME }
32
+ o.lazy
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,61 @@
1
+ module Datadog
2
+ module Contrib
3
+ module RSpec
4
+ # Instrument RSpec::Core::Example
5
+ module Example
6
+ def self.included(base)
7
+ base.send(:prepend, InstanceMethods)
8
+ end
9
+
10
+ # Instance methods for configuration
11
+ module InstanceMethods
12
+ def run(example_group_instance, reporter)
13
+ configuration = Datadog.configuration[:rspec]
14
+ return super unless configuration[:enabled]
15
+
16
+ test_name = "#{example_group.description}::#{description}"
17
+ trace_options = {
18
+ app: Ext::APP,
19
+ resource: test_name,
20
+ service: configuration[:service_name],
21
+ span_type: Datadog::Ext::AppTypes::TEST,
22
+ tags: example_group.instance_variable_get(:@tags).merge(Datadog.configuration.tags)
23
+ }
24
+
25
+ configuration[:tracer].trace(configuration[:operation_name], trace_options) do |span|
26
+ span.set_tag(Datadog::Ext::Test::TAG_FRAMEWORK, Ext::FRAMEWORK)
27
+ span.set_tag(Datadog::Ext::Test::TAG_NAME, test_name)
28
+ span.set_tag(Datadog::Ext::Test::TAG_SUITE, example_group.file_path)
29
+ span.set_tag(Datadog::Ext::Test::TAG_TYPE, Ext::TEST_TYPE)
30
+ span.set_tag(Datadog::Ext::Test::TAG_SPAN_KIND, Datadog::Ext::AppTypes::TEST)
31
+
32
+ # Set analytics sample rate
33
+ if Datadog::Contrib::Analytics.enabled?(configuration[:analytics_enabled])
34
+ Datadog::Contrib::Analytics.set_sample_rate(span, configuration[:analytics_sample_rate])
35
+ end
36
+
37
+ # Measure service stats
38
+ Contrib::Analytics.set_measured(span)
39
+
40
+ result = super
41
+
42
+ case execution_result.status
43
+ when :passed
44
+ span.set_tag(Datadog::Ext::Test::TAG_STATUS, Datadog::Ext::Test::Status::PASS)
45
+ when :failed
46
+ span.status = 1
47
+ span.set_tag(Datadog::Ext::Test::TAG_STATUS, Datadog::Ext::Test::Status::FAIL)
48
+ span.set_error(execution_result.exception)
49
+ else
50
+ if execution_result.example_skipped?
51
+ span.set_tag(Datadog::Ext::Test::TAG_STATUS, Datadog::Ext::Test::Status::SKIP)
52
+ end
53
+ end
54
+ result
55
+ end
56
+ end
57
+ end
58
+ end
59
+ end
60
+ end
61
+ end
@@ -0,0 +1,61 @@
1
+ module Datadog
2
+ module Contrib
3
+ module RSpec
4
+ # Instrument RSpec::Core::ExampleGroup
5
+ module ExampleGroup
6
+ def self.included(base)
7
+ base.singleton_class.send(:prepend, ClassMethods)
8
+ end
9
+
10
+ # Class methods for configuration
11
+ module ClassMethods
12
+ def run(reporter = ::RSpec::Core::NullReporter)
13
+ configuration = Datadog.configuration[:rspec]
14
+ return super unless configuration[:enabled]
15
+
16
+ trace_options = {
17
+ app: Ext::APP,
18
+ resource: description,
19
+ service: configuration[:service_name],
20
+ span_type: Datadog::Ext::AppTypes::TEST,
21
+ tags: tags.merge(Datadog.configuration.tags)
22
+ }
23
+
24
+ configuration[:tracer].trace(Ext::EXAMPLE_GROUP_OPERATION_NAME, trace_options) do |span|
25
+ span.set_tag(Datadog::Ext::Test::TAG_FRAMEWORK, Ext::FRAMEWORK)
26
+ span.set_tag(Datadog::Ext::Test::TAG_NAME, description)
27
+ span.set_tag(Datadog::Ext::Test::TAG_SUITE, file_path)
28
+ span.set_tag(Datadog::Ext::Test::TAG_TYPE, Ext::TEST_TYPE)
29
+ span.set_tag(Datadog::Ext::Test::TAG_SPAN_KIND, Datadog::Ext::AppTypes::TEST)
30
+
31
+ # Set analytics sample rate
32
+ if Datadog::Contrib::Analytics.enabled?(configuration[:analytics_enabled])
33
+ Datadog::Contrib::Analytics.set_sample_rate(span, configuration[:analytics_sample_rate])
34
+ end
35
+
36
+ # Measure service stats
37
+ Contrib::Analytics.set_measured(span)
38
+
39
+ result = super
40
+
41
+ if ::RSpec.world.wants_to_quit
42
+ span.status = 1
43
+ span.set_tag(Datadog::Ext::Test::TAG_STATUS, Datadog::Ext::Test::Status::FAIL)
44
+ else
45
+ span.set_tag(Datadog::Ext::Test::TAG_STATUS, Datadog::Ext::Test::Status::PASS)
46
+ end
47
+
48
+ result
49
+ end
50
+ end
51
+
52
+ private
53
+
54
+ def tags
55
+ @tags ||= Datadog::Ext::CI.tags(ENV)
56
+ end
57
+ end
58
+ end
59
+ end
60
+ end
61
+ end