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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +50 -1
- data/ext/ddtrace_profiling_loader/extconf.rb +1 -1
- data/ext/ddtrace_profiling_native_extension/collectors_cpu_and_wall_time.c +66 -6
- data/ext/ddtrace_profiling_native_extension/collectors_cpu_and_wall_time_worker.c +51 -54
- data/ext/ddtrace_profiling_native_extension/collectors_stack.c +11 -13
- data/ext/ddtrace_profiling_native_extension/extconf.rb +1 -1
- data/ext/ddtrace_profiling_native_extension/private_vm_api_access.c +3 -2
- data/ext/ddtrace_profiling_native_extension/setup_signal_handler.c +96 -0
- data/ext/ddtrace_profiling_native_extension/setup_signal_handler.h +7 -0
- data/ext/ddtrace_profiling_native_extension/stack_recorder.c +70 -18
- data/ext/ddtrace_profiling_native_extension/stack_recorder.h +1 -0
- data/lib/datadog/appsec/assets/blocked.html +98 -3
- data/lib/datadog/appsec/assets/blocked.json +1 -0
- data/lib/datadog/appsec/assets/blocked.text +5 -0
- data/lib/datadog/appsec/assets/waf_rules/recommended.json +35 -46
- data/lib/datadog/appsec/assets/waf_rules/risky.json +1 -1
- data/lib/datadog/appsec/assets/waf_rules/strict.json +46 -1
- data/lib/datadog/appsec/assets.rb +2 -2
- data/lib/datadog/appsec/configuration/settings.rb +6 -0
- data/lib/datadog/appsec/configuration.rb +4 -0
- data/lib/datadog/appsec/contrib/rack/reactive/request.rb +4 -8
- data/lib/datadog/appsec/contrib/rack/request.rb +17 -0
- data/lib/datadog/appsec/contrib/rack/request_body_middleware.rb +2 -2
- data/lib/datadog/appsec/contrib/rack/request_middleware.rb +2 -2
- data/lib/datadog/appsec/contrib/rails/patcher.rb +3 -6
- data/lib/datadog/appsec/contrib/sinatra/ext.rb +1 -0
- data/lib/datadog/appsec/contrib/sinatra/gateway/watcher.rb +1 -1
- data/lib/datadog/appsec/contrib/sinatra/patcher.rb +11 -8
- data/lib/datadog/appsec/extensions.rb +10 -0
- data/lib/datadog/appsec/processor.rb +18 -0
- data/lib/datadog/appsec/response.rb +54 -0
- data/lib/datadog/core/runtime/ext.rb +1 -1
- data/lib/datadog/opentracer/distributed_headers.rb +5 -7
- data/lib/datadog/opentracer/rack_propagator.rb +0 -3
- data/lib/datadog/opentracer/text_map_propagator.rb +5 -7
- data/lib/datadog/profiling/collectors/cpu_and_wall_time.rb +10 -4
- data/lib/datadog/profiling/collectors/cpu_and_wall_time_worker.rb +4 -0
- data/lib/datadog/profiling/collectors/old_stack.rb +7 -0
- data/lib/datadog/profiling/exporter.rb +5 -0
- data/lib/datadog/profiling/old_recorder.rb +8 -0
- data/lib/datadog/profiling/profiler.rb +7 -0
- data/lib/datadog/profiling/scheduler.rb +4 -7
- data/lib/datadog/profiling/stack_recorder.rb +22 -0
- data/lib/datadog/profiling/tasks/setup.rb +0 -7
- data/lib/datadog/tracing/contrib/delayed_job/plugin.rb +4 -0
- data/lib/datadog/tracing/contrib/grpc/datadog_interceptor/client.rb +2 -1
- data/lib/datadog/tracing/contrib/grpc/datadog_interceptor/server.rb +6 -12
- data/lib/datadog/tracing/contrib/grpc/distributed/fetcher.rb +27 -0
- data/lib/datadog/tracing/contrib/grpc/distributed/propagation.rb +38 -0
- data/lib/datadog/tracing/contrib/grpc/patcher.rb +0 -2
- data/lib/datadog/tracing/contrib/http/distributed/fetcher.rb +32 -0
- data/lib/datadog/tracing/contrib/http/distributed/propagation.rb +33 -0
- data/lib/datadog/tracing/contrib/kafka/consumer_event.rb +1 -0
- data/lib/datadog/tracing/contrib/kafka/events/produce_operation/send_messages.rb +1 -0
- data/lib/datadog/tracing/contrib/kafka/events/producer/deliver_messages.rb +1 -0
- data/lib/datadog/tracing/contrib/mongodb/subscribers.rb +2 -0
- data/lib/datadog/tracing/contrib/que/tracer.rb +2 -0
- data/lib/datadog/tracing/contrib/racecar/events/batch.rb +4 -1
- data/lib/datadog/tracing/contrib/racecar/events/message.rb +4 -1
- data/lib/datadog/tracing/contrib/rack/middlewares.rb +2 -0
- data/lib/datadog/tracing/contrib/redis/instrumentation.rb +2 -0
- data/lib/datadog/tracing/contrib/redis/integration.rb +2 -1
- data/lib/datadog/tracing/contrib/redis/patcher.rb +2 -3
- data/lib/datadog/tracing/contrib/resque/resque_job.rb +2 -0
- data/lib/datadog/tracing/contrib/shoryuken/tracer.rb +2 -0
- data/lib/datadog/tracing/contrib/sidekiq/client_tracer.rb +5 -0
- data/lib/datadog/tracing/contrib/sidekiq/server_tracer.rb +5 -0
- data/lib/datadog/tracing/contrib/sneakers/tracer.rb +2 -0
- data/lib/datadog/tracing/distributed/b3.rb +66 -0
- data/lib/datadog/tracing/distributed/b3_single.rb +66 -0
- data/lib/datadog/tracing/distributed/datadog.rb +153 -0
- data/lib/datadog/tracing/distributed/datadog_tags_codec.rb +1 -0
- data/lib/datadog/tracing/distributed/fetcher.rb +30 -0
- data/lib/datadog/tracing/distributed/headers/ext.rb +18 -16
- data/lib/datadog/tracing/distributed/helpers.rb +7 -6
- data/lib/datadog/tracing/distributed/propagation.rb +127 -0
- data/lib/datadog/tracing/propagation/http.rb +3 -106
- data/lib/datadog/tracing/trace_segment.rb +1 -1
- data/lib/ddtrace/transport/trace_formatter.rb +2 -5
- data/lib/ddtrace/version.rb +1 -1
- metadata +19 -14
- data/lib/datadog/tracing/distributed/headers/b3.rb +0 -55
- data/lib/datadog/tracing/distributed/headers/b3_single.rb +0 -67
- data/lib/datadog/tracing/distributed/headers/datadog.rb +0 -144
- data/lib/datadog/tracing/distributed/headers/parser.rb +0 -37
- data/lib/datadog/tracing/distributed/metadata/b3.rb +0 -55
- data/lib/datadog/tracing/distributed/metadata/b3_single.rb +0 -66
- data/lib/datadog/tracing/distributed/metadata/datadog.rb +0 -73
- data/lib/datadog/tracing/distributed/metadata/parser.rb +0 -34
- 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
|
-
|
|
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 '
|
|
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!(
|
|
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
|
-
|
|
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
|
|
@@ -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
|
|
@@ -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(
|
|
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(
|
|
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
|
|
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
|