datadog 2.30.0 → 2.32.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 +44 -1
- data/ext/datadog_profiling_native_extension/collectors_cpu_and_wall_time_worker.c +17 -7
- data/ext/datadog_profiling_native_extension/collectors_thread_context.c +11 -4
- data/ext/datadog_profiling_native_extension/collectors_thread_context.h +6 -0
- 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 +7 -4
- data/ext/datadog_profiling_native_extension/http_transport.c +10 -5
- data/ext/libdatadog_api/crashtracker.c +5 -8
- 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 +127 -0
- data/ext/libdatadog_api/extconf.rb +9 -4
- data/ext/libdatadog_api/init.c +5 -2
- data/ext/libdatadog_extconf_helpers.rb +46 -1
- data/lib/datadog/ai_guard/component.rb +2 -0
- data/lib/datadog/ai_guard/configuration.rb +105 -2
- 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 +37 -7
- data/lib/datadog/ai_guard/ext.rb +1 -0
- 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/configuration.rb +414 -1
- data/lib/datadog/appsec/contrib/devise/patches/signin_tracking_patch.rb +2 -1
- data/lib/datadog/appsec/contrib/rack/gateway/watcher.rb +6 -7
- data/lib/datadog/appsec/instrumentation/gateway.rb +0 -13
- data/lib/datadog/appsec/metrics/telemetry.rb +13 -1
- data/lib/datadog/appsec/monitor/gateway/watcher.rb +2 -0
- data/lib/datadog/appsec/security_engine/runner.rb +1 -1
- data/lib/datadog/appsec/trace_keeper.rb +18 -6
- data/lib/datadog/appsec/utils/http/media_type.rb +1 -2
- data/lib/datadog/appsec/utils/http/url_encoded.rb +3 -3
- data/lib/datadog/appsec.rb +5 -9
- data/lib/datadog/core/configuration/base.rb +17 -5
- data/lib/datadog/core/configuration/components.rb +22 -9
- data/lib/datadog/core/configuration/config_helper.rb +9 -0
- data/lib/datadog/core/configuration/option.rb +30 -5
- data/lib/datadog/core/configuration/option_definition.rb +38 -12
- data/lib/datadog/core/configuration/options.rb +40 -6
- data/lib/datadog/core/configuration/settings.rb +18 -0
- data/lib/datadog/core/configuration/supported_configurations.rb +3 -0
- data/lib/datadog/core/configuration.rb +1 -1
- 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 +3 -3
- data/lib/datadog/core/diagnostics/environment_logger.rb +3 -1
- 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/feature_flags.rb +1 -1
- data/lib/datadog/core/metrics/client.rb +5 -5
- data/lib/datadog/core/remote/client.rb +1 -1
- data/lib/datadog/core/remote/component.rb +38 -21
- data/lib/datadog/core/runtime/metrics.rb +1 -1
- data/lib/datadog/core/telemetry/component.rb +3 -0
- data/lib/datadog/core/telemetry/emitter.rb +1 -1
- 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/transport/http.rb +2 -0
- 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/utils.rb +1 -1
- data/lib/datadog/core/workers/async.rb +1 -1
- data/lib/datadog/core.rb +1 -2
- data/lib/datadog/data_streams/configuration.rb +40 -1
- data/lib/datadog/data_streams/pathway_context.rb +1 -1
- data/lib/datadog/data_streams/processor.rb +1 -1
- data/lib/datadog/data_streams.rb +1 -1
- data/lib/datadog/di/base.rb +8 -5
- data/lib/datadog/di/boot.rb +2 -4
- data/lib/datadog/di/code_tracker.rb +179 -1
- data/lib/datadog/di/component.rb +5 -1
- data/lib/datadog/di/configuration.rb +235 -2
- data/lib/datadog/di/instrumenter.rb +55 -29
- data/lib/datadog/di/probe_builder.rb +1 -1
- data/lib/datadog/di/probe_file_loader.rb +2 -2
- data/lib/datadog/di/probe_manager.rb +6 -6
- data/lib/datadog/di/probe_notification_builder.rb +110 -2
- data/lib/datadog/di/probe_notifier_worker.rb +2 -2
- data/lib/datadog/di/remote.rb +6 -6
- data/lib/datadog/di/transport/input.rb +3 -3
- data/lib/datadog/di.rb +81 -0
- data/lib/datadog/error_tracking/configuration.rb +55 -2
- data/lib/datadog/kit/enable_core_dumps.rb +1 -1
- data/lib/datadog/open_feature/component.rb +18 -1
- data/lib/datadog/open_feature/evaluation_engine.rb +2 -2
- data/lib/datadog/open_feature/hooks/flag_eval_hook.rb +49 -0
- data/lib/datadog/open_feature/metrics/flag_eval_metrics.rb +149 -0
- data/lib/datadog/open_feature/provider.rb +19 -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/opentelemetry/metrics.rb +3 -3
- data/lib/datadog/opentelemetry/sdk/configurator.rb +1 -1
- data/lib/datadog/opentelemetry/sdk/metrics_exporter.rb +1 -1
- data/lib/datadog/profiling/collectors/code_provenance.rb +36 -11
- data/lib/datadog/profiling/collectors/cpu_and_wall_time_worker.rb +31 -2
- data/lib/datadog/profiling/collectors/idle_sampling_helper.rb +8 -2
- data/lib/datadog/profiling/collectors/info.rb +16 -3
- data/lib/datadog/profiling/component.rb +12 -4
- data/lib/datadog/profiling/exporter.rb +37 -12
- data/lib/datadog/profiling/ext.rb +0 -2
- data/lib/datadog/profiling/flush.rb +21 -12
- data/lib/datadog/profiling/http_transport.rb +12 -1
- data/lib/datadog/profiling/load_native_extension.rb +2 -2
- data/lib/datadog/profiling/profiler.rb +13 -5
- data/lib/datadog/profiling/scheduler.rb +2 -2
- data/lib/datadog/profiling/tasks/exec.rb +8 -3
- data/lib/datadog/profiling/tasks/help.rb +1 -0
- 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/symbol_database/configuration.rb +65 -0
- data/lib/datadog/symbol_database/extractor.rb +915 -0
- data/lib/datadog/symbol_database/file_hash.rb +46 -0
- data/lib/datadog/symbol_database/logger.rb +43 -0
- data/lib/datadog/symbol_database/scope.rb +98 -0
- data/lib/datadog/symbol_database/service_version.rb +57 -0
- data/lib/datadog/symbol_database/symbol.rb +66 -0
- data/lib/datadog/symbol_database/transport/http/endpoint.rb +28 -0
- data/lib/datadog/symbol_database/transport/http.rb +45 -0
- data/lib/datadog/symbol_database/transport.rb +54 -0
- data/lib/datadog/symbol_database/uploader.rb +166 -0
- data/lib/datadog/symbol_database.rb +49 -0
- 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 +5 -3
- 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/configuration/resolver.rb +2 -2
- 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/component.rb +1 -1
- data/lib/datadog/tracing/contrib/configurable.rb +18 -3
- data/lib/datadog/tracing/contrib/configuration/resolver.rb +7 -4
- data/lib/datadog/tracing/contrib/dalli/quantize.rb +1 -1
- data/lib/datadog/tracing/contrib/elasticsearch/patcher.rb +1 -1
- data/lib/datadog/tracing/contrib/excon/middleware.rb +2 -2
- data/lib/datadog/tracing/contrib/extensions.rb +9 -0
- data/lib/datadog/tracing/contrib/faraday/middleware.rb +2 -2
- data/lib/datadog/tracing/contrib/grape/endpoint.rb +5 -5
- data/lib/datadog/tracing/contrib/grpc/datadog_interceptor/client.rb +2 -2
- data/lib/datadog/tracing/contrib/grpc/datadog_interceptor/server.rb +2 -2
- data/lib/datadog/tracing/contrib/http/instrumentation.rb +3 -3
- data/lib/datadog/tracing/contrib/httpclient/instrumentation.rb +6 -2
- data/lib/datadog/tracing/contrib/httprb/instrumentation.rb +3 -3
- data/lib/datadog/tracing/contrib/kafka/instrumentation/consumer.rb +2 -2
- data/lib/datadog/tracing/contrib/kafka/instrumentation/producer.rb +2 -2
- data/lib/datadog/tracing/contrib/karafka/patcher.rb +1 -1
- data/lib/datadog/tracing/contrib/mongodb/subscribers.rb +3 -3
- data/lib/datadog/tracing/contrib/opensearch/patcher.rb +1 -1
- data/lib/datadog/tracing/contrib/presto/instrumentation.rb +3 -3
- data/lib/datadog/tracing/contrib/rack/patcher.rb +1 -1
- data/lib/datadog/tracing/contrib/rack/request_queue.rb +1 -1
- 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/quantize.rb +1 -1
- data/lib/datadog/tracing/contrib/redis/tags.rb +1 -1
- data/lib/datadog/tracing/contrib/sidekiq/utils.rb +1 -1
- 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.rb +8 -0
- data/lib/datadog/tracing/diagnostics/environment_logger.rb +3 -1
- data/lib/datadog/tracing/distributed/baggage.rb +59 -5
- data/lib/datadog/tracing/distributed/datadog.rb +13 -11
- data/lib/datadog/tracing/distributed/datadog_tags_codec.rb +1 -1
- data/lib/datadog/tracing/distributed/propagation.rb +2 -2
- data/lib/datadog/tracing/distributed/trace_context.rb +74 -32
- data/lib/datadog/tracing/event.rb +1 -1
- data/lib/datadog/tracing/metadata/tagging.rb +2 -2
- data/lib/datadog/tracing/pipeline.rb +1 -1
- 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 +2 -2
- data/lib/datadog/tracing/span_operation.rb +4 -4
- data/lib/datadog/tracing/trace_operation.rb +53 -9
- data/lib/datadog/tracing/tracer.rb +29 -4
- data/lib/datadog/tracing/transport/io/client.rb +1 -1
- data/lib/datadog/tracing/transport/trace_formatter.rb +1 -1
- data/lib/datadog/tracing/workers.rb +2 -1
- data/lib/datadog/version.rb +1 -1
- metadata +27 -12
- data/lib/datadog/ai_guard/configuration/settings.rb +0 -113
- data/lib/datadog/appsec/configuration/settings.rb +0 -423
- data/lib/datadog/data_streams/configuration/settings.rb +0 -49
- data/lib/datadog/di/configuration/settings.rb +0 -243
- data/lib/datadog/error_tracking/configuration/settings.rb +0 -63
|
@@ -10,13 +10,6 @@ module Datadog
|
|
|
10
10
|
#
|
|
11
11
|
# @api private
|
|
12
12
|
module Event
|
|
13
|
-
extend Core::Utils::Forking
|
|
14
|
-
|
|
15
|
-
# returns sequence that increments every time the configuration changes
|
|
16
|
-
def self.configuration_sequence
|
|
17
|
-
after_fork! { @sequence = Datadog::Core::Utils::Sequence.new(1) }
|
|
18
|
-
@sequence ||= Datadog::Core::Utils::Sequence.new(1)
|
|
19
|
-
end
|
|
20
13
|
end
|
|
21
14
|
end
|
|
22
15
|
end
|
|
@@ -25,6 +18,7 @@ end
|
|
|
25
18
|
require_relative 'event/base'
|
|
26
19
|
require_relative 'event/app_client_configuration_change'
|
|
27
20
|
require_relative 'event/app_closing'
|
|
21
|
+
require_relative 'event/app_extended_heartbeat'
|
|
28
22
|
require_relative 'event/app_dependencies_loaded'
|
|
29
23
|
require_relative 'event/app_endpoints_loaded'
|
|
30
24
|
require_relative 'event/app_heartbeat'
|
|
@@ -7,6 +7,7 @@ module Datadog
|
|
|
7
7
|
ENV_ENABLED = 'DD_INSTRUMENTATION_TELEMETRY_ENABLED'
|
|
8
8
|
ENV_METRICS_ENABLED = 'DD_TELEMETRY_METRICS_ENABLED'
|
|
9
9
|
ENV_HEARTBEAT_INTERVAL = 'DD_TELEMETRY_HEARTBEAT_INTERVAL'
|
|
10
|
+
ENV_EXTENDED_HEARTBEAT_INTERVAL = 'DD_TELEMETRY_EXTENDED_HEARTBEAT_INTERVAL'
|
|
10
11
|
ENV_METRICS_AGGREGATION_INTERVAL = 'DD_TELEMETRY_METRICS_AGGREGATION_INTERVAL'
|
|
11
12
|
ENV_DEPENDENCY_COLLECTION = 'DD_TELEMETRY_DEPENDENCY_COLLECTION_ENABLED'
|
|
12
13
|
ENV_INSTALL_ID = 'DD_INSTRUMENTATION_INSTALL_ID'
|
|
@@ -44,11 +44,16 @@ module Datadog
|
|
|
44
44
|
'DD-Telemetry-Request-Type' => request_type,
|
|
45
45
|
'DD-Client-Library-Language' => Core::Environment::Ext::LANG,
|
|
46
46
|
'DD-Client-Library-Version' => Core::Environment::Identity.gem_datadog_version_semver2,
|
|
47
|
+
'DD-Session-ID' => Core::Environment::Identity.id,
|
|
47
48
|
|
|
48
49
|
# Enable debug mode for telemetry
|
|
49
50
|
# 'DD-Telemetry-Debug-Enabled' => 'true',
|
|
50
51
|
}.tap do |result|
|
|
51
52
|
result['DD-API-KEY'] = api_key unless api_key.nil?
|
|
53
|
+
root = Core::Environment::Identity.root_runtime_id
|
|
54
|
+
result['DD-Root-Session-ID'] = root if root
|
|
55
|
+
parent = Core::Environment::Identity.parent_runtime_id
|
|
56
|
+
result['DD-Parent-Session-ID'] = parent if parent
|
|
52
57
|
end
|
|
53
58
|
end
|
|
54
59
|
end
|
|
@@ -27,6 +27,9 @@ module Datadog
|
|
|
27
27
|
metrics_manager:,
|
|
28
28
|
dependency_collection:,
|
|
29
29
|
logger:,
|
|
30
|
+
settings:,
|
|
31
|
+
agent_settings:,
|
|
32
|
+
extended_heartbeat_interval_seconds:,
|
|
30
33
|
enabled: true,
|
|
31
34
|
shutdown_timeout: Workers::Polling::DEFAULT_SHUTDOWN_TIMEOUT,
|
|
32
35
|
buffer_size: DEFAULT_BUFFER_MAX_SIZE
|
|
@@ -35,8 +38,11 @@ module Datadog
|
|
|
35
38
|
@metrics_manager = metrics_manager
|
|
36
39
|
@dependency_collection = dependency_collection
|
|
37
40
|
@logger = logger
|
|
41
|
+
@settings = settings
|
|
42
|
+
@agent_settings = agent_settings
|
|
38
43
|
|
|
39
44
|
@ticks_per_heartbeat = (heartbeat_interval_seconds / metrics_aggregation_interval_seconds).to_i
|
|
45
|
+
@ticks_per_extended_heartbeat = (extended_heartbeat_interval_seconds / metrics_aggregation_interval_seconds).to_i
|
|
40
46
|
@current_ticks = 0
|
|
41
47
|
|
|
42
48
|
# Workers::Polling settings
|
|
@@ -63,6 +69,7 @@ module Datadog
|
|
|
63
69
|
self.buffer = buffer_klass.new(@buffer_size)
|
|
64
70
|
|
|
65
71
|
@initial_event_once = Utils::OnlyOnceSuccessful.new(APP_STARTED_EVENT_RETRIES)
|
|
72
|
+
@extended_heartbeat_ticks = 0
|
|
66
73
|
end
|
|
67
74
|
|
|
68
75
|
attr_reader :logger
|
|
@@ -151,6 +158,13 @@ module Datadog
|
|
|
151
158
|
end
|
|
152
159
|
|
|
153
160
|
@current_ticks += 1
|
|
161
|
+
@extended_heartbeat_ticks += 1
|
|
162
|
+
|
|
163
|
+
if @extended_heartbeat_ticks >= @ticks_per_extended_heartbeat
|
|
164
|
+
@extended_heartbeat_ticks = 0
|
|
165
|
+
extended_heartbeat!
|
|
166
|
+
end
|
|
167
|
+
|
|
154
168
|
return if @current_ticks < @ticks_per_heartbeat
|
|
155
169
|
|
|
156
170
|
@current_ticks = 0
|
|
@@ -170,6 +184,12 @@ module Datadog
|
|
|
170
184
|
send_event(Event::AppHeartbeat.new)
|
|
171
185
|
end
|
|
172
186
|
|
|
187
|
+
def extended_heartbeat!
|
|
188
|
+
return if !enabled? || !sent_initial_event?
|
|
189
|
+
|
|
190
|
+
send_event(Event::AppExtendedHeartbeat.new(settings: @settings, agent_settings: @agent_settings))
|
|
191
|
+
end
|
|
192
|
+
|
|
173
193
|
def started!
|
|
174
194
|
return unless enabled?
|
|
175
195
|
|
|
@@ -4,6 +4,8 @@ require_relative 'http/builder'
|
|
|
4
4
|
require_relative 'http/adapters/net'
|
|
5
5
|
require_relative 'http/adapters/unix_socket'
|
|
6
6
|
require_relative 'http/adapters/test'
|
|
7
|
+
require_relative '../environment/container'
|
|
8
|
+
require_relative '../environment/ext'
|
|
7
9
|
|
|
8
10
|
module Datadog
|
|
9
11
|
module Core
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
module Datadog
|
|
4
4
|
module Core
|
|
5
5
|
module Utils
|
|
6
|
-
# Helper class to execute something only once such as not repeating warning logs
|
|
6
|
+
# Helper class to execute something only once, such as not repeating warning logs and instrumenting classes
|
|
7
7
|
# only once.
|
|
8
8
|
#
|
|
9
9
|
# Thread-safe when used correctly (e.g. be careful of races when lazily initializing instances of this class).
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Datadog
|
|
4
|
+
module Core
|
|
5
|
+
module Utils
|
|
6
|
+
module SpawnMonkeyPatch
|
|
7
|
+
# @param lineage_envs_provider [#call] returns a Hash of env vars to merge into the child process
|
|
8
|
+
def self.apply!(lineage_envs_provider:)
|
|
9
|
+
@lineage_envs_provider = lineage_envs_provider
|
|
10
|
+
::Process.singleton_class.prepend(ProcessSpawnPatch)
|
|
11
|
+
true
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
module ProcessSpawnPatch
|
|
15
|
+
def spawn(*args, **opts)
|
|
16
|
+
args.replace(SpawnMonkeyPatch.inject_lineage_envs(args))
|
|
17
|
+
super
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
# Process.spawn(env?, cmd, ...): env is optional first arg (Hash). When present, merge
|
|
22
|
+
# runtime_ids into it; when absent, prepend full ENV + runtime_ids so the child inherits both.
|
|
23
|
+
def self.inject_lineage_envs(args)
|
|
24
|
+
runtime_ids = @lineage_envs_provider.call
|
|
25
|
+
env_provided = Hash === args.first
|
|
26
|
+
|
|
27
|
+
base_env = env_provided ? args.first : DATADOG_ENV.to_h
|
|
28
|
+
env = base_env.merge(runtime_ids)
|
|
29
|
+
rest = env_provided ? args.drop(1) : args
|
|
30
|
+
|
|
31
|
+
[env, *rest]
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
data/lib/datadog/core/utils.rb
CHANGED
|
@@ -168,7 +168,7 @@ module Datadog
|
|
|
168
168
|
rescue Exception => e
|
|
169
169
|
@error = e
|
|
170
170
|
Datadog.logger.debug(
|
|
171
|
-
"Worker thread error. Cause: #{e.class
|
|
171
|
+
"Worker thread error. Cause: #{e.class}: #{e.message} Location: #{Array(e.backtrace).first}"
|
|
172
172
|
)
|
|
173
173
|
raise
|
|
174
174
|
|
data/lib/datadog/core.rb
CHANGED
|
@@ -18,11 +18,10 @@ module Datadog
|
|
|
18
18
|
require "libdatadog_api.#{RUBY_VERSION[/\d+.\d+/]}_#{RUBY_PLATFORM}"
|
|
19
19
|
nil
|
|
20
20
|
rescue LoadError => e
|
|
21
|
-
e.message
|
|
21
|
+
"#{e.class}: #{e.message}"
|
|
22
22
|
end
|
|
23
23
|
end
|
|
24
24
|
|
|
25
|
-
DATADOG_ENV = Core::Configuration::ConfigHelper.new
|
|
26
25
|
extend Core::Extensions
|
|
27
26
|
|
|
28
27
|
# Add shutdown hook:
|
|
@@ -1,11 +1,50 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require_relative '
|
|
3
|
+
require_relative '../core/environment/variable_helpers'
|
|
4
|
+
require_relative 'ext'
|
|
4
5
|
|
|
5
6
|
module Datadog
|
|
6
7
|
module DataStreams
|
|
7
8
|
# Configuration for Data Streams Monitoring
|
|
8
9
|
module Configuration
|
|
10
|
+
# Configuration settings for Data Streams Monitoring.
|
|
11
|
+
module Settings
|
|
12
|
+
def self.extended(base)
|
|
13
|
+
base = base.singleton_class unless base.is_a?(Class)
|
|
14
|
+
add_settings!(base)
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def self.add_settings!(base)
|
|
18
|
+
base.class_eval do
|
|
19
|
+
# Data Streams Monitoring configuration
|
|
20
|
+
# @public_api
|
|
21
|
+
settings :data_streams do
|
|
22
|
+
# Whether Data Streams Monitoring is enabled. When enabled, the library will
|
|
23
|
+
# collect and report data lineage information for messaging systems.
|
|
24
|
+
#
|
|
25
|
+
# @default `DD_DATA_STREAMS_ENABLED` environment variable, otherwise `false`.
|
|
26
|
+
# @return [Boolean]
|
|
27
|
+
option :enabled do |o|
|
|
28
|
+
o.type :bool
|
|
29
|
+
o.env Ext::ENV_ENABLED
|
|
30
|
+
o.default false
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
# The interval (in seconds) at which Data Streams Monitoring stats are flushed.
|
|
34
|
+
#
|
|
35
|
+
# @default 10.0
|
|
36
|
+
# @env '_DD_TRACE_STATS_WRITER_INTERVAL'
|
|
37
|
+
# @return [Float]
|
|
38
|
+
# @!visibility private
|
|
39
|
+
option :interval do |o|
|
|
40
|
+
o.type :float
|
|
41
|
+
o.env '_DD_TRACE_STATS_WRITER_INTERVAL'
|
|
42
|
+
o.default 10.0
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
end
|
|
9
48
|
end
|
|
10
49
|
end
|
|
11
50
|
end
|
|
@@ -46,7 +46,7 @@ module Datadog
|
|
|
46
46
|
decode(binary_data)
|
|
47
47
|
rescue ArgumentError => e
|
|
48
48
|
# Invalid base64 encoding - may indicate version mismatch or corruption
|
|
49
|
-
Datadog.logger.debug
|
|
49
|
+
Datadog.logger.debug { "Failed to decode DSM pathway context: #{e.class}: #{e.message}" }
|
|
50
50
|
nil
|
|
51
51
|
end
|
|
52
52
|
end
|
|
@@ -329,7 +329,7 @@ module Datadog
|
|
|
329
329
|
# Send to agent outside mutex to avoid blocking customer code if agent is slow/hung.
|
|
330
330
|
send_stats_to_agent(payload)
|
|
331
331
|
rescue => e
|
|
332
|
-
@logger.debug("Failed to flush DSM stats to agent: #{e.class}: #{e}")
|
|
332
|
+
@logger.debug("Failed to flush DSM stats to agent: #{e.class}: #{e.message}")
|
|
333
333
|
end
|
|
334
334
|
|
|
335
335
|
def get_current_pathway
|
data/lib/datadog/data_streams.rb
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
require_relative 'data_streams/processor'
|
|
4
4
|
require_relative 'data_streams/pathway_context'
|
|
5
|
-
require_relative 'data_streams/configuration
|
|
5
|
+
require_relative 'data_streams/configuration'
|
|
6
6
|
require_relative 'data_streams/extensions'
|
|
7
7
|
require_relative 'core/utils/time'
|
|
8
8
|
|
data/lib/datadog/di/base.rb
CHANGED
|
@@ -17,6 +17,10 @@ module Datadog
|
|
|
17
17
|
module DI
|
|
18
18
|
LOCK = Mutex.new
|
|
19
19
|
|
|
20
|
+
# Initialized eagerly to avoid "instance variable not initialized"
|
|
21
|
+
# warning on Ruby 2.6/2.7 and to simplify the type to non-nullable.
|
|
22
|
+
@current_components = []
|
|
23
|
+
|
|
20
24
|
class << self
|
|
21
25
|
attr_reader :code_tracker
|
|
22
26
|
|
|
@@ -48,12 +52,12 @@ module Datadog
|
|
|
48
52
|
Datadog::DI.activate_tracking!
|
|
49
53
|
rescue => exc
|
|
50
54
|
if defined?(Datadog.logger)
|
|
51
|
-
Datadog.logger.warn { "di: Failed to activate code tracking for DI: #{exc.class}: #{exc}" }
|
|
55
|
+
Datadog.logger.warn { "di: Failed to activate code tracking for DI: #{exc.class}: #{exc.message}" }
|
|
52
56
|
else
|
|
53
57
|
# We do not have Datadog logger potentially because DI code tracker is
|
|
54
58
|
# being loaded early in application boot process and the rest of datadog
|
|
55
59
|
# wasn't loaded yet. Output to standard error.
|
|
56
|
-
warn("datadog: di: Failed to activate code tracking for DI: #{exc.class}: #{exc}")
|
|
60
|
+
warn("datadog: di: Failed to activate code tracking for DI: #{exc.class}: #{exc.message}")
|
|
57
61
|
end
|
|
58
62
|
end
|
|
59
63
|
end
|
|
@@ -88,7 +92,7 @@ module Datadog
|
|
|
88
92
|
# Datadog.components from the code tracker.
|
|
89
93
|
def current_component
|
|
90
94
|
LOCK.synchronize do
|
|
91
|
-
@current_components
|
|
95
|
+
@current_components.last
|
|
92
96
|
end
|
|
93
97
|
end
|
|
94
98
|
|
|
@@ -100,14 +104,13 @@ module Datadog
|
|
|
100
104
|
# guaranteed to not end up with no component when one is running.
|
|
101
105
|
def add_current_component(component)
|
|
102
106
|
LOCK.synchronize do
|
|
103
|
-
@current_components ||= []
|
|
104
107
|
@current_components << component
|
|
105
108
|
end
|
|
106
109
|
end
|
|
107
110
|
|
|
108
111
|
def remove_current_component(component)
|
|
109
112
|
LOCK.synchronize do
|
|
110
|
-
@current_components
|
|
113
|
+
@current_components.delete(component)
|
|
111
114
|
end
|
|
112
115
|
end
|
|
113
116
|
end
|
data/lib/datadog/di/boot.rb
CHANGED
|
@@ -18,8 +18,7 @@ require_relative 'serializer'
|
|
|
18
18
|
require_relative 'transport/http'
|
|
19
19
|
require_relative 'utils'
|
|
20
20
|
|
|
21
|
-
|
|
22
|
-
if %w[1 true yes].include?(Datadog::DATADOG_ENV['DD_DYNAMIC_INSTRUMENTATION_ENABLED']) # steep:ignore ArgumentTypeMismatch
|
|
21
|
+
if %w[1 true yes].include?(Datadog::DATADOG_ENV['DD_DYNAMIC_INSTRUMENTATION_ENABLED'])
|
|
23
22
|
|
|
24
23
|
# For initial release of Dynamic Instrumentation, activate code tracking
|
|
25
24
|
# only if DI is explicitly requested in the environment.
|
|
@@ -37,8 +36,7 @@ require_relative 'contrib'
|
|
|
37
36
|
|
|
38
37
|
Datadog::DI::Contrib.load_now_or_later
|
|
39
38
|
|
|
40
|
-
|
|
41
|
-
if %w[1 true yes].include?(Datadog::DATADOG_ENV['DD_DYNAMIC_INSTRUMENTATION_ENABLED']) # steep:ignore ArgumentTypeMismatch
|
|
39
|
+
if %w[1 true yes].include?(Datadog::DATADOG_ENV['DD_DYNAMIC_INSTRUMENTATION_ENABLED'])
|
|
42
40
|
if Datadog::DATADOG_ENV['DD_DYNAMIC_INSTRUMENTATION_PROBE_FILE']
|
|
43
41
|
require_relative 'probe_file_loader'
|
|
44
42
|
Datadog::DI::ProbeFileLoader.load_now_or_later
|
|
@@ -22,11 +22,114 @@ module Datadog
|
|
|
22
22
|
class CodeTracker
|
|
23
23
|
def initialize
|
|
24
24
|
@registry = {}
|
|
25
|
+
@per_method_registry = {}
|
|
25
26
|
@trace_point_lock = Mutex.new
|
|
26
27
|
@registry_lock = Mutex.new
|
|
27
28
|
@compiled_trace_point = nil
|
|
28
29
|
end
|
|
29
30
|
|
|
31
|
+
# Populates the registry with iseqs for files that were loaded
|
|
32
|
+
# before code tracking started.
|
|
33
|
+
#
|
|
34
|
+
# Uses the all_iseqs C extension to walk the Ruby object space and
|
|
35
|
+
# find instruction sequences for already-loaded code. Whole-file
|
|
36
|
+
# iseqs are stored in the main registry; per-method/block/class
|
|
37
|
+
# iseqs are stored in per_method_registry as fallback for files
|
|
38
|
+
# whose whole-file iseq was GC'd.
|
|
39
|
+
#
|
|
40
|
+
# See docs/DynamicInstrumentationDevelopment.md "Iseq Lifecycle and GC"
|
|
41
|
+
# for which iseq types survive GC and implications for backfill.
|
|
42
|
+
#
|
|
43
|
+
# Whole-file detection uses two strategies:
|
|
44
|
+
# - Ruby 3.1+: DI.iseq_type (wraps rb_iseq_type) returns :top for
|
|
45
|
+
# require/load and :main for the entry script. This is precise.
|
|
46
|
+
# - Ruby < 3.1: falls back to first_lineno == 0, which is true for
|
|
47
|
+
# whole-file iseqs from require/load (INT2FIX(0) in Ruby's
|
|
48
|
+
# rb_iseq_new_top and rb_iseq_new_main) and false for
|
|
49
|
+
# method/block/class definitions (first_lineno >= 1).
|
|
50
|
+
# InstructionSequence.compile passes first_lineno = 1 by default,
|
|
51
|
+
# so eval'd code is not matched. Both strategies produce the same
|
|
52
|
+
# result in practice.
|
|
53
|
+
#
|
|
54
|
+
# Does not overwrite iseqs already in the registry (from
|
|
55
|
+
# :script_compiled), since those are guaranteed to be whole-file
|
|
56
|
+
# iseqs and are authoritative.
|
|
57
|
+
#
|
|
58
|
+
# @return [void]
|
|
59
|
+
def backfill_registry
|
|
60
|
+
iseqs = DI.file_iseqs
|
|
61
|
+
have_iseq_type = DI.respond_to?(:iseq_type)
|
|
62
|
+
registry_lock.synchronize do
|
|
63
|
+
iseqs.each do |iseq|
|
|
64
|
+
path = iseq.absolute_path
|
|
65
|
+
next unless path
|
|
66
|
+
|
|
67
|
+
whole_file = if have_iseq_type
|
|
68
|
+
type = DI.iseq_type(iseq)
|
|
69
|
+
# Require first_lineno == 0 to exclude compile_file/compile
|
|
70
|
+
# iseqs. These are :top type but have first_lineno == 1 and
|
|
71
|
+
# produce iseq objects distinct from require-produced iseqs.
|
|
72
|
+
# Targeted TracePoints are bound to the specific iseq object
|
|
73
|
+
# — a probe on a compile_file iseq silently never fires when
|
|
74
|
+
# the require-produced code runs.
|
|
75
|
+
(type == :top || type == :main) && iseq.first_lineno == 0
|
|
76
|
+
else
|
|
77
|
+
iseq.first_lineno == 0
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
if whole_file
|
|
81
|
+
# Ruby 3.2.9+ creates dummy profiler iseqs during require/load
|
|
82
|
+
# (rb_iseq_alloc_with_dummy_path in iseq.c). These have type
|
|
83
|
+
# :top, first_lineno == 0, and the same absolute_path as the
|
|
84
|
+
# real iseq — but iseq_size == 0 (no bytecode). A targeted
|
|
85
|
+
# TracePoint on a dummy iseq can't find child iseqs and raises
|
|
86
|
+
# ArgumentError "can not enable any hooks". Filter them out:
|
|
87
|
+
# a real top-level iseq always has at least one trace event.
|
|
88
|
+
next if iseq.trace_points.empty?
|
|
89
|
+
|
|
90
|
+
# Do not overwrite entries from :script_compiled — those are
|
|
91
|
+
# captured at load time and are authoritative.
|
|
92
|
+
next if registry.key?(path)
|
|
93
|
+
|
|
94
|
+
registry[path] = iseq
|
|
95
|
+
else
|
|
96
|
+
# Skip top-level script iseqs (:top/:main) produced by
|
|
97
|
+
# RubyVM::InstructionSequence.compile_file and .compile
|
|
98
|
+
# (compile source to bytecode without executing it).
|
|
99
|
+
# These represent the file body,
|
|
100
|
+
# not a method or block. They pass the first_lineno check
|
|
101
|
+
# (lineno != 0) but a targeted TracePoint bound to one
|
|
102
|
+
# of these never fires for method-level code — the
|
|
103
|
+
# user's probe silently produces no snapshots.
|
|
104
|
+
#
|
|
105
|
+
# On Ruby < 3.1 (no iseq_type), we cannot distinguish
|
|
106
|
+
# these from method iseqs, so they leak into
|
|
107
|
+
# per_method_registry. If iseq_for_line selects a leaked
|
|
108
|
+
# top-level iseq instead of the real method iseq, the
|
|
109
|
+
# probe installs but silently never fires — same failure
|
|
110
|
+
# as above. This requires the application to call
|
|
111
|
+
# compile_file and hold the result, which is rare outside
|
|
112
|
+
# tooling like bootsnap (which discards it).
|
|
113
|
+
next if have_iseq_type && (type == :top || type == :main)
|
|
114
|
+
|
|
115
|
+
# Store per-method/block/class iseqs as fallback for files
|
|
116
|
+
# whose whole-file iseq was GC'd. These can be used to
|
|
117
|
+
# target line probes on lines within their range.
|
|
118
|
+
(per_method_registry[path] ||= []) << iseq
|
|
119
|
+
end
|
|
120
|
+
end
|
|
121
|
+
end
|
|
122
|
+
nil
|
|
123
|
+
rescue => exc
|
|
124
|
+
# Backfill is best-effort — if it fails, line probes on
|
|
125
|
+
# pre-loaded code won't work but everything else is unaffected.
|
|
126
|
+
if component = DI.current_component
|
|
127
|
+
component.logger.debug { "di: backfill_registry failed: #{exc.class}: #{exc.message}" }
|
|
128
|
+
component.telemetry&.report(exc, description: "backfill_registry failed")
|
|
129
|
+
end
|
|
130
|
+
nil
|
|
131
|
+
end
|
|
132
|
+
|
|
30
133
|
# Starts tracking loaded code.
|
|
31
134
|
#
|
|
32
135
|
# This method should generally be called early in application boot
|
|
@@ -94,7 +197,7 @@ module Datadog
|
|
|
94
197
|
# but we will have DI.current_component (set to nil).
|
|
95
198
|
if component = DI.current_component
|
|
96
199
|
raise if component.settings.dynamic_instrumentation.internal.propagate_all_exceptions
|
|
97
|
-
component.logger.debug { "di: unhandled exception in script_compiled trace point: #{exc.class}: #{exc}" }
|
|
200
|
+
component.logger.debug { "di: unhandled exception in script_compiled trace point: #{exc.class}: #{exc.message}" }
|
|
98
201
|
component.telemetry&.report(exc, description: "Unhandled exception in script_compiled trace point")
|
|
99
202
|
# TODO test this path
|
|
100
203
|
else
|
|
@@ -104,6 +207,12 @@ module Datadog
|
|
|
104
207
|
# TODO test this path
|
|
105
208
|
end
|
|
106
209
|
end
|
|
210
|
+
|
|
211
|
+
# Backfill the registry with iseqs for files that were loaded
|
|
212
|
+
# before tracking started. This must happen after the trace
|
|
213
|
+
# point is enabled so that any files loaded concurrently are
|
|
214
|
+
# captured by the trace point (backfill won't overwrite them).
|
|
215
|
+
backfill_registry
|
|
107
216
|
end
|
|
108
217
|
end
|
|
109
218
|
|
|
@@ -160,6 +269,51 @@ module Datadog
|
|
|
160
269
|
end
|
|
161
270
|
end
|
|
162
271
|
|
|
272
|
+
# Returns a [path, iseq] pair for a line probe target, or nil.
|
|
273
|
+
#
|
|
274
|
+
# First checks the whole-file iseq registry (via iseqs_for_path_suffix).
|
|
275
|
+
# If no whole-file iseq exists, searches the per-method iseq registry
|
|
276
|
+
# for an iseq whose trace_points include the target line.
|
|
277
|
+
#
|
|
278
|
+
# @param suffix [String] file path or suffix to match
|
|
279
|
+
# @param line [Integer] target line number
|
|
280
|
+
# @return [Array(String, RubyVM::InstructionSequence), nil]
|
|
281
|
+
def iseq_for_line(suffix, line)
|
|
282
|
+
# Try whole-file iseq first — it always covers all lines.
|
|
283
|
+
result = iseqs_for_path_suffix(suffix)
|
|
284
|
+
return result if result
|
|
285
|
+
|
|
286
|
+
# Fall back to per-method iseqs.
|
|
287
|
+
registry_lock.synchronize do
|
|
288
|
+
# Resolve the path using the per-method registry keys.
|
|
289
|
+
path = resolve_path_suffix(suffix, per_method_registry.keys)
|
|
290
|
+
return nil unless path
|
|
291
|
+
|
|
292
|
+
iseqs = per_method_registry[path]
|
|
293
|
+
return nil unless iseqs
|
|
294
|
+
|
|
295
|
+
# Only match event types the instrumenter subscribes to
|
|
296
|
+
# (:line, :return, :b_return — see hook_line). Lines that
|
|
297
|
+
# only carry :call (e.g. a `def` line within the defined
|
|
298
|
+
# method's own iseq, not the enclosing scope) have no
|
|
299
|
+
# subscribed event at that position; TracePoint#enable
|
|
300
|
+
# raises because it cannot bind an enabled event there.
|
|
301
|
+
matches = iseqs.select do |iseq|
|
|
302
|
+
iseq.trace_points.any? do |tp_line, event|
|
|
303
|
+
tp_line == line && (event == :line || event == :return || event == :b_return)
|
|
304
|
+
end
|
|
305
|
+
end
|
|
306
|
+
# When multiple iseqs contain the target line (e.g. a method
|
|
307
|
+
# and an inline block sharing the same line), picking one
|
|
308
|
+
# would silently miss executions in the other context.
|
|
309
|
+
# Raise so the probe is recorded as failed with a clear error.
|
|
310
|
+
if matches.length > 1
|
|
311
|
+
raise Error::MultiplePathsMatch, "Multiple code locations match line #{line}"
|
|
312
|
+
end
|
|
313
|
+
matches.first ? [path, matches.first] : nil
|
|
314
|
+
end
|
|
315
|
+
end
|
|
316
|
+
|
|
163
317
|
# Stops tracking code that is being loaded.
|
|
164
318
|
#
|
|
165
319
|
# This method should ordinarily never be called - if a file is loaded
|
|
@@ -186,6 +340,7 @@ module Datadog
|
|
|
186
340
|
def clear
|
|
187
341
|
registry_lock.synchronize do
|
|
188
342
|
registry.clear
|
|
343
|
+
per_method_registry.clear
|
|
189
344
|
end
|
|
190
345
|
end
|
|
191
346
|
|
|
@@ -195,8 +350,31 @@ module Datadog
|
|
|
195
350
|
# objects representing compiled code of those files.
|
|
196
351
|
attr_reader :registry
|
|
197
352
|
|
|
353
|
+
# Mapping from paths to arrays of per-method/block/class iseqs.
|
|
354
|
+
# Used as fallback when the whole-file iseq has been GC'd.
|
|
355
|
+
attr_reader :per_method_registry
|
|
356
|
+
|
|
198
357
|
attr_reader :trace_point_lock
|
|
199
358
|
attr_reader :registry_lock
|
|
359
|
+
|
|
360
|
+
# Resolves a path suffix against a set of known paths.
|
|
361
|
+
# Returns the matching path or nil.
|
|
362
|
+
#
|
|
363
|
+
# Must be called within registry_lock.
|
|
364
|
+
def resolve_path_suffix(suffix, paths)
|
|
365
|
+
# Exact match.
|
|
366
|
+
return suffix if paths.include?(suffix)
|
|
367
|
+
|
|
368
|
+
# Suffix match.
|
|
369
|
+
suffix = suffix.dup
|
|
370
|
+
loop do
|
|
371
|
+
matches = paths.select { |p| Utils.path_matches_suffix?(p, suffix) }
|
|
372
|
+
raise Error::MultiplePathsMatch, "Multiple paths matched requested suffix" if matches.length > 1
|
|
373
|
+
return matches.first if matches.any?
|
|
374
|
+
return nil unless suffix.include?('/')
|
|
375
|
+
suffix.sub!(%r{.*/+}, '')
|
|
376
|
+
end
|
|
377
|
+
end
|
|
200
378
|
end
|
|
201
379
|
end
|
|
202
380
|
end
|
data/lib/datadog/di/component.rb
CHANGED
|
@@ -49,6 +49,10 @@ module Datadog
|
|
|
49
49
|
logger.warn("di: cannot enable dynamic instrumentation: Ruby 2.6+ is required, but running on #{RUBY_VERSION}")
|
|
50
50
|
return false
|
|
51
51
|
end
|
|
52
|
+
unless DI.respond_to?(:exception_message)
|
|
53
|
+
logger.warn("di: cannot enable dynamic instrumentation: C extension is not available")
|
|
54
|
+
return false
|
|
55
|
+
end
|
|
52
56
|
true
|
|
53
57
|
end
|
|
54
58
|
end
|
|
@@ -118,7 +122,7 @@ module Datadog
|
|
|
118
122
|
payload = probe_notification_builder.build_errored(probe, exc)
|
|
119
123
|
probe_notifier_worker.add_status(payload)
|
|
120
124
|
rescue => nested_exc
|
|
121
|
-
logger.debug { "di: failed to build error notification: #{nested_exc.class}: #{nested_exc}" }
|
|
125
|
+
logger.debug { "di: failed to build error notification: #{nested_exc.class}: #{nested_exc.message}" }
|
|
122
126
|
telemetry&.report(nested_exc, description: 'Error building probe error notification')
|
|
123
127
|
raise
|
|
124
128
|
end
|