ddtrace 0.40.0 → 0.45.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 (150) hide show
  1. checksums.yaml +4 -4
  2. data/.circleci/config.yml +148 -130
  3. data/.circleci/images/primary/Dockerfile-3.0.0 +73 -0
  4. data/.github/workflows/add-milestone-to-pull-requests.yml +42 -0
  5. data/.github/workflows/create-next-milestone.yml +20 -0
  6. data/.simplecov +3 -0
  7. data/Appraisals +414 -135
  8. data/CHANGELOG.md +1112 -342
  9. data/CONTRIBUTING.md +2 -2
  10. data/Gemfile +4 -2
  11. data/README.md +1 -0
  12. data/Rakefile +231 -29
  13. data/ddtrace.gemspec +8 -8
  14. data/docker-compose.yml +30 -0
  15. data/docs/DevelopmentGuide.md +12 -2
  16. data/docs/GettingStarted.md +187 -16
  17. data/lib/ddtrace.rb +10 -0
  18. data/lib/ddtrace/auto_instrument.rb +3 -0
  19. data/lib/ddtrace/auto_instrument_base.rb +6 -0
  20. data/lib/ddtrace/buffer.rb +259 -52
  21. data/lib/ddtrace/configuration.rb +19 -0
  22. data/lib/ddtrace/configuration/options.rb +3 -1
  23. data/lib/ddtrace/configuration/settings.rb +9 -3
  24. data/lib/ddtrace/context.rb +18 -0
  25. data/lib/ddtrace/context_provider.rb +17 -5
  26. data/lib/ddtrace/contrib/action_cable/integration.rb +7 -0
  27. data/lib/ddtrace/contrib/action_pack/integration.rb +7 -0
  28. data/lib/ddtrace/contrib/action_view/event.rb +0 -4
  29. data/lib/ddtrace/contrib/action_view/events/render_partial.rb +1 -0
  30. data/lib/ddtrace/contrib/action_view/events/render_template.rb +1 -0
  31. data/lib/ddtrace/contrib/action_view/integration.rb +7 -0
  32. data/lib/ddtrace/contrib/active_record/events/sql.rb +4 -0
  33. data/lib/ddtrace/contrib/active_record/integration.rb +7 -0
  34. data/lib/ddtrace/contrib/active_record/utils.rb +67 -21
  35. data/lib/ddtrace/contrib/active_support/cache/instrumentation.rb +104 -3
  36. data/lib/ddtrace/contrib/active_support/cache/patcher.rb +21 -0
  37. data/lib/ddtrace/contrib/active_support/ext.rb +3 -0
  38. data/lib/ddtrace/contrib/active_support/integration.rb +7 -1
  39. data/lib/ddtrace/contrib/active_support/notifications/event.rb +10 -0
  40. data/lib/ddtrace/contrib/active_support/notifications/subscription.rb +2 -2
  41. data/lib/ddtrace/contrib/auto_instrument.rb +48 -0
  42. data/lib/ddtrace/contrib/aws/instrumentation.rb +6 -1
  43. data/lib/ddtrace/contrib/aws/patcher.rb +0 -1
  44. data/lib/ddtrace/contrib/aws/services.rb +1 -0
  45. data/lib/ddtrace/contrib/configurable.rb +2 -0
  46. data/lib/ddtrace/contrib/configuration/resolvers/pattern_resolver.rb +6 -5
  47. data/lib/ddtrace/contrib/cucumber/configuration/settings.rb +38 -0
  48. data/lib/ddtrace/contrib/cucumber/ext.rb +19 -0
  49. data/lib/ddtrace/contrib/cucumber/formatter.rb +104 -0
  50. data/lib/ddtrace/contrib/cucumber/instrumentation.rb +24 -0
  51. data/lib/ddtrace/contrib/cucumber/integration.rb +45 -0
  52. data/lib/ddtrace/contrib/cucumber/patcher.rb +23 -0
  53. data/lib/ddtrace/contrib/dalli/instrumentation.rb +4 -0
  54. data/lib/ddtrace/contrib/delayed_job/configuration/settings.rb +2 -0
  55. data/lib/ddtrace/contrib/delayed_job/ext.rb +2 -0
  56. data/lib/ddtrace/contrib/delayed_job/plugin.rb +39 -15
  57. data/lib/ddtrace/contrib/elasticsearch/patcher.rb +4 -0
  58. data/lib/ddtrace/contrib/ethon/easy_patch.rb +10 -7
  59. data/lib/ddtrace/contrib/ethon/ext.rb +1 -0
  60. data/lib/ddtrace/contrib/ethon/multi_patch.rb +4 -0
  61. data/lib/ddtrace/contrib/excon/middleware.rb +11 -1
  62. data/lib/ddtrace/contrib/extensions.rb +27 -1
  63. data/lib/ddtrace/contrib/faraday/middleware.rb +4 -0
  64. data/lib/ddtrace/contrib/faraday/patcher.rb +1 -1
  65. data/lib/ddtrace/contrib/grape/configuration/settings.rb +7 -0
  66. data/lib/ddtrace/contrib/grape/endpoint.rb +53 -18
  67. data/lib/ddtrace/contrib/grape/ext.rb +1 -0
  68. data/lib/ddtrace/contrib/grpc/datadog_interceptor/client.rb +5 -1
  69. data/lib/ddtrace/contrib/grpc/datadog_interceptor/server.rb +4 -0
  70. data/lib/ddtrace/contrib/http/instrumentation.rb +6 -2
  71. data/lib/ddtrace/contrib/httpclient/configuration/settings.rb +32 -0
  72. data/lib/ddtrace/contrib/httpclient/ext.rb +17 -0
  73. data/lib/ddtrace/contrib/httpclient/instrumentation.rb +152 -0
  74. data/lib/ddtrace/contrib/httpclient/integration.rb +43 -0
  75. data/lib/ddtrace/contrib/httpclient/patcher.rb +35 -0
  76. data/lib/ddtrace/contrib/httprb/instrumentation.rb +6 -3
  77. data/lib/ddtrace/contrib/kafka/event.rb +1 -1
  78. data/lib/ddtrace/contrib/mongodb/subscribers.rb +4 -0
  79. data/lib/ddtrace/contrib/mysql2/instrumentation.rb +4 -0
  80. data/lib/ddtrace/contrib/patchable.rb +18 -7
  81. data/lib/ddtrace/contrib/presto/instrumentation.rb +3 -0
  82. data/lib/ddtrace/contrib/qless/configuration/settings.rb +35 -0
  83. data/lib/ddtrace/contrib/qless/ext.rb +20 -0
  84. data/lib/ddtrace/contrib/qless/integration.rb +38 -0
  85. data/lib/ddtrace/contrib/qless/patcher.rb +35 -0
  86. data/lib/ddtrace/contrib/qless/qless_job.rb +72 -0
  87. data/lib/ddtrace/contrib/qless/tracer_cleaner.rb +32 -0
  88. data/lib/ddtrace/contrib/que/configuration/settings.rb +1 -0
  89. data/lib/ddtrace/contrib/que/tracer.rb +2 -1
  90. data/lib/ddtrace/contrib/racecar/event.rb +4 -0
  91. data/lib/ddtrace/contrib/rack/integration.rb +7 -0
  92. data/lib/ddtrace/contrib/rack/middlewares.rb +1 -1
  93. data/lib/ddtrace/contrib/rack/request_queue.rb +6 -1
  94. data/lib/ddtrace/contrib/rails/auto_instrument_railtie.rb +10 -0
  95. data/lib/ddtrace/contrib/rails/patcher.rb +19 -5
  96. data/lib/ddtrace/contrib/rails/utils.rb +4 -0
  97. data/lib/ddtrace/contrib/rake/integration.rb +1 -1
  98. data/lib/ddtrace/contrib/redis/configuration/resolver.rb +3 -1
  99. data/lib/ddtrace/contrib/redis/configuration/settings.rb +5 -0
  100. data/lib/ddtrace/contrib/redis/ext.rb +1 -0
  101. data/lib/ddtrace/contrib/redis/patcher.rb +20 -3
  102. data/lib/ddtrace/contrib/redis/quantize.rb +27 -0
  103. data/lib/ddtrace/contrib/redis/tags.rb +9 -1
  104. data/lib/ddtrace/contrib/resque/configuration/settings.rb +1 -0
  105. data/lib/ddtrace/contrib/resque/integration.rb +1 -1
  106. data/lib/ddtrace/contrib/resque/resque_job.rb +1 -1
  107. data/lib/ddtrace/contrib/rest_client/request_patch.rb +4 -0
  108. data/lib/ddtrace/contrib/rspec/configuration/settings.rb +38 -0
  109. data/lib/ddtrace/contrib/rspec/example.rb +61 -0
  110. data/lib/ddtrace/contrib/rspec/example_group.rb +61 -0
  111. data/lib/ddtrace/contrib/rspec/ext.rb +19 -0
  112. data/lib/ddtrace/contrib/rspec/integration.rb +46 -0
  113. data/lib/ddtrace/contrib/rspec/patcher.rb +25 -0
  114. data/lib/ddtrace/contrib/sequel/database.rb +3 -1
  115. data/lib/ddtrace/contrib/sequel/dataset.rb +3 -2
  116. data/lib/ddtrace/contrib/sequel/ext.rb +1 -0
  117. data/lib/ddtrace/contrib/sequel/utils.rb +16 -5
  118. data/lib/ddtrace/contrib/shoryuken/configuration/settings.rb +1 -0
  119. data/lib/ddtrace/contrib/shoryuken/tracer.rb +4 -1
  120. data/lib/ddtrace/contrib/sidekiq/configuration/settings.rb +1 -0
  121. data/lib/ddtrace/contrib/sidekiq/server_tracer.rb +4 -1
  122. data/lib/ddtrace/contrib/sinatra/tracer_middleware.rb +2 -2
  123. data/lib/ddtrace/contrib/sneakers/configuration/settings.rb +1 -0
  124. data/lib/ddtrace/contrib/sneakers/tracer.rb +17 -20
  125. data/lib/ddtrace/contrib/status_code_matcher.rb +67 -0
  126. data/lib/ddtrace/ext/app_types.rb +1 -0
  127. data/lib/ddtrace/ext/ci.rb +297 -0
  128. data/lib/ddtrace/ext/distributed.rb +8 -2
  129. data/lib/ddtrace/ext/git.rb +11 -0
  130. data/lib/ddtrace/ext/integration.rb +8 -0
  131. data/lib/ddtrace/ext/runtime.rb +2 -0
  132. data/lib/ddtrace/ext/test.rb +24 -0
  133. data/lib/ddtrace/opentracer/distributed_headers.rb +1 -1
  134. data/lib/ddtrace/propagation/grpc_propagator.rb +18 -6
  135. data/lib/ddtrace/propagation/http_propagator.rb +17 -2
  136. data/lib/ddtrace/runtime/identity.rb +4 -5
  137. data/lib/ddtrace/runtime/metrics.rb +6 -2
  138. data/lib/ddtrace/sampler.rb +2 -2
  139. data/lib/ddtrace/sampling/rate_limiter.rb +65 -16
  140. data/lib/ddtrace/span.rb +152 -27
  141. data/lib/ddtrace/tracer.rb +25 -13
  142. data/lib/ddtrace/transport/http/adapters/net.rb +8 -2
  143. data/lib/ddtrace/transport/http/statistics.rb +14 -1
  144. data/lib/ddtrace/transport/traces.rb +7 -2
  145. data/lib/ddtrace/utils.rb +16 -13
  146. data/lib/ddtrace/utils/forking.rb +52 -0
  147. data/lib/ddtrace/version.rb +1 -1
  148. data/lib/ddtrace/workers/runtime_metrics.rb +7 -3
  149. data/lib/ddtrace/writer.rb +19 -1
  150. metadata +111 -19
@@ -22,6 +22,11 @@ module Datadog
22
22
  o.lazy
23
23
  end
24
24
 
25
+ option :command_args do |o|
26
+ o.default { env_to_bool(Ext::ENV_COMMAND_ARGS, true) }
27
+ o.lazy
28
+ end
29
+
25
30
  option :service_name, default: Ext::SERVICE_NAME
26
31
  end
27
32
  end
@@ -9,6 +9,7 @@ module Datadog
9
9
  ENV_ANALYTICS_ENABLED_OLD = 'DD_REDIS_ANALYTICS_ENABLED'.freeze
10
10
  ENV_ANALYTICS_SAMPLE_RATE = 'DD_TRACE_REDIS_ANALYTICS_SAMPLE_RATE'.freeze
11
11
  ENV_ANALYTICS_SAMPLE_RATE_OLD = 'DD_REDIS_ANALYTICS_SAMPLE_RATE'.freeze
12
+ ENV_COMMAND_ARGS = 'DD_REDIS_COMMAND_ARGS'.freeze
12
13
  METRIC_PIPELINE_LEN = 'redis.pipeline_length'.freeze
13
14
  SERVICE_NAME = 'redis'.freeze
14
15
  SPAN_COMMAND = 'redis.command'.freeze
@@ -28,6 +28,7 @@ module Datadog
28
28
 
29
29
  # rubocop:disable Metrics/MethodLength
30
30
  # rubocop:disable Metrics/BlockLength
31
+ # rubocop:disable Metrics/AbcSize
31
32
  def patch_redis_client
32
33
  ::Redis::Client.class_eval do
33
34
  alias_method :call_without_datadog, :call
@@ -40,7 +41,7 @@ module Datadog
40
41
  pin.tracer.trace(Datadog::Contrib::Redis::Ext::SPAN_COMMAND) do |span|
41
42
  span.service = pin.service
42
43
  span.span_type = Datadog::Contrib::Redis::Ext::TYPE
43
- span.resource = Datadog::Contrib::Redis::Quantize.format_command_args(*args)
44
+ span.resource = get_command(args)
44
45
  Datadog::Contrib::Redis::Tags.set_common_tags(self, span)
45
46
 
46
47
  response = call_without_datadog(*args, &block)
@@ -59,10 +60,10 @@ module Datadog
59
60
  pin.tracer.trace(Datadog::Contrib::Redis::Ext::SPAN_COMMAND) do |span|
60
61
  span.service = pin.service
61
62
  span.span_type = Datadog::Contrib::Redis::Ext::TYPE
62
- commands = args[0].commands.map { |c| Datadog::Contrib::Redis::Quantize.format_command_args(c) }
63
+ commands = get_pipeline_commands(args)
63
64
  span.resource = commands.join("\n")
64
- Datadog::Contrib::Redis::Tags.set_common_tags(self, span)
65
65
  span.set_metric Datadog::Contrib::Redis::Ext::METRIC_PIPELINE_LEN, commands.length
66
+ Datadog::Contrib::Redis::Tags.set_common_tags(self, span)
66
67
 
67
68
  response = call_pipeline_without_datadog(*args, &block)
68
69
  end
@@ -84,6 +85,22 @@ module Datadog
84
85
 
85
86
  private
86
87
 
88
+ def get_command(args)
89
+ if datadog_configuration[:command_args]
90
+ Datadog::Contrib::Redis::Quantize.format_command_args(*args)
91
+ else
92
+ Datadog::Contrib::Redis::Quantize.get_verb(*args)
93
+ end
94
+ end
95
+
96
+ def get_pipeline_commands(args)
97
+ if datadog_configuration[:command_args]
98
+ args[0].commands.map { |c| Datadog::Contrib::Redis::Quantize.format_command_args(c) }
99
+ else
100
+ args[0].commands.map { |c| Datadog::Contrib::Redis::Quantize.get_verb(c) }
101
+ end
102
+ end
103
+
87
104
  def datadog_configuration
88
105
  Datadog.configuration[:redis, options]
89
106
  end
@@ -1,3 +1,5 @@
1
+ require 'set'
2
+
1
3
  module Datadog
2
4
  module Contrib
3
5
  module Redis
@@ -8,6 +10,19 @@ module Datadog
8
10
  VALUE_MAX_LEN = 50
9
11
  CMD_MAX_LEN = 500
10
12
 
13
+ MULTI_VERB_COMMANDS = Set.new(
14
+ %w[
15
+ ACL
16
+ CLIENT
17
+ CLUSTER
18
+ COMMAND
19
+ CONFIG
20
+ DEBUG
21
+ LATENCY
22
+ MEMORY
23
+ ]
24
+ ).freeze
25
+
11
26
  module_function
12
27
 
13
28
  def format_arg(arg)
@@ -27,6 +42,18 @@ module Datadog
27
42
  Utils.truncate(cmd, CMD_MAX_LEN, TOO_LONG_MARK)
28
43
  end
29
44
 
45
+ def get_verb(command_args)
46
+ return unless command_args.is_a?(Array)
47
+
48
+ return get_verb(command_args.first) if command_args.first.is_a?(Array)
49
+
50
+ arg = command_args.first
51
+ verb = arg.is_a?(Symbol) ? arg.to_s.upcase : arg.to_s
52
+ return verb unless MULTI_VERB_COMMANDS.include?(verb) && command_args[1]
53
+
54
+ "#{verb} #{command_args[1]}"
55
+ end
56
+
30
57
  def auth_command?(command_args)
31
58
  return false unless command_args.is_a?(Array) && !command_args.empty?
32
59
  command_args.first.to_sym == :auth
@@ -1,3 +1,4 @@
1
+ require 'ddtrace/ext/integration'
1
2
  require 'ddtrace/ext/net'
2
3
  require 'ddtrace/contrib/analytics'
3
4
  require 'ddtrace/contrib/redis/ext'
@@ -9,13 +10,16 @@ module Datadog
9
10
  module Tags
10
11
  class << self
11
12
  def set_common_tags(client, span)
13
+ # Tag as an external peer service
14
+ span.set_tag(Datadog::Ext::Integration::TAG_PEER_SERVICE, span.service)
15
+
12
16
  # Set analytics sample rate
13
17
  Contrib::Analytics.set_sample_rate(span, analytics_sample_rate) if analytics_enabled?
14
18
 
15
19
  span.set_tag Datadog::Ext::NET::TARGET_HOST, client.host
16
20
  span.set_tag Datadog::Ext::NET::TARGET_PORT, client.port
17
21
  span.set_tag Ext::TAG_DB, client.db
18
- span.set_tag Ext::TAG_RAW_COMMAND, span.resource
22
+ span.set_tag Ext::TAG_RAW_COMMAND, span.resource if show_command_args?
19
23
  end
20
24
 
21
25
  private
@@ -31,6 +35,10 @@ module Datadog
31
35
  def analytics_sample_rate
32
36
  datadog_configuration[:analytics_sample_rate]
33
37
  end
38
+
39
+ def show_command_args?
40
+ datadog_configuration[:command_args]
41
+ end
34
42
  end
35
43
  end
36
44
  end
@@ -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
@@ -11,7 +11,7 @@ module Datadog
11
11
 
12
12
  MINIMUM_VERSION = Gem::Version.new('1.0')
13
13
  # Maximum is first version it's NOT compatible with (not inclusive)
14
- MAXIMUM_VERSION = Gem::Version.new('2.0')
14
+ MAXIMUM_VERSION = Gem::Version.new('3.0')
15
15
 
16
16
  register_as :resque, auto_patch: true
17
17
 
@@ -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
@@ -1,5 +1,6 @@
1
1
  require 'ddtrace/ext/net'
2
2
  require 'ddtrace/ext/distributed'
3
+ require 'ddtrace/ext/integration'
3
4
  require 'ddtrace/propagation/http_propagator'
4
5
  require 'ddtrace/contrib/rest_client/ext'
5
6
 
@@ -31,6 +32,9 @@ module Datadog
31
32
  def datadog_tag_request(uri, span)
32
33
  span.resource = method.to_s.upcase
33
34
 
35
+ # Tag as an external peer service
36
+ span.set_tag(Datadog::Ext::Integration::TAG_PEER_SERVICE, span.service)
37
+
34
38
  # Set analytics sample rate
35
39
  Contrib::Analytics.set_sample_rate(span, analytics_sample_rate) if analytics_enabled?
36
40
 
@@ -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
@@ -0,0 +1,19 @@
1
+ module Datadog
2
+ module Contrib
3
+ module RSpec
4
+ # RSpec integration constants
5
+ module Ext
6
+ APP = 'rspec'.freeze
7
+ ENV_ANALYTICS_ENABLED = 'DD_TRACE_RSPEC_ANALYTICS_ENABLED'.freeze
8
+ ENV_ANALYTICS_SAMPLE_RATE = 'DD_TRACE_RSPEC_ANALYTICS_SAMPLE_RATE'.freeze
9
+ ENV_ENABLED = 'DD_TRACE_RSPEC_ENABLED'.freeze
10
+ ENV_OPERATION_NAME = 'DD_TRACE_RSPEC_OPERATION_NAME'.freeze
11
+ FRAMEWORK = 'rspec'.freeze
12
+ OPERATION_NAME = 'rspec.example'.freeze
13
+ EXAMPLE_GROUP_OPERATION_NAME = 'rspec.example_group'.freeze
14
+ SERVICE_NAME = 'rspec'.freeze
15
+ TEST_TYPE = 'test'.freeze
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,46 @@
1
+ require 'ddtrace/contrib/integration'
2
+ require 'ddtrace/contrib/rspec/configuration/settings'
3
+ require 'ddtrace/contrib/rspec/patcher'
4
+ require 'ddtrace/contrib/integration'
5
+
6
+ module Datadog
7
+ module Contrib
8
+ module RSpec
9
+ # Description of RSpec integration
10
+ class Integration
11
+ include Contrib::Integration
12
+
13
+ MINIMUM_VERSION = Gem::Version.new('3.0.0')
14
+
15
+ register_as :rspec, auto_patch: true
16
+
17
+ def self.version
18
+ Gem.loaded_specs['rspec'] \
19
+ && Gem.loaded_specs['rspec'].version
20
+ end
21
+
22
+ def self.loaded?
23
+ !defined?(::RSpec).nil? && !defined?(::RSpec::Core).nil? && \
24
+ !defined?(::RSpec::Core::Example).nil? && !defined?(::RSpec::Core::ExampleGroup).nil?
25
+ end
26
+
27
+ def self.compatible?
28
+ super && version >= MINIMUM_VERSION
29
+ end
30
+
31
+ # test environments should not auto instrument test libraries
32
+ def auto_instrument?
33
+ false
34
+ end
35
+
36
+ def default_configuration
37
+ Configuration::Settings.new
38
+ end
39
+
40
+ def patcher
41
+ Patcher
42
+ end
43
+ end
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,25 @@
1
+ require 'ddtrace/contrib/patcher'
2
+ require 'ddtrace/contrib/rspec/example'
3
+ require 'ddtrace/contrib/rspec/example_group'
4
+
5
+ module Datadog
6
+ module Contrib
7
+ module RSpec
8
+ # Patcher enables patching of 'rspec' module.
9
+ module Patcher
10
+ include Contrib::Patcher
11
+
12
+ module_function
13
+
14
+ def target_version
15
+ Integration.version
16
+ end
17
+
18
+ def patch
19
+ ::RSpec::Core::Example.send(:include, Example)
20
+ ::RSpec::Core::ExampleGroup.send(:include, ExampleGroup)
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end