ddtrace 1.6.1 → 1.7.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (89) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +40 -2
  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/resque/resque_job.rb +2 -0
  64. data/lib/datadog/tracing/contrib/shoryuken/tracer.rb +2 -0
  65. data/lib/datadog/tracing/contrib/sidekiq/client_tracer.rb +5 -0
  66. data/lib/datadog/tracing/contrib/sidekiq/server_tracer.rb +5 -0
  67. data/lib/datadog/tracing/contrib/sneakers/tracer.rb +2 -0
  68. data/lib/datadog/tracing/distributed/b3.rb +66 -0
  69. data/lib/datadog/tracing/distributed/b3_single.rb +66 -0
  70. data/lib/datadog/tracing/distributed/datadog.rb +153 -0
  71. data/lib/datadog/tracing/distributed/datadog_tags_codec.rb +1 -0
  72. data/lib/datadog/tracing/distributed/fetcher.rb +30 -0
  73. data/lib/datadog/tracing/distributed/headers/ext.rb +18 -16
  74. data/lib/datadog/tracing/distributed/helpers.rb +7 -6
  75. data/lib/datadog/tracing/distributed/propagation.rb +127 -0
  76. data/lib/datadog/tracing/propagation/http.rb +3 -106
  77. data/lib/datadog/tracing/trace_segment.rb +1 -1
  78. data/lib/ddtrace/transport/trace_formatter.rb +2 -5
  79. data/lib/ddtrace/version.rb +2 -2
  80. metadata +19 -14
  81. data/lib/datadog/tracing/distributed/headers/b3.rb +0 -55
  82. data/lib/datadog/tracing/distributed/headers/b3_single.rb +0 -67
  83. data/lib/datadog/tracing/distributed/headers/datadog.rb +0 -144
  84. data/lib/datadog/tracing/distributed/headers/parser.rb +0 -37
  85. data/lib/datadog/tracing/distributed/metadata/b3.rb +0 -55
  86. data/lib/datadog/tracing/distributed/metadata/b3_single.rb +0 -66
  87. data/lib/datadog/tracing/distributed/metadata/datadog.rb +0 -73
  88. data/lib/datadog/tracing/distributed/metadata/parser.rb +0 -34
  89. 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
@@ -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