datadog 2.0.0 → 2.2.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 +66 -2
- data/README.md +1 -1
- data/ext/datadog_profiling_native_extension/collectors_cpu_and_wall_time_worker.c +19 -1
- data/ext/datadog_profiling_native_extension/collectors_stack.c +41 -0
- data/ext/datadog_profiling_native_extension/collectors_thread_context.c +1 -1
- data/ext/datadog_profiling_native_extension/crashtracker.c +1 -1
- data/ext/datadog_profiling_native_extension/extconf.rb +6 -4
- data/ext/datadog_profiling_native_extension/native_extension_helpers.rb +47 -1
- data/ext/datadog_profiling_native_extension/setup_signal_handler.c +1 -1
- data/ext/datadog_profiling_native_extension/stack_recorder.c +13 -6
- data/ext/datadog_profiling_native_extension/stack_recorder.h +1 -0
- data/lib/datadog/appsec/configuration/settings.rb +5 -0
- data/lib/datadog/appsec/contrib/rack/request_middleware.rb +0 -1
- data/lib/datadog/appsec/contrib/sinatra/patcher.rb +1 -1
- data/lib/datadog/appsec/extensions.rb +1 -0
- data/lib/datadog/core/configuration/components.rb +6 -3
- data/lib/datadog/core/configuration/ext.rb +1 -0
- data/lib/datadog/core/configuration/option.rb +21 -14
- data/lib/datadog/core/configuration/options.rb +5 -1
- data/lib/datadog/core/configuration/settings.rb +68 -5
- data/lib/datadog/core/configuration.rb +3 -17
- data/lib/datadog/core/deprecations.rb +58 -0
- data/lib/datadog/core/environment/ext.rb +2 -0
- data/lib/datadog/core/environment/yjit.rb +5 -0
- data/lib/datadog/core/runtime/ext.rb +2 -0
- data/lib/datadog/core/runtime/metrics.rb +6 -0
- data/lib/datadog/core/telemetry/component.rb +107 -0
- data/lib/datadog/core/telemetry/event.rb +124 -31
- data/lib/datadog/core/telemetry/ext.rb +2 -0
- data/lib/datadog/core/telemetry/http/adapters/net.rb +1 -1
- data/lib/datadog/core/telemetry/metric.rb +167 -0
- data/lib/datadog/core/telemetry/metrics_collection.rb +81 -0
- data/lib/datadog/core/telemetry/metrics_manager.rb +81 -0
- data/lib/datadog/core/telemetry/request.rb +1 -1
- data/lib/datadog/core/telemetry/worker.rb +173 -0
- data/lib/datadog/core/utils/only_once_successful.rb +76 -0
- data/lib/datadog/core.rb +2 -19
- data/lib/datadog/opentelemetry/sdk/propagator.rb +5 -10
- data/lib/datadog/opentelemetry/sdk/span_processor.rb +5 -2
- data/lib/datadog/profiling/collectors/code_provenance.rb +18 -5
- data/lib/datadog/profiling/component.rb +18 -1
- data/lib/datadog/profiling/ext/dir_monkey_patches.rb +410 -0
- data/lib/datadog/profiling.rb +1 -0
- data/lib/datadog/tracing/configuration/ext.rb +7 -0
- data/lib/datadog/tracing/configuration/settings.rb +52 -3
- data/lib/datadog/tracing/contrib/action_cable/event.rb +1 -1
- data/lib/datadog/tracing/contrib/action_cable/events/broadcast.rb +1 -1
- data/lib/datadog/tracing/contrib/action_cable/events/perform_action.rb +1 -1
- data/lib/datadog/tracing/contrib/action_cable/events/transmit.rb +1 -1
- data/lib/datadog/tracing/contrib/action_mailer/event.rb +4 -6
- data/lib/datadog/tracing/contrib/action_mailer/events/deliver.rb +9 -4
- data/lib/datadog/tracing/contrib/action_mailer/events/process.rb +3 -2
- data/lib/datadog/tracing/contrib/action_view/events/render_partial.rb +1 -5
- data/lib/datadog/tracing/contrib/action_view/events/render_template.rb +1 -1
- data/lib/datadog/tracing/contrib/active_job/events/discard.rb +1 -1
- data/lib/datadog/tracing/contrib/active_job/events/enqueue.rb +1 -1
- data/lib/datadog/tracing/contrib/active_job/events/enqueue_at.rb +1 -1
- data/lib/datadog/tracing/contrib/active_job/events/enqueue_retry.rb +1 -1
- data/lib/datadog/tracing/contrib/active_job/events/perform.rb +1 -1
- data/lib/datadog/tracing/contrib/active_job/events/retry_stopped.rb +1 -1
- data/lib/datadog/tracing/contrib/active_model_serializers/events/render.rb +1 -1
- data/lib/datadog/tracing/contrib/active_model_serializers/events/serialize.rb +1 -1
- data/lib/datadog/tracing/contrib/active_record/events/instantiation.rb +1 -1
- data/lib/datadog/tracing/contrib/active_record/events/sql.rb +1 -1
- data/lib/datadog/tracing/contrib/active_support/cache/event.rb +32 -0
- data/lib/datadog/tracing/contrib/active_support/cache/events/cache.rb +156 -0
- data/lib/datadog/tracing/contrib/active_support/cache/events.rb +34 -0
- data/lib/datadog/tracing/contrib/active_support/cache/instrumentation.rb +45 -41
- data/lib/datadog/tracing/contrib/active_support/cache/patcher.rb +17 -40
- data/lib/datadog/tracing/contrib/active_support/cache/redis.rb +4 -1
- data/lib/datadog/tracing/contrib/active_support/notifications/event.rb +29 -6
- data/lib/datadog/tracing/contrib/active_support/notifications/subscriber.rb +16 -4
- data/lib/datadog/tracing/contrib/active_support/notifications/subscription.rb +33 -29
- data/lib/datadog/tracing/contrib/analytics.rb +5 -0
- data/lib/datadog/tracing/contrib/graphql/configuration/settings.rb +5 -0
- data/lib/datadog/tracing/contrib/graphql/patcher.rb +8 -2
- data/lib/datadog/tracing/contrib/graphql/unified_trace.rb +166 -0
- data/lib/datadog/tracing/contrib/graphql/unified_trace_patcher.rb +25 -0
- data/lib/datadog/tracing/contrib/kafka/consumer_event.rb +1 -1
- data/lib/datadog/tracing/contrib/kafka/consumer_group_event.rb +1 -1
- data/lib/datadog/tracing/contrib/kafka/event.rb +1 -1
- data/lib/datadog/tracing/contrib/kafka/events/connection/request.rb +3 -3
- data/lib/datadog/tracing/contrib/kafka/events/consumer/process_batch.rb +3 -3
- data/lib/datadog/tracing/contrib/kafka/events/consumer/process_message.rb +3 -3
- data/lib/datadog/tracing/contrib/kafka/events/consumer_group/heartbeat.rb +3 -3
- data/lib/datadog/tracing/contrib/kafka/events/produce_operation/send_messages.rb +3 -3
- data/lib/datadog/tracing/contrib/kafka/events/producer/deliver_messages.rb +3 -3
- data/lib/datadog/tracing/contrib/racecar/event.rb +2 -2
- data/lib/datadog/tracing/contrib/rails/ext.rb +9 -0
- data/lib/datadog/tracing/contrib/rails/patcher.rb +7 -0
- data/lib/datadog/tracing/contrib/rails/runner.rb +95 -0
- data/lib/datadog/tracing/distributed/b3_multi.rb +1 -1
- data/lib/datadog/tracing/distributed/b3_single.rb +3 -1
- data/lib/datadog/tracing/distributed/datadog.rb +2 -2
- data/lib/datadog/tracing/distributed/propagation.rb +39 -4
- data/lib/datadog/tracing/distributed/trace_context.rb +5 -3
- data/lib/datadog/tracing/metadata/ext.rb +1 -0
- data/lib/datadog/tracing/span_operation.rb +3 -2
- data/lib/datadog/tracing/trace_operation.rb +7 -3
- data/lib/datadog/tracing/trace_segment.rb +4 -1
- data/lib/datadog/tracing/tracer.rb +9 -2
- data/lib/datadog/tracing.rb +5 -1
- data/lib/datadog/version.rb +2 -2
- metadata +21 -8
- data/lib/datadog/core/telemetry/client.rb +0 -95
- data/lib/datadog/core/telemetry/heartbeat.rb +0 -33
@@ -92,25 +92,38 @@ module Datadog
|
|
92
92
|
|
93
93
|
seen_files << file_path
|
94
94
|
|
95
|
-
|
96
|
-
|
95
|
+
# NOTE: Don't use .find, it allocates a lot more memory (see commit that added this note for details)
|
96
|
+
libraries_by_path.any? do |library_path, library|
|
97
|
+
seen_libraries << library if file_path.start_with?(library_path)
|
98
|
+
end
|
97
99
|
end
|
98
100
|
end
|
99
101
|
|
100
102
|
# Represents metadata we have for a ruby gem
|
103
|
+
#
|
104
|
+
# Important note: This class gets encoded to JSON with the built-in JSON gem. But, we've found that in some
|
105
|
+
# buggy cases, some Ruby gems monkey patch the built-in JSON gem and forget to call #to_json, and instead
|
106
|
+
# encode this class instance-field-by-instance-field.
|
107
|
+
#
|
108
|
+
# Thus, this class was setup to match the JSON output. Take this into consideration if you are adding new
|
109
|
+
# fields. (Also, we have a spec for this)
|
101
110
|
class Library
|
102
|
-
attr_reader :kind, :name, :version
|
111
|
+
attr_reader :kind, :name, :version
|
103
112
|
|
104
113
|
def initialize(kind:, name:, version:, path:)
|
105
114
|
@kind = kind.freeze
|
106
115
|
@name = name.dup.freeze
|
107
116
|
@version = version.to_s.dup.freeze
|
108
|
-
@
|
117
|
+
@paths = [path.dup.freeze].freeze
|
109
118
|
freeze
|
110
119
|
end
|
111
120
|
|
112
121
|
def to_json(arg = nil)
|
113
|
-
{ kind: @kind, name: @name, version: @version, paths:
|
122
|
+
{ kind: @kind, name: @name, version: @version, paths: @paths }.to_json(arg)
|
123
|
+
end
|
124
|
+
|
125
|
+
def path
|
126
|
+
@paths.first
|
114
127
|
end
|
115
128
|
end
|
116
129
|
end
|
@@ -75,6 +75,10 @@ module Datadog
|
|
75
75
|
crashtracker = build_crashtracker(settings, transport)
|
76
76
|
profiler = Profiling::Profiler.new(worker: worker, scheduler: scheduler, optional_crashtracker: crashtracker)
|
77
77
|
|
78
|
+
if dir_interruption_workaround_enabled?(settings, no_signals_workaround_enabled)
|
79
|
+
Datadog::Profiling::Ext::DirMonkeyPatches.apply!
|
80
|
+
end
|
81
|
+
|
78
82
|
[profiler, { profiling_enabled: true }]
|
79
83
|
end
|
80
84
|
|
@@ -397,8 +401,12 @@ module Datadog
|
|
397
401
|
|
398
402
|
# See https://github.com/datadog/dd-trace-rb/issues/2976 for details.
|
399
403
|
private_class_method def self.incompatible_passenger_version?
|
404
|
+
first_compatible_version = Gem::Version.new('6.0.19')
|
405
|
+
|
400
406
|
if Gem.loaded_specs['passenger']
|
401
|
-
Gem.loaded_specs['passenger'].version <
|
407
|
+
Gem.loaded_specs['passenger'].version < first_compatible_version
|
408
|
+
elsif defined?(PhusionPassenger::VERSION_STRING)
|
409
|
+
Gem::Version.new(PhusionPassenger::VERSION_STRING) < first_compatible_version
|
402
410
|
else
|
403
411
|
true
|
404
412
|
end
|
@@ -445,6 +453,15 @@ module Datadog
|
|
445
453
|
libmysqlclient_version < Gem::Version.new('5.0.0') &&
|
446
454
|
header_version >= Gem::Version.new('10.0.0'))
|
447
455
|
end
|
456
|
+
|
457
|
+
private_class_method def self.dir_interruption_workaround_enabled?(settings, no_signals_workaround_enabled)
|
458
|
+
return false if no_signals_workaround_enabled
|
459
|
+
|
460
|
+
# NOTE: In the future this method will evolve to check for Ruby versions affected and not apply the workaround
|
461
|
+
# when it's not needed but currently all known Ruby versions are affected.
|
462
|
+
|
463
|
+
settings.profiling.advanced.dir_interruption_workaround_enabled
|
464
|
+
end
|
448
465
|
end
|
449
466
|
end
|
450
467
|
end
|
@@ -0,0 +1,410 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Datadog
|
4
|
+
module Profiling
|
5
|
+
# Monkey patches needed for profiler features and compatibility
|
6
|
+
module Ext
|
7
|
+
# All Ruby versions as of this writing have bugs in the dir class implementation, causing issues such as
|
8
|
+
# https://github.com/DataDog/dd-trace-rb/issues/3450 .
|
9
|
+
# See also https://bugs.ruby-lang.org/issues/20586 for more details.
|
10
|
+
#
|
11
|
+
# This monkey patch for the Ruby `Dir` class works around these bugs for affected Ruby versions by temporarily
|
12
|
+
# blocking the profiler from interrupting system calls.
|
13
|
+
#
|
14
|
+
# A lot of these APIs do very similar things -- they're provided by Ruby as helpers so users don't need to keep
|
15
|
+
# reimplementing them but share the same underlying buggy code. And so our monkey patches are a bit repetitive
|
16
|
+
# as well.
|
17
|
+
# We don't DRY out this file to have minimal overhead.
|
18
|
+
#
|
19
|
+
# These monkey patches are applied by the profiler when the "dir_interruption_workaround_enabled" setting is
|
20
|
+
# enabled. See the profiling settings for more detail.
|
21
|
+
module DirMonkeyPatches
|
22
|
+
def self.apply!
|
23
|
+
::Dir.singleton_class.prepend(Datadog::Profiling::Ext::DirClassMonkeyPatches)
|
24
|
+
::Dir.prepend(Datadog::Profiling::Ext::DirInstanceMonkeyPatches)
|
25
|
+
|
26
|
+
true
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
if RUBY_VERSION.start_with?('2.')
|
31
|
+
# Monkey patches for Dir.singleton_class (Ruby 2 version). See DirMonkeyPatches above for more details.
|
32
|
+
module DirClassMonkeyPatches
|
33
|
+
def [](*args, &block)
|
34
|
+
Datadog::Profiling::Collectors::CpuAndWallTimeWorker._native_hold_signals
|
35
|
+
super
|
36
|
+
ensure
|
37
|
+
Datadog::Profiling::Collectors::CpuAndWallTimeWorker._native_resume_signals
|
38
|
+
end
|
39
|
+
|
40
|
+
def children(*args, &block)
|
41
|
+
Datadog::Profiling::Collectors::CpuAndWallTimeWorker._native_hold_signals
|
42
|
+
super
|
43
|
+
ensure
|
44
|
+
Datadog::Profiling::Collectors::CpuAndWallTimeWorker._native_resume_signals
|
45
|
+
end
|
46
|
+
|
47
|
+
# NOTE: When wrapping methods that yield, it's OK if the `yield` raises an exception while signals are
|
48
|
+
# enabled. This is because:
|
49
|
+
# * We can call `_native_resume_signals` many times in a row, both because it's idempotent, as well as it's
|
50
|
+
# very low overhead (see benchmarks/profiler_hold_resume_interruptions.rb)
|
51
|
+
# * When an exception is being raised, the iteration will stop anyway, so there's no longer a concern of a
|
52
|
+
# signal causing Ruby to return an incorrect value
|
53
|
+
def each_child(*args, &block)
|
54
|
+
if block
|
55
|
+
begin
|
56
|
+
# <-- Begin critical region
|
57
|
+
Datadog::Profiling::Collectors::CpuAndWallTimeWorker._native_hold_signals
|
58
|
+
super do |entry_name|
|
59
|
+
Datadog::Profiling::Collectors::CpuAndWallTimeWorker._native_resume_signals
|
60
|
+
# <-- We're safe now while running customer code
|
61
|
+
yield entry_name
|
62
|
+
# <-- We'll go back to the Dir internals, critical region again
|
63
|
+
Datadog::Profiling::Collectors::CpuAndWallTimeWorker._native_hold_signals
|
64
|
+
end
|
65
|
+
ensure
|
66
|
+
# <-- End critical region
|
67
|
+
Datadog::Profiling::Collectors::CpuAndWallTimeWorker._native_resume_signals
|
68
|
+
end
|
69
|
+
else
|
70
|
+
# This returns an enumerator. We don't want/need to intercede here, the enumerator will eventually call the
|
71
|
+
# other branch once it gets going.
|
72
|
+
super
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
def empty?(*args, &block)
|
77
|
+
Datadog::Profiling::Collectors::CpuAndWallTimeWorker._native_hold_signals
|
78
|
+
super
|
79
|
+
ensure
|
80
|
+
Datadog::Profiling::Collectors::CpuAndWallTimeWorker._native_resume_signals
|
81
|
+
end
|
82
|
+
|
83
|
+
def entries(*args, &block)
|
84
|
+
Datadog::Profiling::Collectors::CpuAndWallTimeWorker._native_hold_signals
|
85
|
+
super
|
86
|
+
ensure
|
87
|
+
Datadog::Profiling::Collectors::CpuAndWallTimeWorker._native_resume_signals
|
88
|
+
end
|
89
|
+
|
90
|
+
# See note on methods that yield above.
|
91
|
+
def foreach(*args, &block)
|
92
|
+
if block
|
93
|
+
begin
|
94
|
+
# <-- Begin critical region
|
95
|
+
Datadog::Profiling::Collectors::CpuAndWallTimeWorker._native_hold_signals
|
96
|
+
super do |entry_name|
|
97
|
+
Datadog::Profiling::Collectors::CpuAndWallTimeWorker._native_resume_signals
|
98
|
+
# <-- We're safe now while running customer code
|
99
|
+
yield entry_name
|
100
|
+
# <-- We'll go back to the Dir internals, critical region again
|
101
|
+
Datadog::Profiling::Collectors::CpuAndWallTimeWorker._native_hold_signals
|
102
|
+
end
|
103
|
+
ensure
|
104
|
+
# <-- End critical region
|
105
|
+
Datadog::Profiling::Collectors::CpuAndWallTimeWorker._native_resume_signals
|
106
|
+
end
|
107
|
+
else
|
108
|
+
# This returns an enumerator. We don't want/need to intercede here, the enumerator will eventually call the
|
109
|
+
# other branch once it gets going.
|
110
|
+
super
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
# See note on methods that yield above.
|
115
|
+
def glob(*args, &block)
|
116
|
+
if block
|
117
|
+
begin
|
118
|
+
# <-- Begin critical region
|
119
|
+
Datadog::Profiling::Collectors::CpuAndWallTimeWorker._native_hold_signals
|
120
|
+
super do |entry_name|
|
121
|
+
Datadog::Profiling::Collectors::CpuAndWallTimeWorker._native_resume_signals
|
122
|
+
# <-- We're safe now while running customer code
|
123
|
+
yield entry_name
|
124
|
+
# <-- We'll go back to the Dir internals, critical region again
|
125
|
+
Datadog::Profiling::Collectors::CpuAndWallTimeWorker._native_hold_signals
|
126
|
+
end
|
127
|
+
ensure
|
128
|
+
# <-- End critical region
|
129
|
+
Datadog::Profiling::Collectors::CpuAndWallTimeWorker._native_resume_signals
|
130
|
+
end
|
131
|
+
else
|
132
|
+
begin
|
133
|
+
Datadog::Profiling::Collectors::CpuAndWallTimeWorker._native_hold_signals
|
134
|
+
super
|
135
|
+
ensure
|
136
|
+
Datadog::Profiling::Collectors::CpuAndWallTimeWorker._native_resume_signals
|
137
|
+
end
|
138
|
+
end
|
139
|
+
end
|
140
|
+
|
141
|
+
def home(*args, &block)
|
142
|
+
Datadog::Profiling::Collectors::CpuAndWallTimeWorker._native_hold_signals
|
143
|
+
super
|
144
|
+
ensure
|
145
|
+
Datadog::Profiling::Collectors::CpuAndWallTimeWorker._native_resume_signals
|
146
|
+
end
|
147
|
+
end
|
148
|
+
else
|
149
|
+
# Monkey patches for Dir.singleton_class (Ruby 3 version). See DirMonkeyPatches above for more details.
|
150
|
+
module DirClassMonkeyPatches
|
151
|
+
def [](*args, **kwargs, &block)
|
152
|
+
Datadog::Profiling::Collectors::CpuAndWallTimeWorker._native_hold_signals
|
153
|
+
super
|
154
|
+
ensure
|
155
|
+
Datadog::Profiling::Collectors::CpuAndWallTimeWorker._native_resume_signals
|
156
|
+
end
|
157
|
+
|
158
|
+
def children(*args, **kwargs, &block)
|
159
|
+
Datadog::Profiling::Collectors::CpuAndWallTimeWorker._native_hold_signals
|
160
|
+
super
|
161
|
+
ensure
|
162
|
+
Datadog::Profiling::Collectors::CpuAndWallTimeWorker._native_resume_signals
|
163
|
+
end
|
164
|
+
|
165
|
+
# See note on methods that yield above.
|
166
|
+
def each_child(*args, **kwargs, &block)
|
167
|
+
if block
|
168
|
+
begin
|
169
|
+
# <-- Begin critical region
|
170
|
+
Datadog::Profiling::Collectors::CpuAndWallTimeWorker._native_hold_signals
|
171
|
+
super do |entry_name|
|
172
|
+
Datadog::Profiling::Collectors::CpuAndWallTimeWorker._native_resume_signals
|
173
|
+
# <-- We're safe now while running customer code
|
174
|
+
yield entry_name
|
175
|
+
# <-- We'll go back to the Dir internals, critical region again
|
176
|
+
Datadog::Profiling::Collectors::CpuAndWallTimeWorker._native_hold_signals
|
177
|
+
end
|
178
|
+
ensure
|
179
|
+
# <-- End critical region
|
180
|
+
Datadog::Profiling::Collectors::CpuAndWallTimeWorker._native_resume_signals
|
181
|
+
end
|
182
|
+
else
|
183
|
+
# This returns an enumerator. We don't want/need to intercede here, the enumerator will eventually call the
|
184
|
+
# other branch once it gets going.
|
185
|
+
super
|
186
|
+
end
|
187
|
+
end
|
188
|
+
|
189
|
+
def empty?(*args, **kwargs, &block)
|
190
|
+
Datadog::Profiling::Collectors::CpuAndWallTimeWorker._native_hold_signals
|
191
|
+
super
|
192
|
+
ensure
|
193
|
+
Datadog::Profiling::Collectors::CpuAndWallTimeWorker._native_resume_signals
|
194
|
+
end
|
195
|
+
|
196
|
+
def entries(*args, **kwargs, &block)
|
197
|
+
Datadog::Profiling::Collectors::CpuAndWallTimeWorker._native_hold_signals
|
198
|
+
super
|
199
|
+
ensure
|
200
|
+
Datadog::Profiling::Collectors::CpuAndWallTimeWorker._native_resume_signals
|
201
|
+
end
|
202
|
+
|
203
|
+
# See note on methods that yield above.
|
204
|
+
def foreach(*args, **kwargs, &block)
|
205
|
+
if block
|
206
|
+
begin
|
207
|
+
# <-- Begin critical region
|
208
|
+
Datadog::Profiling::Collectors::CpuAndWallTimeWorker._native_hold_signals
|
209
|
+
super do |entry_name|
|
210
|
+
Datadog::Profiling::Collectors::CpuAndWallTimeWorker._native_resume_signals
|
211
|
+
# <-- We're safe now while running customer code
|
212
|
+
yield entry_name
|
213
|
+
# <-- We'll go back to the Dir internals, critical region again
|
214
|
+
Datadog::Profiling::Collectors::CpuAndWallTimeWorker._native_hold_signals
|
215
|
+
end
|
216
|
+
ensure
|
217
|
+
# <-- End critical region
|
218
|
+
Datadog::Profiling::Collectors::CpuAndWallTimeWorker._native_resume_signals
|
219
|
+
end
|
220
|
+
else
|
221
|
+
# This returns an enumerator. We don't want/need to intercede here, the enumerator will eventually call the
|
222
|
+
# other branch once it gets going.
|
223
|
+
super
|
224
|
+
end
|
225
|
+
end
|
226
|
+
|
227
|
+
# See note on methods that yield above.
|
228
|
+
def glob(*args, **kwargs, &block)
|
229
|
+
if block
|
230
|
+
begin
|
231
|
+
# <-- Begin critical region
|
232
|
+
Datadog::Profiling::Collectors::CpuAndWallTimeWorker._native_hold_signals
|
233
|
+
super do |entry_name|
|
234
|
+
Datadog::Profiling::Collectors::CpuAndWallTimeWorker._native_resume_signals
|
235
|
+
# <-- We're safe now while running customer code
|
236
|
+
yield entry_name
|
237
|
+
# <-- We'll go back to the Dir internals, critical region again
|
238
|
+
Datadog::Profiling::Collectors::CpuAndWallTimeWorker._native_hold_signals
|
239
|
+
end
|
240
|
+
ensure
|
241
|
+
# <-- End critical region
|
242
|
+
Datadog::Profiling::Collectors::CpuAndWallTimeWorker._native_resume_signals
|
243
|
+
end
|
244
|
+
else
|
245
|
+
begin
|
246
|
+
Datadog::Profiling::Collectors::CpuAndWallTimeWorker._native_hold_signals
|
247
|
+
super
|
248
|
+
ensure
|
249
|
+
Datadog::Profiling::Collectors::CpuAndWallTimeWorker._native_resume_signals
|
250
|
+
end
|
251
|
+
end
|
252
|
+
end
|
253
|
+
|
254
|
+
def home(*args, **kwargs, &block)
|
255
|
+
Datadog::Profiling::Collectors::CpuAndWallTimeWorker._native_hold_signals
|
256
|
+
super
|
257
|
+
ensure
|
258
|
+
Datadog::Profiling::Collectors::CpuAndWallTimeWorker._native_resume_signals
|
259
|
+
end
|
260
|
+
end
|
261
|
+
end
|
262
|
+
|
263
|
+
if RUBY_VERSION.start_with?('2.')
|
264
|
+
# Monkey patches for Dir (Ruby 2 version). See DirMonkeyPatches above for more details.
|
265
|
+
module DirInstanceMonkeyPatches
|
266
|
+
# See note on methods that yield above.
|
267
|
+
def each(*args, &block)
|
268
|
+
if block
|
269
|
+
begin
|
270
|
+
# <-- Begin critical region
|
271
|
+
Datadog::Profiling::Collectors::CpuAndWallTimeWorker._native_hold_signals
|
272
|
+
super do |entry_name|
|
273
|
+
Datadog::Profiling::Collectors::CpuAndWallTimeWorker._native_resume_signals
|
274
|
+
# <-- We're safe now while running customer code
|
275
|
+
yield entry_name
|
276
|
+
# <-- We'll go back to the Dir internals, critical region again
|
277
|
+
Datadog::Profiling::Collectors::CpuAndWallTimeWorker._native_hold_signals
|
278
|
+
end
|
279
|
+
ensure
|
280
|
+
Datadog::Profiling::Collectors::CpuAndWallTimeWorker._native_resume_signals # <-- End critical region
|
281
|
+
end
|
282
|
+
else
|
283
|
+
# This returns an enumerator. We don't want/need to intercede here, the enumerator will eventually call the
|
284
|
+
# other branch once it gets going.
|
285
|
+
super
|
286
|
+
end
|
287
|
+
end
|
288
|
+
|
289
|
+
unless RUBY_VERSION.start_with?('2.5.') # This is Ruby 2.6+
|
290
|
+
# See note on methods that yield above.
|
291
|
+
def each_child(*args, &block)
|
292
|
+
if block
|
293
|
+
begin
|
294
|
+
# <-- Begin critical region
|
295
|
+
Datadog::Profiling::Collectors::CpuAndWallTimeWorker._native_hold_signals
|
296
|
+
super do |entry_name|
|
297
|
+
Datadog::Profiling::Collectors::CpuAndWallTimeWorker._native_resume_signals
|
298
|
+
# <-- We're safe now while running customer code
|
299
|
+
yield entry_name
|
300
|
+
# <-- We'll go back to the Dir internals, critical region again
|
301
|
+
Datadog::Profiling::Collectors::CpuAndWallTimeWorker._native_hold_signals
|
302
|
+
end
|
303
|
+
ensure
|
304
|
+
# <-- End critical region
|
305
|
+
Datadog::Profiling::Collectors::CpuAndWallTimeWorker._native_resume_signals
|
306
|
+
end
|
307
|
+
else
|
308
|
+
# This returns an enumerator. We don't want/need to intercede here, the enumerator will eventually call the
|
309
|
+
# other branch once it gets going.
|
310
|
+
super
|
311
|
+
end
|
312
|
+
end
|
313
|
+
|
314
|
+
def children(*args, &block)
|
315
|
+
Datadog::Profiling::Collectors::CpuAndWallTimeWorker._native_hold_signals
|
316
|
+
super
|
317
|
+
ensure
|
318
|
+
Datadog::Profiling::Collectors::CpuAndWallTimeWorker._native_resume_signals
|
319
|
+
end
|
320
|
+
end
|
321
|
+
|
322
|
+
def tell(*args, &block)
|
323
|
+
Datadog::Profiling::Collectors::CpuAndWallTimeWorker._native_hold_signals
|
324
|
+
super
|
325
|
+
ensure
|
326
|
+
Datadog::Profiling::Collectors::CpuAndWallTimeWorker._native_resume_signals
|
327
|
+
end
|
328
|
+
|
329
|
+
def pos(*args, &block)
|
330
|
+
Datadog::Profiling::Collectors::CpuAndWallTimeWorker._native_hold_signals
|
331
|
+
super
|
332
|
+
ensure
|
333
|
+
Datadog::Profiling::Collectors::CpuAndWallTimeWorker._native_resume_signals
|
334
|
+
end
|
335
|
+
end
|
336
|
+
else
|
337
|
+
# Monkey patches for Dir (Ruby 3 version). See DirMonkeyPatches above for more details.
|
338
|
+
module DirInstanceMonkeyPatches
|
339
|
+
# See note on methods that yield above.
|
340
|
+
def each(*args, **kwargs, &block)
|
341
|
+
if block
|
342
|
+
begin
|
343
|
+
# <-- Begin critical region
|
344
|
+
Datadog::Profiling::Collectors::CpuAndWallTimeWorker._native_hold_signals
|
345
|
+
super do |entry_name|
|
346
|
+
Datadog::Profiling::Collectors::CpuAndWallTimeWorker._native_resume_signals
|
347
|
+
# <-- We're safe now while running customer code
|
348
|
+
yield entry_name
|
349
|
+
# <-- We'll go back to the Dir internals, critical region again
|
350
|
+
Datadog::Profiling::Collectors::CpuAndWallTimeWorker._native_hold_signals
|
351
|
+
end
|
352
|
+
ensure
|
353
|
+
Datadog::Profiling::Collectors::CpuAndWallTimeWorker._native_resume_signals # <-- End critical region
|
354
|
+
end
|
355
|
+
else
|
356
|
+
# This returns an enumerator. We don't want/need to intercede here, the enumerator will eventually call the
|
357
|
+
# other branch once it gets going.
|
358
|
+
super
|
359
|
+
end
|
360
|
+
end
|
361
|
+
|
362
|
+
# See note on methods that yield above.
|
363
|
+
def each_child(*args, **kwargs, &block)
|
364
|
+
if block
|
365
|
+
begin
|
366
|
+
# <-- Begin critical region
|
367
|
+
Datadog::Profiling::Collectors::CpuAndWallTimeWorker._native_hold_signals
|
368
|
+
super do |entry_name|
|
369
|
+
Datadog::Profiling::Collectors::CpuAndWallTimeWorker._native_resume_signals
|
370
|
+
# <-- We're safe now while running customer code
|
371
|
+
yield entry_name
|
372
|
+
# <-- We'll go back to the Dir internals, critical region again
|
373
|
+
Datadog::Profiling::Collectors::CpuAndWallTimeWorker._native_hold_signals
|
374
|
+
end
|
375
|
+
ensure
|
376
|
+
# <-- End critical region
|
377
|
+
Datadog::Profiling::Collectors::CpuAndWallTimeWorker._native_resume_signals
|
378
|
+
end
|
379
|
+
else
|
380
|
+
# This returns an enumerator. We don't want/need to intercede here, the enumerator will eventually call the
|
381
|
+
# other branch once it gets going.
|
382
|
+
super
|
383
|
+
end
|
384
|
+
end
|
385
|
+
|
386
|
+
def children(*args, **kwargs, &block)
|
387
|
+
Datadog::Profiling::Collectors::CpuAndWallTimeWorker._native_hold_signals
|
388
|
+
super
|
389
|
+
ensure
|
390
|
+
Datadog::Profiling::Collectors::CpuAndWallTimeWorker._native_resume_signals
|
391
|
+
end
|
392
|
+
|
393
|
+
def tell(*args, **kwargs, &block)
|
394
|
+
Datadog::Profiling::Collectors::CpuAndWallTimeWorker._native_hold_signals
|
395
|
+
super
|
396
|
+
ensure
|
397
|
+
Datadog::Profiling::Collectors::CpuAndWallTimeWorker._native_resume_signals
|
398
|
+
end
|
399
|
+
|
400
|
+
def pos(*args, **kwargs, &block)
|
401
|
+
Datadog::Profiling::Collectors::CpuAndWallTimeWorker._native_hold_signals
|
402
|
+
super
|
403
|
+
ensure
|
404
|
+
Datadog::Profiling::Collectors::CpuAndWallTimeWorker._native_resume_signals
|
405
|
+
end
|
406
|
+
end
|
407
|
+
end
|
408
|
+
end
|
409
|
+
end
|
410
|
+
end
|
data/lib/datadog/profiling.rb
CHANGED
@@ -136,6 +136,7 @@ module Datadog
|
|
136
136
|
return false unless supported?
|
137
137
|
|
138
138
|
require_relative 'profiling/ext/forking'
|
139
|
+
require_relative 'profiling/ext/dir_monkey_patches'
|
139
140
|
require_relative 'profiling/collectors/info'
|
140
141
|
require_relative 'profiling/collectors/code_provenance'
|
141
142
|
require_relative 'profiling/collectors/cpu_and_wall_time_worker'
|
@@ -9,6 +9,7 @@ module Datadog
|
|
9
9
|
# e.g. Env vars, default values, enums, etc...
|
10
10
|
module Ext
|
11
11
|
ENV_ENABLED = 'DD_TRACE_ENABLED'
|
12
|
+
ENV_OTEL_TRACES_EXPORTER = 'OTEL_TRACES_EXPORTER'
|
12
13
|
ENV_HEADER_TAGS = 'DD_TRACE_HEADER_TAGS'
|
13
14
|
ENV_TRACE_ID_128_BIT_GENERATION_ENABLED = 'DD_TRACE_128_BIT_TRACEID_GENERATION_ENABLED'
|
14
15
|
|
@@ -39,10 +40,14 @@ module Datadog
|
|
39
40
|
# W3C Trace Context
|
40
41
|
PROPAGATION_STYLE_TRACE_CONTEXT = 'tracecontext'
|
41
42
|
|
43
|
+
PROPAGATION_STYLE_SUPPORTED = [PROPAGATION_STYLE_DATADOG, PROPAGATION_STYLE_B3_MULTI_HEADER,
|
44
|
+
PROPAGATION_STYLE_B3_SINGLE_HEADER, PROPAGATION_STYLE_TRACE_CONTEXT].freeze
|
45
|
+
|
42
46
|
# Sets both extract and inject propagation style tho the provided value.
|
43
47
|
# Has lower precedence than `DD_TRACE_PROPAGATION_STYLE_INJECT` or
|
44
48
|
# `DD_TRACE_PROPAGATION_STYLE_EXTRACT`.
|
45
49
|
ENV_PROPAGATION_STYLE = 'DD_TRACE_PROPAGATION_STYLE'
|
50
|
+
ENV_OTEL_PROPAGATION_STYLE = 'OTEL_PROPAGATORS'
|
46
51
|
|
47
52
|
ENV_PROPAGATION_STYLE_INJECT = 'DD_TRACE_PROPAGATION_STYLE_INJECT'
|
48
53
|
|
@@ -68,6 +73,8 @@ module Datadog
|
|
68
73
|
ENV_SAMPLE_RATE = 'DD_TRACE_SAMPLE_RATE'
|
69
74
|
ENV_RATE_LIMIT = 'DD_TRACE_RATE_LIMIT'
|
70
75
|
ENV_RULES = 'DD_TRACE_SAMPLING_RULES'
|
76
|
+
ENV_OTEL_TRACES_SAMPLER = 'OTEL_TRACES_SAMPLER'
|
77
|
+
OTEL_TRACES_SAMPLER_ARG = 'OTEL_TRACES_SAMPLER_ARG'
|
71
78
|
|
72
79
|
# @public_api
|
73
80
|
module Span
|
@@ -13,6 +13,8 @@ module Datadog
|
|
13
13
|
# rubocop:disable Metrics/BlockLength
|
14
14
|
# rubocop:disable Metrics/MethodLength
|
15
15
|
# rubocop:disable Layout/LineLength
|
16
|
+
# rubocop:disable Metrics/CyclomaticComplexity
|
17
|
+
# rubocop:disable Metrics/PerceivedComplexity
|
16
18
|
module Settings
|
17
19
|
def self.extended(base)
|
18
20
|
base.class_eval do
|
@@ -89,7 +91,7 @@ module Datadog
|
|
89
91
|
# @return [Array<String>]
|
90
92
|
option :propagation_style do |o|
|
91
93
|
o.type :array
|
92
|
-
o.env Configuration::Ext::Distributed::ENV_PROPAGATION_STYLE
|
94
|
+
o.env [Configuration::Ext::Distributed::ENV_PROPAGATION_STYLE, Configuration::Ext::Distributed::ENV_OTEL_PROPAGATION_STYLE]
|
93
95
|
o.default []
|
94
96
|
o.after_set do |styles|
|
95
97
|
next if styles.empty?
|
@@ -97,6 +99,14 @@ module Datadog
|
|
97
99
|
# Make values case-insensitive
|
98
100
|
styles.map!(&:downcase)
|
99
101
|
|
102
|
+
styles.select! do |s|
|
103
|
+
if Configuration::Ext::Distributed::PROPAGATION_STYLE_SUPPORTED.include?(s)
|
104
|
+
true
|
105
|
+
else
|
106
|
+
Datadog.logger.warn("Unsupported propagation style: #{s}")
|
107
|
+
false
|
108
|
+
end
|
109
|
+
end
|
100
110
|
set_option(:propagation_style_extract, styles)
|
101
111
|
set_option(:propagation_style_inject, styles)
|
102
112
|
end
|
@@ -121,9 +131,23 @@ module Datadog
|
|
121
131
|
# @default `DD_TRACE_ENABLED` environment variable, otherwise `true`
|
122
132
|
# @return [Boolean]
|
123
133
|
option :enabled do |o|
|
124
|
-
o.env Tracing::Configuration::Ext::ENV_ENABLED
|
134
|
+
o.env [Tracing::Configuration::Ext::ENV_ENABLED, Tracing::Configuration::Ext::ENV_OTEL_TRACES_EXPORTER]
|
125
135
|
o.default true
|
126
136
|
o.type :bool
|
137
|
+
o.env_parser do |value|
|
138
|
+
value = value&.downcase
|
139
|
+
# Tracing is disabled when OTEL_TRACES_EXPORTER is none or
|
140
|
+
# DD_TRACE_ENABLED is 0 or false.
|
141
|
+
if ['none', 'false', '0'].include?(value)
|
142
|
+
false
|
143
|
+
# Tracing is enabled when DD_TRACE_ENABLED is true or 1
|
144
|
+
elsif ['true', '1'].include?(value)
|
145
|
+
true
|
146
|
+
else
|
147
|
+
Datadog.logger.warn("Unsupported value for exporting datadog traces: #{value}. Traces will be sent to Datadog.")
|
148
|
+
nil
|
149
|
+
end
|
150
|
+
end
|
127
151
|
end
|
128
152
|
|
129
153
|
# Comma-separated, case-insensitive list of header names that are reported in incoming and outgoing HTTP requests.
|
@@ -245,7 +269,30 @@ module Datadog
|
|
245
269
|
# @return [Float, nil]
|
246
270
|
option :default_rate do |o|
|
247
271
|
o.type :float, nilable: true
|
248
|
-
o.env Tracing::Configuration::Ext::Sampling::ENV_SAMPLE_RATE
|
272
|
+
o.env [Tracing::Configuration::Ext::Sampling::ENV_SAMPLE_RATE, Tracing::Configuration::Ext::Sampling::ENV_OTEL_TRACES_SAMPLER]
|
273
|
+
o.env_parser do |value|
|
274
|
+
# Parse the value as a float
|
275
|
+
next if value.nil?
|
276
|
+
|
277
|
+
value = value&.downcase
|
278
|
+
if ['always_on', 'always_off', 'traceidratio'].include?(value)
|
279
|
+
Datadog.logger.warn("The value '#{value}' is not yet supported. 'parentbased_#{value}' will be used instead.")
|
280
|
+
value = "parentbased_#{value}"
|
281
|
+
end
|
282
|
+
# OTEL_TRACES_SAMPLER can be set to always_on, always_off, traceidratio, and/or parentbased value.
|
283
|
+
# These values are mapped to a sample rate.
|
284
|
+
# DD_TRACE_SAMPLE_RATE sets the sample rate to float.
|
285
|
+
case value
|
286
|
+
when 'parentbased_always_on'
|
287
|
+
1.0
|
288
|
+
when 'parentbased_always_off'
|
289
|
+
0.0
|
290
|
+
when 'parentbased_traceidratio'
|
291
|
+
ENV.fetch(Tracing::Configuration::Ext::Sampling::OTEL_TRACES_SAMPLER_ARG, 1.0).to_f
|
292
|
+
else
|
293
|
+
value.to_f
|
294
|
+
end
|
295
|
+
end
|
249
296
|
end
|
250
297
|
|
251
298
|
# Rate limit for number of spans per second.
|
@@ -417,6 +464,8 @@ module Datadog
|
|
417
464
|
# rubocop:enable Metrics/BlockLength
|
418
465
|
# rubocop:enable Metrics/MethodLength
|
419
466
|
# rubocop:enable Layout/LineLength
|
467
|
+
# rubocop:enable Metrics/CyclomaticComplexity
|
468
|
+
# rubocop:enable Metrics/PerceivedComplexity
|
420
469
|
end
|
421
470
|
end
|
422
471
|
end
|
@@ -34,7 +34,7 @@ module Datadog
|
|
34
34
|
Tracing::Metadata::Ext::AppTypes::TYPE_WEB
|
35
35
|
end
|
36
36
|
|
37
|
-
def
|
37
|
+
def on_start(span, _event, _id, payload)
|
38
38
|
channel = payload[:broadcasting] # Channel has high cardinality
|
39
39
|
span.service = configuration[:service_name] if configuration[:service_name]
|
40
40
|
span.type = span_type
|
@@ -33,7 +33,7 @@ module Datadog
|
|
33
33
|
Tracing::Metadata::Ext::AppTypes::TYPE_WEB
|
34
34
|
end
|
35
35
|
|
36
|
-
def
|
36
|
+
def on_start(span, _event, _id, payload)
|
37
37
|
channel_class = payload[:channel_class]
|
38
38
|
|
39
39
|
span.service = configuration[:service_name] if configuration[:service_name]
|