ddtrace 1.6.1 → 1.8.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 (171) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +89 -2
  3. data/README.md +2 -2
  4. data/ext/ddtrace_profiling_loader/extconf.rb +5 -2
  5. data/ext/ddtrace_profiling_native_extension/NativeExtensionDesign.md +1 -1
  6. data/ext/ddtrace_profiling_native_extension/clock_id_from_pthread.c +3 -2
  7. data/ext/ddtrace_profiling_native_extension/collectors_cpu_and_wall_time.c +81 -47
  8. data/ext/ddtrace_profiling_native_extension/collectors_cpu_and_wall_time.h +1 -1
  9. data/ext/ddtrace_profiling_native_extension/collectors_cpu_and_wall_time_worker.c +332 -125
  10. data/ext/ddtrace_profiling_native_extension/collectors_dynamic_sampling_rate.c +142 -0
  11. data/ext/ddtrace_profiling_native_extension/collectors_dynamic_sampling_rate.h +14 -0
  12. data/ext/ddtrace_profiling_native_extension/collectors_idle_sampling_helper.c +241 -0
  13. data/ext/ddtrace_profiling_native_extension/collectors_idle_sampling_helper.h +3 -0
  14. data/ext/ddtrace_profiling_native_extension/collectors_stack.c +11 -13
  15. data/ext/ddtrace_profiling_native_extension/extconf.rb +22 -8
  16. data/ext/ddtrace_profiling_native_extension/helpers.h +5 -0
  17. data/ext/ddtrace_profiling_native_extension/native_extension_helpers.rb +8 -0
  18. data/ext/ddtrace_profiling_native_extension/private_vm_api_access.c +111 -26
  19. data/ext/ddtrace_profiling_native_extension/private_vm_api_access.h +9 -0
  20. data/ext/ddtrace_profiling_native_extension/profiling.c +205 -0
  21. data/ext/ddtrace_profiling_native_extension/ruby_helpers.c +86 -0
  22. data/ext/ddtrace_profiling_native_extension/ruby_helpers.h +28 -6
  23. data/ext/ddtrace_profiling_native_extension/setup_signal_handler.c +115 -0
  24. data/ext/ddtrace_profiling_native_extension/setup_signal_handler.h +11 -0
  25. data/ext/ddtrace_profiling_native_extension/stack_recorder.c +84 -35
  26. data/ext/ddtrace_profiling_native_extension/stack_recorder.h +1 -0
  27. data/ext/ddtrace_profiling_native_extension/time_helpers.c +17 -0
  28. data/ext/ddtrace_profiling_native_extension/time_helpers.h +10 -0
  29. data/lib/datadog/appsec/assets/blocked.html +98 -3
  30. data/lib/datadog/appsec/assets/blocked.json +1 -0
  31. data/lib/datadog/appsec/assets/blocked.text +5 -0
  32. data/lib/datadog/appsec/assets/waf_rules/recommended.json +35 -46
  33. data/lib/datadog/appsec/assets/waf_rules/risky.json +1 -1
  34. data/lib/datadog/appsec/assets/waf_rules/strict.json +46 -1
  35. data/lib/datadog/appsec/assets.rb +2 -2
  36. data/lib/datadog/appsec/configuration/settings.rb +6 -0
  37. data/lib/datadog/appsec/configuration.rb +4 -0
  38. data/lib/datadog/appsec/contrib/rack/reactive/request.rb +4 -8
  39. data/lib/datadog/appsec/contrib/rack/request.rb +17 -0
  40. data/lib/datadog/appsec/contrib/rack/request_body_middleware.rb +2 -2
  41. data/lib/datadog/appsec/contrib/rack/request_middleware.rb +2 -2
  42. data/lib/datadog/appsec/contrib/rails/patcher.rb +3 -6
  43. data/lib/datadog/appsec/contrib/sinatra/ext.rb +1 -0
  44. data/lib/datadog/appsec/contrib/sinatra/gateway/watcher.rb +1 -1
  45. data/lib/datadog/appsec/contrib/sinatra/patcher.rb +11 -8
  46. data/lib/datadog/appsec/extensions.rb +10 -0
  47. data/lib/datadog/appsec/processor.rb +18 -0
  48. data/lib/datadog/appsec/response.rb +54 -0
  49. data/lib/datadog/core/configuration/components.rb +27 -6
  50. data/lib/datadog/core/configuration/ext.rb +18 -0
  51. data/lib/datadog/core/configuration/settings.rb +14 -341
  52. data/lib/datadog/core/diagnostics/health.rb +4 -22
  53. data/lib/datadog/core/environment/variable_helpers.rb +58 -10
  54. data/lib/datadog/core/runtime/ext.rb +1 -1
  55. data/lib/datadog/core/utils.rb +0 -21
  56. data/lib/datadog/core.rb +21 -1
  57. data/lib/datadog/opentracer/distributed_headers.rb +7 -9
  58. data/lib/datadog/opentracer/rack_propagator.rb +0 -3
  59. data/lib/datadog/opentracer/text_map_propagator.rb +5 -7
  60. data/lib/datadog/profiling/collectors/cpu_and_wall_time.rb +10 -4
  61. data/lib/datadog/profiling/collectors/cpu_and_wall_time_worker.rb +20 -5
  62. data/lib/datadog/profiling/collectors/dynamic_sampling_rate.rb +14 -0
  63. data/lib/datadog/profiling/collectors/idle_sampling_helper.rb +68 -0
  64. data/lib/datadog/profiling/collectors/old_stack.rb +7 -0
  65. data/lib/datadog/profiling/exporter.rb +5 -0
  66. data/lib/datadog/profiling/old_recorder.rb +8 -0
  67. data/lib/datadog/profiling/profiler.rb +7 -0
  68. data/lib/datadog/profiling/scheduler.rb +4 -7
  69. data/lib/datadog/profiling/stack_recorder.rb +36 -0
  70. data/lib/datadog/profiling/tasks/setup.rb +0 -7
  71. data/lib/datadog/profiling.rb +2 -0
  72. data/lib/datadog/tracing/configuration/ext.rb +33 -3
  73. data/lib/datadog/tracing/configuration/settings.rb +433 -0
  74. data/lib/datadog/tracing/contrib/aws/configuration/settings.rb +4 -1
  75. data/lib/datadog/tracing/contrib/aws/ext.rb +1 -0
  76. data/lib/datadog/tracing/contrib/dalli/configuration/settings.rb +4 -1
  77. data/lib/datadog/tracing/contrib/dalli/ext.rb +1 -0
  78. data/lib/datadog/tracing/contrib/delayed_job/plugin.rb +4 -0
  79. data/lib/datadog/tracing/contrib/elasticsearch/configuration/settings.rb +5 -1
  80. data/lib/datadog/tracing/contrib/elasticsearch/ext.rb +1 -0
  81. data/lib/datadog/tracing/contrib/ethon/configuration/settings.rb +6 -1
  82. data/lib/datadog/tracing/contrib/ethon/ext.rb +1 -0
  83. data/lib/datadog/tracing/contrib/excon/configuration/settings.rb +5 -1
  84. data/lib/datadog/tracing/contrib/excon/ext.rb +1 -0
  85. data/lib/datadog/tracing/contrib/faraday/configuration/settings.rb +5 -1
  86. data/lib/datadog/tracing/contrib/faraday/ext.rb +1 -0
  87. data/lib/datadog/tracing/contrib/grpc/configuration/settings.rb +6 -1
  88. data/lib/datadog/tracing/contrib/grpc/datadog_interceptor/client.rb +2 -1
  89. data/lib/datadog/tracing/contrib/grpc/datadog_interceptor/server.rb +6 -12
  90. data/lib/datadog/tracing/contrib/grpc/distributed/fetcher.rb +27 -0
  91. data/lib/datadog/tracing/contrib/grpc/distributed/propagation.rb +43 -0
  92. data/lib/datadog/tracing/contrib/grpc/ext.rb +1 -0
  93. data/lib/datadog/tracing/contrib/grpc/patcher.rb +0 -2
  94. data/lib/datadog/tracing/contrib/http/configuration/settings.rb +6 -1
  95. data/lib/datadog/tracing/contrib/http/distributed/fetcher.rb +32 -0
  96. data/lib/datadog/tracing/contrib/http/distributed/propagation.rb +38 -0
  97. data/lib/datadog/tracing/contrib/http/ext.rb +1 -0
  98. data/lib/datadog/tracing/contrib/httpclient/configuration/settings.rb +6 -1
  99. data/lib/datadog/tracing/contrib/httpclient/ext.rb +1 -0
  100. data/lib/datadog/tracing/contrib/httprb/configuration/settings.rb +6 -1
  101. data/lib/datadog/tracing/contrib/httprb/ext.rb +1 -0
  102. data/lib/datadog/tracing/contrib/kafka/consumer_event.rb +1 -0
  103. data/lib/datadog/tracing/contrib/kafka/events/produce_operation/send_messages.rb +1 -0
  104. data/lib/datadog/tracing/contrib/kafka/events/producer/deliver_messages.rb +1 -0
  105. data/lib/datadog/tracing/contrib/mongodb/configuration/settings.rb +5 -1
  106. data/lib/datadog/tracing/contrib/mongodb/ext.rb +1 -0
  107. data/lib/datadog/tracing/contrib/mongodb/subscribers.rb +2 -0
  108. data/lib/datadog/tracing/contrib/mysql2/configuration/settings.rb +4 -1
  109. data/lib/datadog/tracing/contrib/mysql2/ext.rb +1 -0
  110. data/lib/datadog/tracing/contrib/mysql2/instrumentation.rb +2 -2
  111. data/lib/datadog/tracing/contrib/patcher.rb +3 -2
  112. data/lib/datadog/tracing/contrib/pg/configuration/settings.rb +4 -1
  113. data/lib/datadog/tracing/contrib/pg/ext.rb +1 -0
  114. data/lib/datadog/tracing/contrib/pg/instrumentation.rb +12 -2
  115. data/lib/datadog/tracing/contrib/presto/configuration/settings.rb +4 -1
  116. data/lib/datadog/tracing/contrib/presto/ext.rb +1 -0
  117. data/lib/datadog/tracing/contrib/propagation/sql_comment/ext.rb +1 -0
  118. data/lib/datadog/tracing/contrib/propagation/sql_comment.rb +10 -12
  119. data/lib/datadog/tracing/contrib/que/tracer.rb +2 -0
  120. data/lib/datadog/tracing/contrib/racecar/events/batch.rb +4 -1
  121. data/lib/datadog/tracing/contrib/racecar/events/message.rb +4 -1
  122. data/lib/datadog/tracing/contrib/rack/middlewares.rb +2 -0
  123. data/lib/datadog/tracing/contrib/redis/configuration/settings.rb +4 -1
  124. data/lib/datadog/tracing/contrib/redis/ext.rb +1 -0
  125. data/lib/datadog/tracing/contrib/redis/instrumentation.rb +30 -21
  126. data/lib/datadog/tracing/contrib/redis/integration.rb +34 -2
  127. data/lib/datadog/tracing/contrib/redis/patcher.rb +18 -14
  128. data/lib/datadog/tracing/contrib/redis/quantize.rb +12 -9
  129. data/lib/datadog/tracing/contrib/redis/tags.rb +4 -6
  130. data/lib/datadog/tracing/contrib/redis/trace_middleware.rb +72 -0
  131. data/lib/datadog/tracing/contrib/resque/resque_job.rb +2 -0
  132. data/lib/datadog/tracing/contrib/rest_client/configuration/settings.rb +6 -1
  133. data/lib/datadog/tracing/contrib/rest_client/ext.rb +1 -0
  134. data/lib/datadog/tracing/contrib/shoryuken/tracer.rb +2 -0
  135. data/lib/datadog/tracing/contrib/sidekiq/client_tracer.rb +5 -0
  136. data/lib/datadog/tracing/contrib/sidekiq/server_tracer.rb +5 -0
  137. data/lib/datadog/tracing/contrib/sneakers/tracer.rb +2 -0
  138. data/lib/datadog/{core → tracing}/diagnostics/ext.rb +1 -6
  139. data/lib/datadog/tracing/diagnostics/health.rb +40 -0
  140. data/lib/datadog/tracing/distributed/b3_multi.rb +66 -0
  141. data/lib/datadog/tracing/distributed/b3_single.rb +66 -0
  142. data/lib/datadog/tracing/distributed/datadog.rb +153 -0
  143. data/lib/datadog/tracing/distributed/datadog_tags_codec.rb +1 -0
  144. data/lib/datadog/tracing/distributed/fetcher.rb +30 -0
  145. data/lib/datadog/tracing/distributed/headers/ext.rb +18 -16
  146. data/lib/datadog/tracing/distributed/helpers.rb +9 -7
  147. data/lib/datadog/tracing/distributed/none.rb +19 -0
  148. data/lib/datadog/tracing/distributed/propagation.rb +127 -0
  149. data/lib/datadog/tracing/distributed/trace_context.rb +369 -0
  150. data/lib/datadog/tracing/metadata/ext.rb +1 -1
  151. data/lib/datadog/tracing/propagation/http.rb +3 -106
  152. data/lib/datadog/tracing/sampling/priority_sampler.rb +11 -0
  153. data/lib/datadog/tracing/sampling/rate_sampler.rb +3 -3
  154. data/lib/datadog/tracing/span.rb +3 -19
  155. data/lib/datadog/tracing/span_operation.rb +5 -4
  156. data/lib/datadog/tracing/trace_digest.rb +75 -2
  157. data/lib/datadog/tracing/trace_operation.rb +5 -4
  158. data/lib/datadog/tracing/trace_segment.rb +1 -1
  159. data/lib/datadog/tracing/utils.rb +50 -0
  160. data/lib/ddtrace/transport/trace_formatter.rb +2 -5
  161. data/lib/ddtrace/version.rb +2 -2
  162. metadata +35 -15
  163. data/lib/datadog/tracing/distributed/headers/b3.rb +0 -55
  164. data/lib/datadog/tracing/distributed/headers/b3_single.rb +0 -67
  165. data/lib/datadog/tracing/distributed/headers/datadog.rb +0 -144
  166. data/lib/datadog/tracing/distributed/headers/parser.rb +0 -37
  167. data/lib/datadog/tracing/distributed/metadata/b3.rb +0 -55
  168. data/lib/datadog/tracing/distributed/metadata/b3_single.rb +0 -66
  169. data/lib/datadog/tracing/distributed/metadata/datadog.rb +0 -73
  170. data/lib/datadog/tracing/distributed/metadata/parser.rb +0 -34
  171. data/lib/datadog/tracing/propagation/grpc.rb +0 -98
@@ -10,7 +10,7 @@ module Datadog
10
10
  module Tracing
11
11
  module Contrib
12
12
  module Redis
13
- # Instrumentation for Redis
13
+ # Instrumentation for Redis < 5
14
14
  module Instrumentation
15
15
  def self.included(base)
16
16
  base.prepend(InstanceMethods)
@@ -19,49 +19,58 @@ module Datadog
19
19
  # InstanceMethods - implementing instrumentation
20
20
  module InstanceMethods
21
21
  def call(*args, &block)
22
- response = nil
22
+ show_command_args = command_args?
23
+
23
24
  Tracing.trace(Contrib::Redis::Ext::SPAN_COMMAND) do |span|
24
- span.service = Datadog.configuration_for(redis_instance, :service_name) ||
25
- datadog_configuration[:service_name]
25
+ span.service = service_name
26
26
  span.span_type = Contrib::Redis::Ext::TYPE
27
- span.resource = get_command(args)
28
- Contrib::Redis::Tags.set_common_tags(self, span)
27
+ span.resource = get_command(args, show_command_args)
28
+ Contrib::Redis::Tags.set_common_tags(self, span, show_command_args)
29
29
 
30
- response = super
30
+ super
31
31
  end
32
-
33
- response
34
32
  end
35
33
 
36
34
  def call_pipeline(*args, &block)
37
- response = nil
35
+ show_command_args = command_args?
36
+
38
37
  Tracing.trace(Contrib::Redis::Ext::SPAN_COMMAND) do |span|
39
- span.service = Datadog.configuration_for(redis_instance, :service_name) ||
40
- datadog_configuration[:service_name]
38
+ span.service = service_name
41
39
  span.span_type = Contrib::Redis::Ext::TYPE
42
- commands = get_pipeline_commands(args)
40
+ commands = get_pipeline_commands(args, show_command_args)
43
41
  span.resource = commands.any? ? commands.join("\n") : '(none)'
44
42
  span.set_metric Contrib::Redis::Ext::METRIC_PIPELINE_LEN, commands.length
45
- Contrib::Redis::Tags.set_common_tags(self, span)
43
+ Contrib::Redis::Tags.set_common_tags(self, span, show_command_args)
46
44
 
47
- response = super
45
+ super
48
46
  end
49
-
50
- response
51
47
  end
52
48
 
53
49
  private
54
50
 
55
- def get_command(args)
56
- if datadog_configuration[:command_args]
51
+ def command_args?
52
+ pinned = Datadog.configuration_for(redis_instance, :command_args)
53
+
54
+ return pinned unless pinned.nil?
55
+
56
+ datadog_configuration[:command_args]
57
+ end
58
+
59
+ def service_name
60
+ Datadog.configuration_for(redis_instance, :service_name) ||
61
+ datadog_configuration[:service_name]
62
+ end
63
+
64
+ def get_command(args, show_command_args)
65
+ if show_command_args
57
66
  Contrib::Redis::Quantize.format_command_args(*args)
58
67
  else
59
68
  Contrib::Redis::Quantize.get_verb(*args)
60
69
  end
61
70
  end
62
71
 
63
- def get_pipeline_commands(args)
64
- if datadog_configuration[:command_args]
72
+ def get_pipeline_commands(args, show_command_args)
73
+ if show_command_args
65
74
  args[0].commands.map { |c| Contrib::Redis::Quantize.format_command_args(c) }
66
75
  else
67
76
  args[0].commands.map { |c| Contrib::Redis::Quantize.get_verb(c) }
@@ -13,21 +13,53 @@ module Datadog
13
13
  include Contrib::Integration
14
14
 
15
15
  MINIMUM_VERSION = Gem::Version.new('3.2')
16
- MAX_VERSION = Gem::Version.new('5')
16
+
17
+ # Support `Config#custom`
18
+ # https://github.com/redis-rb/redis-client/blob/master/CHANGELOG.md#0110
19
+ REDISCLIENT_MINIMUM_VERSION = Gem::Version.new('0.11.0')
17
20
 
18
21
  # @public_api Changing the integration name or integration options can cause breaking changes
19
22
  register_as :redis, auto_patch: true
20
23
 
24
+ # Until Redis 4, all instrumentation happened in one gem: redis.
25
+ # Since Redis 5, instrumentation happens in a separate gem: redis-client.
26
+ # Because Redis 4 does not depend on redis-client, it's possible for both gems to be installed at the same time.
27
+ # For example, if Sidekiq 7 and Redis 4 are installed: both redis and redis-client will be installed.
28
+ # If redis-client and redis > 5 are installed, than they will be in sync, and only redis-client will be installed.
21
29
  def self.version
30
+ redis_version || redis_client_version
31
+ end
32
+
33
+ def self.redis_version
22
34
  Gem.loaded_specs['redis'] && Gem.loaded_specs['redis'].version
23
35
  end
24
36
 
37
+ def self.redis_client_version
38
+ Gem.loaded_specs['redis-client'] && Gem.loaded_specs['redis-client'].version
39
+ end
40
+
25
41
  def self.loaded?
42
+ redis_loaded? || redis_client_loaded?
43
+ end
44
+
45
+ def self.redis_loaded?
26
46
  !defined?(::Redis).nil?
27
47
  end
28
48
 
49
+ def self.redis_client_loaded?
50
+ !defined?(::RedisClient).nil?
51
+ end
52
+
29
53
  def self.compatible?
30
- super && version >= MINIMUM_VERSION && version < MAX_VERSION
54
+ super && (redis_compatible? || redis_client_compatible?)
55
+ end
56
+
57
+ def self.redis_compatible?
58
+ !!(redis_version && redis_version >= MINIMUM_VERSION)
59
+ end
60
+
61
+ def self.redis_client_compatible?
62
+ !!(redis_client_version && redis_client_version >= REDISCLIENT_MINIMUM_VERSION)
31
63
  end
32
64
 
33
65
  def new_configuration
@@ -1,4 +1,4 @@
1
- # typed: false
1
+ # typed: ignore
2
2
 
3
3
  require_relative '../patcher'
4
4
  require_relative 'ext'
@@ -49,24 +49,28 @@ module Datadog
49
49
 
50
50
  module_function
51
51
 
52
- def target_version
53
- Integration.version
52
+ def default_tags
53
+ [].tap do |tags|
54
+ tags << "target_redis_version:#{Integration.redis_version}" if Integration.redis_version
55
+ tags << "target_redis_client_version:#{Integration.redis_client_version}" if Integration.redis_client_version
56
+ end
54
57
  end
55
58
 
56
- # patch applies our patch if needed
57
59
  def patch
58
- # do not require these by default, but only when actually patching
59
- require 'redis'
60
- require_relative 'tags'
61
- require_relative 'quantize'
62
- require_relative 'instrumentation'
60
+ # Redis 5+ extracts RedisClient to its own gem and provide instrumentation interface
61
+ if Integration.redis_client_compatible?
62
+ require_relative 'trace_middleware'
63
+
64
+ ::RedisClient.register(TraceMiddleware)
65
+ end
63
66
 
64
- # InstancePatch and ClientPatch allows the client object to access pin on redis instance
65
- ::Redis.include(InstancePatch)
66
- ::Redis::Client.include(ClientPatch)
67
+ if Integration.redis_compatible? && Integration.redis_version < Gem::Version.new('5.0.0')
68
+ require_relative 'instrumentation'
67
69
 
68
- # TODO: To support redis-rb 5.x, Redis::Client -> RedisClient
69
- ::Redis::Client.include(Instrumentation)
70
+ ::Redis.include(InstancePatch)
71
+ ::Redis::Client.include(ClientPatch)
72
+ ::Redis::Client.include(Instrumentation)
73
+ end
70
74
  end
71
75
  end
72
76
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # typed: true
2
4
 
3
5
  require 'set'
@@ -8,11 +10,13 @@ module Datadog
8
10
  module Redis
9
11
  # Quantize contains Redis-specific resource quantization tools.
10
12
  module Quantize
11
- PLACEHOLDER = '?'.freeze
12
- TOO_LONG_MARK = '...'.freeze
13
+ PLACEHOLDER = '?'
14
+ TOO_LONG_MARK = '...'
13
15
  VALUE_MAX_LEN = 50
14
16
  CMD_MAX_LEN = 500
15
17
 
18
+ AUTH_COMMANDS = %w[AUTH auth].freeze
19
+
16
20
  MULTI_VERB_COMMANDS = Set.new(
17
21
  %w[
18
22
  ACL
@@ -29,8 +33,7 @@ module Datadog
29
33
  module_function
30
34
 
31
35
  def format_arg(arg)
32
- str = arg.is_a?(Symbol) ? arg.to_s.upcase : arg.to_s
33
- str = Core::Utils.utf8_encode(str, binary: true, placeholder: PLACEHOLDER)
36
+ str = Core::Utils.utf8_encode(arg, binary: true, placeholder: PLACEHOLDER)
34
37
  Core::Utils.truncate(str, VALUE_MAX_LEN, TOO_LONG_MARK)
35
38
  rescue => e
36
39
  Datadog.logger.debug("non formattable Redis arg #{str}: #{e}")
@@ -41,8 +44,8 @@ module Datadog
41
44
  command_args = resolve_command_args(command_args)
42
45
  return 'AUTH ?' if auth_command?(command_args)
43
46
 
44
- cmd = command_args.map { |x| format_arg(x) }.join(' ')
45
- Core::Utils.truncate(cmd, CMD_MAX_LEN, TOO_LONG_MARK)
47
+ verb, *args = command_args.map { |x| format_arg(x) }
48
+ Core::Utils.truncate("#{verb.upcase} #{args.join(' ')}", CMD_MAX_LEN, TOO_LONG_MARK)
46
49
  end
47
50
 
48
51
  def get_verb(command_args)
@@ -50,8 +53,7 @@ module Datadog
50
53
 
51
54
  return get_verb(command_args.first) if command_args.first.is_a?(Array)
52
55
 
53
- arg = command_args.first
54
- verb = arg.is_a?(Symbol) ? arg.to_s.upcase : arg.to_s
56
+ verb = command_args.first.to_s.upcase
55
57
  return verb unless MULTI_VERB_COMMANDS.include?(verb) && command_args[1]
56
58
 
57
59
  "#{verb} #{command_args[1]}"
@@ -60,7 +62,8 @@ module Datadog
60
62
  def auth_command?(command_args)
61
63
  return false unless command_args.is_a?(Array) && !command_args.empty?
62
64
 
63
- command_args.first.to_sym == :auth
65
+ verb = command_args.first.to_s
66
+ AUTH_COMMANDS.include?(verb)
64
67
  end
65
68
 
66
69
  # Unwraps command array when Redis is called with the following syntax:
@@ -12,7 +12,7 @@ module Datadog
12
12
  # Tags handles generic common tags assignment.
13
13
  module Tags
14
14
  class << self
15
- def set_common_tags(client, span)
15
+ def set_common_tags(client, span, show_command_args)
16
16
  span.set_tag(Tracing::Metadata::Ext::TAG_COMPONENT, Ext::TAG_COMPONENT)
17
17
  span.set_tag(Tracing::Metadata::Ext::TAG_OPERATION, Ext::TAG_OPERATION_COMMAND)
18
18
 
@@ -20,6 +20,8 @@ module Datadog
20
20
  span.set_tag(Tracing::Metadata::Ext::TAG_PEER_SERVICE, span.service)
21
21
  span.set_tag(Tracing::Metadata::Ext::TAG_PEER_HOSTNAME, client.host)
22
22
 
23
+ span.set_tag(Tracing::Metadata::Ext::TAG_KIND, Tracing::Metadata::Ext::SpanKind::TAG_CLIENT)
24
+
23
25
  # Set analytics sample rate
24
26
  Contrib::Analytics.set_sample_rate(span, analytics_sample_rate) if analytics_enabled?
25
27
 
@@ -30,7 +32,7 @@ module Datadog
30
32
 
31
33
  span.set_tag Ext::TAG_DATABASE_INDEX, client.db.to_s
32
34
  span.set_tag Ext::TAG_DB, client.db
33
- span.set_tag Ext::TAG_RAW_COMMAND, span.resource if show_command_args?
35
+ span.set_tag Ext::TAG_RAW_COMMAND, span.resource if show_command_args
34
36
  end
35
37
 
36
38
  private
@@ -46,10 +48,6 @@ module Datadog
46
48
  def analytics_sample_rate
47
49
  datadog_configuration[:analytics_sample_rate]
48
50
  end
49
-
50
- def show_command_args?
51
- datadog_configuration[:command_args]
52
- end
53
51
  end
54
52
  end
55
53
  end
@@ -0,0 +1,72 @@
1
+ # typed: false
2
+
3
+ require_relative '../patcher'
4
+ require_relative 'ext'
5
+ require_relative 'quantize'
6
+ require_relative 'tags'
7
+
8
+ module Datadog
9
+ module Tracing
10
+ module Contrib
11
+ module Redis
12
+ # Instrumentation for Redis 5+
13
+ module TraceMiddleware
14
+ def call(commands, redis_config)
15
+ Tracing.trace(Contrib::Redis::Ext::SPAN_COMMAND) do |span|
16
+ datadog_configuration = resolve(redis_config)
17
+ resource = get_command(commands, datadog_configuration[:command_args])
18
+
19
+ span.service = datadog_configuration[:service_name]
20
+ span.span_type = Contrib::Redis::Ext::TYPE
21
+ span.resource = resource
22
+
23
+ Contrib::Redis::Tags.set_common_tags(redis_config, span, datadog_configuration[:command_args])
24
+
25
+ super
26
+ end
27
+ end
28
+
29
+ def call_pipelined(commands, redis_config)
30
+ Tracing.trace(Contrib::Redis::Ext::SPAN_COMMAND) do |span|
31
+ datadog_configuration = resolve(redis_config)
32
+ pipelined_commands = get_pipeline_commands(commands, datadog_configuration[:command_args])
33
+
34
+ span.service = datadog_configuration[:service_name]
35
+ span.span_type = Contrib::Redis::Ext::TYPE
36
+ span.resource = pipelined_commands.join("\n")
37
+ span.set_metric Contrib::Redis::Ext::METRIC_PIPELINE_LEN, pipelined_commands.length
38
+
39
+ Contrib::Redis::Tags.set_common_tags(redis_config, span, datadog_configuration[:command_args])
40
+
41
+ super
42
+ end
43
+ end
44
+
45
+ private
46
+
47
+ def get_command(commands, boolean)
48
+ if boolean
49
+ Contrib::Redis::Quantize.format_command_args(commands)
50
+ else
51
+ Contrib::Redis::Quantize.get_verb(commands)
52
+ end
53
+ end
54
+
55
+ def get_pipeline_commands(commands, boolean)
56
+ if boolean
57
+ commands.map { |c| Contrib::Redis::Quantize.format_command_args(c) }
58
+ else
59
+ commands.map { |c| Contrib::Redis::Quantize.get_verb(c) }
60
+ end
61
+ end
62
+
63
+ def resolve(redis_config)
64
+ custom = redis_config.custom[:datadog] || {}
65
+
66
+ Datadog.configuration.tracing[:redis, redis_config.server_url].to_h.merge(custom)
67
+ end
68
+ end
69
+ end
70
+ end
71
+ end
72
+ end
@@ -41,6 +41,8 @@ module Datadog
41
41
  span.set_tag(Tracing::Metadata::Ext::TAG_COMPONENT, Ext::TAG_COMPONENT)
42
42
  span.set_tag(Tracing::Metadata::Ext::TAG_OPERATION, Ext::TAG_OPERATION_JOB)
43
43
 
44
+ span.set_tag(Tracing::Metadata::Ext::TAG_KIND, Tracing::Metadata::Ext::SpanKind::TAG_CONSUMER)
45
+
44
46
  # Set analytics sample rate
45
47
  if Contrib::Analytics.enabled?(datadog_configuration[:analytics_enabled])
46
48
  Contrib::Analytics.set_sample_rate(span, datadog_configuration[:analytics_sample_rate])
@@ -27,7 +27,12 @@ module Datadog
27
27
  end
28
28
 
29
29
  option :distributed_tracing, default: true
30
- option :service_name, default: Ext::DEFAULT_PEER_SERVICE_NAME
30
+
31
+ option :service_name do |o|
32
+ o.default { ENV.fetch(Ext::ENV_SERVICE_NAME, Ext::DEFAULT_PEER_SERVICE_NAME) }
33
+ o.lazy
34
+ end
35
+
31
36
  option :split_by_domain, default: false
32
37
  end
33
38
  end
@@ -8,6 +8,7 @@ module Datadog
8
8
  # @public_api Changing resource names, tag names, or environment variables creates breaking changes.
9
9
  module Ext
10
10
  ENV_ENABLED = 'DD_TRACE_REST_CLIENT_ENABLED'.freeze
11
+ ENV_SERVICE_NAME = 'DD_TRACE_REST_CLIENT_SERVICE_NAME'.freeze
11
12
  ENV_ANALYTICS_ENABLED = 'DD_TRACE_REST_CLIENT_ANALYTICS_ENABLED'.freeze
12
13
  ENV_ANALYTICS_SAMPLE_RATE = 'DD_TRACE_REST_CLIENT_ANALYTICS_SAMPLE_RATE'.freeze
13
14
  DEFAULT_PEER_SERVICE_NAME = 'rest_client'.freeze
@@ -37,6 +37,8 @@ module Datadog
37
37
  span.set_tag(Ext::TAG_JOB_ATTRIBUTES, sqs_msg.attributes) if sqs_msg.respond_to?(:attributes)
38
38
  span.set_tag(Ext::TAG_JOB_BODY, body) if configuration[:tag_body]
39
39
 
40
+ span.set_tag(Tracing::Metadata::Ext::TAG_KIND, Tracing::Metadata::Ext::SpanKind::TAG_CONSUMER)
41
+
40
42
  yield
41
43
  end
42
44
  end
@@ -28,6 +28,11 @@ module Datadog
28
28
  span.set_tag(Datadog::Tracing::Metadata::Ext::TAG_COMPONENT, Ext::TAG_COMPONENT)
29
29
  span.set_tag(Datadog::Tracing::Metadata::Ext::TAG_OPERATION, Ext::TAG_OPERATION_PUSH)
30
30
 
31
+ span.set_tag(
32
+ Datadog::Tracing::Metadata::Ext::TAG_KIND,
33
+ Datadog::Tracing::Metadata::Ext::SpanKind::TAG_PRODUCER
34
+ )
35
+
31
36
  # Set analytics sample rate
32
37
  if Contrib::Analytics.enabled?(configuration[:analytics_enabled])
33
38
  Contrib::Analytics.set_sample_rate(span, configuration[:analytics_sample_rate])
@@ -40,6 +40,11 @@ module Datadog
40
40
  span.set_tag(Datadog::Tracing::Metadata::Ext::TAG_COMPONENT, Ext::TAG_COMPONENT)
41
41
  span.set_tag(Datadog::Tracing::Metadata::Ext::TAG_OPERATION, Ext::TAG_OPERATION_JOB)
42
42
 
43
+ span.set_tag(
44
+ Datadog::Tracing::Metadata::Ext::TAG_KIND,
45
+ Datadog::Tracing::Metadata::Ext::SpanKind::TAG_CONSUMER
46
+ )
47
+
43
48
  # Set analytics sample rate
44
49
  if Contrib::Analytics.enabled?(configuration[:analytics_enabled])
45
50
  Contrib::Analytics.set_sample_rate(span, configuration[:analytics_sample_rate])
@@ -41,6 +41,8 @@ module Datadog
41
41
 
42
42
  request_span.set_tag(Ext::TAG_JOB_BODY, deserialized_msg) if configuration[:tag_body]
43
43
 
44
+ request_span.set_tag(Tracing::Metadata::Ext::TAG_KIND, Tracing::Metadata::Ext::SpanKind::TAG_CONSUMER)
45
+
44
46
  @app.call(deserialized_msg, delivery_info, metadata, handler)
45
47
  end
46
48
  end
@@ -1,19 +1,14 @@
1
1
  # typed: true
2
2
 
3
3
  module Datadog
4
- module Core
4
+ module Tracing
5
5
  module Diagnostics
6
6
  # @public_api
7
7
  module Ext
8
- DD_TRACE_STARTUP_LOGS = 'DD_TRACE_STARTUP_LOGS'.freeze
9
- DD_TRACE_DEBUG = 'DD_TRACE_DEBUG'.freeze
10
- DD_TRACE_ENABLED = 'DD_TRACE_ENABLED'.freeze
11
8
  # Health
12
9
  module Health
13
10
  # Metrics
14
11
  module Metrics
15
- ENV_ENABLED = 'DD_HEALTH_METRICS_ENABLED'.freeze
16
-
17
12
  METRIC_API_ERRORS = 'datadog.tracer.api.errors'.freeze
18
13
  METRIC_API_REQUESTS = 'datadog.tracer.api.requests'.freeze
19
14
  METRIC_API_RESPONSES = 'datadog.tracer.api.responses'.freeze
@@ -0,0 +1,40 @@
1
+ # typed: ignore
2
+
3
+ require_relative 'ext'
4
+
5
+ module Datadog
6
+ module Tracing
7
+ module Diagnostics
8
+ # Health-related diagnostics
9
+ module Health
10
+ # Health metrics for diagnostics
11
+ module Metrics
12
+ def self.extended(base)
13
+ base.class_eval do
14
+ count :api_errors, Ext::Health::Metrics::METRIC_API_ERRORS
15
+ count :api_requests, Ext::Health::Metrics::METRIC_API_REQUESTS
16
+ count :api_responses, Ext::Health::Metrics::METRIC_API_RESPONSES
17
+ count :error_context_overflow, Ext::Health::Metrics::METRIC_ERROR_CONTEXT_OVERFLOW
18
+ count :error_instrumentation_patch, Ext::Health::Metrics::METRIC_ERROR_INSTRUMENTATION_PATCH
19
+ count :error_span_finish, Ext::Health::Metrics::METRIC_ERROR_SPAN_FINISH
20
+ count :error_unfinished_spans, Ext::Health::Metrics::METRIC_ERROR_UNFINISHED_SPANS
21
+ count :instrumentation_patched, Ext::Health::Metrics::METRIC_INSTRUMENTATION_PATCHED
22
+ count :queue_accepted, Ext::Health::Metrics::METRIC_QUEUE_ACCEPTED
23
+ count :queue_accepted_lengths, Ext::Health::Metrics::METRIC_QUEUE_ACCEPTED_LENGTHS
24
+ count :queue_dropped, Ext::Health::Metrics::METRIC_QUEUE_DROPPED
25
+ count :traces_filtered, Ext::Health::Metrics::METRIC_TRACES_FILTERED
26
+ count :transport_trace_too_large, Ext::Health::Metrics::METRIC_TRANSPORT_TRACE_TOO_LARGE
27
+ count :transport_chunked, Ext::Health::Metrics::METRIC_TRANSPORT_CHUNKED
28
+ count :writer_cpu_time, Ext::Health::Metrics::METRIC_WRITER_CPU_TIME
29
+
30
+ gauge :queue_length, Ext::Health::Metrics::METRIC_QUEUE_LENGTH
31
+ gauge :queue_max_length, Ext::Health::Metrics::METRIC_QUEUE_MAX_LENGTH
32
+ gauge :queue_spans, Ext::Health::Metrics::METRIC_QUEUE_SPANS
33
+ gauge :sampling_service_cache_length, Ext::Health::Metrics::METRIC_SAMPLING_SERVICE_CACHE_LENGTH
34
+ end
35
+ end
36
+ end
37
+ end
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,66 @@
1
+ # frozen_string_literal: true
2
+ # typed: true
3
+
4
+ require_relative 'helpers'
5
+ require_relative '../trace_digest'
6
+
7
+ module Datadog
8
+ module Tracing
9
+ module Distributed
10
+ # B3 multi header-style trace propagation.
11
+ # @see https://github.com/openzipkin/b3-propagation#multiple-headers
12
+ class B3Multi
13
+ B3_TRACE_ID_KEY = 'x-b3-traceid'
14
+ B3_SPAN_ID_KEY = 'x-b3-spanid'
15
+ B3_SAMPLED_KEY = 'x-b3-sampled'
16
+
17
+ def initialize(
18
+ fetcher:,
19
+ trace_id_key: B3_TRACE_ID_KEY,
20
+ span_id_key: B3_SPAN_ID_KEY,
21
+ sampled_key: B3_SAMPLED_KEY
22
+ )
23
+ @trace_id_key = trace_id_key
24
+ @span_id_key = span_id_key
25
+ @sampled_key = sampled_key
26
+ @fetcher = fetcher
27
+ end
28
+
29
+ def inject!(digest, data = {})
30
+ return if digest.nil?
31
+
32
+ # DEV: We need these to be hex encoded
33
+ data[@trace_id_key] = digest.trace_id.to_s(16)
34
+ data[@span_id_key] = digest.span_id.to_s(16)
35
+
36
+ if digest.trace_sampling_priority
37
+ sampling_priority = Helpers.clamp_sampling_priority(
38
+ digest.trace_sampling_priority
39
+ )
40
+ data[@sampled_key] = sampling_priority.to_s
41
+ end
42
+
43
+ data
44
+ end
45
+
46
+ def extract(data)
47
+ # DEV: B3 doesn't have "origin"
48
+ fetcher = @fetcher.new(data)
49
+ trace_id = fetcher.id(@trace_id_key, base: 16)
50
+ span_id = fetcher.id(@span_id_key, base: 16)
51
+ # We don't need to try and convert sampled since B3 supports 0/1 (AUTO_REJECT/AUTO_KEEP)
52
+ sampling_priority = fetcher.number(@sampled_key)
53
+
54
+ # Return early if this propagation is not valid
55
+ return unless trace_id && span_id
56
+
57
+ TraceDigest.new(
58
+ trace_id: trace_id,
59
+ span_id: span_id,
60
+ trace_sampling_priority: sampling_priority
61
+ )
62
+ end
63
+ end
64
+ end
65
+ end
66
+ end
@@ -0,0 +1,66 @@
1
+ # frozen_string_literal: true
2
+ # typed: true
3
+
4
+ require_relative 'helpers'
5
+ require_relative '../trace_digest'
6
+
7
+ module Datadog
8
+ module Tracing
9
+ module Distributed
10
+ # B3 single header-style trace propagation.
11
+ #
12
+ # DEV: Format:
13
+ # DEV: b3: {TraceId}-{SpanId}-{SamplingState}-{ParentSpanId}
14
+ # DEV: https://github.com/apache/incubator-zipkin-b3-propagation/tree/7c6e9f14d6627832bd80baa87ac7dabee7be23cf#single-header
15
+ # DEV: `{SamplingState}` and `{ParentSpanId}` are optional
16
+ #
17
+ # @see https://github.com/openzipkin/b3-propagation#single-header
18
+ class B3Single
19
+ B3_SINGLE_HEADER_KEY = 'b3'
20
+
21
+ def initialize(fetcher:, key: B3_SINGLE_HEADER_KEY)
22
+ @key = key
23
+ @fetcher = fetcher
24
+ end
25
+
26
+ def inject!(digest, env)
27
+ return if digest.nil?
28
+
29
+ # DEV: We need these to be hex encoded
30
+ value = "#{digest.trace_id.to_s(16)}-#{digest.span_id.to_s(16)}"
31
+
32
+ if digest.trace_sampling_priority
33
+ sampling_priority = Helpers.clamp_sampling_priority(
34
+ digest.trace_sampling_priority
35
+ )
36
+ value += "-#{sampling_priority}"
37
+ end
38
+
39
+ env[@key] = value
40
+ env
41
+ end
42
+
43
+ def extract(env)
44
+ fetcher = @fetcher.new(env)
45
+ value = fetcher[@key]
46
+
47
+ return unless value
48
+
49
+ parts = value.split('-')
50
+ trace_id = Helpers.value_to_id(parts[0], 16) unless parts.empty?
51
+ span_id = Helpers.value_to_id(parts[1], 16) if parts.length > 1
52
+ sampling_priority = Helpers.value_to_number(parts[2]) if parts.length > 2
53
+
54
+ # Return if this propagation is not valid
55
+ return unless trace_id && span_id
56
+
57
+ TraceDigest.new(
58
+ span_id: span_id,
59
+ trace_id: trace_id,
60
+ trace_sampling_priority: sampling_priority
61
+ )
62
+ end
63
+ end
64
+ end
65
+ end
66
+ end