datadog 2.2.0 → 2.4.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 +87 -2
- data/ext/datadog_profiling_loader/datadog_profiling_loader.c +9 -1
- data/ext/datadog_profiling_loader/extconf.rb +14 -26
- data/ext/datadog_profiling_native_extension/clock_id.h +1 -0
- data/ext/datadog_profiling_native_extension/clock_id_from_pthread.c +1 -2
- data/ext/datadog_profiling_native_extension/clock_id_noop.c +1 -2
- data/ext/datadog_profiling_native_extension/collectors_cpu_and_wall_time_worker.c +257 -69
- data/ext/datadog_profiling_native_extension/collectors_discrete_dynamic_sampler.c +53 -28
- data/ext/datadog_profiling_native_extension/collectors_discrete_dynamic_sampler.h +34 -4
- data/ext/datadog_profiling_native_extension/collectors_idle_sampling_helper.c +4 -0
- data/ext/datadog_profiling_native_extension/collectors_stack.c +136 -81
- data/ext/datadog_profiling_native_extension/collectors_stack.h +2 -2
- data/ext/datadog_profiling_native_extension/collectors_thread_context.c +661 -48
- data/ext/datadog_profiling_native_extension/collectors_thread_context.h +10 -1
- data/ext/datadog_profiling_native_extension/datadog_ruby_common.c +83 -0
- data/ext/datadog_profiling_native_extension/datadog_ruby_common.h +53 -0
- data/ext/datadog_profiling_native_extension/extconf.rb +91 -69
- data/ext/datadog_profiling_native_extension/gvl_profiling_helper.c +50 -0
- data/ext/datadog_profiling_native_extension/gvl_profiling_helper.h +75 -0
- data/ext/datadog_profiling_native_extension/heap_recorder.c +54 -12
- data/ext/datadog_profiling_native_extension/heap_recorder.h +3 -1
- data/ext/datadog_profiling_native_extension/helpers.h +6 -17
- data/ext/datadog_profiling_native_extension/http_transport.c +41 -9
- data/ext/datadog_profiling_native_extension/libdatadog_helpers.c +0 -86
- data/ext/datadog_profiling_native_extension/libdatadog_helpers.h +2 -23
- data/ext/datadog_profiling_native_extension/native_extension_helpers.rb +61 -172
- data/ext/datadog_profiling_native_extension/private_vm_api_access.c +116 -139
- data/ext/datadog_profiling_native_extension/private_vm_api_access.h +20 -11
- data/ext/datadog_profiling_native_extension/profiling.c +1 -3
- data/ext/datadog_profiling_native_extension/ruby_helpers.c +0 -33
- data/ext/datadog_profiling_native_extension/ruby_helpers.h +1 -26
- data/ext/datadog_profiling_native_extension/setup_signal_handler.h +1 -0
- data/ext/datadog_profiling_native_extension/stack_recorder.c +14 -2
- data/ext/datadog_profiling_native_extension/stack_recorder.h +2 -0
- data/ext/datadog_profiling_native_extension/time_helpers.c +0 -15
- data/ext/datadog_profiling_native_extension/time_helpers.h +36 -6
- data/ext/{datadog_profiling_native_extension → libdatadog_api}/crashtracker.c +37 -22
- data/ext/libdatadog_api/datadog_ruby_common.c +83 -0
- data/ext/libdatadog_api/datadog_ruby_common.h +53 -0
- data/ext/libdatadog_api/extconf.rb +108 -0
- data/ext/libdatadog_api/macos_development.md +26 -0
- data/ext/libdatadog_extconf_helpers.rb +130 -0
- data/lib/datadog/appsec/assets/waf_rules/recommended.json +2184 -108
- data/lib/datadog/appsec/assets/waf_rules/strict.json +1430 -2
- data/lib/datadog/appsec/component.rb +29 -8
- data/lib/datadog/appsec/configuration/settings.rb +2 -2
- data/lib/datadog/appsec/contrib/devise/patcher/authenticatable_patch.rb +1 -0
- data/lib/datadog/appsec/contrib/devise/patcher/rememberable_patch.rb +21 -0
- data/lib/datadog/appsec/contrib/devise/patcher.rb +12 -2
- data/lib/datadog/appsec/contrib/graphql/appsec_trace.rb +35 -0
- data/lib/datadog/appsec/contrib/graphql/gateway/multiplex.rb +109 -0
- data/lib/datadog/appsec/contrib/graphql/gateway/watcher.rb +71 -0
- data/lib/datadog/appsec/contrib/graphql/integration.rb +54 -0
- data/lib/datadog/appsec/contrib/graphql/patcher.rb +37 -0
- data/lib/datadog/appsec/contrib/graphql/reactive/multiplex.rb +59 -0
- data/lib/datadog/appsec/contrib/rack/gateway/request.rb +3 -6
- data/lib/datadog/appsec/event.rb +1 -1
- data/lib/datadog/appsec/processor/actions.rb +1 -1
- data/lib/datadog/appsec/processor/rule_loader.rb +3 -1
- data/lib/datadog/appsec/processor/rule_merger.rb +33 -15
- data/lib/datadog/appsec/processor.rb +36 -37
- data/lib/datadog/appsec/rate_limiter.rb +25 -40
- data/lib/datadog/appsec/remote.rb +7 -3
- data/lib/datadog/appsec/response.rb +15 -1
- data/lib/datadog/appsec.rb +3 -2
- data/lib/datadog/core/configuration/components.rb +18 -15
- data/lib/datadog/core/configuration/settings.rb +135 -9
- data/lib/datadog/core/crashtracking/agent_base_url.rb +21 -0
- data/lib/datadog/core/crashtracking/component.rb +111 -0
- data/lib/datadog/core/crashtracking/tag_builder.rb +39 -0
- data/lib/datadog/core/diagnostics/environment_logger.rb +8 -11
- data/lib/datadog/core/environment/execution.rb +5 -5
- data/lib/datadog/core/metrics/client.rb +7 -0
- data/lib/datadog/core/rate_limiter.rb +183 -0
- data/lib/datadog/core/remote/client/capabilities.rb +4 -3
- data/lib/datadog/core/remote/component.rb +4 -2
- data/lib/datadog/core/remote/negotiation.rb +4 -4
- data/lib/datadog/core/remote/tie.rb +2 -0
- data/lib/datadog/core/runtime/metrics.rb +1 -1
- data/lib/datadog/core/telemetry/component.rb +51 -2
- data/lib/datadog/core/telemetry/emitter.rb +9 -11
- data/lib/datadog/core/telemetry/event.rb +37 -1
- data/lib/datadog/core/telemetry/ext.rb +1 -0
- data/lib/datadog/core/telemetry/http/adapters/net.rb +10 -12
- data/lib/datadog/core/telemetry/http/ext.rb +3 -0
- data/lib/datadog/core/telemetry/http/transport.rb +38 -9
- data/lib/datadog/core/telemetry/logger.rb +51 -0
- data/lib/datadog/core/telemetry/logging.rb +71 -0
- data/lib/datadog/core/telemetry/request.rb +13 -1
- data/lib/datadog/core/utils/at_fork_monkey_patch.rb +102 -0
- data/lib/datadog/core/utils/time.rb +12 -0
- data/lib/datadog/di/code_tracker.rb +168 -0
- data/lib/datadog/di/configuration/settings.rb +163 -0
- data/lib/datadog/di/configuration.rb +11 -0
- data/lib/datadog/di/error.rb +31 -0
- data/lib/datadog/di/extensions.rb +16 -0
- data/lib/datadog/di/probe.rb +133 -0
- data/lib/datadog/di/probe_builder.rb +41 -0
- data/lib/datadog/di/redactor.rb +188 -0
- data/lib/datadog/di/serializer.rb +193 -0
- data/lib/datadog/di.rb +14 -0
- data/lib/datadog/kit/appsec/events.rb +2 -4
- data/lib/datadog/opentelemetry/sdk/propagator.rb +2 -0
- data/lib/datadog/opentelemetry/sdk/span_processor.rb +10 -0
- data/lib/datadog/opentelemetry/sdk/trace/span.rb +23 -0
- data/lib/datadog/profiling/collectors/code_provenance.rb +7 -7
- data/lib/datadog/profiling/collectors/cpu_and_wall_time_worker.rb +28 -26
- data/lib/datadog/profiling/collectors/idle_sampling_helper.rb +11 -13
- data/lib/datadog/profiling/collectors/info.rb +15 -6
- data/lib/datadog/profiling/collectors/thread_context.rb +30 -2
- data/lib/datadog/profiling/component.rb +89 -95
- data/lib/datadog/profiling/exporter.rb +3 -3
- data/lib/datadog/profiling/ext/dir_monkey_patches.rb +3 -3
- data/lib/datadog/profiling/ext.rb +21 -21
- data/lib/datadog/profiling/flush.rb +1 -1
- data/lib/datadog/profiling/http_transport.rb +14 -7
- data/lib/datadog/profiling/load_native_extension.rb +5 -5
- data/lib/datadog/profiling/preload.rb +1 -1
- data/lib/datadog/profiling/profiler.rb +5 -8
- data/lib/datadog/profiling/scheduler.rb +33 -25
- data/lib/datadog/profiling/stack_recorder.rb +3 -0
- data/lib/datadog/profiling/tag_builder.rb +2 -2
- data/lib/datadog/profiling/tasks/exec.rb +5 -5
- data/lib/datadog/profiling/tasks/setup.rb +16 -35
- data/lib/datadog/profiling.rb +4 -5
- data/lib/datadog/single_step_instrument.rb +12 -0
- data/lib/datadog/tracing/contrib/action_cable/instrumentation.rb +8 -12
- data/lib/datadog/tracing/contrib/action_pack/action_controller/instrumentation.rb +5 -0
- data/lib/datadog/tracing/contrib/action_pack/action_dispatch/instrumentation.rb +78 -0
- data/lib/datadog/tracing/contrib/action_pack/action_dispatch/patcher.rb +33 -0
- data/lib/datadog/tracing/contrib/action_pack/patcher.rb +2 -0
- data/lib/datadog/tracing/contrib/active_record/configuration/resolver.rb +4 -0
- data/lib/datadog/tracing/contrib/active_record/events/instantiation.rb +3 -1
- data/lib/datadog/tracing/contrib/active_record/events/sql.rb +4 -1
- data/lib/datadog/tracing/contrib/active_support/cache/events/cache.rb +5 -1
- data/lib/datadog/tracing/contrib/aws/instrumentation.rb +5 -0
- data/lib/datadog/tracing/contrib/elasticsearch/patcher.rb +6 -1
- data/lib/datadog/tracing/contrib/ext.rb +14 -0
- data/lib/datadog/tracing/contrib/faraday/middleware.rb +9 -0
- data/lib/datadog/tracing/contrib/grape/endpoint.rb +19 -0
- data/lib/datadog/tracing/contrib/graphql/patcher.rb +9 -12
- data/lib/datadog/tracing/contrib/graphql/trace_patcher.rb +3 -3
- data/lib/datadog/tracing/contrib/graphql/tracing_patcher.rb +3 -3
- data/lib/datadog/tracing/contrib/graphql/unified_trace.rb +14 -10
- data/lib/datadog/tracing/contrib/graphql/unified_trace_patcher.rb +10 -4
- data/lib/datadog/tracing/contrib/http/instrumentation.rb +18 -15
- data/lib/datadog/tracing/contrib/httpclient/instrumentation.rb +6 -5
- data/lib/datadog/tracing/contrib/httpclient/patcher.rb +1 -14
- data/lib/datadog/tracing/contrib/httprb/instrumentation.rb +5 -0
- data/lib/datadog/tracing/contrib/httprb/patcher.rb +1 -14
- data/lib/datadog/tracing/contrib/lograge/patcher.rb +15 -0
- data/lib/datadog/tracing/contrib/mongodb/subscribers.rb +2 -0
- data/lib/datadog/tracing/contrib/mysql2/configuration/settings.rb +5 -0
- data/lib/datadog/tracing/contrib/mysql2/instrumentation.rb +17 -13
- data/lib/datadog/tracing/contrib/opensearch/patcher.rb +13 -6
- data/lib/datadog/tracing/contrib/patcher.rb +2 -1
- data/lib/datadog/tracing/contrib/pg/configuration/settings.rb +5 -0
- data/lib/datadog/tracing/contrib/pg/instrumentation.rb +4 -1
- data/lib/datadog/tracing/contrib/presto/patcher.rb +1 -13
- data/lib/datadog/tracing/contrib/propagation/sql_comment/ext.rb +28 -0
- data/lib/datadog/tracing/contrib/propagation/sql_comment/mode.rb +5 -1
- data/lib/datadog/tracing/contrib/propagation/sql_comment.rb +22 -10
- data/lib/datadog/tracing/contrib/rack/middlewares.rb +27 -0
- data/lib/datadog/tracing/contrib/redis/tags.rb +4 -0
- data/lib/datadog/tracing/contrib/sinatra/tracer.rb +4 -0
- data/lib/datadog/tracing/contrib/stripe/request.rb +3 -2
- data/lib/datadog/tracing/contrib/trilogy/configuration/settings.rb +5 -0
- data/lib/datadog/tracing/contrib/trilogy/instrumentation.rb +4 -1
- data/lib/datadog/tracing/diagnostics/environment_logger.rb +14 -16
- data/lib/datadog/tracing/distributed/propagation.rb +7 -0
- data/lib/datadog/tracing/metadata/errors.rb +9 -1
- data/lib/datadog/tracing/metadata/ext.rb +6 -0
- data/lib/datadog/tracing/pipeline/span_filter.rb +2 -2
- data/lib/datadog/tracing/remote.rb +5 -2
- data/lib/datadog/tracing/sampling/matcher.rb +6 -1
- data/lib/datadog/tracing/sampling/rate_sampler.rb +1 -1
- data/lib/datadog/tracing/sampling/rule.rb +2 -0
- data/lib/datadog/tracing/sampling/rule_sampler.rb +9 -5
- data/lib/datadog/tracing/sampling/span/ext.rb +1 -1
- data/lib/datadog/tracing/sampling/span/rule.rb +2 -2
- data/lib/datadog/tracing/span.rb +9 -2
- data/lib/datadog/tracing/span_event.rb +41 -0
- data/lib/datadog/tracing/span_operation.rb +6 -2
- data/lib/datadog/tracing/trace_operation.rb +26 -2
- data/lib/datadog/tracing/tracer.rb +14 -12
- data/lib/datadog/tracing/transport/http/client.rb +1 -0
- data/lib/datadog/tracing/transport/io/client.rb +1 -0
- data/lib/datadog/tracing/transport/serializable_trace.rb +3 -0
- data/lib/datadog/tracing/workers/trace_writer.rb +1 -1
- data/lib/datadog/tracing/workers.rb +1 -1
- data/lib/datadog/version.rb +1 -1
- metadata +46 -11
- data/lib/datadog/profiling/crashtracker.rb +0 -91
- data/lib/datadog/profiling/ext/forking.rb +0 -98
- data/lib/datadog/tracing/sampling/rate_limiter.rb +0 -185
@@ -8,7 +8,7 @@ module Datadog
|
|
8
8
|
# * Code Hotspots panel in the trace viewer, as well as scoping a profile down to a span
|
9
9
|
# * Endpoint aggregation in the profiler UX, including normalization (resource per endpoint call)
|
10
10
|
def self.build_profiler_component(settings:, agent_settings:, optional_tracer:) # rubocop:disable Metrics/MethodLength
|
11
|
-
return [nil, {
|
11
|
+
return [nil, {profiling_enabled: false}] unless settings.profiling.enabled
|
12
12
|
|
13
13
|
# Workaround for weird dependency direction: the Core::Configuration::Components class currently has a
|
14
14
|
# dependency on individual products, in this case the Profiler.
|
@@ -27,9 +27,9 @@ module Datadog
|
|
27
27
|
# On the other hand, if datadog/core is loaded by a different product and no general `require 'datadog'` is
|
28
28
|
# done, then profiling may not be loaded, and thus to avoid this issue we do a require here (which is a
|
29
29
|
# no-op if profiling is already loaded).
|
30
|
-
require_relative
|
30
|
+
require_relative "../profiling"
|
31
31
|
|
32
|
-
return [nil, {
|
32
|
+
return [nil, {profiling_enabled: false}] unless Profiling.supported?
|
33
33
|
|
34
34
|
# Activate forking extensions
|
35
35
|
Profiling::Tasks::Setup.new.run
|
@@ -47,7 +47,7 @@ module Datadog
|
|
47
47
|
upload_period_seconds = [60, settings.profiling.advanced.upload_period_seconds].max
|
48
48
|
|
49
49
|
recorder = Datadog::Profiling::StackRecorder.new(
|
50
|
-
cpu_time_enabled: RUBY_PLATFORM.include?(
|
50
|
+
cpu_time_enabled: RUBY_PLATFORM.include?("linux"), # Only supported on Linux currently
|
51
51
|
alloc_samples_enabled: allocation_profiling_enabled,
|
52
52
|
heap_samples_enabled: heap_profiling_enabled,
|
53
53
|
heap_size_enabled: heap_size_profiling_enabled,
|
@@ -61,6 +61,8 @@ module Datadog
|
|
61
61
|
thread_context_collector: thread_context_collector,
|
62
62
|
dynamic_sampling_rate_overhead_target_percentage: overhead_target_percentage,
|
63
63
|
allocation_profiling_enabled: allocation_profiling_enabled,
|
64
|
+
allocation_counting_enabled: settings.profiling.advanced.allocation_counting_enabled,
|
65
|
+
gvl_profiling_enabled: enable_gvl_profiling?(settings),
|
64
66
|
)
|
65
67
|
|
66
68
|
internal_metadata = {
|
@@ -72,14 +74,13 @@ module Datadog
|
|
72
74
|
exporter = build_profiler_exporter(settings, recorder, worker, internal_metadata: internal_metadata)
|
73
75
|
transport = build_profiler_transport(settings, agent_settings)
|
74
76
|
scheduler = Profiling::Scheduler.new(exporter: exporter, transport: transport, interval: upload_period_seconds)
|
75
|
-
|
76
|
-
profiler = Profiling::Profiler.new(worker: worker, scheduler: scheduler, optional_crashtracker: crashtracker)
|
77
|
+
profiler = Profiling::Profiler.new(worker: worker, scheduler: scheduler)
|
77
78
|
|
78
79
|
if dir_interruption_workaround_enabled?(settings, no_signals_workaround_enabled)
|
79
80
|
Datadog::Profiling::Ext::DirMonkeyPatches.apply!
|
80
81
|
end
|
81
82
|
|
82
|
-
[profiler, {
|
83
|
+
[profiler, {profiling_enabled: true}]
|
83
84
|
end
|
84
85
|
|
85
86
|
private_class_method def self.build_thread_context_collector(settings, recorder, optional_tracer, timeline_enabled)
|
@@ -89,6 +90,8 @@ module Datadog
|
|
89
90
|
tracer: optional_tracer,
|
90
91
|
endpoint_collection_enabled: settings.profiling.advanced.endpoint.collection.enabled,
|
91
92
|
timeline_enabled: timeline_enabled,
|
93
|
+
waiting_for_gvl_threshold_ns: settings.profiling.advanced.waiting_for_gvl_threshold_ns,
|
94
|
+
otel_context_enabled: settings.profiling.advanced.preview_otel_context_enabled,
|
92
95
|
)
|
93
96
|
end
|
94
97
|
|
@@ -116,28 +119,6 @@ module Datadog
|
|
116
119
|
)
|
117
120
|
end
|
118
121
|
|
119
|
-
private_class_method def self.build_crashtracker(settings, transport)
|
120
|
-
return unless settings.profiling.advanced.experimental_crash_tracking_enabled
|
121
|
-
|
122
|
-
# By default, the transport is an instance of HttpTransport, which validates the configuration and makes
|
123
|
-
# it available for us to use here.
|
124
|
-
# But we support overriding the transport with a user-specific one, which may e.g. write stuff to a file,
|
125
|
-
# and thus can't really provide a valid configuration to talk to a Datadog agent. Thus, in this situation,
|
126
|
-
# we can't use the crashtracker, even if enabled.
|
127
|
-
unless transport.respond_to?(:exporter_configuration)
|
128
|
-
Datadog.logger.warn(
|
129
|
-
'Cannot enable profiling crash tracking as a custom settings.profiling.exporter.transport is configured'
|
130
|
-
)
|
131
|
-
return
|
132
|
-
end
|
133
|
-
|
134
|
-
Datadog::Profiling::Crashtracker.new(
|
135
|
-
exporter_configuration: transport.exporter_configuration,
|
136
|
-
tags: Datadog::Profiling::TagBuilder.call(settings: settings),
|
137
|
-
upload_timeout_seconds: settings.profiling.upload.timeout_seconds,
|
138
|
-
)
|
139
|
-
end
|
140
|
-
|
141
122
|
private_class_method def self.enable_gc_profiling?(settings)
|
142
123
|
return false unless settings.profiling.advanced.gc_enabled
|
143
124
|
|
@@ -146,19 +127,19 @@ module Datadog
|
|
146
127
|
# that causes a segmentation fault during garbage collection of Ractors
|
147
128
|
# (https://bugs.ruby-lang.org/issues/18464). We don't allow enabling gc profiling on such Rubies.
|
148
129
|
# This bug is fixed on Ruby versions 3.1.4, 3.2.3 and 3.3.0.
|
149
|
-
if RUBY_VERSION.start_with?(
|
150
|
-
(RUBY_VERSION.start_with?(
|
151
|
-
(RUBY_VERSION.start_with?(
|
130
|
+
if RUBY_VERSION.start_with?("3.0.") ||
|
131
|
+
(RUBY_VERSION.start_with?("3.1.") && RUBY_VERSION < "3.1.4") ||
|
132
|
+
(RUBY_VERSION.start_with?("3.2.") && RUBY_VERSION < "3.2.3")
|
152
133
|
Datadog.logger.warn(
|
153
|
-
"Current Ruby version (#{RUBY_VERSION}) has a VM bug where enabling GC profiling would cause "\
|
154
|
-
|
134
|
+
"Current Ruby version (#{RUBY_VERSION}) has a VM bug where enabling GC profiling would cause " \
|
135
|
+
"crashes (https://bugs.ruby-lang.org/issues/18464). GC profiling has been disabled."
|
155
136
|
)
|
156
137
|
return false
|
157
|
-
elsif RUBY_VERSION.start_with?(
|
138
|
+
elsif RUBY_VERSION.start_with?("3.")
|
158
139
|
Datadog.logger.debug(
|
159
|
-
|
160
|
-
|
161
|
-
|
140
|
+
"In all known versions of Ruby 3.x, using Ractors may result in GC profiling unexpectedly " \
|
141
|
+
"stopping (https://bugs.ruby-lang.org/issues/19112). Note that this stop has no impact in your " \
|
142
|
+
"application stability or performance. This does not happen if Ractors are not used."
|
162
143
|
)
|
163
144
|
end
|
164
145
|
|
@@ -182,11 +163,11 @@ module Datadog
|
|
182
163
|
# Ruby 3.2.0 to 3.2.2 have a bug in the newobj tracepoint (https://bugs.ruby-lang.org/issues/19482,
|
183
164
|
# https://github.com/ruby/ruby/pull/7464) that makes this crash in any configuration. This bug is
|
184
165
|
# fixed on Ruby versions 3.2.3 and 3.3.0.
|
185
|
-
if RUBY_VERSION.start_with?(
|
166
|
+
if RUBY_VERSION.start_with?("3.2.") && RUBY_VERSION < "3.2.3"
|
186
167
|
Datadog.logger.warn(
|
187
|
-
|
188
|
-
|
189
|
-
|
168
|
+
"Allocation profiling is not supported in Ruby versions 3.2.0, 3.2.1 and 3.2.2 and will be forcibly " \
|
169
|
+
"disabled. This is due to a VM bug that can lead to crashes (https://bugs.ruby-lang.org/issues/19482). " \
|
170
|
+
"Other Ruby versions do not suffer from this issue."
|
190
171
|
)
|
191
172
|
return false
|
192
173
|
end
|
@@ -196,26 +177,26 @@ module Datadog
|
|
196
177
|
# that causes a segmentation fault during garbage collection of Ractors
|
197
178
|
# (https://bugs.ruby-lang.org/issues/18464). We don't recommend using this feature on such Rubies.
|
198
179
|
# This bug is fixed on Ruby versions 3.1.4, 3.2.3 and 3.3.0.
|
199
|
-
if RUBY_VERSION.start_with?(
|
200
|
-
(RUBY_VERSION.start_with?(
|
201
|
-
(RUBY_VERSION.start_with?(
|
180
|
+
if RUBY_VERSION.start_with?("3.0.") ||
|
181
|
+
(RUBY_VERSION.start_with?("3.1.") && RUBY_VERSION < "3.1.4") ||
|
182
|
+
(RUBY_VERSION.start_with?("3.2.") && RUBY_VERSION < "3.2.3")
|
202
183
|
Datadog.logger.warn(
|
203
|
-
"Current Ruby version (#{RUBY_VERSION}) has a VM bug where enabling allocation profiling while using "\
|
204
|
-
|
205
|
-
|
184
|
+
"Current Ruby version (#{RUBY_VERSION}) has a VM bug where enabling allocation profiling while using " \
|
185
|
+
"Ractors may cause unexpected issues, including crashes (https://bugs.ruby-lang.org/issues/18464). " \
|
186
|
+
"This does not happen if Ractors are not used."
|
206
187
|
)
|
207
188
|
# ANNOYANCE - Only with Ractors
|
208
189
|
# On all known versions of Ruby 3.x, due to https://bugs.ruby-lang.org/issues/19112, when a ractor gets
|
209
190
|
# garbage collected, Ruby will disable all active tracepoints, which this feature internally relies on.
|
210
|
-
elsif RUBY_VERSION.start_with?(
|
191
|
+
elsif RUBY_VERSION.start_with?("3.")
|
211
192
|
Datadog.logger.warn(
|
212
|
-
|
213
|
-
|
214
|
-
|
193
|
+
"In all known versions of Ruby 3.x, using Ractors may result in allocation profiling unexpectedly " \
|
194
|
+
"stopping (https://bugs.ruby-lang.org/issues/19112). Note that this stop has no impact in your " \
|
195
|
+
"application stability or performance. This does not happen if Ractors are not used."
|
215
196
|
)
|
216
197
|
end
|
217
198
|
|
218
|
-
Datadog.logger.debug(
|
199
|
+
Datadog.logger.debug("Enabled allocation profiling")
|
219
200
|
|
220
201
|
true
|
221
202
|
end
|
@@ -225,33 +206,33 @@ module Datadog
|
|
225
206
|
|
226
207
|
return false unless heap_profiling_enabled
|
227
208
|
|
228
|
-
if RUBY_VERSION.start_with?(
|
209
|
+
if RUBY_VERSION.start_with?("2.") && RUBY_VERSION < "2.7"
|
229
210
|
Datadog.logger.warn(
|
230
|
-
|
231
|
-
|
211
|
+
"Heap profiling currently relies on features introduced in Ruby 2.7 and will be forcibly disabled. " \
|
212
|
+
"Please upgrade to Ruby >= 2.7 in order to use this feature."
|
232
213
|
)
|
233
214
|
return false
|
234
215
|
end
|
235
216
|
|
236
|
-
if RUBY_VERSION <
|
217
|
+
if RUBY_VERSION < "3.1"
|
237
218
|
Datadog.logger.debug(
|
238
219
|
"Current Ruby version (#{RUBY_VERSION}) supports forced object recycling which has a bug that the " \
|
239
|
-
|
220
|
+
"heap profiler is forced to work around to remain accurate. This workaround requires force-setting " \
|
240
221
|
"the SEEN_OBJ_ID flag on objects that should have it but don't. Full details can be found in " \
|
241
|
-
|
242
|
-
|
243
|
-
|
222
|
+
"https://github.com/DataDog/dd-trace-rb/pull/3360. This workaround should be safe but can be " \
|
223
|
+
"bypassed by disabling the heap profiler or upgrading to Ruby >= 3.1 where forced object recycling " \
|
224
|
+
"was completely removed (https://bugs.ruby-lang.org/issues/18290)."
|
244
225
|
)
|
245
226
|
end
|
246
227
|
|
247
228
|
unless allocation_profiling_enabled
|
248
229
|
raise ArgumentError,
|
249
|
-
|
230
|
+
"Heap profiling requires allocation profiling to be enabled"
|
250
231
|
end
|
251
232
|
|
252
233
|
Datadog.logger.warn(
|
253
234
|
"Enabled experimental heap profiling: heap_sample_rate=#{heap_sample_rate}. This is experimental, not " \
|
254
|
-
|
235
|
+
"recommended, and will increase overhead!"
|
255
236
|
)
|
256
237
|
|
257
238
|
true
|
@@ -263,7 +244,7 @@ module Datadog
|
|
263
244
|
return false unless heap_profiling_enabled && heap_size_profiling_enabled
|
264
245
|
|
265
246
|
Datadog.logger.warn(
|
266
|
-
|
247
|
+
"Enabled experimental heap size profiling. This is experimental, not recommended, and will increase overhead!"
|
267
248
|
)
|
268
249
|
|
269
250
|
true
|
@@ -271,12 +252,13 @@ module Datadog
|
|
271
252
|
|
272
253
|
private_class_method def self.no_signals_workaround_enabled?(settings) # rubocop:disable Metrics/MethodLength
|
273
254
|
setting_value = settings.profiling.advanced.no_signals_workaround_enabled
|
274
|
-
legacy_ruby_that_should_use_workaround = RUBY_VERSION.start_with?(
|
255
|
+
legacy_ruby_that_should_use_workaround = RUBY_VERSION.start_with?("2.5.")
|
275
256
|
|
276
257
|
unless [true, false, :auto].include?(setting_value)
|
258
|
+
# TODO: Replace with a warning instead.
|
277
259
|
Datadog.logger.error(
|
278
260
|
"Ignoring invalid value for profiling no_signals_workaround_enabled setting: #{setting_value.inspect}. " \
|
279
|
-
|
261
|
+
"Valid options are `true`, `false` or (default) `:auto`."
|
280
262
|
)
|
281
263
|
|
282
264
|
setting_value = :auto
|
@@ -286,10 +268,10 @@ module Datadog
|
|
286
268
|
if legacy_ruby_that_should_use_workaround
|
287
269
|
Datadog.logger.warn(
|
288
270
|
'The profiling "no signals" workaround has been disabled via configuration on a legacy Ruby version ' \
|
289
|
-
|
290
|
-
|
291
|
-
|
292
|
-
|
271
|
+
"(< 2.6). This is not recommended " \
|
272
|
+
"in production environments, as due to limitations in Ruby APIs, we suspect it may lead to crashes " \
|
273
|
+
"in very rare situations. Please report any issues you run into to Datadog support or " \
|
274
|
+
"via <https://github.com/datadog/dd-trace-rb/issues/new>!"
|
293
275
|
)
|
294
276
|
else
|
295
277
|
Datadog.logger.warn('Profiling "no signals" workaround disabled via configuration')
|
@@ -311,30 +293,30 @@ module Datadog
|
|
311
293
|
# We don't warn users in this situation because "upgrade your Ruby" is not a great warning
|
312
294
|
return true if legacy_ruby_that_should_use_workaround
|
313
295
|
|
314
|
-
if Gem.loaded_specs[
|
296
|
+
if Gem.loaded_specs["mysql2"] && incompatible_libmysqlclient_version?(settings)
|
315
297
|
Datadog.logger.warn(
|
316
298
|
'Enabling the profiling "no signals" workaround because an incompatible version of the mysql2 gem is ' \
|
317
|
-
|
318
|
-
|
299
|
+
"installed. Profiling data will have lower quality. " \
|
300
|
+
"To fix this, upgrade the libmysqlclient in your OS image to version 8.0.0 or above."
|
319
301
|
)
|
320
302
|
return true
|
321
303
|
end
|
322
304
|
|
323
|
-
if Gem.loaded_specs[
|
305
|
+
if Gem.loaded_specs["rugged"]
|
324
306
|
Datadog.logger.warn(
|
325
307
|
'Enabling the profiling "no signals" workaround because the rugged gem is installed. ' \
|
326
|
-
|
327
|
-
|
328
|
-
|
308
|
+
"This is needed because some operations on this gem are currently incompatible with the normal working mode " \
|
309
|
+
"of the profiler, as detailed in <https://github.com/datadog/dd-trace-rb/issues/2721>. " \
|
310
|
+
"Profiling data will have lower quality."
|
329
311
|
)
|
330
312
|
return true
|
331
313
|
end
|
332
314
|
|
333
|
-
if (defined?(::PhusionPassenger) || Gem.loaded_specs[
|
315
|
+
if (defined?(::PhusionPassenger) || Gem.loaded_specs["passenger"]) && incompatible_passenger_version?
|
334
316
|
Datadog.logger.warn(
|
335
317
|
'Enabling the profiling "no signals" workaround because an incompatible version of the passenger gem is ' \
|
336
|
-
|
337
|
-
|
318
|
+
"installed. Profiling data will have lower quality." \
|
319
|
+
"To fix this, upgrade the passenger gem to version 6.0.19 or above."
|
338
320
|
)
|
339
321
|
return true
|
340
322
|
end
|
@@ -355,11 +337,11 @@ module Datadog
|
|
355
337
|
return true if settings.profiling.advanced.skip_mysql2_check
|
356
338
|
|
357
339
|
Datadog.logger.debug(
|
358
|
-
|
340
|
+
"Requiring `mysql2` to check if the `libmysqlclient` version it uses is compatible with profiling"
|
359
341
|
)
|
360
342
|
|
361
343
|
begin
|
362
|
-
require
|
344
|
+
require "mysql2"
|
363
345
|
|
364
346
|
# The mysql2-aurora gem likes to monkey patch itself in replacement of Mysql2::Client, and uses
|
365
347
|
# `method_missing` to delegate to the original BUT unfortunately does not implement `respond_to_missing?` and
|
@@ -380,18 +362,18 @@ module Datadog
|
|
380
362
|
libmysqlclient_version = Gem::Version.new(info[:version])
|
381
363
|
|
382
364
|
compatible =
|
383
|
-
libmysqlclient_version >= Gem::Version.new(
|
365
|
+
libmysqlclient_version >= Gem::Version.new("8.0.0") ||
|
384
366
|
looks_like_mariadb?(info, libmysqlclient_version)
|
385
367
|
|
386
368
|
Datadog.logger.debug(
|
387
|
-
"The `mysql2` gem is using #{compatible ?
|
369
|
+
"The `mysql2` gem is using #{compatible ? "a compatible" : "an incompatible"} version of " \
|
388
370
|
"the `libmysqlclient` library (#{libmysqlclient_version})"
|
389
371
|
)
|
390
372
|
|
391
373
|
!compatible
|
392
374
|
rescue StandardError, LoadError => e
|
393
375
|
Datadog.logger.warn(
|
394
|
-
|
376
|
+
"Failed to probe `mysql2` gem information. " \
|
395
377
|
"Cause: #{e.class.name} #{e.message} Location: #{Array(e.backtrace).first}"
|
396
378
|
)
|
397
379
|
|
@@ -401,10 +383,10 @@ module Datadog
|
|
401
383
|
|
402
384
|
# See https://github.com/datadog/dd-trace-rb/issues/2976 for details.
|
403
385
|
private_class_method def self.incompatible_passenger_version?
|
404
|
-
first_compatible_version = Gem::Version.new(
|
386
|
+
first_compatible_version = Gem::Version.new("6.0.19")
|
405
387
|
|
406
|
-
if Gem.loaded_specs[
|
407
|
-
Gem.loaded_specs[
|
388
|
+
if Gem.loaded_specs["passenger"]
|
389
|
+
Gem.loaded_specs["passenger"].version < first_compatible_version
|
408
390
|
elsif defined?(PhusionPassenger::VERSION_STRING)
|
409
391
|
Gem::Version.new(PhusionPassenger::VERSION_STRING) < first_compatible_version
|
410
392
|
else
|
@@ -416,8 +398,9 @@ module Datadog
|
|
416
398
|
if overhead_target_percentage > 0 && overhead_target_percentage <= 20
|
417
399
|
overhead_target_percentage
|
418
400
|
else
|
401
|
+
# TODO: Replace with a warning instead.
|
419
402
|
Datadog.logger.error(
|
420
|
-
|
403
|
+
"Ignoring invalid value for profiling overhead_target_percentage setting: " \
|
421
404
|
"#{overhead_target_percentage.inspect}. Falling back to default value."
|
422
405
|
)
|
423
406
|
|
@@ -450,18 +433,29 @@ module Datadog
|
|
450
433
|
header_version = Gem::Version.new(info[:header_version]) if info[:header_version]
|
451
434
|
|
452
435
|
!!(header_version &&
|
453
|
-
libmysqlclient_version < Gem::Version.new(
|
454
|
-
header_version >= Gem::Version.new(
|
436
|
+
libmysqlclient_version < Gem::Version.new("5.0.0") &&
|
437
|
+
header_version >= Gem::Version.new("10.0.0"))
|
455
438
|
end
|
456
439
|
|
457
440
|
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.
|
441
|
+
return false if no_signals_workaround_enabled || RUBY_VERSION >= "3.4"
|
462
442
|
|
463
443
|
settings.profiling.advanced.dir_interruption_workaround_enabled
|
464
444
|
end
|
445
|
+
|
446
|
+
private_class_method def self.enable_gvl_profiling?(settings)
|
447
|
+
if RUBY_VERSION < "3.2"
|
448
|
+
if settings.profiling.advanced.preview_gvl_enabled
|
449
|
+
Datadog.logger.warn("GVL profiling is currently not supported in Ruby < 3.2 and will not be enabled.")
|
450
|
+
end
|
451
|
+
|
452
|
+
return false
|
453
|
+
end
|
454
|
+
|
455
|
+
# GVL profiling only makes sense in the context of timeline. We could emit a warning here, but not sure how
|
456
|
+
# useful it is -- if a customer disables timeline, there's nowhere to look for GVL profiling anyway!
|
457
|
+
settings.profiling.advanced.timeline_enabled && settings.profiling.advanced.preview_gvl_enabled
|
458
|
+
end
|
465
459
|
end
|
466
460
|
end
|
467
461
|
end
|
@@ -1,7 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require_relative
|
4
|
-
require_relative
|
3
|
+
require_relative "ext"
|
4
|
+
require_relative "tag_builder"
|
5
5
|
|
6
6
|
module Datadog
|
7
7
|
module Profiling
|
@@ -61,7 +61,7 @@ module Datadog
|
|
61
61
|
@last_flush_finish_at = finish
|
62
62
|
|
63
63
|
if duration_below_threshold?(start, finish)
|
64
|
-
Datadog.logger.debug(
|
64
|
+
Datadog.logger.debug("Skipped exporting profiling events as profile duration is below minimum")
|
65
65
|
return
|
66
66
|
end
|
67
67
|
|
@@ -27,7 +27,7 @@ module Datadog
|
|
27
27
|
end
|
28
28
|
end
|
29
29
|
|
30
|
-
if RUBY_VERSION.start_with?(
|
30
|
+
if RUBY_VERSION.start_with?("2.")
|
31
31
|
# Monkey patches for Dir.singleton_class (Ruby 2 version). See DirMonkeyPatches above for more details.
|
32
32
|
module DirClassMonkeyPatches
|
33
33
|
def [](*args, &block)
|
@@ -260,7 +260,7 @@ module Datadog
|
|
260
260
|
end
|
261
261
|
end
|
262
262
|
|
263
|
-
if RUBY_VERSION.start_with?(
|
263
|
+
if RUBY_VERSION.start_with?("2.")
|
264
264
|
# Monkey patches for Dir (Ruby 2 version). See DirMonkeyPatches above for more details.
|
265
265
|
module DirInstanceMonkeyPatches
|
266
266
|
# See note on methods that yield above.
|
@@ -286,7 +286,7 @@ module Datadog
|
|
286
286
|
end
|
287
287
|
end
|
288
288
|
|
289
|
-
unless RUBY_VERSION.start_with?(
|
289
|
+
unless RUBY_VERSION.start_with?("2.5.") # This is Ruby 2.6+
|
290
290
|
# See note on methods that yield above.
|
291
291
|
def each_child(*args, &block)
|
292
292
|
if block
|
@@ -3,31 +3,31 @@
|
|
3
3
|
module Datadog
|
4
4
|
module Profiling
|
5
5
|
module Ext
|
6
|
-
ENV_ENABLED =
|
7
|
-
ENV_UPLOAD_TIMEOUT =
|
8
|
-
ENV_MAX_FRAMES =
|
9
|
-
ENV_AGENTLESS =
|
10
|
-
ENV_ENDPOINT_COLLECTION_ENABLED =
|
6
|
+
ENV_ENABLED = "DD_PROFILING_ENABLED"
|
7
|
+
ENV_UPLOAD_TIMEOUT = "DD_PROFILING_UPLOAD_TIMEOUT"
|
8
|
+
ENV_MAX_FRAMES = "DD_PROFILING_MAX_FRAMES"
|
9
|
+
ENV_AGENTLESS = "DD_PROFILING_AGENTLESS"
|
10
|
+
ENV_ENDPOINT_COLLECTION_ENABLED = "DD_PROFILING_ENDPOINT_COLLECTION_ENABLED"
|
11
11
|
|
12
12
|
module Transport
|
13
13
|
module HTTP
|
14
|
-
FORM_FIELD_TAG_ENV =
|
15
|
-
FORM_FIELD_TAG_HOST =
|
16
|
-
FORM_FIELD_TAG_LANGUAGE =
|
17
|
-
FORM_FIELD_TAG_PID =
|
18
|
-
FORM_FIELD_TAG_PROFILER_VERSION =
|
19
|
-
FORM_FIELD_TAG_RUNTIME =
|
20
|
-
FORM_FIELD_TAG_RUNTIME_ENGINE =
|
21
|
-
FORM_FIELD_TAG_RUNTIME_ID =
|
22
|
-
FORM_FIELD_TAG_RUNTIME_PLATFORM =
|
23
|
-
FORM_FIELD_TAG_RUNTIME_VERSION =
|
24
|
-
FORM_FIELD_TAG_SERVICE =
|
25
|
-
FORM_FIELD_TAG_VERSION =
|
26
|
-
TAG_GIT_REPOSITORY_URL =
|
27
|
-
TAG_GIT_COMMIT_SHA =
|
14
|
+
FORM_FIELD_TAG_ENV = "env"
|
15
|
+
FORM_FIELD_TAG_HOST = "host"
|
16
|
+
FORM_FIELD_TAG_LANGUAGE = "language"
|
17
|
+
FORM_FIELD_TAG_PID = "process_id"
|
18
|
+
FORM_FIELD_TAG_PROFILER_VERSION = "profiler_version"
|
19
|
+
FORM_FIELD_TAG_RUNTIME = "runtime"
|
20
|
+
FORM_FIELD_TAG_RUNTIME_ENGINE = "runtime_engine"
|
21
|
+
FORM_FIELD_TAG_RUNTIME_ID = "runtime-id"
|
22
|
+
FORM_FIELD_TAG_RUNTIME_PLATFORM = "runtime_platform"
|
23
|
+
FORM_FIELD_TAG_RUNTIME_VERSION = "runtime_version"
|
24
|
+
FORM_FIELD_TAG_SERVICE = "service"
|
25
|
+
FORM_FIELD_TAG_VERSION = "version"
|
26
|
+
TAG_GIT_REPOSITORY_URL = "git.repository_url"
|
27
|
+
TAG_GIT_COMMIT_SHA = "git.commit.sha"
|
28
28
|
|
29
|
-
PPROF_DEFAULT_FILENAME =
|
30
|
-
CODE_PROVENANCE_FILENAME =
|
29
|
+
PPROF_DEFAULT_FILENAME = "rubyprofile.pprof"
|
30
|
+
CODE_PROVENANCE_FILENAME = "code-provenance.json"
|
31
31
|
end
|
32
32
|
end
|
33
33
|
end
|
@@ -1,6 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require_relative
|
3
|
+
require_relative "../core/transport/ext"
|
4
|
+
require_relative "../core/telemetry/logger"
|
4
5
|
|
5
6
|
module Datadog
|
6
7
|
module Profiling
|
@@ -53,17 +54,21 @@ module Datadog
|
|
53
54
|
|
54
55
|
if status == :ok
|
55
56
|
if (200..299).cover?(result)
|
56
|
-
Datadog.logger.debug(
|
57
|
+
Datadog.logger.debug("Successfully reported profiling data")
|
57
58
|
true
|
58
59
|
else
|
59
60
|
Datadog.logger.error(
|
60
61
|
"Failed to report profiling data (#{config_without_api_key}): " \
|
61
62
|
"server returned unexpected HTTP #{result} status code"
|
62
63
|
)
|
64
|
+
Datadog::Core::Telemetry::Logger.error(
|
65
|
+
"Failed to report profiling data: unexpected HTTP #{result} status code"
|
66
|
+
)
|
63
67
|
false
|
64
68
|
end
|
65
69
|
else
|
66
70
|
Datadog.logger.error("Failed to report profiling data (#{config_without_api_key}): #{result}")
|
71
|
+
Datadog::Core::Telemetry::Logger.error("Failed to report profiling data")
|
67
72
|
false
|
68
73
|
end
|
69
74
|
end
|
@@ -73,7 +78,7 @@ module Datadog
|
|
73
78
|
def base_url_from(agent_settings)
|
74
79
|
case agent_settings.adapter
|
75
80
|
when Datadog::Core::Configuration::Ext::Agent::HTTP::ADAPTER
|
76
|
-
"#{agent_settings.ssl ?
|
81
|
+
"#{agent_settings.ssl ? "https" : "http"}://#{agent_settings.hostname}:#{agent_settings.port}/"
|
77
82
|
when Datadog::Core::Configuration::Ext::Agent::UnixSocket::ADAPTER
|
78
83
|
"unix://#{agent_settings.uds_path}"
|
79
84
|
else
|
@@ -82,12 +87,14 @@ module Datadog
|
|
82
87
|
end
|
83
88
|
|
84
89
|
def validate_agent_settings(agent_settings)
|
85
|
-
supported_adapters = [
|
86
|
-
|
90
|
+
supported_adapters = [
|
91
|
+
Datadog::Core::Configuration::Ext::Agent::UnixSocket::ADAPTER,
|
92
|
+
Datadog::Core::Configuration::Ext::Agent::HTTP::ADAPTER
|
93
|
+
]
|
87
94
|
unless supported_adapters.include?(agent_settings.adapter)
|
88
95
|
raise ArgumentError,
|
89
96
|
"Unsupported transport configuration for profiling: Adapter #{agent_settings.adapter} " \
|
90
|
-
|
97
|
+
" is not supported"
|
91
98
|
end
|
92
99
|
end
|
93
100
|
|
@@ -132,7 +139,7 @@ module Datadog
|
|
132
139
|
end
|
133
140
|
|
134
141
|
def config_without_api_key
|
135
|
-
[exporter_configuration[
|
142
|
+
"#{exporter_configuration[0]}: #{exporter_configuration[1]}"
|
136
143
|
end
|
137
144
|
end
|
138
145
|
end
|
@@ -15,26 +15,26 @@ begin
|
|
15
15
|
require "datadog_profiling_loader.#{RUBY_VERSION}_#{RUBY_PLATFORM}"
|
16
16
|
rescue LoadError => e
|
17
17
|
raise LoadError,
|
18
|
-
|
18
|
+
"Failed to load the profiling loader extension. To fix this, please remove and then reinstall datadog " \
|
19
19
|
"(Details: #{e.message})"
|
20
20
|
end
|
21
21
|
|
22
22
|
extension_name = "datadog_profiling_native_extension.#{RUBY_VERSION}_#{RUBY_PLATFORM}"
|
23
|
-
file_name = "#{extension_name}.#{RbConfig::CONFIG[
|
23
|
+
file_name = "#{extension_name}.#{RbConfig::CONFIG["DLEXT"]}"
|
24
24
|
full_file_path = "#{__dir__}/../../#{file_name}"
|
25
25
|
|
26
26
|
unless File.exist?(full_file_path)
|
27
|
-
extension_dir = Gem.loaded_specs[
|
27
|
+
extension_dir = Gem.loaded_specs["datadog"].extension_dir
|
28
28
|
candidate_path = "#{extension_dir}/#{file_name}"
|
29
29
|
if File.exist?(candidate_path)
|
30
30
|
full_file_path = candidate_path
|
31
|
-
else
|
31
|
+
else
|
32
32
|
# We found none of the files. This is unexpected. Let's go ahead anyway, the error is going to be reported further
|
33
33
|
# down anyway.
|
34
34
|
end
|
35
35
|
end
|
36
36
|
|
37
|
-
init_function_name = "Init_#{extension_name.split(
|
37
|
+
init_function_name = "Init_#{extension_name.split(".").first}"
|
38
38
|
|
39
39
|
status, result = Datadog::Profiling::Loader._native_load(full_file_path, init_function_name)
|
40
40
|
|