datadog 2.29.0 → 2.31.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_native_extension/collectors_cpu_and_wall_time_worker.c +21 -12
- data/ext/datadog_profiling_native_extension/collectors_thread_context.c +9 -7
- data/ext/datadog_profiling_native_extension/datadog_ruby_common.c +18 -0
- data/ext/datadog_profiling_native_extension/datadog_ruby_common.h +10 -0
- data/ext/datadog_profiling_native_extension/extconf.rb +6 -24
- data/ext/datadog_profiling_native_extension/heap_recorder.c +5 -6
- data/ext/datadog_profiling_native_extension/http_transport.c +51 -64
- data/ext/datadog_profiling_native_extension/native_extension_helpers.rb +0 -13
- data/ext/datadog_profiling_native_extension/profiling.c +3 -1
- data/ext/datadog_profiling_native_extension/setup_signal_handler.c +24 -8
- data/ext/datadog_profiling_native_extension/setup_signal_handler.h +1 -3
- data/ext/datadog_profiling_native_extension/stack_recorder.c +29 -43
- data/ext/libdatadog_api/crashtracker.c +5 -8
- data/ext/libdatadog_api/crashtracker_report_exception.c +34 -144
- data/ext/libdatadog_api/datadog_ruby_common.c +18 -0
- data/ext/libdatadog_api/datadog_ruby_common.h +10 -0
- data/ext/libdatadog_api/di.c +79 -0
- data/ext/libdatadog_api/extconf.rb +5 -20
- data/ext/libdatadog_api/init.c +5 -2
- data/ext/libdatadog_extconf_helpers.rb +57 -11
- data/lib/datadog/ai_guard/component.rb +2 -0
- data/lib/datadog/ai_guard/configuration/settings.rb +3 -0
- data/lib/datadog/ai_guard/contrib/ruby_llm/chat_instrumentation.rb +41 -3
- data/lib/datadog/ai_guard/evaluation/content_builder.rb +31 -0
- data/lib/datadog/ai_guard/evaluation/content_part.rb +36 -0
- data/lib/datadog/ai_guard/evaluation/no_op_result.rb +3 -1
- data/lib/datadog/ai_guard/evaluation/request.rb +14 -9
- data/lib/datadog/ai_guard/evaluation/result.rb +3 -1
- data/lib/datadog/ai_guard/evaluation.rb +36 -7
- data/lib/datadog/ai_guard.rb +26 -8
- data/lib/datadog/appsec/autoload.rb +1 -1
- data/lib/datadog/appsec/component.rb +11 -7
- data/lib/datadog/appsec/contrib/active_record/patcher.rb +3 -0
- data/lib/datadog/appsec/contrib/devise/integration.rb +1 -1
- data/lib/datadog/appsec/contrib/excon/patcher.rb +2 -0
- data/lib/datadog/appsec/contrib/excon/ssrf_detection_middleware.rb +1 -1
- data/lib/datadog/appsec/contrib/graphql/gateway/watcher.rb +1 -1
- data/lib/datadog/appsec/contrib/rack/gateway/request.rb +1 -1
- data/lib/datadog/appsec/contrib/rack/gateway/watcher.rb +10 -11
- data/lib/datadog/appsec/contrib/rack/integration.rb +1 -1
- data/lib/datadog/appsec/contrib/rack/request_middleware.rb +25 -2
- data/lib/datadog/appsec/contrib/rack/response_body.rb +36 -0
- data/lib/datadog/appsec/contrib/rails/gateway/watcher.rb +2 -2
- data/lib/datadog/appsec/contrib/rails/integration.rb +1 -1
- data/lib/datadog/appsec/contrib/rails/patcher.rb +2 -2
- data/lib/datadog/appsec/contrib/rest_client/patcher.rb +2 -0
- data/lib/datadog/appsec/contrib/rest_client/request_ssrf_detection_patch.rb +2 -2
- data/lib/datadog/appsec/contrib/sinatra/gateway/watcher.rb +3 -3
- data/lib/datadog/appsec/event.rb +1 -17
- data/lib/datadog/appsec/instrumentation/gateway/middleware.rb +2 -3
- data/lib/datadog/appsec/instrumentation/gateway.rb +2 -15
- data/lib/datadog/appsec/monitor/gateway/watcher.rb +4 -2
- data/lib/datadog/appsec/utils/http/media_type.rb +1 -2
- data/lib/datadog/appsec/utils/http/url_encoded.rb +2 -2
- data/lib/datadog/appsec.rb +5 -9
- data/lib/datadog/core/configuration/base.rb +17 -5
- data/lib/datadog/core/configuration/components.rb +21 -8
- data/lib/datadog/core/configuration/config_helper.rb +9 -0
- data/lib/datadog/core/configuration/option.rb +32 -6
- data/lib/datadog/core/configuration/option_definition.rb +38 -12
- data/lib/datadog/core/configuration/options.rb +41 -7
- data/lib/datadog/core/configuration/settings.rb +42 -3
- data/lib/datadog/core/configuration/supported_configurations.rb +17 -0
- data/lib/datadog/core/contrib/rails/railtie.rb +32 -0
- data/lib/datadog/core/contrib/rails/utils.rb +7 -3
- data/lib/datadog/core/crashtracking/component.rb +7 -15
- data/lib/datadog/core/environment/container.rb +2 -2
- data/lib/datadog/core/environment/ext.rb +1 -0
- data/lib/datadog/core/environment/identity.rb +25 -3
- data/lib/datadog/core/environment/process.rb +12 -0
- data/lib/datadog/core/metrics/client.rb +5 -5
- data/lib/datadog/core/process_discovery.rb +5 -0
- data/lib/datadog/core/remote/component.rb +38 -21
- data/lib/datadog/core/runtime/metrics.rb +2 -3
- data/lib/datadog/core/telemetry/component.rb +3 -0
- data/lib/datadog/core/telemetry/event/app_client_configuration_change.rb +2 -3
- data/lib/datadog/core/telemetry/event/app_extended_heartbeat.rb +32 -0
- data/lib/datadog/core/telemetry/event/app_started.rb +151 -169
- data/lib/datadog/core/telemetry/event.rb +1 -7
- data/lib/datadog/core/telemetry/ext.rb +1 -0
- data/lib/datadog/core/telemetry/transport/http/telemetry.rb +5 -0
- data/lib/datadog/core/telemetry/worker.rb +20 -0
- data/lib/datadog/core/utils/base64.rb +1 -1
- data/lib/datadog/core/utils/only_once.rb +1 -1
- data/lib/datadog/core/utils/spawn_monkey_patch.rb +36 -0
- data/lib/datadog/core/workers/async.rb +1 -1
- data/lib/datadog/core/workers/interval_loop.rb +13 -6
- data/lib/datadog/core/workers/queue.rb +0 -4
- data/lib/datadog/core/workers/runtime_metrics.rb +9 -1
- data/lib/datadog/core.rb +0 -1
- data/lib/datadog/data_streams/pathway_context.rb +1 -1
- data/lib/datadog/data_streams/processor.rb +1 -0
- data/lib/datadog/di/boot.rb +3 -4
- data/lib/datadog/di/component.rb +20 -4
- data/lib/datadog/di/instrumenter.rb +20 -10
- data/lib/datadog/di/probe_manager.rb +79 -62
- data/lib/datadog/di/probe_notification_builder.rb +148 -33
- data/lib/datadog/di/probe_notifier_worker.rb +52 -6
- data/lib/datadog/di/probe_repository.rb +198 -0
- data/lib/datadog/di/remote.rb +5 -6
- data/lib/datadog/di/serializer.rb +127 -9
- data/lib/datadog/di/transport/http.rb +12 -3
- data/lib/datadog/di/transport/input.rb +46 -8
- data/lib/datadog/di.rb +81 -0
- data/lib/datadog/kit/enable_core_dumps.rb +1 -1
- data/lib/datadog/open_feature/configuration.rb +2 -0
- data/lib/datadog/open_feature/evaluation_engine.rb +1 -1
- data/lib/datadog/open_feature/exposures/reporter.rb +1 -1
- data/lib/datadog/open_feature/exposures/worker.rb +1 -1
- data/lib/datadog/open_feature/remote.rb +1 -1
- data/lib/datadog/open_feature/transport.rb +1 -1
- data/lib/datadog/opentelemetry/configuration/settings.rb +2 -0
- data/lib/datadog/profiling/collectors/code_provenance.rb +2 -3
- data/lib/datadog/profiling/collectors/cpu_and_wall_time_worker.rb +14 -1
- data/lib/datadog/profiling/collectors/idle_sampling_helper.rb +1 -1
- data/lib/datadog/profiling/component.rb +31 -1
- data/lib/datadog/profiling/http_transport.rb +5 -6
- data/lib/datadog/profiling/load_native_extension.rb +1 -1
- data/lib/datadog/profiling/profiler.rb +15 -12
- data/lib/datadog/profiling/scheduler.rb +2 -2
- data/lib/datadog/profiling/tasks/exec.rb +2 -2
- data/lib/datadog/profiling/tasks/setup.rb +2 -2
- data/lib/datadog/profiling.rb +1 -2
- data/lib/datadog/single_step_instrument.rb +1 -1
- data/lib/datadog/tracing/buffer.rb +3 -3
- data/lib/datadog/tracing/component.rb +11 -0
- data/lib/datadog/tracing/configuration/settings.rb +2 -1
- data/lib/datadog/tracing/contrib/action_pack/action_controller/instrumentation.rb +2 -2
- data/lib/datadog/tracing/contrib/action_pack/action_dispatch/instrumentation.rb +20 -0
- data/lib/datadog/tracing/contrib/action_pack/action_dispatch/patcher.rb +3 -1
- 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_record/utils.rb +1 -1
- data/lib/datadog/tracing/contrib/active_support/cache/events/cache.rb +1 -1
- data/lib/datadog/tracing/contrib/active_support/notifications/subscription.rb +2 -2
- data/lib/datadog/tracing/contrib/aws/instrumentation.rb +1 -1
- data/lib/datadog/tracing/contrib/configurable.rb +18 -3
- data/lib/datadog/tracing/contrib/dalli/integration.rb +4 -1
- data/lib/datadog/tracing/contrib/elasticsearch/patcher.rb +1 -1
- data/lib/datadog/tracing/contrib/ethon/configuration/settings.rb +5 -1
- data/lib/datadog/tracing/contrib/ethon/ext.rb +1 -0
- data/lib/datadog/tracing/contrib/excon/configuration/settings.rb +5 -2
- data/lib/datadog/tracing/contrib/excon/ext.rb +1 -0
- data/lib/datadog/tracing/contrib/excon/middleware.rb +2 -2
- data/lib/datadog/tracing/contrib/faraday/configuration/settings.rb +5 -2
- data/lib/datadog/tracing/contrib/faraday/ext.rb +1 -0
- data/lib/datadog/tracing/contrib/faraday/middleware.rb +2 -2
- data/lib/datadog/tracing/contrib/grape/endpoint.rb +7 -7
- data/lib/datadog/tracing/contrib/grape/instrumentation.rb +13 -8
- data/lib/datadog/tracing/contrib/grape/patcher.rb +6 -1
- data/lib/datadog/tracing/contrib/grpc/configuration/settings.rb +5 -2
- data/lib/datadog/tracing/contrib/grpc/ext.rb +1 -0
- data/lib/datadog/tracing/contrib/http/configuration/settings.rb +5 -2
- data/lib/datadog/tracing/contrib/http/ext.rb +1 -0
- data/lib/datadog/tracing/contrib/http/instrumentation.rb +1 -1
- data/lib/datadog/tracing/contrib/httpclient/configuration/settings.rb +5 -2
- data/lib/datadog/tracing/contrib/httpclient/ext.rb +1 -0
- data/lib/datadog/tracing/contrib/httprb/configuration/settings.rb +5 -2
- data/lib/datadog/tracing/contrib/httprb/ext.rb +1 -0
- data/lib/datadog/tracing/contrib/httprb/instrumentation.rb +1 -1
- data/lib/datadog/tracing/contrib/karafka/configuration/settings.rb +5 -1
- data/lib/datadog/tracing/contrib/karafka/ext.rb +1 -0
- data/lib/datadog/tracing/contrib/opensearch/patcher.rb +1 -1
- data/lib/datadog/tracing/contrib/que/configuration/settings.rb +5 -2
- data/lib/datadog/tracing/contrib/que/ext.rb +1 -0
- data/lib/datadog/tracing/contrib/rack/configuration/settings.rb +5 -1
- data/lib/datadog/tracing/contrib/rack/ext.rb +1 -0
- data/lib/datadog/tracing/contrib/rails/configuration/settings.rb +5 -2
- data/lib/datadog/tracing/contrib/rails/ext.rb +1 -0
- data/lib/datadog/tracing/contrib/rails/log_injection.rb +1 -1
- data/lib/datadog/tracing/contrib/rails/patcher.rb +0 -1
- data/lib/datadog/tracing/contrib/rails/runner.rb +1 -1
- data/lib/datadog/tracing/contrib/rake/instrumentation.rb +2 -2
- data/lib/datadog/tracing/contrib/redis/tags.rb +1 -1
- data/lib/datadog/tracing/contrib/rest_client/configuration/settings.rb +5 -2
- data/lib/datadog/tracing/contrib/rest_client/ext.rb +1 -0
- data/lib/datadog/tracing/contrib/sidekiq/configuration/settings.rb +5 -1
- data/lib/datadog/tracing/contrib/sidekiq/ext.rb +1 -0
- data/lib/datadog/tracing/contrib/sinatra/configuration/settings.rb +5 -1
- data/lib/datadog/tracing/contrib/sinatra/ext.rb +1 -0
- data/lib/datadog/tracing/contrib/status_range_matcher.rb +4 -0
- data/lib/datadog/tracing/contrib/stripe/request.rb +1 -1
- data/lib/datadog/tracing/contrib/waterdrop/configuration/settings.rb +5 -1
- data/lib/datadog/tracing/contrib/waterdrop/ext.rb +1 -0
- data/lib/datadog/tracing/distributed/datadog.rb +4 -2
- data/lib/datadog/tracing/event.rb +1 -1
- data/lib/datadog/tracing/metadata/ext.rb +4 -0
- data/lib/datadog/tracing/remote.rb +1 -1
- data/lib/datadog/tracing/sampling/ext.rb +2 -0
- data/lib/datadog/tracing/sampling/priority_sampler.rb +13 -0
- data/lib/datadog/tracing/sampling/rule.rb +1 -1
- data/lib/datadog/tracing/sampling/rule_sampler.rb +54 -25
- data/lib/datadog/tracing/sampling/span/rule_parser.rb +1 -1
- data/lib/datadog/tracing/span_operation.rb +1 -1
- data/lib/datadog/tracing/sync_writer.rb +0 -1
- data/lib/datadog/tracing/trace_operation.rb +50 -6
- data/lib/datadog/tracing/tracer.rb +25 -0
- data/lib/datadog/tracing/transport/io/client.rb +1 -1
- data/lib/datadog/tracing/transport/trace_formatter.rb +11 -0
- data/lib/datadog/tracing/writer.rb +0 -1
- data/lib/datadog/version.rb +1 -1
- metadata +15 -8
- data/lib/datadog/tracing/workers/trace_writer.rb +0 -204
|
@@ -52,9 +52,10 @@ module Datadog
|
|
|
52
52
|
def self.input(
|
|
53
53
|
agent_settings:,
|
|
54
54
|
logger:,
|
|
55
|
-
headers: nil
|
|
55
|
+
headers: nil,
|
|
56
|
+
telemetry: nil
|
|
56
57
|
)
|
|
57
|
-
Core::Transport::HTTP.build(
|
|
58
|
+
builder = Core::Transport::HTTP.build(
|
|
58
59
|
logger: logger,
|
|
59
60
|
agent_settings: agent_settings,
|
|
60
61
|
headers: headers,
|
|
@@ -64,7 +65,15 @@ module Datadog
|
|
|
64
65
|
|
|
65
66
|
# Call block to apply any customization, if provided
|
|
66
67
|
yield(transport) if block_given?
|
|
67
|
-
end
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
# Create transport with telemetry
|
|
71
|
+
DI::Transport::Input::Transport.new(
|
|
72
|
+
builder.to_api_instances,
|
|
73
|
+
builder.default_api,
|
|
74
|
+
logger: logger,
|
|
75
|
+
telemetry: telemetry
|
|
76
|
+
)
|
|
68
77
|
end
|
|
69
78
|
end
|
|
70
79
|
end
|
|
@@ -24,6 +24,13 @@ module Datadog
|
|
|
24
24
|
end
|
|
25
25
|
|
|
26
26
|
class Transport < Core::Transport::Transport
|
|
27
|
+
attr_reader :telemetry
|
|
28
|
+
|
|
29
|
+
def initialize(apis, default_api, logger:, telemetry: nil)
|
|
30
|
+
super(apis, default_api, logger: logger)
|
|
31
|
+
@telemetry = telemetry
|
|
32
|
+
end
|
|
33
|
+
|
|
27
34
|
# The limit on an individual snapshot payload, aka "log line",
|
|
28
35
|
# is 1 MB.
|
|
29
36
|
#
|
|
@@ -43,22 +50,52 @@ module Datadog
|
|
|
43
50
|
# max chunk size, it will still get sent out.
|
|
44
51
|
DEFAULT_CHUNK_SIZE = 2 * 1024 * 1024
|
|
45
52
|
|
|
46
|
-
|
|
47
|
-
|
|
53
|
+
# Sends snapshot payloads to the agent.
|
|
54
|
+
#
|
|
55
|
+
# Each snapshot is serialized individually. If serialization fails
|
|
56
|
+
# for a snapshot (e.g., due to binary data from custom serializers),
|
|
57
|
+
# the on_serialization_error callback is invoked with the probe ID
|
|
58
|
+
# and exception, allowing the caller to disable the affected probe.
|
|
59
|
+
# Successfully serialized snapshots are still sent.
|
|
60
|
+
#
|
|
61
|
+
# Large snapshots (> 1MB) are dropped. Batches are split into chunks
|
|
62
|
+
# of ~2MB each to avoid large network requests.
|
|
63
|
+
#
|
|
64
|
+
# @param payload [Array<Hash>] Array of snapshot payloads
|
|
65
|
+
# @param tags [Hash] Tags to send with the snapshots
|
|
66
|
+
# @param on_serialization_error [Proc] Called with (probe_id, exception)
|
|
67
|
+
# when a snapshot fails to serialize.
|
|
68
|
+
def send_input(payload, tags, on_serialization_error:)
|
|
48
69
|
serialized_tags = Core::TagBuilder.serialize_tags(tags)
|
|
49
70
|
|
|
50
|
-
|
|
71
|
+
# Serialize each snapshot individually to isolate failures
|
|
72
|
+
encoded_snapshots = []
|
|
73
|
+
payload.each do |snapshot|
|
|
51
74
|
encoded = encoder.encode(snapshot)
|
|
52
75
|
if encoded.length > MAX_SERIALIZED_SNAPSHOT_SIZE
|
|
53
|
-
# Drop the snapshot.
|
|
54
|
-
# TODO report via telemetry metric?
|
|
55
76
|
logger.debug { "di: dropping too big snapshot" }
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
77
|
+
next
|
|
78
|
+
end
|
|
79
|
+
encoded_snapshots << encoded
|
|
80
|
+
rescue => exc
|
|
81
|
+
# Serialization failed for this snapshot - report via callback
|
|
82
|
+
# This catches JSON::GeneratorError, Encoding errors, TypeError, etc.
|
|
83
|
+
probe_id = snapshot.dig(:debugger, :snapshot, :probe, :id)
|
|
84
|
+
logger.debug { "di: JSON encoding failed for snapshot (probe #{probe_id}): #{exc.class}: #{exc}" }
|
|
85
|
+
telemetry&.report(exc, description: "JSON encoding failed for snapshot")
|
|
86
|
+
|
|
87
|
+
if probe_id
|
|
88
|
+
begin
|
|
89
|
+
on_serialization_error.call(probe_id, exc)
|
|
90
|
+
rescue => callback_exc
|
|
91
|
+
logger.debug { "di: error in serialization error callback for probe #{probe_id}: #{callback_exc.class}: #{callback_exc}" }
|
|
92
|
+
telemetry&.report(callback_exc, description: "Error in serialization error callback")
|
|
93
|
+
end
|
|
59
94
|
end
|
|
60
95
|
end
|
|
61
96
|
|
|
97
|
+
return payload if encoded_snapshots.empty?
|
|
98
|
+
|
|
62
99
|
Datadog::Core::Chunker.chunk_by_size(
|
|
63
100
|
encoded_snapshots, DEFAULT_CHUNK_SIZE,
|
|
64
101
|
).each do |chunk|
|
|
@@ -74,6 +111,7 @@ module Datadog
|
|
|
74
111
|
send_input_chunk(chunked_payload, serialized_tags)
|
|
75
112
|
rescue => exc
|
|
76
113
|
logger.debug { "di: failed to send snapshot chunk: #{exc.class}: #{exc} (at #{exc.backtrace.first})" }
|
|
114
|
+
telemetry&.report(exc, description: "Error sending snapshot chunk")
|
|
77
115
|
end
|
|
78
116
|
end
|
|
79
117
|
|
data/lib/datadog/di.rb
CHANGED
|
@@ -11,11 +11,92 @@ module Datadog
|
|
|
11
11
|
module DI
|
|
12
12
|
INSTRUMENTED_COUNTERS_LOCK = Mutex.new
|
|
13
13
|
|
|
14
|
+
# Captured at load time from Exception itself (not a subclass).
|
|
15
|
+
# Used to bypass subclass overrides of backtrace_locations.
|
|
16
|
+
#
|
|
17
|
+
# This does NOT protect against monkeypatching Exception#backtrace_locations
|
|
18
|
+
# before dd-trace-rb loads — in that case we'd capture the monkeypatch.
|
|
19
|
+
# The practical threat model is customer subclasses overriding the method:
|
|
20
|
+
#
|
|
21
|
+
# class MyError < StandardError
|
|
22
|
+
# def backtrace_locations; []; end
|
|
23
|
+
# end
|
|
24
|
+
#
|
|
25
|
+
# The UnboundMethod bypasses subclass overrides: bind(exception).call
|
|
26
|
+
# always dispatches to the original Exception implementation.
|
|
27
|
+
#
|
|
28
|
+
# Note: if the subclass overrides #backtrace (not #backtrace_locations),
|
|
29
|
+
# MRI's setup_exception skips storing the VM backtrace entirely — both
|
|
30
|
+
# @bt and @bt_locations stay nil. In that case this UnboundMethod also
|
|
31
|
+
# returns nil. See EXCEPTION_BACKTRACE comment for details.
|
|
32
|
+
EXCEPTION_BACKTRACE_LOCATIONS = Exception.instance_method(:backtrace_locations)
|
|
33
|
+
|
|
34
|
+
# Same UnboundMethod trick for Exception#backtrace (Array<String>).
|
|
35
|
+
# Used as a fallback when backtrace_locations returns nil — which happens
|
|
36
|
+
# when someone calls Exception#set_backtrace with an Array<String>.
|
|
37
|
+
#
|
|
38
|
+
# set_backtrace accepts Array<String> or nil. When called with strings,
|
|
39
|
+
# it replaces the VM-level backtrace: backtrace returns the new strings,
|
|
40
|
+
# but backtrace_locations returns nil because the VM cannot reconstruct
|
|
41
|
+
# Location objects from formatted strings. This occurs in exception
|
|
42
|
+
# wrapping patterns where a library catches an exception, creates a new
|
|
43
|
+
# one, and copies the original's string backtrace onto it via
|
|
44
|
+
# set_backtrace before re-raising.
|
|
45
|
+
#
|
|
46
|
+
# Ruby 3.4+ also allows set_backtrace(Array<Location>), which preserves
|
|
47
|
+
# backtrace_locations — but older Rubies and most existing code use
|
|
48
|
+
# the string form.
|
|
49
|
+
#
|
|
50
|
+
# Like EXCEPTION_BACKTRACE_LOCATIONS, this UnboundMethod bypasses
|
|
51
|
+
# subclass overrides of #backtrace: bind(exception).call dispatches
|
|
52
|
+
# to Exception#backtrace regardless of what the subclass defines.
|
|
53
|
+
#
|
|
54
|
+
# However, when a subclass overrides #backtrace, MRI's setup_exception
|
|
55
|
+
# (eval.c) calls the override via rb_get_backtrace during raise. If it
|
|
56
|
+
# gets a non-nil result, it skips storing the VM backtrace in @bt and
|
|
57
|
+
# @bt_locations entirely. So the UnboundMethod bypasses the override
|
|
58
|
+
# at dispatch but reads nil from @bt because the data was never stored.
|
|
59
|
+
#
|
|
60
|
+
# This constant is used as a fallback when backtrace_locations returns
|
|
61
|
+
# nil. In the common set_backtrace-with-strings case, no subclass
|
|
62
|
+
# override is involved and the fallback works. The only unrecoverable
|
|
63
|
+
# case: a subclass overrides #backtrace, the exception is raised
|
|
64
|
+
# normally, and set_backtrace is never called. Both @bt and
|
|
65
|
+
# @bt_locations are nil — DI reports an empty stacktrace (type and
|
|
66
|
+
# message are still reported).
|
|
67
|
+
EXCEPTION_BACKTRACE = Exception.instance_method(:backtrace)
|
|
68
|
+
|
|
14
69
|
class << self
|
|
15
70
|
def enabled?
|
|
16
71
|
Datadog.configuration.dynamic_instrumentation.enabled
|
|
17
72
|
end
|
|
18
73
|
|
|
74
|
+
# Returns iseqs that correspond to loaded files (filtering out eval'd code).
|
|
75
|
+
#
|
|
76
|
+
# There are several types of iseqs returned by +all_iseqs+:
|
|
77
|
+
#
|
|
78
|
+
# 1. Eval'd code — these have a nil +absolute_path+ and are filtered out here.
|
|
79
|
+
# 2. Whole-file iseqs — have +absolute_path+ set and +first_lineno+ of 0.
|
|
80
|
+
# Only available for a subset of loaded files (the full-file iseq may be
|
|
81
|
+
# garbage collected after loading completes). Easiest to work with since
|
|
82
|
+
# we just match the file path to the probe specification.
|
|
83
|
+
# 3. Per-method iseqs — have +absolute_path+ set and +first_lineno+ > 0.
|
|
84
|
+
# Often the only iseqs available for third-party code. Require identifying
|
|
85
|
+
# the correct iseq containing the target line, which may involve examining
|
|
86
|
+
# the iseq's +trace_points+ since +define_method+ can create nested,
|
|
87
|
+
# non-contiguous line ranges.
|
|
88
|
+
#
|
|
89
|
+
# Note: the same line of code can appear in multiple iseqs (e.g. when
|
|
90
|
+
# +define_method+ is used inside a method). DI treats this as an error
|
|
91
|
+
# since a probe must resolve to exactly one code location.
|
|
92
|
+
#
|
|
93
|
+
# @return [Array<RubyVM::InstructionSequence>] iseqs with non-nil +absolute_path+
|
|
94
|
+
def file_iseqs
|
|
95
|
+
all_iseqs.select do |iseq|
|
|
96
|
+
iseq.absolute_path
|
|
97
|
+
end
|
|
98
|
+
end
|
|
99
|
+
|
|
19
100
|
# This method is called from DI Remote handler to issue DI operations
|
|
20
101
|
# to the probe manager (add or remove probes).
|
|
21
102
|
#
|
|
@@ -30,7 +30,7 @@ module Datadog
|
|
|
30
30
|
Process.setrlimit(:CORE, maximum_size)
|
|
31
31
|
rescue => e
|
|
32
32
|
Kernel.warn(
|
|
33
|
-
"[datadog] Failed to enable core dumps. Cause: #{e.class
|
|
33
|
+
"[datadog] Failed to enable core dumps. Cause: #{e.class}: #{e} " \
|
|
34
34
|
"Location: #{Array(e.backtrace).first}"
|
|
35
35
|
)
|
|
36
36
|
return
|
|
@@ -12,6 +12,8 @@ module Datadog
|
|
|
12
12
|
|
|
13
13
|
def self.add_settings!(base)
|
|
14
14
|
base.class_eval do
|
|
15
|
+
# Steep does not update `self` for this `class_eval` block.
|
|
16
|
+
# @type self: Datadog::Core::Configuration::Base::_DslContext
|
|
15
17
|
settings :open_feature do
|
|
16
18
|
option :enabled do |o|
|
|
17
19
|
o.type :bool
|
|
@@ -60,7 +60,7 @@ module Datadog
|
|
|
60
60
|
rescue => e
|
|
61
61
|
message = 'OpenFeature: Failed to reconfigure, reverting to the previous configuration'
|
|
62
62
|
|
|
63
|
-
@logger.error("#{message}, #{e.class}: #{e
|
|
63
|
+
@logger.error("#{message}, #{e.class}: #{e}")
|
|
64
64
|
@telemetry.report(e, description: "#{message} (#{e.class})")
|
|
65
65
|
|
|
66
66
|
raise ReconfigurationError, e.message
|
|
@@ -29,7 +29,7 @@ module Datadog
|
|
|
29
29
|
event = Event.build(result, flag_key: flag_key, context: context)
|
|
30
30
|
@worker.enqueue(event)
|
|
31
31
|
rescue => e
|
|
32
|
-
@logger.debug { "OpenFeature: Failed to report resolution details: #{e.class}: #{e
|
|
32
|
+
@logger.debug { "OpenFeature: Failed to report resolution details: #{e.class}: #{e}" }
|
|
33
33
|
@telemetry.report(e, description: 'OpenFeature: Failed to report resolution details')
|
|
34
34
|
|
|
35
35
|
false
|
|
@@ -105,7 +105,7 @@ module Datadog
|
|
|
105
105
|
|
|
106
106
|
response
|
|
107
107
|
rescue => e
|
|
108
|
-
@logger.debug { "OpenFeature: Failed to flush resolution details events: #{e.class}: #{e
|
|
108
|
+
@logger.debug { "OpenFeature: Failed to flush resolution details events: #{e.class}: #{e}" }
|
|
109
109
|
@telemetry.report(e, description: 'OpenFeature: Failed to flush resolution details events')
|
|
110
110
|
|
|
111
111
|
nil
|
|
@@ -41,7 +41,7 @@ module Datadog
|
|
|
41
41
|
engine.reconfigure!(read_content(content))
|
|
42
42
|
content.applied
|
|
43
43
|
rescue EvaluationEngine::ReconfigurationError => e
|
|
44
|
-
content.errored("Error applying OpenFeature configuration: #{e.
|
|
44
|
+
content.errored("Error applying OpenFeature configuration: #{e.class}: #{e}")
|
|
45
45
|
end
|
|
46
46
|
when :delete
|
|
47
47
|
# NOTE: For now, we treat deletion as clearing the configuration
|
|
@@ -55,7 +55,7 @@ module Datadog
|
|
|
55
55
|
@api.call(env)
|
|
56
56
|
end
|
|
57
57
|
rescue => e
|
|
58
|
-
message = "Internal error during request. Cause: #{e.class
|
|
58
|
+
message = "Internal error during request. Cause: #{e.class}: #{e} " \
|
|
59
59
|
"Location: #{Array(e.backtrace).first}"
|
|
60
60
|
@logger.debug(message)
|
|
61
61
|
|
|
@@ -76,6 +76,7 @@ module Datadog
|
|
|
76
76
|
end
|
|
77
77
|
|
|
78
78
|
option :headers do |o|
|
|
79
|
+
o.skip_telemetry true
|
|
79
80
|
o.type :hash
|
|
80
81
|
o.env 'OTEL_EXPORTER_OTLP_HEADERS'
|
|
81
82
|
o.default { {} }
|
|
@@ -131,6 +132,7 @@ module Datadog
|
|
|
131
132
|
end
|
|
132
133
|
|
|
133
134
|
option :headers do |o|
|
|
135
|
+
o.skip_telemetry true
|
|
134
136
|
o.type :hash, nilable: true
|
|
135
137
|
o.env 'OTEL_EXPORTER_OTLP_METRICS_HEADERS'
|
|
136
138
|
o.default nil
|
|
@@ -135,7 +135,7 @@ module Datadog
|
|
|
135
135
|
rescue Exception => e # rubocop:disable Lint/RescueException
|
|
136
136
|
Datadog.logger.debug(
|
|
137
137
|
"CodeProvenance#bundler_bin_path failed. " \
|
|
138
|
-
"Cause: #{e.class
|
|
138
|
+
"Cause: #{e.class}: #{e} Location: #{Array(e.backtrace).first}"
|
|
139
139
|
)
|
|
140
140
|
nil
|
|
141
141
|
end
|
|
@@ -161,8 +161,7 @@ module Datadog
|
|
|
161
161
|
end
|
|
162
162
|
|
|
163
163
|
def to_json(arg = nil)
|
|
164
|
-
|
|
165
|
-
{kind: @kind, name: @name, version: @version, paths: @paths}.to_json(arg) # steep:ignore ArgumentTypeMismatch
|
|
164
|
+
{kind: @kind, name: @name, version: @version, paths: @paths}.to_json(arg)
|
|
166
165
|
end
|
|
167
166
|
|
|
168
167
|
def path
|
|
@@ -24,6 +24,7 @@ module Datadog
|
|
|
24
24
|
allocation_counting_enabled:,
|
|
25
25
|
gvl_profiling_enabled:,
|
|
26
26
|
sighandler_sampling_enabled:,
|
|
27
|
+
cpu_sampling_interval_ms:,
|
|
27
28
|
# **NOTE**: This should only be used for testing; disabling the dynamic sampling rate will increase the
|
|
28
29
|
# profiler overhead!
|
|
29
30
|
dynamic_sampling_rate_enabled: true,
|
|
@@ -39,6 +40,10 @@ module Datadog
|
|
|
39
40
|
)
|
|
40
41
|
end
|
|
41
42
|
|
|
43
|
+
if cpu_sampling_interval_ms < 1
|
|
44
|
+
raise ArgumentError, "cpu_sampling_interval_ms must be a positive integer, got #{cpu_sampling_interval_ms}"
|
|
45
|
+
end
|
|
46
|
+
|
|
42
47
|
self.class._native_initialize(
|
|
43
48
|
self_instance: self,
|
|
44
49
|
thread_context_collector: thread_context_collector,
|
|
@@ -52,6 +57,7 @@ module Datadog
|
|
|
52
57
|
gvl_profiling_enabled: gvl_profiling_enabled,
|
|
53
58
|
sighandler_sampling_enabled: sighandler_sampling_enabled,
|
|
54
59
|
skip_idle_samples_for_testing: skip_idle_samples_for_testing,
|
|
60
|
+
cpu_sampling_interval_ms: cpu_sampling_interval_ms,
|
|
55
61
|
)
|
|
56
62
|
@worker_thread = nil
|
|
57
63
|
@failure_exception = nil
|
|
@@ -75,12 +81,19 @@ module Datadog
|
|
|
75
81
|
self.class._native_sampling_loop(self)
|
|
76
82
|
|
|
77
83
|
Datadog.logger.debug("CpuAndWallTimeWorker thread stopping cleanly")
|
|
84
|
+
rescue Profiling::ExistingSignalHandler => e
|
|
85
|
+
@failure_exception = e
|
|
86
|
+
Datadog.logger.warn(
|
|
87
|
+
"Profiling was not started as another profiler or gem is already using the SIGPROF signal. " \
|
|
88
|
+
"Please disable the other profiler to use Datadog profiling."
|
|
89
|
+
)
|
|
90
|
+
on_failure_proc&.call(log_failure: false)
|
|
78
91
|
rescue Exception => e # rubocop:disable Lint/RescueException
|
|
79
92
|
@failure_exception = e
|
|
80
93
|
operation_name = self.class._native_failure_exception_during_operation(self).inspect
|
|
81
94
|
Datadog.logger.warn(
|
|
82
95
|
"CpuAndWallTimeWorker thread error. " \
|
|
83
|
-
"Operation: #{operation_name} Cause: #{e.class
|
|
96
|
+
"Operation: #{operation_name} Cause: #{e.class}: #{e} Location: #{Array(e.backtrace).first}"
|
|
84
97
|
)
|
|
85
98
|
on_failure_proc&.call
|
|
86
99
|
Datadog::Core::Telemetry::Logger.report(e, description: "CpuAndWallTimeWorker thread error: #{operation_name}")
|
|
@@ -39,7 +39,7 @@ module Datadog
|
|
|
39
39
|
@failure_exception = e
|
|
40
40
|
Datadog.logger.warn(
|
|
41
41
|
"IdleSamplingHelper thread error. " \
|
|
42
|
-
"Cause: #{e.class
|
|
42
|
+
"Cause: #{e.class}: #{e} Location: #{Array(e.backtrace).first}"
|
|
43
43
|
)
|
|
44
44
|
Datadog::Core::Telemetry::Logger.report(e, description: "IdleSamplingHelper thread error")
|
|
45
45
|
end
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
+
require_relative "../core/telemetry/logger"
|
|
4
|
+
|
|
3
5
|
module Datadog
|
|
4
6
|
module Profiling
|
|
5
7
|
# Responsible for wiring up the Profiler for execution
|
|
@@ -45,6 +47,8 @@ module Datadog
|
|
|
45
47
|
|
|
46
48
|
overhead_target_percentage = valid_overhead_target(settings.profiling.advanced.overhead_target_percentage, logger)
|
|
47
49
|
upload_period_seconds = [60, settings.profiling.advanced.upload_period_seconds].max
|
|
50
|
+
cpu_sampling_interval_ms =
|
|
51
|
+
valid_cpu_sampling_interval(settings.profiling.advanced.experimental_cpu_sampling_interval_ms, logger)
|
|
48
52
|
|
|
49
53
|
recorder = Datadog::Profiling::StackRecorder.new(
|
|
50
54
|
cpu_time_enabled: RUBY_PLATFORM.include?("linux"), # Only supported on Linux currently
|
|
@@ -65,6 +69,7 @@ module Datadog
|
|
|
65
69
|
allocation_counting_enabled: settings.profiling.advanced.allocation_counting_enabled,
|
|
66
70
|
gvl_profiling_enabled: enable_gvl_profiling?(settings, logger),
|
|
67
71
|
sighandler_sampling_enabled: settings.profiling.advanced.sighandler_sampling_enabled,
|
|
72
|
+
cpu_sampling_interval_ms: cpu_sampling_interval_ms,
|
|
68
73
|
)
|
|
69
74
|
|
|
70
75
|
internal_metadata = {
|
|
@@ -87,6 +92,14 @@ module Datadog
|
|
|
87
92
|
end
|
|
88
93
|
|
|
89
94
|
[profiler, {profiling_enabled: true}]
|
|
95
|
+
rescue Exception => e # rubocop:disable Lint/RescueException
|
|
96
|
+
logger.warn do
|
|
97
|
+
"Failed to initialize profiling: #{e.class}: #{e} " \
|
|
98
|
+
"Location: #{Array(e.backtrace).first}"
|
|
99
|
+
end
|
|
100
|
+
Datadog::Core::Telemetry::Logger.report(e, description: "Failed to initialize profiling")
|
|
101
|
+
|
|
102
|
+
[nil, {profiling_enabled: false}]
|
|
90
103
|
end
|
|
91
104
|
|
|
92
105
|
private_class_method def self.build_thread_context_collector(settings, recorder, optional_tracer, timeline_enabled)
|
|
@@ -123,6 +136,7 @@ module Datadog
|
|
|
123
136
|
site: settings.site,
|
|
124
137
|
api_key: settings.api_key,
|
|
125
138
|
upload_timeout_seconds: settings.profiling.upload.timeout_seconds,
|
|
139
|
+
use_system_dns: settings.profiling.advanced.experimental_use_system_dns,
|
|
126
140
|
)
|
|
127
141
|
end
|
|
128
142
|
|
|
@@ -364,7 +378,7 @@ module Datadog
|
|
|
364
378
|
rescue StandardError, LoadError => e
|
|
365
379
|
logger.warn(
|
|
366
380
|
"Failed to probe `mysql2` gem information. " \
|
|
367
|
-
"Cause: #{e.class
|
|
381
|
+
"Cause: #{e.class}: #{e} Location: #{Array(e.backtrace).first}"
|
|
368
382
|
)
|
|
369
383
|
|
|
370
384
|
true
|
|
@@ -397,6 +411,22 @@ module Datadog
|
|
|
397
411
|
end
|
|
398
412
|
end
|
|
399
413
|
|
|
414
|
+
private_class_method def self.valid_cpu_sampling_interval(cpu_sampling_interval_ms, logger)
|
|
415
|
+
if cpu_sampling_interval_ms > 10
|
|
416
|
+
logger.warn(
|
|
417
|
+
"Profiling cpu_sampling_interval_ms is set to #{cpu_sampling_interval_ms}ms, but values above 10ms are " \
|
|
418
|
+
"not supported. Using 10ms instead. To reduce profiler overhead, consider adjusting the " \
|
|
419
|
+
"overhead_target_percentage setting."
|
|
420
|
+
)
|
|
421
|
+
10
|
|
422
|
+
elsif cpu_sampling_interval_ms < 10
|
|
423
|
+
logger.debug { "Profiling cpu_sampling_interval_ms set to #{cpu_sampling_interval_ms}ms" }
|
|
424
|
+
cpu_sampling_interval_ms
|
|
425
|
+
else
|
|
426
|
+
cpu_sampling_interval_ms
|
|
427
|
+
end
|
|
428
|
+
end
|
|
429
|
+
|
|
400
430
|
# To add just a bit more complexity to our detection code, in https://github.com/DataDog/dd-trace-rb/issues/3334
|
|
401
431
|
# a user reported that our code was incorrectly flagging the mariadb variant of libmysqlclient as being
|
|
402
432
|
# incompatible. In fact we have no reports of the mariadb variant needing the "no signals" workaround,
|
|
@@ -10,17 +10,17 @@ module Datadog
|
|
|
10
10
|
class HttpTransport
|
|
11
11
|
attr_reader :exporter_configuration
|
|
12
12
|
|
|
13
|
-
def initialize(agent_settings:, site:, api_key:, upload_timeout_seconds:)
|
|
14
|
-
|
|
13
|
+
def initialize(agent_settings:, site:, api_key:, upload_timeout_seconds:, use_system_dns:)
|
|
14
|
+
timeout_milliseconds = (upload_timeout_seconds * 1_000).to_i
|
|
15
15
|
|
|
16
16
|
# Steep: multiple issues here
|
|
17
17
|
# first https://github.com/soutaro/steep/issues/363
|
|
18
18
|
# then https://github.com/soutaro/steep/issues/1603 (remove the .freeze to see it)
|
|
19
19
|
@exporter_configuration = # steep:ignore IncompatibleAssignment
|
|
20
20
|
if agentless?(site, api_key)
|
|
21
|
-
[:agentless, site, api_key].freeze
|
|
21
|
+
[:agentless, timeout_milliseconds, use_system_dns, site, api_key].freeze
|
|
22
22
|
else
|
|
23
|
-
[:agent, agent_settings.url].freeze
|
|
23
|
+
[:agent, timeout_milliseconds, use_system_dns, agent_settings.url].freeze
|
|
24
24
|
end
|
|
25
25
|
|
|
26
26
|
status, result = self.class._native_validate_exporter(exporter_configuration)
|
|
@@ -31,7 +31,6 @@ module Datadog
|
|
|
31
31
|
def export(flush)
|
|
32
32
|
status, result = self.class._native_do_export(
|
|
33
33
|
exporter_configuration,
|
|
34
|
-
@upload_timeout_milliseconds,
|
|
35
34
|
flush
|
|
36
35
|
)
|
|
37
36
|
|
|
@@ -63,7 +62,7 @@ module Datadog
|
|
|
63
62
|
end
|
|
64
63
|
|
|
65
64
|
def config_without_api_key
|
|
66
|
-
"#{exporter_configuration[0]}: #{exporter_configuration[
|
|
65
|
+
"#{exporter_configuration[0]}: #{exporter_configuration[3]}"
|
|
67
66
|
end
|
|
68
67
|
end
|
|
69
68
|
end
|
|
@@ -4,6 +4,6 @@ begin
|
|
|
4
4
|
require "datadog_profiling_native_extension.#{RUBY_VERSION}_#{RUBY_PLATFORM}"
|
|
5
5
|
rescue LoadError => e
|
|
6
6
|
raise LoadError,
|
|
7
|
-
"Failed to load the profiling
|
|
7
|
+
"Failed to load the profiling native extension. To fix this, please remove and then reinstall datadog " \
|
|
8
8
|
"(Details: #{e.message})"
|
|
9
9
|
end
|
|
@@ -17,17 +17,18 @@ module Datadog
|
|
|
17
17
|
@scheduler = scheduler
|
|
18
18
|
end
|
|
19
19
|
|
|
20
|
-
def enabled?
|
|
21
|
-
scheduler.running?
|
|
22
|
-
end
|
|
23
|
-
|
|
24
20
|
def start
|
|
25
21
|
after_fork! do
|
|
26
22
|
worker.reset_after_fork
|
|
27
23
|
scheduler.reset_after_fork
|
|
28
24
|
end
|
|
29
25
|
|
|
30
|
-
worker.start(
|
|
26
|
+
worker.start(
|
|
27
|
+
on_failure_proc: ->(log_failure: true) do
|
|
28
|
+
# @type var log_failure: bool
|
|
29
|
+
component_failed(:worker, log_failure: log_failure)
|
|
30
|
+
end
|
|
31
|
+
)
|
|
31
32
|
scheduler.start(on_failure_proc: proc { component_failed(:scheduler) })
|
|
32
33
|
end
|
|
33
34
|
|
|
@@ -50,13 +51,15 @@ module Datadog
|
|
|
50
51
|
scheduler.stop(true)
|
|
51
52
|
end
|
|
52
53
|
|
|
53
|
-
def component_failed(failed_component)
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
54
|
+
def component_failed(failed_component, log_failure: true)
|
|
55
|
+
if log_failure
|
|
56
|
+
Datadog.logger.warn(
|
|
57
|
+
"Detected issue with profiler (#{failed_component} component), stopping profiling. " \
|
|
58
|
+
"See previous log messages for details."
|
|
59
|
+
)
|
|
60
|
+
Datadog::Core::Telemetry::Logger
|
|
61
|
+
.error("Detected issue with profiler (#{failed_component} component), stopping profiling")
|
|
62
|
+
end
|
|
60
63
|
|
|
61
64
|
if failed_component == :worker
|
|
62
65
|
scheduler.disable_reporting
|
|
@@ -65,7 +65,7 @@ module Datadog
|
|
|
65
65
|
rescue Exception => e # rubocop:disable Lint/RescueException
|
|
66
66
|
Datadog.logger.warn(
|
|
67
67
|
"Profiling::Scheduler thread error. " \
|
|
68
|
-
"Cause: #{e.class
|
|
68
|
+
"Cause: #{e.class}: #{e} Location: #{Array(e.backtrace).first}"
|
|
69
69
|
)
|
|
70
70
|
on_failure_proc&.call
|
|
71
71
|
Datadog::Core::Telemetry::Logger.report(e, description: "Profiling::Scheduler thread error")
|
|
@@ -136,7 +136,7 @@ module Datadog
|
|
|
136
136
|
transport.export(flush)
|
|
137
137
|
rescue => e
|
|
138
138
|
Datadog.logger.warn(
|
|
139
|
-
"Unable to report profile. Cause: #{e.class
|
|
139
|
+
"Unable to report profile. Cause: #{e.class}: #{e} Location: #{Array(e.backtrace).first}"
|
|
140
140
|
)
|
|
141
141
|
Datadog::Core::Telemetry::Logger.report(e, description: "Unable to report profile")
|
|
142
142
|
end
|
|
@@ -38,10 +38,10 @@ module Datadog
|
|
|
38
38
|
def exec_with_error_handling(args)
|
|
39
39
|
Kernel.exec(*args)
|
|
40
40
|
rescue Errno::ENOENT => e
|
|
41
|
-
Kernel.warn "ddprofrb exec failed: #{e.class
|
|
41
|
+
Kernel.warn "ddprofrb exec failed: #{e.class}: #{e} (command was '#{args.join(" ")}')"
|
|
42
42
|
Kernel.exit 127
|
|
43
43
|
rescue Errno::EACCES, Errno::ENOEXEC => e
|
|
44
|
-
Kernel.warn "ddprofrb exec failed: #{e.class
|
|
44
|
+
Kernel.warn "ddprofrb exec failed: #{e.class}: #{e} (command was '#{args.join(" ")}')"
|
|
45
45
|
Kernel.exit 126
|
|
46
46
|
end
|
|
47
47
|
end
|
|
@@ -16,7 +16,7 @@ module Datadog
|
|
|
16
16
|
setup_at_fork_hooks
|
|
17
17
|
rescue StandardError, ScriptError => e
|
|
18
18
|
Datadog.logger.warn do
|
|
19
|
-
"Profiler extensions unavailable. Cause: #{e.class
|
|
19
|
+
"Profiler extensions unavailable. Cause: #{e.class}: #{e} " \
|
|
20
20
|
"Location: #{Array(e.backtrace).first}"
|
|
21
21
|
end
|
|
22
22
|
Datadog::Core::Telemetry::Logger.report(e, description: "Profiler extensions unavailable")
|
|
@@ -31,7 +31,7 @@ module Datadog
|
|
|
31
31
|
Profiling.start_if_enabled
|
|
32
32
|
rescue => e
|
|
33
33
|
Datadog.logger.warn do
|
|
34
|
-
"Error during post-fork hooks. Cause: #{e.class
|
|
34
|
+
"Error during post-fork hooks. Cause: #{e.class}: #{e} " \
|
|
35
35
|
"Location: #{Array(e.backtrace).first}"
|
|
36
36
|
end
|
|
37
37
|
Datadog::Core::Telemetry::Logger.report(e, description: "Error during post-fork hooks")
|
data/lib/datadog/profiling.rb
CHANGED
|
@@ -17,5 +17,5 @@ begin
|
|
|
17
17
|
require_relative 'auto_instrument'
|
|
18
18
|
Datadog::SingleStepInstrument.const_set(:LOADED, true)
|
|
19
19
|
rescue StandardError, LoadError => e
|
|
20
|
-
warn "Single step instrumentation failed: #{e.class}
|
|
20
|
+
warn "Single step instrumentation failed: #{e.class}: #{e}\n\tSource:\n\t#{Array(e.backtrace).join("\n\t")}"
|
|
21
21
|
end
|
|
@@ -56,7 +56,7 @@ module Datadog
|
|
|
56
56
|
@buffer_spans += trace.length
|
|
57
57
|
rescue => e
|
|
58
58
|
Datadog.logger.debug(
|
|
59
|
-
"Failed to measure queue accept. Cause: #{e.class
|
|
59
|
+
"Failed to measure queue accept. Cause: #{e.class}: #{e} Source: #{Array(e.backtrace).first}"
|
|
60
60
|
)
|
|
61
61
|
end
|
|
62
62
|
|
|
@@ -66,7 +66,7 @@ module Datadog
|
|
|
66
66
|
@buffer_spans -= trace.length
|
|
67
67
|
rescue => e
|
|
68
68
|
Datadog.logger.debug(
|
|
69
|
-
"Failed to measure queue drop. Cause: #{e.class
|
|
69
|
+
"Failed to measure queue drop. Cause: #{e.class}: #{e} Source: #{Array(e.backtrace).first}"
|
|
70
70
|
)
|
|
71
71
|
end
|
|
72
72
|
|
|
@@ -91,7 +91,7 @@ module Datadog
|
|
|
91
91
|
@buffer_spans = 0
|
|
92
92
|
rescue => e
|
|
93
93
|
Datadog.logger.debug(
|
|
94
|
-
"Failed to measure queue. Cause: #{e.class
|
|
94
|
+
"Failed to measure queue. Cause: #{e.class}: #{e} Source: #{Array(e.backtrace).first}"
|
|
95
95
|
)
|
|
96
96
|
end
|
|
97
97
|
end
|