ddtrace 1.6.0 → 1.7.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 (91) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +50 -1
  3. data/ext/ddtrace_profiling_loader/extconf.rb +1 -1
  4. data/ext/ddtrace_profiling_native_extension/collectors_cpu_and_wall_time.c +66 -6
  5. data/ext/ddtrace_profiling_native_extension/collectors_cpu_and_wall_time_worker.c +51 -54
  6. data/ext/ddtrace_profiling_native_extension/collectors_stack.c +11 -13
  7. data/ext/ddtrace_profiling_native_extension/extconf.rb +1 -1
  8. data/ext/ddtrace_profiling_native_extension/private_vm_api_access.c +3 -2
  9. data/ext/ddtrace_profiling_native_extension/setup_signal_handler.c +96 -0
  10. data/ext/ddtrace_profiling_native_extension/setup_signal_handler.h +7 -0
  11. data/ext/ddtrace_profiling_native_extension/stack_recorder.c +70 -18
  12. data/ext/ddtrace_profiling_native_extension/stack_recorder.h +1 -0
  13. data/lib/datadog/appsec/assets/blocked.html +98 -3
  14. data/lib/datadog/appsec/assets/blocked.json +1 -0
  15. data/lib/datadog/appsec/assets/blocked.text +5 -0
  16. data/lib/datadog/appsec/assets/waf_rules/recommended.json +35 -46
  17. data/lib/datadog/appsec/assets/waf_rules/risky.json +1 -1
  18. data/lib/datadog/appsec/assets/waf_rules/strict.json +46 -1
  19. data/lib/datadog/appsec/assets.rb +2 -2
  20. data/lib/datadog/appsec/configuration/settings.rb +6 -0
  21. data/lib/datadog/appsec/configuration.rb +4 -0
  22. data/lib/datadog/appsec/contrib/rack/reactive/request.rb +4 -8
  23. data/lib/datadog/appsec/contrib/rack/request.rb +17 -0
  24. data/lib/datadog/appsec/contrib/rack/request_body_middleware.rb +2 -2
  25. data/lib/datadog/appsec/contrib/rack/request_middleware.rb +2 -2
  26. data/lib/datadog/appsec/contrib/rails/patcher.rb +3 -6
  27. data/lib/datadog/appsec/contrib/sinatra/ext.rb +1 -0
  28. data/lib/datadog/appsec/contrib/sinatra/gateway/watcher.rb +1 -1
  29. data/lib/datadog/appsec/contrib/sinatra/patcher.rb +11 -8
  30. data/lib/datadog/appsec/extensions.rb +10 -0
  31. data/lib/datadog/appsec/processor.rb +18 -0
  32. data/lib/datadog/appsec/response.rb +54 -0
  33. data/lib/datadog/core/runtime/ext.rb +1 -1
  34. data/lib/datadog/opentracer/distributed_headers.rb +5 -7
  35. data/lib/datadog/opentracer/rack_propagator.rb +0 -3
  36. data/lib/datadog/opentracer/text_map_propagator.rb +5 -7
  37. data/lib/datadog/profiling/collectors/cpu_and_wall_time.rb +10 -4
  38. data/lib/datadog/profiling/collectors/cpu_and_wall_time_worker.rb +4 -0
  39. data/lib/datadog/profiling/collectors/old_stack.rb +7 -0
  40. data/lib/datadog/profiling/exporter.rb +5 -0
  41. data/lib/datadog/profiling/old_recorder.rb +8 -0
  42. data/lib/datadog/profiling/profiler.rb +7 -0
  43. data/lib/datadog/profiling/scheduler.rb +4 -7
  44. data/lib/datadog/profiling/stack_recorder.rb +22 -0
  45. data/lib/datadog/profiling/tasks/setup.rb +0 -7
  46. data/lib/datadog/tracing/contrib/delayed_job/plugin.rb +4 -0
  47. data/lib/datadog/tracing/contrib/grpc/datadog_interceptor/client.rb +2 -1
  48. data/lib/datadog/tracing/contrib/grpc/datadog_interceptor/server.rb +6 -12
  49. data/lib/datadog/tracing/contrib/grpc/distributed/fetcher.rb +27 -0
  50. data/lib/datadog/tracing/contrib/grpc/distributed/propagation.rb +38 -0
  51. data/lib/datadog/tracing/contrib/grpc/patcher.rb +0 -2
  52. data/lib/datadog/tracing/contrib/http/distributed/fetcher.rb +32 -0
  53. data/lib/datadog/tracing/contrib/http/distributed/propagation.rb +33 -0
  54. data/lib/datadog/tracing/contrib/kafka/consumer_event.rb +1 -0
  55. data/lib/datadog/tracing/contrib/kafka/events/produce_operation/send_messages.rb +1 -0
  56. data/lib/datadog/tracing/contrib/kafka/events/producer/deliver_messages.rb +1 -0
  57. data/lib/datadog/tracing/contrib/mongodb/subscribers.rb +2 -0
  58. data/lib/datadog/tracing/contrib/que/tracer.rb +2 -0
  59. data/lib/datadog/tracing/contrib/racecar/events/batch.rb +4 -1
  60. data/lib/datadog/tracing/contrib/racecar/events/message.rb +4 -1
  61. data/lib/datadog/tracing/contrib/rack/middlewares.rb +2 -0
  62. data/lib/datadog/tracing/contrib/redis/instrumentation.rb +2 -0
  63. data/lib/datadog/tracing/contrib/redis/integration.rb +2 -1
  64. data/lib/datadog/tracing/contrib/redis/patcher.rb +2 -3
  65. data/lib/datadog/tracing/contrib/resque/resque_job.rb +2 -0
  66. data/lib/datadog/tracing/contrib/shoryuken/tracer.rb +2 -0
  67. data/lib/datadog/tracing/contrib/sidekiq/client_tracer.rb +5 -0
  68. data/lib/datadog/tracing/contrib/sidekiq/server_tracer.rb +5 -0
  69. data/lib/datadog/tracing/contrib/sneakers/tracer.rb +2 -0
  70. data/lib/datadog/tracing/distributed/b3.rb +66 -0
  71. data/lib/datadog/tracing/distributed/b3_single.rb +66 -0
  72. data/lib/datadog/tracing/distributed/datadog.rb +153 -0
  73. data/lib/datadog/tracing/distributed/datadog_tags_codec.rb +1 -0
  74. data/lib/datadog/tracing/distributed/fetcher.rb +30 -0
  75. data/lib/datadog/tracing/distributed/headers/ext.rb +18 -16
  76. data/lib/datadog/tracing/distributed/helpers.rb +7 -6
  77. data/lib/datadog/tracing/distributed/propagation.rb +127 -0
  78. data/lib/datadog/tracing/propagation/http.rb +3 -106
  79. data/lib/datadog/tracing/trace_segment.rb +1 -1
  80. data/lib/ddtrace/transport/trace_formatter.rb +2 -5
  81. data/lib/ddtrace/version.rb +1 -1
  82. metadata +19 -14
  83. data/lib/datadog/tracing/distributed/headers/b3.rb +0 -55
  84. data/lib/datadog/tracing/distributed/headers/b3_single.rb +0 -67
  85. data/lib/datadog/tracing/distributed/headers/datadog.rb +0 -144
  86. data/lib/datadog/tracing/distributed/headers/parser.rb +0 -37
  87. data/lib/datadog/tracing/distributed/metadata/b3.rb +0 -55
  88. data/lib/datadog/tracing/distributed/metadata/b3_single.rb +0 -66
  89. data/lib/datadog/tracing/distributed/metadata/datadog.rb +0 -73
  90. data/lib/datadog/tracing/distributed/metadata/parser.rb +0 -34
  91. data/lib/datadog/tracing/propagation/grpc.rb +0 -98
@@ -218,6 +218,13 @@ module Datadog
218
218
  )
219
219
  end
220
220
 
221
+ def reset_after_fork
222
+ recorder.reset_after_fork
223
+
224
+ # NOTE: We could perhaps also call #reset_cpu_time_tracking here, although it's not needed because we always
225
+ # call in in #start.
226
+ end
227
+
221
228
  private
222
229
 
223
230
  # If the profiler is started for a while, stopped and then restarted OR whenever the process forks, we need to
@@ -70,6 +70,11 @@ module Datadog
70
70
  !duration_below_threshold?(last_flush_finish_at || created_at, time_provider.now.utc)
71
71
  end
72
72
 
73
+ def reset_after_fork
74
+ @last_flush_finish_at = time_provider.now.utc
75
+ nil
76
+ end
77
+
73
78
  private
74
79
 
75
80
  def duration_below_threshold?(start, finish)
@@ -73,6 +73,14 @@ module Datadog
73
73
  [start, finish, encoded_pprof]
74
74
  end
75
75
 
76
+ def reset_after_fork
77
+ Datadog.logger.debug('Resetting OldRecorder in child process after fork')
78
+
79
+ # NOTE: A bit of a heavy-handed approach, but it doesn't happen often and this class will be removed soon anyway
80
+ serialize
81
+ nil
82
+ end
83
+
76
84
  # Error when event of an unknown type is used with the OldRecorder
77
85
  class UnknownEventError < StandardError
78
86
  attr_reader :event_class
@@ -4,6 +4,8 @@ module Datadog
4
4
  module Profiling
5
5
  # Profiling entry point, which coordinates collectors and a scheduler
6
6
  class Profiler
7
+ include Datadog::Core::Utils::Forking
8
+
7
9
  attr_reader \
8
10
  :collectors,
9
11
  :scheduler
@@ -14,6 +16,11 @@ module Datadog
14
16
  end
15
17
 
16
18
  def start
19
+ after_fork! do
20
+ collectors.each(&:reset_after_fork)
21
+ scheduler.reset_after_fork
22
+ end
23
+
17
24
  collectors.each(&:start)
18
25
  scheduler.start
19
26
  end
@@ -66,13 +66,6 @@ module Datadog
66
66
  end
67
67
  end
68
68
 
69
- def after_fork
70
- # Clear any existing profiling state.
71
- # We don't want the child process to report profiling data from its parent.
72
- Datadog.logger.debug('Flushing exporter in child process #after_fork and discarding data')
73
- exporter.flush
74
- end
75
-
76
69
  # Configure Workers::IntervalLoop to not report immediately when scheduler starts
77
70
  #
78
71
  # When a scheduler gets created (or reset), we don't want it to immediately try to flush; we want it to wait for
@@ -86,6 +79,10 @@ module Datadog
86
79
  exporter.can_flush?
87
80
  end
88
81
 
82
+ def reset_after_fork
83
+ exporter.reset_after_fork
84
+ end
85
+
89
86
  private
90
87
 
91
88
  def flush_and_wait
@@ -34,10 +34,32 @@ module Datadog
34
34
  end
35
35
  end
36
36
 
37
+ def clear
38
+ status, result = @no_concurrent_synchronize_mutex.synchronize { self.class._native_clear(self) }
39
+
40
+ if status == :ok
41
+ finish_timestamp = result
42
+
43
+ Datadog.logger.debug { "Cleared profile at #{finish_timestamp}" }
44
+
45
+ finish_timestamp
46
+ else
47
+ error_message = result
48
+
49
+ Datadog.logger.error("Failed to clear profiling data: #{error_message}")
50
+
51
+ nil
52
+ end
53
+ end
54
+
37
55
  # Used only for Ruby 2.2 which doesn't have the native `rb_time_timespec_new` API; called from native code
38
56
  def self.ruby_time_from(timespec_seconds, timespec_nanoseconds)
39
57
  Time.at(0).utc + timespec_seconds + (timespec_nanoseconds.to_r / 1_000_000_000)
40
58
  end
59
+
60
+ def reset_after_fork
61
+ self.class._native_reset_after_fork(self)
62
+ end
41
63
  end
42
64
  end
43
65
  end
@@ -55,13 +55,6 @@ module Datadog
55
55
  if Process.respond_to?(:at_fork)
56
56
  Process.at_fork(:child) do
57
57
  begin
58
- # When Ruby forks, clock IDs for each of the threads
59
- # will change. We can only update these IDs from the
60
- # execution context of the thread that owns it.
61
- # This hook will update the IDs for the main thread
62
- # after a fork occurs.
63
- Thread.current.send(:update_native_ids) if Thread.current.respond_to?(:update_native_ids, true)
64
-
65
58
  # Restart profiler, if enabled
66
59
  Profiling.start_if_enabled
67
60
  rescue StandardError => e
@@ -35,6 +35,8 @@ module Datadog
35
35
  span.set_tag(Tracing::Metadata::Ext::TAG_COMPONENT, Ext::TAG_COMPONENT)
36
36
  span.set_tag(Tracing::Metadata::Ext::TAG_OPERATION, Ext::TAG_OPERATION_JOB)
37
37
 
38
+ span.set_tag(Tracing::Metadata::Ext::TAG_KIND, Tracing::Metadata::Ext::SpanKind::TAG_CONSUMER)
39
+
38
40
  yield job
39
41
  end
40
42
  end
@@ -59,6 +61,8 @@ module Datadog
59
61
  span.set_tag(Tracing::Metadata::Ext::TAG_COMPONENT, Ext::TAG_COMPONENT)
60
62
  span.set_tag(Tracing::Metadata::Ext::TAG_OPERATION, Ext::TAG_OPERATION_ENQUEUE)
61
63
 
64
+ span.set_tag(Tracing::Metadata::Ext::TAG_KIND, Tracing::Metadata::Ext::SpanKind::TAG_PRODUCER)
65
+
62
66
  yield job
63
67
  end
64
68
  end
@@ -2,6 +2,7 @@
2
2
 
3
3
  require_relative '../../../../tracing'
4
4
  require_relative '../../../metadata/ext'
5
+ require_relative '../distributed/propagation'
5
6
  require_relative '../../analytics'
6
7
  require_relative '../ext'
7
8
  require_relative '../../ext'
@@ -55,7 +56,7 @@ module Datadog
55
56
  # Set analytics sample rate
56
57
  Contrib::Analytics.set_sample_rate(span, analytics_sample_rate) if analytics_enabled?
57
58
 
58
- Tracing::Propagation::GRPC.inject!(trace, metadata) if distributed_tracing?
59
+ Distributed::Propagation::INSTANCE.inject!(trace, metadata) if distributed_tracing?
59
60
  rescue StandardError => e
60
61
  Datadog.logger.debug("GRPC client trace failed: #{e}")
61
62
  end
@@ -1,9 +1,8 @@
1
1
  # typed: ignore
2
2
 
3
3
  require_relative '../../../../tracing'
4
- require_relative '../../../distributed/headers/ext'
5
4
  require_relative '../../../metadata/ext'
6
- require_relative '../../../propagation/grpc'
5
+ require_relative '../distributed/propagation'
7
6
  require_relative '../../analytics'
8
7
  require_relative '../ext'
9
8
  require_relative '../../ext'
@@ -45,7 +44,7 @@ module Datadog
45
44
  private
46
45
 
47
46
  def set_distributed_context!(metadata)
48
- Tracing.continue_trace!(Tracing::Propagation::GRPC.extract(metadata))
47
+ Tracing.continue_trace!(Distributed::Propagation::INSTANCE.extract(metadata))
49
48
  rescue StandardError => e
50
49
  Datadog.logger.debug(
51
50
  "unable to propagate GRPC metadata to context: #{e}"
@@ -54,11 +53,14 @@ module Datadog
54
53
 
55
54
  def annotate!(span, metadata)
56
55
  metadata.each do |header, value|
57
- next if reserved_headers.include?(header)
56
+ # Datadog propagation headers are considered internal implementation detail.
57
+ next if header.to_s.start_with?(Tracing::Distributed::Datadog::TAGS_PREFIX)
58
58
 
59
59
  span.set_tag(header, value)
60
60
  end
61
61
 
62
+ span.set_tag(Tracing::Metadata::Ext::TAG_KIND, Tracing::Metadata::Ext::SpanKind::TAG_SERVER)
63
+
62
64
  span.set_tag(Tracing::Metadata::Ext::TAG_COMPONENT, Ext::TAG_COMPONENT)
63
65
  span.set_tag(Tracing::Metadata::Ext::TAG_OPERATION, Ext::TAG_OPERATION_SERVICE)
64
66
 
@@ -71,14 +73,6 @@ module Datadog
71
73
  Datadog.logger.debug("GRPC client trace failed: #{e}")
72
74
  end
73
75
 
74
- def reserved_headers
75
- [
76
- Tracing::Distributed::Headers::Ext::GRPC_METADATA_TRACE_ID,
77
- Tracing::Distributed::Headers::Ext::GRPC_METADATA_PARENT_ID,
78
- Tracing::Distributed::Headers::Ext::GRPC_METADATA_SAMPLING_PRIORITY
79
- ]
80
- end
81
-
82
76
  def format_resource(proto_method)
83
77
  proto_method
84
78
  .owner
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+ # typed: true
3
+
4
+ require_relative '../../../distributed/fetcher'
5
+
6
+ module Datadog
7
+ module Tracing
8
+ module Contrib
9
+ module GRPC
10
+ module Distributed
11
+ # Retrieves values from the gRPC metadata.
12
+ # One metadata key can be associated with multiple values.
13
+ #
14
+ # @see https://github.com/grpc/grpc-go/blob/56ac86fa0f3940cb79946ce2c6e56f7ee7ecae84/Documentation/grpc-metadata.md#constructing-metadata
15
+ class Fetcher < Tracing::Distributed::Fetcher
16
+ def [](key)
17
+ # Metadata values are normally integrals but can also be
18
+ # arrays when multiple values are associated with the same key.
19
+ value = super(key)
20
+ value.is_a?(::Array) ? value[0] : value
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,38 @@
1
+ # frozen_string_literal: true
2
+ # typed: true
3
+
4
+ require_relative 'fetcher'
5
+ require_relative '../../../distributed/b3'
6
+ require_relative '../../../distributed/b3_single'
7
+ require_relative '../../../distributed/datadog'
8
+ require_relative '../../../distributed/propagation'
9
+
10
+ module Datadog
11
+ module Tracing
12
+ module Contrib
13
+ module GRPC
14
+ module Distributed
15
+ # Extracts and injects propagation through gRPC metadata.
16
+ # @see https://github.com/grpc/grpc-go/blob/v1.50.1/Documentation/grpc-metadata.md
17
+ class Propagation < Tracing::Distributed::Propagation
18
+ def initialize
19
+ super(
20
+ propagation_styles: {
21
+ Tracing::Configuration::Ext::Distributed::PROPAGATION_STYLE_B3 =>
22
+ Tracing::Distributed::B3.new(fetcher: Fetcher),
23
+ Tracing::Configuration::Ext::Distributed::PROPAGATION_STYLE_B3_SINGLE_HEADER =>
24
+ Tracing::Distributed::B3Single.new(fetcher: Fetcher),
25
+ Tracing::Configuration::Ext::Distributed::PROPAGATION_STYLE_DATADOG =>
26
+ Tracing::Distributed::Datadog.new(fetcher: Fetcher)
27
+ })
28
+ end
29
+
30
+ # DEV: Singleton kept until a larger refactor is performed.
31
+ # DEV: See {Datadog::Tracing::Distributed::Propagation#initialize} for more information.
32
+ INSTANCE = Propagation.new
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end
38
+ end
@@ -19,8 +19,6 @@ module Datadog
19
19
  end
20
20
 
21
21
  def patch
22
- require_relative '../../propagation/grpc'
23
- require_relative 'datadog_interceptor'
24
22
  require_relative 'intercept_with_datadog'
25
23
 
26
24
  prepend_interceptor
@@ -0,0 +1,32 @@
1
+ # frozen_string_literal: false
2
+ # typed: false
3
+
4
+ require_relative '../../../distributed/fetcher'
5
+
6
+ module Datadog
7
+ module Tracing
8
+ module Contrib
9
+ module HTTP
10
+ module Distributed
11
+ # Retrieves Rack formatted headers from HTTP headers.
12
+ class Fetcher < Tracing::Distributed::Fetcher
13
+ # TODO: Don't assume Rack format.
14
+ # Make distributed tracing headers apathetic.
15
+ # DEV: Should we try to parse both verbatim an Rack-formatted headers,
16
+ # DEV: given Rack-formatted is the most common format in Ruby?
17
+ def [](name)
18
+ rack_header = "HTTP-#{name}"
19
+ rack_header.upcase!
20
+ rack_header.tr!('-'.freeze, '_'.freeze)
21
+
22
+ hdr = super(rack_header)
23
+
24
+ # Only return the value if it is not an empty string
25
+ hdr if hdr != ''
26
+ end
27
+ end
28
+ end
29
+ end
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,33 @@
1
+ # frozen_string_literal: true
2
+ # typed: true
3
+
4
+ require_relative 'fetcher'
5
+ require_relative '../../../distributed/propagation'
6
+ require_relative '../../../distributed/b3'
7
+ require_relative '../../../distributed/b3_single'
8
+ require_relative '../../../distributed/datadog'
9
+
10
+ module Datadog
11
+ module Tracing
12
+ module Contrib
13
+ module HTTP
14
+ module Distributed
15
+ # Extracts and injects propagation through HTTP headers.
16
+ class Propagation < Tracing::Distributed::Propagation
17
+ def initialize
18
+ super(
19
+ propagation_styles: {
20
+ Tracing::Configuration::Ext::Distributed::PROPAGATION_STYLE_B3 =>
21
+ Tracing::Distributed::B3.new(fetcher: Fetcher),
22
+ Tracing::Configuration::Ext::Distributed::PROPAGATION_STYLE_B3_SINGLE_HEADER =>
23
+ Tracing::Distributed::B3Single.new(fetcher: Fetcher),
24
+ Tracing::Configuration::Ext::Distributed::PROPAGATION_STYLE_DATADOG =>
25
+ Tracing::Distributed::Datadog.new(fetcher: Fetcher)
26
+ })
27
+ end
28
+ end
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end
@@ -10,6 +10,7 @@ module Datadog
10
10
  super
11
11
 
12
12
  span.set_tag(Ext::TAG_GROUP, payload[:group_id])
13
+ span.set_tag(Tracing::Metadata::Ext::TAG_KIND, Tracing::Metadata::Ext::SpanKind::TAG_CONSUMER)
13
14
  end
14
15
  end
15
16
  end
@@ -20,6 +20,7 @@ module Datadog
20
20
 
21
21
  span.set_tag(Ext::TAG_MESSAGE_COUNT, payload[:message_count]) if payload.key?(:message_count)
22
22
  span.set_tag(Ext::TAG_SENT_MESSAGE_COUNT, payload[:sent_message_count]) if payload.key?(:sent_message_count)
23
+ span.set_tag(Tracing::Metadata::Ext::TAG_KIND, Tracing::Metadata::Ext::SpanKind::TAG_PRODUCER)
23
24
  end
24
25
 
25
26
  module_function
@@ -23,6 +23,7 @@ module Datadog
23
23
  if payload.key?(:delivered_message_count)
24
24
  span.set_tag(Ext::TAG_DELIVERED_MESSAGE_COUNT, payload[:delivered_message_count])
25
25
  end
26
+ span.set_tag(Tracing::Metadata::Ext::TAG_KIND, Tracing::Metadata::Ext::SpanKind::TAG_PRODUCER)
26
27
  end
27
28
 
28
29
  module_function
@@ -33,6 +33,8 @@ module Datadog
33
33
 
34
34
  span.set_tag(Contrib::Ext::DB::TAG_SYSTEM, Ext::TAG_SYSTEM)
35
35
 
36
+ span.set_tag(Tracing::Metadata::Ext::TAG_KIND, Tracing::Metadata::Ext::SpanKind::TAG_CLIENT)
37
+
36
38
  span.set_tag(Tracing::Metadata::Ext::TAG_COMPONENT, Ext::TAG_COMPONENT)
37
39
  span.set_tag(Tracing::Metadata::Ext::TAG_OPERATION, Ext::TAG_OPERATION_COMMAND)
38
40
 
@@ -33,6 +33,8 @@ module Datadog
33
33
  request_span.set_tag(Ext::TAG_JOB_ARGS, job.que_attrs[:args]) if configuration[:tag_args]
34
34
  request_span.set_tag(Ext::TAG_JOB_DATA, job.que_attrs[:data]) if configuration[:tag_data]
35
35
 
36
+ request_span.set_tag(Tracing::Metadata::Ext::TAG_KIND, Tracing::Metadata::Ext::SpanKind::TAG_CONSUMER)
37
+
36
38
  set_sample_rate(request_span)
37
39
  Contrib::Analytics.set_measured(request_span)
38
40
 
@@ -25,7 +25,10 @@ module Datadog
25
25
  end
26
26
 
27
27
  def span_options
28
- super.merge(tags: { Tracing::Metadata::Ext::TAG_OPERATION => Ext::TAG_OPERATION_BATCH })
28
+ super.merge(
29
+ tags: { Tracing::Metadata::Ext::TAG_OPERATION => Ext::TAG_OPERATION_BATCH,
30
+ Tracing::Metadata::Ext::TAG_KIND => Tracing::Metadata::Ext::SpanKind::TAG_CONSUMER }
31
+ )
29
32
  end
30
33
  end
31
34
  end
@@ -25,7 +25,10 @@ module Datadog
25
25
  end
26
26
 
27
27
  def span_options
28
- super.merge(tags: { Tracing::Metadata::Ext::TAG_OPERATION => Ext::TAG_OPERATION_MESSAGE })
28
+ super.merge(
29
+ tags: { Tracing::Metadata::Ext::TAG_OPERATION => Ext::TAG_OPERATION_MESSAGE,
30
+ Tracing::Metadata::Ext::TAG_KIND => Tracing::Metadata::Ext::SpanKind::TAG_CONSUMER }
31
+ )
29
32
  end
30
33
  end
31
34
  end
@@ -45,6 +45,7 @@ module Datadog
45
45
  # Tag this span as belonging to Rack
46
46
  frontend_span.set_tag(Tracing::Metadata::Ext::TAG_COMPONENT, Ext::TAG_COMPONENT)
47
47
  frontend_span.set_tag(Tracing::Metadata::Ext::TAG_OPERATION, Ext::TAG_OPERATION_HTTP_SERVER_QUEUE)
48
+ frontend_span.set_tag(Tracing::Metadata::Ext::TAG_KIND, Tracing::Metadata::Ext::SpanKind::TAG_SERVER)
48
49
 
49
50
  # Set peer service (so its not believed to belong to this app)
50
51
  frontend_span.set_tag(Tracing::Metadata::Ext::TAG_PEER_SERVICE, configuration[:web_service_name])
@@ -157,6 +158,7 @@ module Datadog
157
158
 
158
159
  request_span.set_tag(Tracing::Metadata::Ext::TAG_COMPONENT, Ext::TAG_COMPONENT)
159
160
  request_span.set_tag(Tracing::Metadata::Ext::TAG_OPERATION, Ext::TAG_OPERATION_REQUEST)
161
+ request_span.set_tag(Tracing::Metadata::Ext::TAG_KIND, Tracing::Metadata::Ext::SpanKind::TAG_SERVER)
160
162
 
161
163
  # Set analytics sample rate
162
164
  if Contrib::Analytics.enabled?(configuration[:analytics_enabled])
@@ -26,6 +26,7 @@ module Datadog
26
26
  span.span_type = Contrib::Redis::Ext::TYPE
27
27
  span.resource = get_command(args)
28
28
  Contrib::Redis::Tags.set_common_tags(self, span)
29
+ span.set_tag(Tracing::Metadata::Ext::TAG_KIND, Tracing::Metadata::Ext::SpanKind::TAG_CLIENT)
29
30
 
30
31
  response = super
31
32
  end
@@ -43,6 +44,7 @@ module Datadog
43
44
  span.resource = commands.any? ? commands.join("\n") : '(none)'
44
45
  span.set_metric Contrib::Redis::Ext::METRIC_PIPELINE_LEN, commands.length
45
46
  Contrib::Redis::Tags.set_common_tags(self, span)
47
+ span.set_tag(Tracing::Metadata::Ext::TAG_KIND, Tracing::Metadata::Ext::SpanKind::TAG_CLIENT)
46
48
 
47
49
  response = super
48
50
  end
@@ -13,6 +13,7 @@ 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
 
17
18
  # @public_api Changing the integration name or integration options can cause breaking changes
18
19
  register_as :redis, auto_patch: true
@@ -26,7 +27,7 @@ module Datadog
26
27
  end
27
28
 
28
29
  def self.compatible?
29
- super && version >= MINIMUM_VERSION
30
+ super && version >= MINIMUM_VERSION && version < MAX_VERSION
30
31
  end
31
32
 
32
33
  def new_configuration
@@ -20,10 +20,9 @@ module Datadog
20
20
 
21
21
  # Instance method patch for redis instance
22
22
  module InstanceMethods
23
+ # `options` could be frozen
23
24
  def initialize(options = {})
24
- options[:redis_instance] = self
25
-
26
- super(options)
25
+ super(options.merge(redis_instance: self))
27
26
  end
28
27
  end
29
28
  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])
@@ -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
@@ -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-style trace propagation.
11
+ # @see https://github.com/openzipkin/b3-propagation#multiple-headers
12
+ class B3
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