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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +89 -2
- data/README.md +2 -2
- data/ext/ddtrace_profiling_loader/extconf.rb +5 -2
- data/ext/ddtrace_profiling_native_extension/NativeExtensionDesign.md +1 -1
- data/ext/ddtrace_profiling_native_extension/clock_id_from_pthread.c +3 -2
- data/ext/ddtrace_profiling_native_extension/collectors_cpu_and_wall_time.c +81 -47
- data/ext/ddtrace_profiling_native_extension/collectors_cpu_and_wall_time.h +1 -1
- data/ext/ddtrace_profiling_native_extension/collectors_cpu_and_wall_time_worker.c +332 -125
- data/ext/ddtrace_profiling_native_extension/collectors_dynamic_sampling_rate.c +142 -0
- data/ext/ddtrace_profiling_native_extension/collectors_dynamic_sampling_rate.h +14 -0
- data/ext/ddtrace_profiling_native_extension/collectors_idle_sampling_helper.c +241 -0
- data/ext/ddtrace_profiling_native_extension/collectors_idle_sampling_helper.h +3 -0
- data/ext/ddtrace_profiling_native_extension/collectors_stack.c +11 -13
- data/ext/ddtrace_profiling_native_extension/extconf.rb +22 -8
- data/ext/ddtrace_profiling_native_extension/helpers.h +5 -0
- data/ext/ddtrace_profiling_native_extension/native_extension_helpers.rb +8 -0
- data/ext/ddtrace_profiling_native_extension/private_vm_api_access.c +111 -26
- data/ext/ddtrace_profiling_native_extension/private_vm_api_access.h +9 -0
- data/ext/ddtrace_profiling_native_extension/profiling.c +205 -0
- data/ext/ddtrace_profiling_native_extension/ruby_helpers.c +86 -0
- data/ext/ddtrace_profiling_native_extension/ruby_helpers.h +28 -6
- data/ext/ddtrace_profiling_native_extension/setup_signal_handler.c +115 -0
- data/ext/ddtrace_profiling_native_extension/setup_signal_handler.h +11 -0
- data/ext/ddtrace_profiling_native_extension/stack_recorder.c +84 -35
- data/ext/ddtrace_profiling_native_extension/stack_recorder.h +1 -0
- data/ext/ddtrace_profiling_native_extension/time_helpers.c +17 -0
- data/ext/ddtrace_profiling_native_extension/time_helpers.h +10 -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/configuration/components.rb +27 -6
- data/lib/datadog/core/configuration/ext.rb +18 -0
- data/lib/datadog/core/configuration/settings.rb +14 -341
- data/lib/datadog/core/diagnostics/health.rb +4 -22
- data/lib/datadog/core/environment/variable_helpers.rb +58 -10
- data/lib/datadog/core/runtime/ext.rb +1 -1
- data/lib/datadog/core/utils.rb +0 -21
- data/lib/datadog/core.rb +21 -1
- data/lib/datadog/opentracer/distributed_headers.rb +7 -9
- 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 +20 -5
- data/lib/datadog/profiling/collectors/dynamic_sampling_rate.rb +14 -0
- data/lib/datadog/profiling/collectors/idle_sampling_helper.rb +68 -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 +36 -0
- data/lib/datadog/profiling/tasks/setup.rb +0 -7
- data/lib/datadog/profiling.rb +2 -0
- data/lib/datadog/tracing/configuration/ext.rb +33 -3
- data/lib/datadog/tracing/configuration/settings.rb +433 -0
- data/lib/datadog/tracing/contrib/aws/configuration/settings.rb +4 -1
- data/lib/datadog/tracing/contrib/aws/ext.rb +1 -0
- data/lib/datadog/tracing/contrib/dalli/configuration/settings.rb +4 -1
- data/lib/datadog/tracing/contrib/dalli/ext.rb +1 -0
- data/lib/datadog/tracing/contrib/delayed_job/plugin.rb +4 -0
- data/lib/datadog/tracing/contrib/elasticsearch/configuration/settings.rb +5 -1
- data/lib/datadog/tracing/contrib/elasticsearch/ext.rb +1 -0
- data/lib/datadog/tracing/contrib/ethon/configuration/settings.rb +6 -1
- data/lib/datadog/tracing/contrib/ethon/ext.rb +1 -0
- data/lib/datadog/tracing/contrib/excon/configuration/settings.rb +5 -1
- data/lib/datadog/tracing/contrib/excon/ext.rb +1 -0
- data/lib/datadog/tracing/contrib/faraday/configuration/settings.rb +5 -1
- data/lib/datadog/tracing/contrib/faraday/ext.rb +1 -0
- data/lib/datadog/tracing/contrib/grpc/configuration/settings.rb +6 -1
- 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 +43 -0
- data/lib/datadog/tracing/contrib/grpc/ext.rb +1 -0
- data/lib/datadog/tracing/contrib/grpc/patcher.rb +0 -2
- data/lib/datadog/tracing/contrib/http/configuration/settings.rb +6 -1
- data/lib/datadog/tracing/contrib/http/distributed/fetcher.rb +32 -0
- data/lib/datadog/tracing/contrib/http/distributed/propagation.rb +38 -0
- data/lib/datadog/tracing/contrib/http/ext.rb +1 -0
- data/lib/datadog/tracing/contrib/httpclient/configuration/settings.rb +6 -1
- data/lib/datadog/tracing/contrib/httpclient/ext.rb +1 -0
- data/lib/datadog/tracing/contrib/httprb/configuration/settings.rb +6 -1
- data/lib/datadog/tracing/contrib/httprb/ext.rb +1 -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/configuration/settings.rb +5 -1
- data/lib/datadog/tracing/contrib/mongodb/ext.rb +1 -0
- data/lib/datadog/tracing/contrib/mongodb/subscribers.rb +2 -0
- data/lib/datadog/tracing/contrib/mysql2/configuration/settings.rb +4 -1
- data/lib/datadog/tracing/contrib/mysql2/ext.rb +1 -0
- data/lib/datadog/tracing/contrib/mysql2/instrumentation.rb +2 -2
- data/lib/datadog/tracing/contrib/patcher.rb +3 -2
- data/lib/datadog/tracing/contrib/pg/configuration/settings.rb +4 -1
- data/lib/datadog/tracing/contrib/pg/ext.rb +1 -0
- data/lib/datadog/tracing/contrib/pg/instrumentation.rb +12 -2
- data/lib/datadog/tracing/contrib/presto/configuration/settings.rb +4 -1
- data/lib/datadog/tracing/contrib/presto/ext.rb +1 -0
- data/lib/datadog/tracing/contrib/propagation/sql_comment/ext.rb +1 -0
- data/lib/datadog/tracing/contrib/propagation/sql_comment.rb +10 -12
- 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/configuration/settings.rb +4 -1
- data/lib/datadog/tracing/contrib/redis/ext.rb +1 -0
- data/lib/datadog/tracing/contrib/redis/instrumentation.rb +30 -21
- data/lib/datadog/tracing/contrib/redis/integration.rb +34 -2
- data/lib/datadog/tracing/contrib/redis/patcher.rb +18 -14
- data/lib/datadog/tracing/contrib/redis/quantize.rb +12 -9
- data/lib/datadog/tracing/contrib/redis/tags.rb +4 -6
- data/lib/datadog/tracing/contrib/redis/trace_middleware.rb +72 -0
- data/lib/datadog/tracing/contrib/resque/resque_job.rb +2 -0
- data/lib/datadog/tracing/contrib/rest_client/configuration/settings.rb +6 -1
- data/lib/datadog/tracing/contrib/rest_client/ext.rb +1 -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/{core → tracing}/diagnostics/ext.rb +1 -6
- data/lib/datadog/tracing/diagnostics/health.rb +40 -0
- data/lib/datadog/tracing/distributed/b3_multi.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 +9 -7
- data/lib/datadog/tracing/distributed/none.rb +19 -0
- data/lib/datadog/tracing/distributed/propagation.rb +127 -0
- data/lib/datadog/tracing/distributed/trace_context.rb +369 -0
- data/lib/datadog/tracing/metadata/ext.rb +1 -1
- data/lib/datadog/tracing/propagation/http.rb +3 -106
- data/lib/datadog/tracing/sampling/priority_sampler.rb +11 -0
- data/lib/datadog/tracing/sampling/rate_sampler.rb +3 -3
- data/lib/datadog/tracing/span.rb +3 -19
- data/lib/datadog/tracing/span_operation.rb +5 -4
- data/lib/datadog/tracing/trace_digest.rb +75 -2
- data/lib/datadog/tracing/trace_operation.rb +5 -4
- data/lib/datadog/tracing/trace_segment.rb +1 -1
- data/lib/datadog/tracing/utils.rb +50 -0
- data/lib/ddtrace/transport/trace_formatter.rb +2 -5
- data/lib/ddtrace/version.rb +2 -2
- metadata +35 -15
- 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
|
@@ -1,15 +1,13 @@
|
|
|
1
1
|
# typed: true
|
|
2
2
|
|
|
3
|
-
require_relative '../tracing/
|
|
4
|
-
require_relative '../tracing/
|
|
3
|
+
require_relative '../tracing/distributed/datadog'
|
|
4
|
+
require_relative '../tracing/utils'
|
|
5
5
|
|
|
6
6
|
module Datadog
|
|
7
7
|
module OpenTracer
|
|
8
8
|
# DistributedHeaders provides easy access and validation to headers
|
|
9
9
|
# @public_api
|
|
10
10
|
class DistributedHeaders
|
|
11
|
-
include Tracing::Distributed::Headers::Ext
|
|
12
|
-
|
|
13
11
|
def initialize(carrier)
|
|
14
12
|
@carrier = carrier
|
|
15
13
|
end
|
|
@@ -20,15 +18,15 @@ module Datadog
|
|
|
20
18
|
end
|
|
21
19
|
|
|
22
20
|
def trace_id
|
|
23
|
-
id
|
|
21
|
+
id Tracing::Distributed::Datadog::TRACE_ID_KEY
|
|
24
22
|
end
|
|
25
23
|
|
|
26
24
|
def parent_id
|
|
27
|
-
id
|
|
25
|
+
id Tracing::Distributed::Datadog::PARENT_ID_KEY
|
|
28
26
|
end
|
|
29
27
|
|
|
30
28
|
def sampling_priority
|
|
31
|
-
hdr = @carrier[
|
|
29
|
+
hdr = @carrier[Tracing::Distributed::Datadog::SAMPLING_PRIORITY_KEY]
|
|
32
30
|
# It's important to make a difference between no header,
|
|
33
31
|
# and a header defined to zero.
|
|
34
32
|
return unless hdr
|
|
@@ -40,7 +38,7 @@ module Datadog
|
|
|
40
38
|
end
|
|
41
39
|
|
|
42
40
|
def origin
|
|
43
|
-
hdr = @carrier[
|
|
41
|
+
hdr = @carrier[Tracing::Distributed::Datadog::ORIGIN_KEY]
|
|
44
42
|
# Only return the value if it is not an empty string
|
|
45
43
|
hdr if hdr != ''
|
|
46
44
|
end
|
|
@@ -49,7 +47,7 @@ module Datadog
|
|
|
49
47
|
|
|
50
48
|
def id(header)
|
|
51
49
|
value = @carrier[header].to_i
|
|
52
|
-
return if value.zero? || value >= Datadog::Tracing::
|
|
50
|
+
return if value.zero? || value >= Datadog::Tracing::Utils::EXTERNAL_MAX_ID
|
|
53
51
|
|
|
54
52
|
value < 0 ? value + 0x1_0000_0000_0000_0000 : value
|
|
55
53
|
end
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
# typed: true
|
|
2
2
|
|
|
3
3
|
require_relative '../tracing/context'
|
|
4
|
-
require_relative '../tracing/distributed/headers/ext'
|
|
5
4
|
require_relative '../tracing/propagation/http'
|
|
6
5
|
require_relative '../tracing/trace_operation'
|
|
7
6
|
require_relative 'propagator'
|
|
@@ -11,8 +10,6 @@ module Datadog
|
|
|
11
10
|
# OpenTracing propagator for Datadog::OpenTracer::Tracer
|
|
12
11
|
module RackPropagator
|
|
13
12
|
extend Propagator
|
|
14
|
-
extend Tracing::Distributed::Headers::Ext
|
|
15
|
-
include Tracing::Distributed::Headers::Ext
|
|
16
13
|
|
|
17
14
|
BAGGAGE_PREFIX = 'ot-baggage-'.freeze
|
|
18
15
|
BAGGAGE_PREFIX_FORMATTED = 'HTTP_OT_BAGGAGE_'.freeze
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# typed: true
|
|
2
2
|
|
|
3
3
|
require_relative '../tracing/context'
|
|
4
|
-
require_relative '../tracing/distributed/
|
|
4
|
+
require_relative '../tracing/distributed/datadog'
|
|
5
5
|
require_relative '../tracing/trace_operation'
|
|
6
6
|
require_relative 'propagator'
|
|
7
7
|
|
|
@@ -10,8 +10,6 @@ module Datadog
|
|
|
10
10
|
# OpenTracing propagator for Datadog::OpenTracer::Tracer
|
|
11
11
|
module TextMapPropagator
|
|
12
12
|
extend Propagator
|
|
13
|
-
extend Tracing::Distributed::Headers::Ext
|
|
14
|
-
include Tracing::Distributed::Headers::Ext
|
|
15
13
|
|
|
16
14
|
BAGGAGE_PREFIX = 'ot-baggage-'.freeze
|
|
17
15
|
|
|
@@ -34,10 +32,10 @@ module Datadog
|
|
|
34
32
|
end
|
|
35
33
|
return unless digest
|
|
36
34
|
|
|
37
|
-
carrier[
|
|
38
|
-
carrier[
|
|
39
|
-
carrier[
|
|
40
|
-
carrier[
|
|
35
|
+
carrier[Tracing::Distributed::Datadog::ORIGIN_KEY] = digest.trace_origin
|
|
36
|
+
carrier[Tracing::Distributed::Datadog::PARENT_ID_KEY] = digest.span_id
|
|
37
|
+
carrier[Tracing::Distributed::Datadog::SAMPLING_PRIORITY_KEY] = digest.trace_sampling_priority
|
|
38
|
+
carrier[Tracing::Distributed::Datadog::TRACE_ID_KEY] = digest.trace_id
|
|
41
39
|
|
|
42
40
|
nil
|
|
43
41
|
end
|
|
@@ -23,13 +23,19 @@ module Datadog
|
|
|
23
23
|
result
|
|
24
24
|
end
|
|
25
25
|
|
|
26
|
+
def reset_after_fork
|
|
27
|
+
self.class._native_reset_after_fork(self)
|
|
28
|
+
end
|
|
29
|
+
|
|
26
30
|
private
|
|
27
31
|
|
|
28
32
|
def safely_extract_context_key_from(tracer)
|
|
29
|
-
tracer &&
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
+
provider = tracer && tracer.respond_to?(:provider) && tracer.provider
|
|
34
|
+
|
|
35
|
+
return unless provider
|
|
36
|
+
|
|
37
|
+
context = provider.instance_variable_get(:@context)
|
|
38
|
+
context && context.instance_variable_get(:@key)
|
|
33
39
|
end
|
|
34
40
|
end
|
|
35
41
|
end
|
|
@@ -20,12 +20,14 @@ module Datadog
|
|
|
20
20
|
max_frames:,
|
|
21
21
|
tracer:,
|
|
22
22
|
gc_profiling_enabled:,
|
|
23
|
-
cpu_and_wall_time_collector: CpuAndWallTime.new(recorder: recorder, max_frames: max_frames, tracer: tracer)
|
|
23
|
+
cpu_and_wall_time_collector: CpuAndWallTime.new(recorder: recorder, max_frames: max_frames, tracer: tracer),
|
|
24
|
+
idle_sampling_helper: IdleSamplingHelper.new
|
|
24
25
|
)
|
|
25
|
-
self.class._native_initialize(self, cpu_and_wall_time_collector, gc_profiling_enabled)
|
|
26
|
+
self.class._native_initialize(self, cpu_and_wall_time_collector, gc_profiling_enabled, idle_sampling_helper)
|
|
26
27
|
@worker_thread = nil
|
|
27
28
|
@failure_exception = nil
|
|
28
29
|
@start_stop_mutex = Mutex.new
|
|
30
|
+
@idle_sampling_helper = idle_sampling_helper
|
|
29
31
|
end
|
|
30
32
|
|
|
31
33
|
def start
|
|
@@ -33,6 +35,9 @@ module Datadog
|
|
|
33
35
|
return if @worker_thread && @worker_thread.alive?
|
|
34
36
|
|
|
35
37
|
Datadog.logger.debug { "Starting thread for: #{self}" }
|
|
38
|
+
|
|
39
|
+
@idle_sampling_helper.start
|
|
40
|
+
|
|
36
41
|
@worker_thread = Thread.new do
|
|
37
42
|
begin
|
|
38
43
|
Thread.current.name = self.class.name unless Gem::Version.new(RUBY_VERSION) < Gem::Version.new('2.3')
|
|
@@ -43,7 +48,8 @@ module Datadog
|
|
|
43
48
|
rescue Exception => e # rubocop:disable Lint/RescueException
|
|
44
49
|
@failure_exception = e
|
|
45
50
|
Datadog.logger.warn(
|
|
46
|
-
|
|
51
|
+
'CpuAndWallTimeWorker thread error. ' \
|
|
52
|
+
"Cause: #{e.class.name} #{e.message} Location: #{Array(e.backtrace).first}"
|
|
47
53
|
)
|
|
48
54
|
end
|
|
49
55
|
end
|
|
@@ -60,16 +66,25 @@ module Datadog
|
|
|
60
66
|
@start_stop_mutex.synchronize do
|
|
61
67
|
Datadog.logger.debug('Requesting CpuAndWallTimeWorker thread shut down')
|
|
62
68
|
|
|
69
|
+
@idle_sampling_helper.stop
|
|
70
|
+
|
|
63
71
|
return unless @worker_thread
|
|
64
72
|
|
|
65
|
-
@worker_thread
|
|
66
|
-
self.class._native_stop(self)
|
|
73
|
+
self.class._native_stop(self, @worker_thread)
|
|
67
74
|
|
|
68
75
|
@worker_thread.join
|
|
69
76
|
@worker_thread = nil
|
|
70
77
|
@failure_exception = nil
|
|
71
78
|
end
|
|
72
79
|
end
|
|
80
|
+
|
|
81
|
+
def reset_after_fork
|
|
82
|
+
self.class._native_reset_after_fork(self)
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
def stats
|
|
86
|
+
self.class._native_stats(self)
|
|
87
|
+
end
|
|
73
88
|
end
|
|
74
89
|
end
|
|
75
90
|
end
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
# typed: false
|
|
2
|
+
|
|
3
|
+
module Datadog
|
|
4
|
+
module Profiling
|
|
5
|
+
module Collectors
|
|
6
|
+
# Used to pace the rate of profiling samples based on the last observed time for a sample.
|
|
7
|
+
# All of this module is implemented as native code.
|
|
8
|
+
#
|
|
9
|
+
# Methods prefixed with _native_ are implemented in `collectors_dynamic_sampling_rate.c`
|
|
10
|
+
module DynamicSamplingRate
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
end
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
# typed: false
|
|
2
|
+
|
|
3
|
+
module Datadog
|
|
4
|
+
module Profiling
|
|
5
|
+
module Collectors
|
|
6
|
+
# Used by the Collectors::CpuAndWallTimeWorker to gather samples when the Ruby process is idle.
|
|
7
|
+
# Almost all of this class is implemented as native code.
|
|
8
|
+
#
|
|
9
|
+
# Methods prefixed with _native_ are implemented in `collectors_idle_sampling_helper.c`
|
|
10
|
+
class IdleSamplingHelper
|
|
11
|
+
private
|
|
12
|
+
|
|
13
|
+
attr_accessor :failure_exception
|
|
14
|
+
|
|
15
|
+
public
|
|
16
|
+
|
|
17
|
+
def initialize
|
|
18
|
+
@worker_thread = nil
|
|
19
|
+
@start_stop_mutex = Mutex.new
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def start
|
|
23
|
+
@start_stop_mutex.synchronize do
|
|
24
|
+
return if @worker_thread && @worker_thread.alive?
|
|
25
|
+
|
|
26
|
+
Datadog.logger.debug { "Starting thread for: #{self}" }
|
|
27
|
+
|
|
28
|
+
# The same instance of the IdleSamplingHelper can be reused multiple times, and this resets it back to
|
|
29
|
+
# a pristine state before recreating the worker thread
|
|
30
|
+
self.class._native_reset(self)
|
|
31
|
+
|
|
32
|
+
@worker_thread = Thread.new do
|
|
33
|
+
begin
|
|
34
|
+
Thread.current.name = self.class.name unless Gem::Version.new(RUBY_VERSION) < Gem::Version.new('2.3')
|
|
35
|
+
|
|
36
|
+
self.class._native_idle_sampling_loop(self)
|
|
37
|
+
|
|
38
|
+
Datadog.logger.debug('IdleSamplingHelper thread stopping cleanly')
|
|
39
|
+
rescue Exception => e # rubocop:disable Lint/RescueException
|
|
40
|
+
@failure_exception = e
|
|
41
|
+
Datadog.logger.warn(
|
|
42
|
+
'IdleSamplingHelper thread error. ' \
|
|
43
|
+
"Cause: #{e.class.name} #{e.message} Location: #{Array(e.backtrace).first}"
|
|
44
|
+
)
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
true
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
def stop(*_)
|
|
53
|
+
@start_stop_mutex.synchronize do
|
|
54
|
+
Datadog.logger.debug('Requesting IdleSamplingHelper thread shut down')
|
|
55
|
+
|
|
56
|
+
return unless @worker_thread
|
|
57
|
+
|
|
58
|
+
self.class._native_stop(self)
|
|
59
|
+
|
|
60
|
+
@worker_thread.join
|
|
61
|
+
@worker_thread = nil
|
|
62
|
+
@failure_exception = nil
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
end
|
|
@@ -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,46 @@ module Datadog
|
|
|
34
34
|
end
|
|
35
35
|
end
|
|
36
36
|
|
|
37
|
+
def serialize!
|
|
38
|
+
status, result = @no_concurrent_synchronize_mutex.synchronize { self.class._native_serialize(self) }
|
|
39
|
+
|
|
40
|
+
if status == :ok
|
|
41
|
+
_start, _finish, encoded_pprof = result
|
|
42
|
+
|
|
43
|
+
encoded_pprof
|
|
44
|
+
else
|
|
45
|
+
error_message = result
|
|
46
|
+
|
|
47
|
+
raise("Failed to serialize profiling data: #{error_message}")
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
def clear
|
|
52
|
+
status, result = @no_concurrent_synchronize_mutex.synchronize { self.class._native_clear(self) }
|
|
53
|
+
|
|
54
|
+
if status == :ok
|
|
55
|
+
finish_timestamp = result
|
|
56
|
+
|
|
57
|
+
Datadog.logger.debug { "Cleared profile at #{finish_timestamp}" }
|
|
58
|
+
|
|
59
|
+
finish_timestamp
|
|
60
|
+
else
|
|
61
|
+
error_message = result
|
|
62
|
+
|
|
63
|
+
Datadog.logger.error("Failed to clear profiling data: #{error_message}")
|
|
64
|
+
|
|
65
|
+
nil
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
|
|
37
69
|
# Used only for Ruby 2.2 which doesn't have the native `rb_time_timespec_new` API; called from native code
|
|
38
70
|
def self.ruby_time_from(timespec_seconds, timespec_nanoseconds)
|
|
39
71
|
Time.at(0).utc + timespec_seconds + (timespec_nanoseconds.to_r / 1_000_000_000)
|
|
40
72
|
end
|
|
73
|
+
|
|
74
|
+
def reset_after_fork
|
|
75
|
+
self.class._native_reset_after_fork(self)
|
|
76
|
+
end
|
|
41
77
|
end
|
|
42
78
|
end
|
|
43
79
|
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
|
data/lib/datadog/profiling.rb
CHANGED
|
@@ -149,6 +149,8 @@ module Datadog
|
|
|
149
149
|
require_relative 'profiling/collectors/code_provenance'
|
|
150
150
|
require_relative 'profiling/collectors/cpu_and_wall_time'
|
|
151
151
|
require_relative 'profiling/collectors/cpu_and_wall_time_worker'
|
|
152
|
+
require_relative 'profiling/collectors/dynamic_sampling_rate'
|
|
153
|
+
require_relative 'profiling/collectors/idle_sampling_helper'
|
|
152
154
|
require_relative 'profiling/collectors/old_stack'
|
|
153
155
|
require_relative 'profiling/collectors/stack'
|
|
154
156
|
require_relative 'profiling/stack_recorder'
|
|
@@ -3,7 +3,11 @@
|
|
|
3
3
|
module Datadog
|
|
4
4
|
module Tracing
|
|
5
5
|
module Configuration
|
|
6
|
+
# Constants for configuration settings
|
|
7
|
+
# e.g. Env vars, default values, enums, etc...
|
|
6
8
|
module Ext
|
|
9
|
+
ENV_ENABLED = 'DD_TRACE_ENABLED'.freeze
|
|
10
|
+
|
|
7
11
|
# @public_api
|
|
8
12
|
module Analytics
|
|
9
13
|
ENV_TRACE_ANALYTICS_ENABLED = 'DD_TRACE_ANALYTICS_ENABLED'.freeze
|
|
@@ -16,11 +20,37 @@ module Datadog
|
|
|
16
20
|
|
|
17
21
|
# @public_api
|
|
18
22
|
module Distributed
|
|
23
|
+
# Custom Datadog format
|
|
19
24
|
PROPAGATION_STYLE_DATADOG = 'Datadog'.freeze
|
|
25
|
+
|
|
26
|
+
PROPAGATION_STYLE_B3_MULTI_HEADER = 'b3multi'.freeze
|
|
27
|
+
# @deprecated Use `b3multi` instead.
|
|
20
28
|
PROPAGATION_STYLE_B3 = 'B3'.freeze
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
29
|
+
|
|
30
|
+
PROPAGATION_STYLE_B3_SINGLE_HEADER = 'b3'.freeze
|
|
31
|
+
# @deprecated Use `b3` instead.
|
|
32
|
+
PROPAGATION_STYLE_B3_SINGLE_HEADER_OLD = 'B3 single header'.freeze
|
|
33
|
+
|
|
34
|
+
# W3C Trace Context
|
|
35
|
+
PROPAGATION_STYLE_TRACE_CONTEXT = 'tracecontext'.freeze
|
|
36
|
+
|
|
37
|
+
# Sets both extract and inject propagation style tho the provided value.
|
|
38
|
+
# Has lower precedence than `DD_TRACE_PROPAGATION_STYLE_INJECT` or
|
|
39
|
+
# `DD_TRACE_PROPAGATION_STYLE_EXTRACT`.
|
|
40
|
+
ENV_PROPAGATION_STYLE = 'DD_TRACE_PROPAGATION_STYLE'.freeze
|
|
41
|
+
|
|
42
|
+
ENV_PROPAGATION_STYLE_INJECT = 'DD_TRACE_PROPAGATION_STYLE_INJECT'.freeze
|
|
43
|
+
# @deprecated Use `DD_TRACE_PROPAGATION_STYLE_INJECT` instead.
|
|
44
|
+
ENV_PROPAGATION_STYLE_INJECT_OLD = 'DD_PROPAGATION_STYLE_INJECT'.freeze
|
|
45
|
+
|
|
46
|
+
ENV_PROPAGATION_STYLE_EXTRACT = 'DD_TRACE_PROPAGATION_STYLE_EXTRACT'.freeze
|
|
47
|
+
# @deprecated Use `DD_TRACE_PROPAGATION_STYLE_EXTRACT` instead.
|
|
48
|
+
ENV_PROPAGATION_STYLE_EXTRACT_OLD = 'DD_PROPAGATION_STYLE_EXTRACT'.freeze
|
|
49
|
+
|
|
50
|
+
# A no-op propagator. Compatible with OpenTelemetry's `none` propagator.
|
|
51
|
+
# @see https://opentelemetry.io/docs/concepts/sdk-configuration/general-sdk-configuration/#otel_propagators
|
|
52
|
+
PROPAGATION_STYLE_NONE = 'none'.freeze
|
|
53
|
+
|
|
24
54
|
ENV_X_DATADOG_TAGS_MAX_LENGTH = 'DD_TRACE_X_DATADOG_TAGS_MAX_LENGTH'.freeze
|
|
25
55
|
end
|
|
26
56
|
|