ddtrace 0.39.0 → 0.44.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (146) hide show
  1. checksums.yaml +4 -4
  2. data/.circleci/config.yml +142 -115
  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/.gitlab-ci.yml +1 -0
  7. data/.simplecov +41 -0
  8. data/Appraisals +476 -120
  9. data/CHANGELOG.md +1115 -325
  10. data/CONTRIBUTING.md +2 -2
  11. data/Gemfile +4 -2
  12. data/Rakefile +665 -477
  13. data/ddtrace.gemspec +8 -8
  14. data/docker-compose.yml +30 -0
  15. data/docs/DevelopmentGuide.md +28 -2
  16. data/docs/GettingStarted.md +170 -41
  17. data/lib/ddtrace.rb +4 -0
  18. data/lib/ddtrace/buffer.rb +259 -52
  19. data/lib/ddtrace/configuration.rb +55 -5
  20. data/lib/ddtrace/configuration/components.rb +4 -7
  21. data/lib/ddtrace/configuration/options.rb +3 -1
  22. data/lib/ddtrace/configuration/settings.rb +9 -3
  23. data/lib/ddtrace/context.rb +18 -0
  24. data/lib/ddtrace/context_provider.rb +17 -5
  25. data/lib/ddtrace/contrib/action_pack/action_controller/instrumentation.rb +0 -7
  26. data/lib/ddtrace/contrib/action_view/event.rb +0 -4
  27. data/lib/ddtrace/contrib/action_view/events/render_partial.rb +1 -0
  28. data/lib/ddtrace/contrib/action_view/events/render_template.rb +1 -0
  29. data/lib/ddtrace/contrib/active_record/events/sql.rb +4 -0
  30. data/lib/ddtrace/contrib/active_record/utils.rb +11 -1
  31. data/lib/ddtrace/contrib/active_support/cache/instrumentation.rb +104 -3
  32. data/lib/ddtrace/contrib/active_support/cache/patcher.rb +21 -0
  33. data/lib/ddtrace/contrib/active_support/ext.rb +3 -0
  34. data/lib/ddtrace/contrib/active_support/notifications/event.rb +10 -0
  35. data/lib/ddtrace/contrib/active_support/notifications/subscription.rb +2 -2
  36. data/lib/ddtrace/contrib/aws/instrumentation.rb +6 -1
  37. data/lib/ddtrace/contrib/aws/patcher.rb +0 -1
  38. data/lib/ddtrace/contrib/aws/services.rb +1 -0
  39. data/lib/ddtrace/contrib/configurable.rb +2 -0
  40. data/lib/ddtrace/contrib/configuration/resolvers/pattern_resolver.rb +6 -5
  41. data/lib/ddtrace/contrib/cucumber/configuration/settings.rb +38 -0
  42. data/lib/ddtrace/contrib/cucumber/ext.rb +19 -0
  43. data/lib/ddtrace/contrib/cucumber/formatter.rb +104 -0
  44. data/lib/ddtrace/contrib/cucumber/instrumentation.rb +24 -0
  45. data/lib/ddtrace/contrib/cucumber/integration.rb +40 -0
  46. data/lib/ddtrace/contrib/cucumber/patcher.rb +23 -0
  47. data/lib/ddtrace/contrib/dalli/instrumentation.rb +4 -0
  48. data/lib/ddtrace/contrib/delayed_job/configuration/settings.rb +2 -0
  49. data/lib/ddtrace/contrib/delayed_job/ext.rb +2 -0
  50. data/lib/ddtrace/contrib/delayed_job/plugin.rb +39 -15
  51. data/lib/ddtrace/contrib/elasticsearch/patcher.rb +4 -0
  52. data/lib/ddtrace/contrib/ethon/easy_patch.rb +5 -3
  53. data/lib/ddtrace/contrib/ethon/ext.rb +1 -0
  54. data/lib/ddtrace/contrib/ethon/multi_patch.rb +4 -0
  55. data/lib/ddtrace/contrib/excon/middleware.rb +11 -1
  56. data/lib/ddtrace/contrib/faraday/middleware.rb +4 -0
  57. data/lib/ddtrace/contrib/faraday/patcher.rb +1 -1
  58. data/lib/ddtrace/contrib/grape/configuration/settings.rb +7 -0
  59. data/lib/ddtrace/contrib/grape/endpoint.rb +53 -18
  60. data/lib/ddtrace/contrib/grape/ext.rb +1 -0
  61. data/lib/ddtrace/contrib/grpc/datadog_interceptor/client.rb +5 -1
  62. data/lib/ddtrace/contrib/grpc/datadog_interceptor/server.rb +4 -0
  63. data/lib/ddtrace/contrib/http/instrumentation.rb +6 -2
  64. data/lib/ddtrace/contrib/httprb/instrumentation.rb +6 -3
  65. data/lib/ddtrace/contrib/kafka/event.rb +1 -1
  66. data/lib/ddtrace/contrib/mongodb/subscribers.rb +4 -0
  67. data/lib/ddtrace/contrib/mysql2/instrumentation.rb +4 -0
  68. data/lib/ddtrace/contrib/presto/instrumentation.rb +3 -0
  69. data/lib/ddtrace/contrib/qless/configuration/settings.rb +35 -0
  70. data/lib/ddtrace/contrib/qless/ext.rb +20 -0
  71. data/lib/ddtrace/contrib/qless/integration.rb +38 -0
  72. data/lib/ddtrace/contrib/qless/patcher.rb +35 -0
  73. data/lib/ddtrace/contrib/qless/qless_job.rb +72 -0
  74. data/lib/ddtrace/contrib/qless/tracer_cleaner.rb +32 -0
  75. data/lib/ddtrace/contrib/que/configuration/settings.rb +43 -0
  76. data/lib/ddtrace/contrib/que/ext.rb +30 -0
  77. data/lib/ddtrace/contrib/que/integration.rb +42 -0
  78. data/lib/ddtrace/contrib/que/patcher.rb +24 -0
  79. data/lib/ddtrace/contrib/que/tracer.rb +57 -0
  80. data/lib/ddtrace/contrib/racecar/event.rb +4 -0
  81. data/lib/ddtrace/contrib/racecar/events.rb +2 -0
  82. data/lib/ddtrace/contrib/racecar/events/consume.rb +27 -0
  83. data/lib/ddtrace/contrib/racecar/ext.rb +1 -0
  84. data/lib/ddtrace/contrib/rack/middlewares.rb +2 -0
  85. data/lib/ddtrace/contrib/rails/configuration/settings.rb +5 -0
  86. data/lib/ddtrace/contrib/rails/ext.rb +1 -0
  87. data/lib/ddtrace/contrib/rails/log_injection.rb +81 -0
  88. data/lib/ddtrace/contrib/rails/middlewares.rb +7 -2
  89. data/lib/ddtrace/contrib/rails/patcher.rb +29 -0
  90. data/lib/ddtrace/contrib/redis/configuration/resolver.rb +3 -1
  91. data/lib/ddtrace/contrib/redis/configuration/settings.rb +5 -0
  92. data/lib/ddtrace/contrib/redis/ext.rb +1 -0
  93. data/lib/ddtrace/contrib/redis/patcher.rb +20 -3
  94. data/lib/ddtrace/contrib/redis/quantize.rb +27 -0
  95. data/lib/ddtrace/contrib/redis/tags.rb +9 -1
  96. data/lib/ddtrace/contrib/resque/configuration/settings.rb +1 -0
  97. data/lib/ddtrace/contrib/resque/integration.rb +1 -1
  98. data/lib/ddtrace/contrib/resque/resque_job.rb +1 -1
  99. data/lib/ddtrace/contrib/rest_client/request_patch.rb +4 -0
  100. data/lib/ddtrace/contrib/rspec/configuration/settings.rb +38 -0
  101. data/lib/ddtrace/contrib/rspec/example.rb +61 -0
  102. data/lib/ddtrace/contrib/rspec/example_group.rb +61 -0
  103. data/lib/ddtrace/contrib/rspec/ext.rb +19 -0
  104. data/lib/ddtrace/contrib/rspec/integration.rb +41 -0
  105. data/lib/ddtrace/contrib/rspec/patcher.rb +25 -0
  106. data/lib/ddtrace/contrib/sequel/database.rb +3 -1
  107. data/lib/ddtrace/contrib/sequel/dataset.rb +3 -2
  108. data/lib/ddtrace/contrib/sequel/ext.rb +1 -0
  109. data/lib/ddtrace/contrib/sequel/utils.rb +16 -5
  110. data/lib/ddtrace/contrib/shoryuken/configuration/settings.rb +1 -0
  111. data/lib/ddtrace/contrib/shoryuken/tracer.rb +4 -1
  112. data/lib/ddtrace/contrib/sidekiq/configuration/settings.rb +1 -0
  113. data/lib/ddtrace/contrib/sidekiq/server_tracer.rb +4 -1
  114. data/lib/ddtrace/contrib/sinatra/env.rb +5 -4
  115. data/lib/ddtrace/contrib/sinatra/tracer.rb +21 -42
  116. data/lib/ddtrace/contrib/sinatra/tracer_middleware.rb +50 -23
  117. data/lib/ddtrace/contrib/sneakers/configuration/settings.rb +1 -0
  118. data/lib/ddtrace/contrib/sneakers/tracer.rb +17 -20
  119. data/lib/ddtrace/contrib/status_code_matcher.rb +67 -0
  120. data/lib/ddtrace/ext/app_types.rb +1 -0
  121. data/lib/ddtrace/ext/ci.rb +264 -0
  122. data/lib/ddtrace/ext/distributed.rb +8 -2
  123. data/lib/ddtrace/ext/git.rb +12 -0
  124. data/lib/ddtrace/ext/integration.rb +8 -0
  125. data/lib/ddtrace/ext/runtime.rb +2 -0
  126. data/lib/ddtrace/ext/test.rb +24 -0
  127. data/lib/ddtrace/opentracer/distributed_headers.rb +1 -1
  128. data/lib/ddtrace/propagation/grpc_propagator.rb +18 -6
  129. data/lib/ddtrace/runtime/identity.rb +4 -5
  130. data/lib/ddtrace/runtime/metrics.rb +6 -2
  131. data/lib/ddtrace/sampler.rb +2 -2
  132. data/lib/ddtrace/sampling/rate_limiter.rb +65 -16
  133. data/lib/ddtrace/span.rb +152 -27
  134. data/lib/ddtrace/tracer.rb +25 -13
  135. data/lib/ddtrace/transport/http/adapters/net.rb +8 -2
  136. data/lib/ddtrace/transport/http/statistics.rb +14 -1
  137. data/lib/ddtrace/transport/traces.rb +7 -2
  138. data/lib/ddtrace/utils.rb +16 -13
  139. data/lib/ddtrace/utils/forking.rb +52 -0
  140. data/lib/ddtrace/version.rb +1 -1
  141. data/lib/ddtrace/workers/async.rb +2 -2
  142. data/lib/ddtrace/workers/loop.rb +1 -1
  143. data/lib/ddtrace/workers/polling.rb +1 -1
  144. data/lib/ddtrace/workers/runtime_metrics.rb +7 -3
  145. data/lib/ddtrace/writer.rb +19 -1
  146. metadata +147 -42
@@ -1,6 +1,7 @@
1
1
  require 'ddtrace/contrib/analytics'
2
2
  require 'ddtrace/contrib/active_support/notifications/event'
3
3
  require 'ddtrace/contrib/racecar/ext'
4
+ require 'ddtrace/ext/integration'
4
5
 
5
6
  module Datadog
6
7
  module Contrib
@@ -37,6 +38,9 @@ module Datadog
37
38
  span.service = configuration[:service_name]
38
39
  span.resource = payload[:consumer_class]
39
40
 
41
+ # Tag as an external peer service
42
+ span.set_tag(Datadog::Ext::Integration::TAG_PEER_SERVICE, span.service)
43
+
40
44
  # Set analytics sample rate
41
45
  if Contrib::Analytics.enabled?(configuration[:analytics_enabled])
42
46
  Contrib::Analytics.set_sample_rate(span, configuration[:analytics_sample_rate])
@@ -1,5 +1,6 @@
1
1
  require 'ddtrace/contrib/racecar/events/batch'
2
2
  require 'ddtrace/contrib/racecar/events/message'
3
+ require 'ddtrace/contrib/racecar/events/consume'
3
4
 
4
5
  module Datadog
5
6
  module Contrib
@@ -7,6 +8,7 @@ module Datadog
7
8
  # Defines collection of instrumented Racecar events
8
9
  module Events
9
10
  ALL = [
11
+ Events::Consume,
10
12
  Events::Batch,
11
13
  Events::Message
12
14
  ].freeze
@@ -0,0 +1,27 @@
1
+ require 'ddtrace/contrib/racecar/ext'
2
+ require 'ddtrace/contrib/racecar/event'
3
+
4
+ module Datadog
5
+ module Contrib
6
+ module Racecar
7
+ module Events
8
+ # Defines instrumentation for main_loop.racecar event
9
+ module Consume
10
+ include Racecar::Event
11
+
12
+ EVENT_NAME = 'main_loop.racecar'.freeze
13
+
14
+ module_function
15
+
16
+ def event_name
17
+ self::EVENT_NAME
18
+ end
19
+
20
+ def span_name
21
+ Ext::SPAN_CONSUME
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
@@ -10,6 +10,7 @@ module Datadog
10
10
  ENV_ANALYTICS_SAMPLE_RATE = 'DD_TRACE_RACECAR_ANALYTICS_SAMPLE_RATE'.freeze
11
11
  ENV_ANALYTICS_SAMPLE_RATE_OLD = 'DD_RACECAR_ANALYTICS_SAMPLE_RATE'.freeze
12
12
  SERVICE_NAME = 'racecar'.freeze
13
+ SPAN_CONSUME = 'racecar.consume'.freeze
13
14
  SPAN_BATCH = 'racecar.batch'.freeze
14
15
  SPAN_MESSAGE = 'racecar.message'.freeze
15
16
  TAG_CONSUMER = 'kafka.consumer'.freeze
@@ -4,6 +4,8 @@ require 'ddtrace/propagation/http_propagator'
4
4
  require 'ddtrace/contrib/analytics'
5
5
  require 'ddtrace/contrib/rack/ext'
6
6
  require 'ddtrace/contrib/rack/request_queue'
7
+ require 'ddtrace/environment'
8
+ require 'date'
7
9
 
8
10
  module Datadog
9
11
  module Contrib
@@ -81,6 +81,11 @@ module Datadog
81
81
  Datadog.configuration[:action_view][:template_base_path] = value
82
82
  end
83
83
  end
84
+
85
+ option :log_injection do |o|
86
+ o.default { env_to_bool(Ext::ENV_LOGS_INJECTION_ENABLED, false) }
87
+ o.lazy
88
+ end
84
89
  end
85
90
  end
86
91
  end
@@ -10,6 +10,7 @@ module Datadog
10
10
  ENV_ANALYTICS_SAMPLE_RATE = 'DD_TRACE_RAILS_ANALYTICS_SAMPLE_RATE'.freeze
11
11
  ENV_ANALYTICS_SAMPLE_RATE_OLD = 'DD_RAILS_ANALYTICS_SAMPLE_RATE'.freeze
12
12
  ENV_DISABLE = 'DISABLE_DATADOG_RAILS'.freeze
13
+ ENV_LOGS_INJECTION_ENABLED = 'DD_LOGS_INJECTION'.freeze
13
14
  end
14
15
  end
15
16
  end
@@ -0,0 +1,81 @@
1
+ module Datadog
2
+ module Contrib
3
+ # Instrument Rails.
4
+ module Rails
5
+ # Rails log injection helper methods
6
+ module LogInjection
7
+ module_function
8
+
9
+ def add_lograge_logger(app)
10
+ # custom_options defaults to nil and can be either a hash or a lambda which returns a hash
11
+ # https://github.com/roidrage/lograge/blob/1729eab7956bb95c5992e4adab251e4f93ff9280/lib/lograge.rb#L28
12
+ if (custom_options = app.config.lograge.custom_options).nil?
13
+ # if it's not set, we set to a lambda that returns DD tracing context
14
+ app.config.lograge.custom_options = lambda do |_event|
15
+ # Retrieves trace information for current thread
16
+ correlation = Datadog.tracer.active_correlation
17
+
18
+ datadog_trace_log_hash(correlation)
19
+ end
20
+ # check if lambda, if so then define a new lambda which invokes the original lambda and
21
+ # merges the returned hash with the the DD tracing context hash.
22
+ elsif custom_options.respond_to?(:call)
23
+ app.config.lograge.custom_options = lambda do |event|
24
+ # invoke original lambda
25
+ result = custom_options.call(event)
26
+ # Retrieves trace information for current thread
27
+ correlation = Datadog.tracer.active_correlation
28
+ # merge original lambda with datadog context
29
+ result.merge(datadog_trace_log_hash(correlation))
30
+ end
31
+ # otherwise if it's just a static hash, we have to wrap that hash in a lambda to retrieve
32
+ # the DD tracing context, then merge the tracing context with the original static hash.
33
+ # don't modify if custom_options is not an accepted format.
34
+ elsif custom_options.is_a?(Hash)
35
+ app.config.lograge.custom_options = lambda do |_event|
36
+ # Retrieves trace information for current thread
37
+ correlation = Datadog.tracer.active_correlation
38
+
39
+ # merge original lambda with datadog context
40
+ custom_options.merge(datadog_trace_log_hash(correlation))
41
+ end
42
+ end
43
+ rescue StandardError => e
44
+ # TODO: can we use Datadog.logger at this point?
45
+ Datadog.logger.warn("Unable to add Datadog Trace context to Lograge: #{e.message}")
46
+ false
47
+ end
48
+
49
+ def add_as_tagged_logging_logger(app)
50
+ # we want to check if the current logger is a tagger logger instance
51
+ # log_tags defaults to nil so we have to set as an array if nothing exists yet
52
+ if (log_tags = app.config.log_tags).nil?
53
+ app.config.log_tags = [proc { Datadog.tracer.active_correlation.to_s }]
54
+ # if existing log_tags configuration exists, append to the end of the array
55
+ elsif log_tags.is_a?(Array)
56
+ app.config.log_tags << proc { Datadog.tracer.active_correlation.to_s }
57
+ end
58
+ rescue StandardError => e
59
+ # TODO: can we use Datadog.logger at this point?
60
+ Datadog.logger.warn("Unable to add Datadog Trace context to ActiveSupport::TaggedLogging: #{e.message}")
61
+ false
62
+ end
63
+
64
+ def datadog_trace_log_hash(correlation)
65
+ {
66
+ # Adds IDs as tags to log output
67
+ dd: {
68
+ # To preserve precision during JSON serialization, use strings for large numbers
69
+ trace_id: correlation.trace_id.to_s,
70
+ span_id: correlation.span_id.to_s,
71
+ env: correlation.env.to_s,
72
+ service: correlation.service.to_s,
73
+ version: correlation.version.to_s
74
+ },
75
+ ddsource: ['ruby']
76
+ }
77
+ end
78
+ end
79
+ end
80
+ end
81
+ end
@@ -24,11 +24,16 @@ module Datadog
24
24
  rescue Exception => e
25
25
  tracer = Datadog.configuration[:rails][:tracer]
26
26
  span = tracer.active_span
27
- unless span.nil?
27
+ if !span.nil? && ActionPack::Utils.exception_is_error?(e)
28
28
  # Only set error if it's supposed to be flagged as such
29
29
  # e.g. we don't want to flag 404s.
30
30
  # You can add custom errors via `config.action_dispatch.rescue_responses`
31
- span.set_error(e) if ActionPack::Utils.exception_is_error?(e)
31
+ span.set_error(e)
32
+
33
+ # Some exception gets handled by Rails middleware before it can be set on Rack middleware
34
+ # The rack span is the root span of the request and should make sure it has the full exception
35
+ # set on it.
36
+ env[:datadog_rack_request_span].set_error(e) if env[:datadog_rack_request_span]
32
37
  end
33
38
  raise e
34
39
  end
@@ -1,6 +1,7 @@
1
1
  require 'ddtrace/contrib/rails/utils'
2
2
  require 'ddtrace/contrib/rails/framework'
3
3
  require 'ddtrace/contrib/rails/middlewares'
4
+ require 'ddtrace/contrib/rails/log_injection'
4
5
  require 'ddtrace/contrib/rack/middlewares'
5
6
 
6
7
  module Datadog
@@ -33,6 +34,7 @@ module Datadog
33
34
  # Otherwise the middleware stack will be frozen.
34
35
  # Sometimes we don't want to activate middleware e.g. OpenTracing, etc.
35
36
  add_middleware(app) if Datadog.configuration[:rails][:middleware]
37
+ add_logger(app) if Datadog.configuration[:rails][:log_injection]
36
38
  end
37
39
  end
38
40
 
@@ -50,6 +52,33 @@ module Datadog
50
52
  )
51
53
  end
52
54
 
55
+ def add_logger(app)
56
+ should_warn = true
57
+ # check if lograge key exists
58
+ # Note: Rails executes initializers sequentially based on alphabetical order,
59
+ # and lograge config could occur after dd config.
60
+ # Checking for `app.config.lograge.enabled` may yield a false negative.
61
+ # Instead we should naively add custom options if `config.lograge` exists from the lograge Railtie,
62
+ # since the custom options get ignored without lograge explicitly being enabled.
63
+ # See: https://github.com/roidrage/lograge/blob/1729eab7956bb95c5992e4adab251e4f93ff9280/lib/lograge/railtie.rb#L7-L12
64
+ if app.config.respond_to?(:lograge)
65
+ Datadog::Contrib::Rails::LogInjection.add_lograge_logger(app)
66
+ should_warn = false
67
+ end
68
+
69
+ # if lograge isn't set, check if tagged logged is enabled.
70
+ # if so, add proc that injects trace identifiers for tagged logging.
71
+ if (logger = app.config.logger) &&
72
+ defined?(::ActiveSupport::TaggedLogging) &&
73
+ logger.is_a?(::ActiveSupport::TaggedLogging)
74
+
75
+ Datadog::Contrib::Rails::LogInjection.add_as_tagged_logging_logger(app)
76
+ should_warn = false
77
+ end
78
+
79
+ Datadog.logger.warn("Unable to enable Datadog Trace context, Logger #{logger} is not supported") if should_warn
80
+ end
81
+
53
82
  def patch_after_intialize
54
83
  ::ActiveSupport.on_load(:after_initialize) do
55
84
  Datadog::Contrib::Rails::Patcher.after_intialize(self)
@@ -4,6 +4,8 @@ module Datadog
4
4
  module Contrib
5
5
  module Redis
6
6
  module Configuration
7
+ UNIX_SCHEME = 'unix'.freeze
8
+
7
9
  # Converts Symbols, Strings, and Hashes to a normalized connection settings Hash.
8
10
  class Resolver < Contrib::Configuration::Resolver
9
11
  def resolve(key_or_hash)
@@ -13,7 +15,7 @@ module Datadog
13
15
  end
14
16
 
15
17
  def normalize(hash)
16
- return { url: hash[:url] } if hash[:scheme] == 'unix'
18
+ return { url: hash[:url] } if hash[:scheme] == UNIX_SCHEME
17
19
 
18
20
  # Connexion strings are always converted to host, port, db and scheme
19
21
  # but the host, port, db and scheme will generate the :url only after
@@ -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