datadog 2.39.0 → 2.47.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 +269 -44
- data/README.md +3 -0
- data/ext/datadog_profiling_native_extension/NativeExtensionDesign.md +12 -24
- data/ext/datadog_profiling_native_extension/collectors_cpu_and_wall_time_worker.c +256 -193
- data/ext/datadog_profiling_native_extension/collectors_discrete_dynamic_sampler.c +1 -5
- data/ext/datadog_profiling_native_extension/collectors_gc_profiling_helper.c +0 -2
- data/ext/datadog_profiling_native_extension/collectors_idle_sampling_helper.c +19 -20
- data/ext/datadog_profiling_native_extension/collectors_idle_sampling_helper.h +5 -1
- data/ext/datadog_profiling_native_extension/collectors_stack.c +267 -171
- data/ext/datadog_profiling_native_extension/collectors_stack.h +17 -3
- data/ext/datadog_profiling_native_extension/collectors_thread_context.c +307 -217
- data/ext/datadog_profiling_native_extension/collectors_thread_context.h +10 -5
- data/ext/datadog_profiling_native_extension/crashtracking_runtime_stacks.c +5 -4
- data/ext/datadog_profiling_native_extension/datadog_ruby_common.c +19 -11
- data/ext/datadog_profiling_native_extension/datadog_ruby_common.h +7 -10
- data/ext/datadog_profiling_native_extension/extconf.rb +67 -99
- data/ext/datadog_profiling_native_extension/heap_recorder.c +353 -257
- data/ext/datadog_profiling_native_extension/heap_recorder.h +50 -31
- data/ext/datadog_profiling_native_extension/native_extension_helpers.rb +3 -27
- data/ext/datadog_profiling_native_extension/private_vm_api_access.c +853 -496
- data/ext/datadog_profiling_native_extension/private_vm_api_access.h +42 -15
- data/ext/datadog_profiling_native_extension/profiling.c +30 -23
- data/ext/datadog_profiling_native_extension/ruby_helpers.c +4 -80
- data/ext/datadog_profiling_native_extension/ruby_helpers.h +4 -7
- data/ext/datadog_profiling_native_extension/setup_signal_handler.c +0 -2
- data/ext/datadog_profiling_native_extension/stack_recorder.c +116 -89
- data/ext/datadog_profiling_native_extension/stack_recorder.h +12 -5
- data/ext/datadog_profiling_native_extension/time_helpers.c +2 -4
- data/ext/datadog_profiling_native_extension/time_helpers.h +15 -15
- data/ext/libdatadog_api/datadog_ruby_common.c +19 -11
- data/ext/libdatadog_api/datadog_ruby_common.h +7 -10
- data/ext/libdatadog_api/di.c +43 -3
- data/ext/libdatadog_api/extconf.rb +6 -1
- data/ext/libdatadog_api/feature_flags.c +8 -0
- data/ext/libdatadog_api/init.c +9 -1
- data/ext/libdatadog_api/otel_thread_context.c +274 -0
- data/ext/libdatadog_api/otel_thread_context.h +5 -0
- data/ext/libdatadog_api/process_discovery.c +15 -1
- data/ext/libdatadog_api/trace_exporter.c +2078 -0
- data/ext/libdatadog_api/trace_exporter.h +5 -0
- data/ext/libdatadog_extconf_helpers.rb +14 -9
- data/lib/datadog/ai_guard/component.rb +17 -8
- data/lib/datadog/ai_guard/configuration/ext.rb +2 -0
- data/lib/datadog/ai_guard/configuration.rb +13 -0
- data/lib/datadog/ai_guard/contrib/ruby_llm/chat_instrumentation.rb +48 -55
- data/lib/datadog/ai_guard/contrib/ruby_llm/integration.rb +1 -1
- data/lib/datadog/ai_guard/contrib/ruby_llm/message_adapter.rb +76 -0
- data/lib/datadog/ai_guard/contrib/ruby_llm/patcher.rb +1 -0
- data/lib/datadog/ai_guard/contrib/ruby_llm/redaction_change_set.rb +135 -0
- data/lib/datadog/ai_guard/evaluation/client.rb +50 -0
- data/lib/datadog/ai_guard/evaluation/content_part.rb +12 -0
- data/lib/datadog/ai_guard/evaluation/message.rb +25 -7
- data/lib/datadog/ai_guard/evaluation/message_builder.rb +31 -0
- data/lib/datadog/ai_guard/evaluation/no_op_result.rb +6 -6
- data/lib/datadog/ai_guard/evaluation/outcome.rb +24 -0
- data/lib/datadog/ai_guard/evaluation/request.rb +8 -64
- data/lib/datadog/ai_guard/evaluation/response.rb +33 -0
- data/lib/datadog/ai_guard/evaluation/result.rb +11 -18
- data/lib/datadog/ai_guard/evaluation/tool_call.rb +15 -2
- data/lib/datadog/ai_guard/evaluation.rb +36 -14
- data/lib/datadog/ai_guard/ext.rb +4 -1
- data/lib/datadog/ai_guard/{api_client.rb → http_client.rb} +7 -5
- data/lib/datadog/ai_guard/metrics/telemetry.rb +43 -0
- data/lib/datadog/ai_guard/redaction/replacements.rb +97 -0
- data/lib/datadog/ai_guard/redaction/result.rb +29 -0
- data/lib/datadog/ai_guard/redaction.rb +80 -0
- data/lib/datadog/ai_guard.rb +58 -57
- data/lib/datadog/appsec/actions_handler/serializable_backtrace.rb +21 -42
- data/lib/datadog/appsec/api_security/endpoint_collection/grape_route_serializer.rb +1 -1
- data/lib/datadog/appsec/api_security/endpoint_collection/rails_route_serializer.rb +1 -1
- data/lib/datadog/appsec/api_security/endpoint_collection/sinatra_route_serializer.rb +1 -1
- data/lib/datadog/appsec/assets/blocked.html +1 -108
- data/lib/datadog/appsec/configuration.rb +11 -2
- data/lib/datadog/appsec/context.rb +1 -1
- data/lib/datadog/appsec/contrib/active_record/instrumentation.rb +1 -1
- data/lib/datadog/appsec/contrib/aws_lambda/waf_addresses.rb +2 -2
- data/lib/datadog/appsec/contrib/devise/configuration.rb +1 -1
- data/lib/datadog/appsec/contrib/devise/patcher.rb +1 -1
- data/lib/datadog/appsec/contrib/excon/ssrf_detection_middleware.rb +2 -2
- data/lib/datadog/appsec/contrib/faraday/ssrf_detection_middleware.rb +2 -2
- data/lib/datadog/appsec/contrib/graphql/gateway/watcher.rb +1 -1
- data/lib/datadog/appsec/contrib/rack/ext.rb +2 -2
- data/lib/datadog/appsec/contrib/rack/gateway/watcher.rb +2 -2
- data/lib/datadog/appsec/contrib/rack/patcher.rb +1 -1
- data/lib/datadog/appsec/contrib/rack/request_body_middleware.rb +6 -3
- data/lib/datadog/appsec/contrib/rails/gateway/watcher.rb +30 -3
- data/lib/datadog/appsec/contrib/rails/patches/render_to_body_patch.rb +8 -7
- data/lib/datadog/appsec/contrib/rails/request_middleware.rb +2 -1
- data/lib/datadog/appsec/contrib/rest_client/request_ssrf_detection_patch.rb +2 -2
- data/lib/datadog/appsec/contrib/sinatra/gateway/watcher.rb +15 -3
- data/lib/datadog/appsec/contrib/sinatra/patches/json_patch.rb +8 -7
- data/lib/datadog/appsec/contrib/sinatra/request_middleware.rb +2 -1
- data/lib/datadog/appsec/processor/rule_loader.rb +12 -12
- data/lib/datadog/appsec/response.rb +1 -1
- data/lib/datadog/appsec/route_normalizer/route_pattern.rb +3 -3
- data/lib/datadog/appsec/security_engine/engine.rb +5 -4
- data/lib/datadog/core/configuration/components.rb +50 -19
- data/lib/datadog/core/configuration/components_state.rb +8 -1
- data/lib/datadog/core/configuration/option_definition.rb +1 -1
- data/lib/datadog/core/configuration/options.rb +1 -1
- data/lib/datadog/core/configuration/settings.rb +38 -43
- data/lib/datadog/core/configuration/supported_configurations.rb +18 -2
- data/lib/datadog/core/crashtracking/component.rb +5 -1
- data/lib/datadog/core/diagnostics/environment_logger.rb +36 -1
- data/lib/datadog/core/environment/gc.rb +1 -1
- data/lib/datadog/core/environment/vm_cache.rb +1 -1
- data/lib/datadog/core/environment/yjit.rb +2 -2
- data/lib/datadog/core/metrics/helpers.rb +1 -1
- data/lib/datadog/core/metrics/options.rb +2 -2
- data/lib/datadog/core/process_discovery.rb +6 -2
- data/lib/datadog/core/remote/client/capabilities.rb +32 -21
- data/lib/datadog/core/remote/client.rb +45 -4
- data/lib/datadog/core/remote/component.rb +30 -7
- data/lib/datadog/core/remote/configuration/repository.rb +2 -2
- data/lib/datadog/core/remote/dispatcher.rb +47 -6
- data/lib/datadog/core/remote/worker.rb +8 -0
- data/lib/datadog/core/telemetry/configuration_value.rb +38 -0
- data/lib/datadog/core/telemetry/event/app_client_configuration_change.rb +3 -1
- data/lib/datadog/core/telemetry/event/app_endpoints_loaded.rb +1 -1
- data/lib/datadog/core/telemetry/event/app_started.rb +5 -24
- data/lib/datadog/core/telemetry/event/generate_metrics.rb +1 -1
- data/lib/datadog/core/telemetry/event/log.rb +2 -2
- data/lib/datadog/core/telemetry/event/synth_app_client_configuration_change.rb +1 -1
- data/lib/datadog/core/telemetry/metric.rb +2 -2
- data/lib/datadog/core/telemetry/request.rb +2 -2
- data/lib/datadog/core/transport/http.rb +1 -1
- data/lib/datadog/core/transport/transport.rb +1 -1
- data/lib/datadog/core/utils/at_fork_monkey_patch.rb +170 -18
- data/lib/datadog/core/utils/sequence.rb +3 -6
- data/lib/datadog/core/utils/time.rb +16 -54
- data/lib/datadog/core/workers/runtime_metrics.rb +1 -1
- data/lib/datadog/data_streams/pathway_context.rb +20 -22
- data/lib/datadog/data_streams/processor.rb +45 -14
- data/lib/datadog/di/boot.rb +1 -0
- data/lib/datadog/di/capture_expression_evaluator/result.rb +30 -0
- data/lib/datadog/di/capture_expression_evaluator.rb +39 -9
- data/lib/datadog/di/component.rb +108 -3
- data/lib/datadog/di/configuration.rb +53 -2
- data/lib/datadog/di/context.rb +7 -2
- data/lib/datadog/di/contrib/active_record.rb +8 -2
- data/lib/datadog/di/el/compiler.rb +88 -12
- data/lib/datadog/di/el/evaluator.rb +82 -2
- data/lib/datadog/di/el/expression.rb +13 -2
- data/lib/datadog/di/evaluation_failure.rb +28 -0
- data/lib/datadog/di/guardrails_telemetry/reason.rb +87 -0
- data/lib/datadog/di/guardrails_telemetry.rb +203 -0
- data/lib/datadog/di/instrumenter.rb +106 -15
- data/lib/datadog/di/logger.rb +32 -10
- data/lib/datadog/di/probe.rb +9 -1
- data/lib/datadog/di/probe_builder.rb +7 -6
- data/lib/datadog/di/probe_manager.rb +56 -8
- data/lib/datadog/di/probe_notification_builder.rb +31 -28
- data/lib/datadog/di/probe_notifier_worker.rb +56 -6
- data/lib/datadog/di/proc_responder.rb +1 -1
- data/lib/datadog/di/remote.rb +49 -5
- data/lib/datadog/di/serializer.rb +172 -55
- data/lib/datadog/di/snapshot_event.rb +38 -0
- data/lib/datadog/di/transport/http.rb +13 -3
- data/lib/datadog/di/transport/input.rb +32 -7
- data/lib/datadog/error_tracking/component.rb +1 -1
- data/lib/datadog/kit/appsec/events/v2.rb +2 -2
- data/lib/datadog/open_feature/activation.rb +268 -0
- data/lib/datadog/open_feature/agentless/configuration_source.rb +246 -0
- data/lib/datadog/open_feature/agentless/parser.rb +43 -0
- data/lib/datadog/open_feature/agentless/response.rb +19 -0
- data/lib/datadog/open_feature/agentless/transport.rb +103 -0
- data/lib/datadog/open_feature/component.rb +85 -13
- data/lib/datadog/open_feature/configuration/agentless_endpoint.rb +90 -0
- data/lib/datadog/open_feature/configuration/source/resolution.rb +22 -0
- data/lib/datadog/open_feature/configuration/source.rb +43 -0
- data/lib/datadog/open_feature/configuration.rb +124 -0
- data/lib/datadog/open_feature/evaluation_engine.rb +29 -3
- data/lib/datadog/open_feature/exposures/batch_builder.rb +1 -1
- data/lib/datadog/open_feature/exposures/event.rb +15 -8
- data/lib/datadog/open_feature/ext.rb +19 -0
- data/lib/datadog/open_feature/flag_evaluation/aggregator.rb +236 -80
- data/lib/datadog/open_feature/flag_evaluation/writer.rb +179 -68
- data/lib/datadog/open_feature/hooks/evaluation_telemetry_opt_out_hook.rb +25 -0
- data/lib/datadog/open_feature/hooks/flag_eval_evp_hook.rb +24 -21
- data/lib/datadog/open_feature/native_evaluator.rb +20 -6
- data/lib/datadog/open_feature/noop_evaluator.rb +5 -0
- data/lib/datadog/open_feature/provider.rb +315 -10
- data/lib/datadog/open_feature/remote.rb +5 -5
- data/lib/datadog/open_feature/transport.rb +5 -0
- data/lib/datadog/open_feature.rb +31 -1
- data/lib/datadog/opentelemetry/sdk/propagator.rb +1 -1
- data/lib/datadog/opentelemetry/signal_configuration.rb +13 -9
- data/lib/datadog/opentelemetry/trace.rb +3 -0
- data/lib/datadog/profiling/collectors/cpu_and_wall_time_worker.rb +10 -2
- data/lib/datadog/profiling/collectors/idle_sampling_helper.rb +5 -7
- data/lib/datadog/profiling/collectors/info.rb +40 -13
- data/lib/datadog/profiling/collectors/thread_context.rb +6 -17
- data/lib/datadog/profiling/component.rb +33 -39
- data/lib/datadog/profiling/exporter.rb +10 -10
- data/lib/datadog/profiling/tasks/exec.rb +1 -1
- data/lib/datadog/profiling.rb +4 -0
- data/lib/datadog/symbol_database/extractor.rb +89 -107
- data/lib/datadog/tracing/component.rb +44 -2
- data/lib/datadog/tracing/configuration/dynamic/option.rb +4 -0
- data/lib/datadog/tracing/configuration/dynamic.rb +5 -3
- data/lib/datadog/tracing/configuration/ext.rb +4 -0
- data/lib/datadog/tracing/configuration/settings.rb +36 -0
- data/lib/datadog/tracing/context.rb +24 -2
- data/lib/datadog/tracing/context_provider.rb +17 -5
- data/lib/datadog/tracing/contrib/action_cable/events.rb +1 -1
- data/lib/datadog/tracing/contrib/action_mailer/events.rb +1 -1
- data/lib/datadog/tracing/contrib/action_pack/action_controller/instrumentation.rb +2 -2
- data/lib/datadog/tracing/contrib/action_view/events.rb +1 -1
- data/lib/datadog/tracing/contrib/active_model_serializers/events.rb +1 -1
- data/lib/datadog/tracing/contrib/active_record/configuration/resolver.rb +1 -1
- data/lib/datadog/tracing/contrib/active_record/events/sql.rb +1 -0
- data/lib/datadog/tracing/contrib/active_record/events.rb +1 -1
- data/lib/datadog/tracing/contrib/active_support/cache/events/cache.rb +2 -2
- data/lib/datadog/tracing/contrib/aws/ext.rb +1 -1
- data/lib/datadog/tracing/contrib/aws/services.rb +1 -1
- data/lib/datadog/tracing/contrib/elasticsearch/quantize.rb +1 -1
- data/lib/datadog/tracing/contrib/ethon/easy_patch.rb +10 -5
- data/lib/datadog/tracing/contrib/excon/middleware.rb +10 -3
- data/lib/datadog/tracing/contrib/ext.rb +3 -3
- data/lib/datadog/tracing/contrib/faraday/middleware.rb +10 -4
- data/lib/datadog/tracing/contrib/grape/endpoint.rb +32 -5
- data/lib/datadog/tracing/contrib/grpc/datadog_interceptor/client.rb +1 -1
- data/lib/datadog/tracing/contrib/grpc/datadog_interceptor/server.rb +1 -1
- data/lib/datadog/tracing/contrib/grpc/distributed/propagation.rb +1 -1
- data/lib/datadog/tracing/contrib/hanami/router_tracing.rb +2 -1
- data/lib/datadog/tracing/contrib/http/instrumentation.rb +16 -1
- data/lib/datadog/tracing/contrib/httpclient/instrumentation.rb +8 -2
- data/lib/datadog/tracing/contrib/httprb/instrumentation.rb +10 -4
- data/lib/datadog/tracing/contrib/kafka/events/connection/request.rb +4 -0
- data/lib/datadog/tracing/contrib/kafka/events/produce_operation/send_messages.rb +7 -2
- data/lib/datadog/tracing/contrib/kafka/events/producer/deliver_messages.rb +7 -2
- data/lib/datadog/tracing/contrib/kafka/events.rb +1 -1
- data/lib/datadog/tracing/contrib/karafka/distributed/propagation.rb +1 -1
- data/lib/datadog/tracing/contrib/mongodb/parsers.rb +1 -1
- data/lib/datadog/tracing/contrib/opensearch/ext.rb +1 -1
- data/lib/datadog/tracing/contrib/opensearch/quantize.rb +1 -1
- data/lib/datadog/tracing/contrib/patchable.rb +1 -1
- data/lib/datadog/tracing/contrib/patcher.rb +1 -1
- data/lib/datadog/tracing/contrib/que/tracer.rb +1 -1
- data/lib/datadog/tracing/contrib/racecar/events.rb +1 -1
- data/lib/datadog/tracing/contrib/rack/configuration/settings.rb +1 -1
- data/lib/datadog/tracing/contrib/rack/header_tagging.rb +1 -1
- data/lib/datadog/tracing/contrib/rack/patcher.rb +1 -1
- data/lib/datadog/tracing/contrib/rack/trace_proxy_middleware.rb +1 -1
- data/lib/datadog/tracing/contrib/redis/configuration/resolver.rb +1 -1
- data/lib/datadog/tracing/contrib/redis/quantize.rb +36 -2
- data/lib/datadog/tracing/contrib/redis/trace_middleware.rb +9 -3
- data/lib/datadog/tracing/contrib/rest_client/request_patch.rb +10 -3
- data/lib/datadog/tracing/contrib/sequel/database.rb +1 -5
- data/lib/datadog/tracing/contrib/sequel/jdbc_connection_string.rb +140 -0
- data/lib/datadog/tracing/contrib/sequel/utils.rb +50 -63
- data/lib/datadog/tracing/contrib/sidekiq/distributed/propagation.rb +1 -1
- data/lib/datadog/tracing/contrib/sinatra/configuration/settings.rb +1 -1
- data/lib/datadog/tracing/contrib/sneakers/tracer.rb +1 -1
- data/lib/datadog/tracing/contrib/utils/quantization/hash_formatter.rb +1 -1
- data/lib/datadog/tracing/contrib/utils/quantization/http.rb +108 -3
- data/lib/datadog/tracing/contrib/waterdrop/distributed/propagation.rb +1 -1
- data/lib/datadog/tracing/correlation.rb +2 -2
- data/lib/datadog/tracing/diagnostics/environment_logger.rb +3 -2
- data/lib/datadog/tracing/distributed/baggage.rb +1 -3
- data/lib/datadog/tracing/distributed/datadog.rb +3 -3
- data/lib/datadog/tracing/distributed/propagation.rb +3 -0
- data/lib/datadog/tracing/distributed/propagation_policy.rb +5 -0
- data/lib/datadog/tracing/distributed/trace_context.rb +14 -271
- data/lib/datadog/tracing/distributed/trace_state/datadog.rb +233 -0
- data/lib/datadog/tracing/distributed/trace_state/ext.rb +44 -0
- data/lib/datadog/tracing/distributed/trace_state/open_telemetry.rb +156 -0
- data/lib/datadog/tracing/distributed/trace_state.rb +121 -0
- data/lib/datadog/tracing/metadata/ext.rb +3 -0
- data/lib/datadog/tracing/metadata/tagging.rb +1 -1
- data/lib/datadog/tracing/otel_thread_context.rb +97 -0
- data/lib/datadog/tracing/remote.rb +236 -37
- data/lib/datadog/tracing/sampling/rule_sampler.rb +2 -0
- data/lib/datadog/tracing/span.rb +1 -1
- data/lib/datadog/tracing/span_operation.rb +1 -1
- data/lib/datadog/tracing/sync_writer.rb +8 -3
- data/lib/datadog/tracing/trace_digest.rb +22 -4
- data/lib/datadog/tracing/trace_operation.rb +22 -10
- data/lib/datadog/tracing/tracer.rb +28 -7
- data/lib/datadog/tracing/transport/http/telemetry.rb +94 -0
- data/lib/datadog/tracing/transport/http/traces.rb +2 -0
- data/lib/datadog/tracing/transport/io/traces.rb +1 -1
- data/lib/datadog/tracing/transport/native/response.rb +71 -0
- data/lib/datadog/tracing/transport/native/telemetry.rb +17 -0
- data/lib/datadog/tracing/transport/native.rb +395 -0
- data/lib/datadog/tracing/transport/span_events_negotiation.rb +41 -0
- data/lib/datadog/tracing/transport/telemetry.rb +62 -0
- data/lib/datadog/tracing/transport/trace_formatter.rb +14 -4
- data/lib/datadog/tracing/transport/traces.rb +85 -38
- data/lib/datadog/tracing/writer.rb +17 -4
- data/lib/datadog/version.rb +1 -1
- metadata +51 -13
- data/lib/datadog/ai_guard/evaluation/content_builder.rb +0 -31
- data/lib/datadog/appsec/utils/hash_coercion.rb +0 -23
- data/lib/datadog/tracing/distributed/datadog_tags_codec.rb +0 -69
|
@@ -62,10 +62,27 @@ module Datadog
|
|
|
62
62
|
|
|
63
63
|
super()
|
|
64
64
|
self.loop_base_interval = interval
|
|
65
|
+
# Without this, a preload-then-fork deployment model (e.g. Puma cluster mode with
|
|
66
|
+
# preload_app!, or Sidekiq Enterprise's sidekiqswarm with SIDEKIQ_PRELOAD_APP) leaves
|
|
67
|
+
# every forked child with a dead flush thread: Ruby threads don't survive fork, and the
|
|
68
|
+
# default FORK_POLICY_STOP means #perform would otherwise just mark the worker stopped
|
|
69
|
+
# instead of restarting it. See #restart_flush_thread.
|
|
70
|
+
self.fork_policy = Core::Workers::Async::Thread::FORK_POLICY_RESTART
|
|
65
71
|
|
|
66
72
|
perform
|
|
67
73
|
end
|
|
68
74
|
|
|
75
|
+
# Restarts the flush thread if a fork has been detected since this processor was created.
|
|
76
|
+
# Called by Components#after_fork. Safe to call even when no fork occurred: #perform (via
|
|
77
|
+
# Workers::Async::Thread) only restarts the worker when +forked?+ is true. Deliberately not
|
|
78
|
+
# named +after_fork+: Workers::Async::Thread already defines a protected +after_fork+
|
|
79
|
+
# template method that #perform's internal restart path (+restart_after_fork+) calls on
|
|
80
|
+
# every restart -- overriding it here would recurse.
|
|
81
|
+
def restart_flush_thread
|
|
82
|
+
discard_inherited_state_after_fork! if forked?
|
|
83
|
+
perform
|
|
84
|
+
end
|
|
85
|
+
|
|
69
86
|
# Track Kafka produce offset for lag monitoring
|
|
70
87
|
# @param topic [String] The Kafka topic name
|
|
71
88
|
# @param partition [Integer] The partition number
|
|
@@ -79,7 +96,7 @@ module Datadog
|
|
|
79
96
|
topic: topic,
|
|
80
97
|
partition: partition,
|
|
81
98
|
offset: offset,
|
|
82
|
-
timestamp_ns: (now.to_f * 1e9).to_i
|
|
99
|
+
timestamp_ns: (now.to_f * 1e9).to_i,
|
|
83
100
|
}
|
|
84
101
|
)
|
|
85
102
|
true
|
|
@@ -98,7 +115,7 @@ module Datadog
|
|
|
98
115
|
topic: topic,
|
|
99
116
|
partition: partition,
|
|
100
117
|
offset: offset,
|
|
101
|
-
timestamp: now
|
|
118
|
+
timestamp: now,
|
|
102
119
|
}
|
|
103
120
|
)
|
|
104
121
|
true
|
|
@@ -186,7 +203,7 @@ module Datadog
|
|
|
186
203
|
|
|
187
204
|
bucket[:latest_produce_offsets][partition_key] = [
|
|
188
205
|
event[:offset],
|
|
189
|
-
bucket[:latest_produce_offsets][partition_key] || 0
|
|
206
|
+
bucket[:latest_produce_offsets][partition_key] || 0,
|
|
190
207
|
].max
|
|
191
208
|
end
|
|
192
209
|
|
|
@@ -196,7 +213,7 @@ module Datadog
|
|
|
196
213
|
partition: event[:partition],
|
|
197
214
|
offset: event[:offset],
|
|
198
215
|
timestamp: event[:timestamp],
|
|
199
|
-
timestamp_sec: event[:timestamp].to_f
|
|
216
|
+
timestamp_sec: event[:timestamp].to_f,
|
|
200
217
|
}
|
|
201
218
|
|
|
202
219
|
timestamp_ns = (event[:timestamp].to_f * 1e9).to_i
|
|
@@ -216,7 +233,7 @@ module Datadog
|
|
|
216
233
|
expected_offset: previous_offset + 1,
|
|
217
234
|
actual_offset: event[:offset],
|
|
218
235
|
gap_size: event[:offset] - previous_offset - 1,
|
|
219
|
-
timestamp_sec: event[:timestamp].to_f
|
|
236
|
+
timestamp_sec: event[:timestamp].to_f,
|
|
220
237
|
}
|
|
221
238
|
end
|
|
222
239
|
|
|
@@ -302,6 +319,20 @@ module Datadog
|
|
|
302
319
|
PathwayContext.decode_b64(encoded_ctx)
|
|
303
320
|
end
|
|
304
321
|
|
|
322
|
+
# A fork copies whatever was buffered in the parent (unflushed events, aggregated
|
|
323
|
+
# buckets, consumer stats) into the child. If the parent process is still alive and
|
|
324
|
+
# flushing (e.g. a supervisor process that stays up after forking workers), letting
|
|
325
|
+
# the child flush that same inherited data as well would double-report it to the
|
|
326
|
+
# agent. Discard it instead: losing a few seconds of pre-fork stats is preferable to
|
|
327
|
+
# corrupting pipeline throughput/lag numbers with duplicates.
|
|
328
|
+
def discard_inherited_state_after_fork!
|
|
329
|
+
@event_buffer.pop
|
|
330
|
+
@stats_mutex.synchronize do
|
|
331
|
+
@buckets.clear
|
|
332
|
+
@consumer_stats.clear
|
|
333
|
+
end
|
|
334
|
+
end
|
|
335
|
+
|
|
305
336
|
def flush_stats
|
|
306
337
|
stats_buckets = @stats_mutex.synchronize do
|
|
307
338
|
return if @buckets.empty? && @consumer_stats.empty?
|
|
@@ -321,7 +352,7 @@ module Datadog
|
|
|
321
352
|
"TracerVersion" => Datadog::VERSION::STRING,
|
|
322
353
|
"Lang" => "ruby",
|
|
323
354
|
"Stats" => stats_buckets,
|
|
324
|
-
"Hostname" => hostname
|
|
355
|
+
"Hostname" => hostname,
|
|
325
356
|
} # : ::Hash[::String, (::String | ::Array[::String])]
|
|
326
357
|
|
|
327
358
|
payload["ProcessTags"] = Core::Environment::Process.tags if @settings.experimental_propagate_process_tags_enabled
|
|
@@ -400,7 +431,7 @@ module Datadog
|
|
|
400
431
|
full_pathway_latency_sec: full_pathway_latency_sec,
|
|
401
432
|
payload_size: payload_size,
|
|
402
433
|
tags: tags,
|
|
403
|
-
timestamp_sec: timestamp_sec
|
|
434
|
+
timestamp_sec: timestamp_sec,
|
|
404
435
|
}
|
|
405
436
|
)
|
|
406
437
|
true
|
|
@@ -449,14 +480,14 @@ module Datadog
|
|
|
449
480
|
topic, partition = key.split(":", 2)
|
|
450
481
|
backlogs << {
|
|
451
482
|
"Tags" => ["type:kafka_produce", "topic:#{topic}", "partition:#{partition}"],
|
|
452
|
-
"Value" => offset
|
|
483
|
+
"Value" => offset,
|
|
453
484
|
}
|
|
454
485
|
end
|
|
455
486
|
bucket[:latest_commit_offsets].each do |key, offset|
|
|
456
487
|
group, topic, partition = key.split(":", 3)
|
|
457
488
|
backlogs << {
|
|
458
489
|
"Tags" => ["type:kafka_commit", "consumer_group:#{group}", "topic:#{topic}", "partition:#{partition}"],
|
|
459
|
-
"Value" => offset
|
|
490
|
+
"Value" => offset,
|
|
460
491
|
}
|
|
461
492
|
end
|
|
462
493
|
|
|
@@ -464,7 +495,7 @@ module Datadog
|
|
|
464
495
|
"Start" => bucket_time_ns,
|
|
465
496
|
"Duration" => @bucket_size_ns,
|
|
466
497
|
"Stats" => bucket_stats,
|
|
467
|
-
"Backlogs" => backlogs + serialize_consumer_backlogs
|
|
498
|
+
"Backlogs" => backlogs + serialize_consumer_backlogs,
|
|
468
499
|
}
|
|
469
500
|
end
|
|
470
501
|
|
|
@@ -479,9 +510,9 @@ module Datadog
|
|
|
479
510
|
"Tags" => [
|
|
480
511
|
"type:kafka_commit",
|
|
481
512
|
"topic:#{stat[:topic]}",
|
|
482
|
-
"partition:#{stat[:partition]}"
|
|
513
|
+
"partition:#{stat[:partition]}",
|
|
483
514
|
],
|
|
484
|
-
"Value" => stat[:offset]
|
|
515
|
+
"Value" => stat[:offset],
|
|
485
516
|
}
|
|
486
517
|
end
|
|
487
518
|
end
|
|
@@ -494,7 +525,7 @@ module Datadog
|
|
|
494
525
|
{
|
|
495
526
|
pathway_stats: {},
|
|
496
527
|
latest_produce_offsets: {},
|
|
497
|
-
latest_commit_offsets: {}
|
|
528
|
+
latest_commit_offsets: {},
|
|
498
529
|
}
|
|
499
530
|
end
|
|
500
531
|
|
|
@@ -503,7 +534,7 @@ module Datadog
|
|
|
503
534
|
edge_latency: Datadog::Core::DDSketch.new,
|
|
504
535
|
full_pathway_latency: Datadog::Core::DDSketch.new,
|
|
505
536
|
payload_size_sum: 0,
|
|
506
|
-
payload_size_count: 0
|
|
537
|
+
payload_size_count: 0,
|
|
507
538
|
}
|
|
508
539
|
end
|
|
509
540
|
end
|
data/lib/datadog/di/boot.rb
CHANGED
|
@@ -7,6 +7,7 @@ require_relative "code_tracker"
|
|
|
7
7
|
require_relative "component"
|
|
8
8
|
require_relative "context"
|
|
9
9
|
require_relative "capture_limits"
|
|
10
|
+
require_relative "guardrails_telemetry"
|
|
10
11
|
require_relative "capture_expression"
|
|
11
12
|
require_relative "capture_expression_evaluator"
|
|
12
13
|
require_relative "instrumenter"
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Datadog
|
|
4
|
+
module DI
|
|
5
|
+
class CaptureExpressionEvaluator
|
|
6
|
+
# The result of evaluating a probe's capture expressions: the
|
|
7
|
+
# serialized values and the evaluation errors.
|
|
8
|
+
class Result
|
|
9
|
+
# Initializes the result.
|
|
10
|
+
#
|
|
11
|
+
# @param serialized_values [Hash{String => untyped}] serialized values keyed by capture expression name
|
|
12
|
+
# @param errors [Array<EvaluationFailure>] evaluation errors of the expressions that failed to evaluate or serialize
|
|
13
|
+
# @return [void]
|
|
14
|
+
def initialize(serialized_values:, errors:)
|
|
15
|
+
@serialized_values = serialized_values
|
|
16
|
+
@errors = errors
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
# The serialized values keyed by capture expression name.
|
|
20
|
+
# @return [Hash{String => untyped}]
|
|
21
|
+
attr_reader :serialized_values
|
|
22
|
+
|
|
23
|
+
# The evaluation errors; one entry per expression that failed to
|
|
24
|
+
# evaluate or serialize.
|
|
25
|
+
# @return [Array<EvaluationFailure>]
|
|
26
|
+
attr_reader :errors
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
@@ -2,17 +2,28 @@
|
|
|
2
2
|
|
|
3
3
|
require_relative "capture_expression"
|
|
4
4
|
require_relative "capture_limits"
|
|
5
|
+
require_relative "capture_expression_evaluator/result"
|
|
6
|
+
require_relative "evaluation_failure"
|
|
5
7
|
require_relative "fatal_exceptions"
|
|
8
|
+
require_relative "guardrails_telemetry"
|
|
9
|
+
require_relative "../core/utils/time"
|
|
6
10
|
|
|
7
11
|
module Datadog
|
|
8
12
|
module DI
|
|
9
13
|
class CaptureExpressionEvaluator
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
14
|
+
# Initializes the evaluator.
|
|
15
|
+
#
|
|
16
|
+
# @param settings [Datadog::Core::Configuration::Settings] tracer settings
|
|
17
|
+
# @param serializer [Serializer] serializer for captured expression values
|
|
18
|
+
# @param logger [DI::Logger] logger for evaluation failure diagnostics
|
|
19
|
+
# @param guardrails_telemetry [GuardrailsTelemetry] emitter for the canonical capture-timeout skip metric
|
|
20
|
+
# @param telemetry [Datadog::Core::Telemetry::Component, nil] component evaluation failures are reported through
|
|
21
|
+
# @return [void]
|
|
22
|
+
def initialize(settings:, serializer:, logger:, guardrails_telemetry:, telemetry: nil)
|
|
13
23
|
@settings = settings
|
|
14
24
|
@serializer = serializer
|
|
15
25
|
@logger = logger
|
|
26
|
+
@guardrails_telemetry = guardrails_telemetry
|
|
16
27
|
@telemetry = telemetry
|
|
17
28
|
end
|
|
18
29
|
|
|
@@ -22,11 +33,25 @@ module Datadog
|
|
|
22
33
|
|
|
23
34
|
attr_reader :logger
|
|
24
35
|
|
|
36
|
+
# The guardrails metric emitter.
|
|
37
|
+
# @return [GuardrailsTelemetry]
|
|
38
|
+
attr_reader :guardrails_telemetry
|
|
39
|
+
|
|
25
40
|
attr_reader :telemetry
|
|
26
41
|
|
|
42
|
+
# Evaluates each of the probe's capture expressions against the given
|
|
43
|
+
# context, serializing the captured values under one capture deadline
|
|
44
|
+
# resolved through the serializer and shared across all expressions.
|
|
45
|
+
# An expression that fails to evaluate or serialize contributes an entry
|
|
46
|
+
# to the returned errors.
|
|
47
|
+
#
|
|
48
|
+
# @param probe [Probe] the probe whose capture expressions are evaluated
|
|
49
|
+
# @param context [Context] evaluation context the expressions are evaluated against
|
|
50
|
+
# @return [Result] the evaluation result: the serialized values keyed by
|
|
51
|
+
# capture expression name and the errors of the expressions that failed
|
|
52
|
+
# to evaluate or serialize
|
|
27
53
|
def evaluate(probe, context)
|
|
28
|
-
|
|
29
|
-
deadline_ns = ::Process.clock_gettime(::Process::CLOCK_MONOTONIC, :nanosecond) + budget_ns
|
|
54
|
+
deadline = serializer.serialization_deadline
|
|
30
55
|
|
|
31
56
|
output = {}
|
|
32
57
|
evaluation_errors = []
|
|
@@ -34,9 +59,13 @@ module Datadog
|
|
|
34
59
|
probe.capture_expressions.each do |capture_expression|
|
|
35
60
|
name = capture_expression.name
|
|
36
61
|
|
|
37
|
-
if
|
|
62
|
+
if Process.clock_gettime(Process::CLOCK_THREAD_CPUTIME_ID, :float_second) >= deadline
|
|
38
63
|
output[name] = {notCapturedReason: "timeout"}
|
|
39
|
-
telemetry&.inc(TELEMETRY_NAMESPACE, "capture_expressions_skipped_by_timeout", 1)
|
|
64
|
+
telemetry&.inc(DI::TELEMETRY_NAMESPACE, "capture_expressions_skipped_by_timeout", 1)
|
|
65
|
+
guardrails_telemetry.skipped(
|
|
66
|
+
reason: GuardrailsTelemetry::Reason::EVALUATION_TIMEOUT,
|
|
67
|
+
probe: probe,
|
|
68
|
+
)
|
|
40
69
|
next
|
|
41
70
|
end
|
|
42
71
|
|
|
@@ -53,10 +82,11 @@ module Datadog
|
|
|
53
82
|
attribute_count: limits[:attribute_count],
|
|
54
83
|
length: limits[:length],
|
|
55
84
|
collection_size: limits[:collection_size],
|
|
85
|
+
deadline: deadline,
|
|
56
86
|
)
|
|
57
87
|
rescue Exception => exc # standard:disable Lint/RescueException
|
|
58
88
|
Datadog::DI.reraise_if_fatal(exc)
|
|
59
|
-
evaluation_errors <<
|
|
89
|
+
evaluation_errors << EvaluationFailure.new(expr: name, message: "#{exc.class}: #{exc.message}")
|
|
60
90
|
logger.debug do
|
|
61
91
|
"di: probe #{probe.id}: capture expression #{name}: evaluation failed: #{exc.class}: #{exc.message}"
|
|
62
92
|
end
|
|
@@ -64,7 +94,7 @@ module Datadog
|
|
|
64
94
|
end
|
|
65
95
|
end
|
|
66
96
|
|
|
67
|
-
|
|
97
|
+
Result.new(serialized_values: output, errors: evaluation_errors)
|
|
68
98
|
end
|
|
69
99
|
end
|
|
70
100
|
end
|
data/lib/datadog/di/component.rb
CHANGED
|
@@ -16,6 +16,16 @@ module Datadog
|
|
|
16
16
|
# resources and installed tracepoints upon shutdown.
|
|
17
17
|
class Component
|
|
18
18
|
class << self
|
|
19
|
+
# Builds and registers the DI component, or returns nil without
|
|
20
|
+
# building one when the settings have no dynamic_instrumentation
|
|
21
|
+
# section, DI is explicitly disabled, the runtime is unsupported,
|
|
22
|
+
# or Remote Configuration is disabled.
|
|
23
|
+
#
|
|
24
|
+
# @param settings [Datadog::Core::Configuration::Settings]
|
|
25
|
+
# @param agent_settings [Datadog::Core::Configuration::AgentSettings]
|
|
26
|
+
# @param logger [Core::Logger]
|
|
27
|
+
# @param telemetry [Core::Telemetry::Component, nil]
|
|
28
|
+
# @return [Component, nil] the built component, or nil when no component was built
|
|
19
29
|
def build(settings, agent_settings, logger, telemetry: nil)
|
|
20
30
|
return unless settings.respond_to?(:dynamic_instrumentation)
|
|
21
31
|
|
|
@@ -65,40 +75,66 @@ module Datadog
|
|
|
65
75
|
end
|
|
66
76
|
end
|
|
67
77
|
|
|
78
|
+
# Initializes the DI component.
|
|
79
|
+
#
|
|
80
|
+
# @param settings [Datadog::Core::Configuration::Settings] tracer settings
|
|
81
|
+
# @param agent_settings [Datadog::Core::Configuration::AgentSettings] agent connection settings for the transports
|
|
82
|
+
# @param logger [Datadog::Core::Logger] diagnostics logger, wrapped in the DI logger facade
|
|
83
|
+
# @param code_tracker [CodeTracker, nil] code tracker for line probe installation
|
|
84
|
+
# @param telemetry [Datadog::Core::Telemetry::Component, nil] component DI errors and guardrails metrics are emitted through
|
|
85
|
+
# @return [void]
|
|
68
86
|
def initialize(settings, agent_settings, logger, code_tracker: nil, telemetry: nil)
|
|
69
87
|
@settings = settings
|
|
70
88
|
@agent_settings = agent_settings
|
|
71
89
|
logger = DI::Logger.new(settings, logger)
|
|
72
90
|
@logger = logger
|
|
73
91
|
@telemetry = telemetry
|
|
92
|
+
@guardrails_telemetry = GuardrailsTelemetry.new(settings: settings, logger: logger, telemetry: telemetry)
|
|
74
93
|
@code_tracker = code_tracker
|
|
75
94
|
@redactor = Redactor.new(settings)
|
|
76
|
-
@serializer = Serializer.new(settings, redactor,
|
|
77
|
-
|
|
95
|
+
@serializer = Serializer.new(settings, redactor, logger: logger,
|
|
96
|
+
guardrails_telemetry: guardrails_telemetry, telemetry: telemetry)
|
|
97
|
+
@capture_expression_evaluator = CaptureExpressionEvaluator.new(
|
|
98
|
+
settings: settings, serializer: serializer, logger: logger,
|
|
99
|
+
guardrails_telemetry: guardrails_telemetry, telemetry: telemetry,
|
|
100
|
+
)
|
|
101
|
+
@instrumenter = Instrumenter.new(settings, serializer, logger, code_tracker: code_tracker, telemetry: telemetry,
|
|
102
|
+
guardrails_telemetry: guardrails_telemetry,
|
|
103
|
+
capture_expression_evaluator: capture_expression_evaluator,)
|
|
78
104
|
@probe_repository = ProbeRepository.new
|
|
79
|
-
@probe_notification_builder = ProbeNotificationBuilder.new(settings, serializer, logger,
|
|
105
|
+
@probe_notification_builder = ProbeNotificationBuilder.new(settings, serializer, logger,
|
|
106
|
+
capture_expression_evaluator: capture_expression_evaluator,)
|
|
80
107
|
@probe_notifier_worker = ProbeNotifierWorker.new(
|
|
81
108
|
settings, logger,
|
|
82
109
|
agent_settings: agent_settings,
|
|
83
110
|
probe_repository: probe_repository,
|
|
84
111
|
probe_notification_builder: probe_notification_builder,
|
|
85
112
|
telemetry: telemetry,
|
|
113
|
+
guardrails_telemetry: guardrails_telemetry,
|
|
86
114
|
)
|
|
87
115
|
@probe_manager = ProbeManager.new(
|
|
88
116
|
settings, instrumenter, probe_notification_builder, probe_notifier_worker, logger, probe_repository,
|
|
89
117
|
telemetry: telemetry,
|
|
118
|
+
guardrails_telemetry: guardrails_telemetry,
|
|
90
119
|
)
|
|
91
120
|
# @started transitions are serialized by @lifecycle_mutex so that
|
|
92
121
|
# concurrent RC callbacks (which run on the remote-config thread)
|
|
93
122
|
# cannot race a foreground start! with a background stop!.
|
|
94
123
|
@lifecycle_mutex = Mutex.new
|
|
95
124
|
@started = false
|
|
125
|
+
@rc_enablement_signal_paths = []
|
|
96
126
|
end
|
|
97
127
|
|
|
98
128
|
attr_reader :settings
|
|
99
129
|
attr_reader :agent_settings
|
|
100
130
|
attr_reader :logger
|
|
101
131
|
attr_reader :telemetry
|
|
132
|
+
# The guardrails metric emitter.
|
|
133
|
+
# @return [GuardrailsTelemetry]
|
|
134
|
+
attr_reader :guardrails_telemetry
|
|
135
|
+
# The capture expression evaluator.
|
|
136
|
+
# @return [CaptureExpressionEvaluator]
|
|
137
|
+
attr_reader :capture_expression_evaluator
|
|
102
138
|
attr_reader :code_tracker
|
|
103
139
|
attr_reader :instrumenter
|
|
104
140
|
attr_reader :probe_repository
|
|
@@ -166,6 +202,75 @@ module Datadog
|
|
|
166
202
|
@started
|
|
167
203
|
end
|
|
168
204
|
|
|
205
|
+
# Whether the component is started while the customer left
|
|
206
|
+
# DD_DYNAMIC_INSTRUMENTATION_ENABLED at its default, the state produced
|
|
207
|
+
# by remote-configuration enablement.
|
|
208
|
+
#
|
|
209
|
+
# An explicit `enabled = false` takes precedence over a prior RC
|
|
210
|
+
# enablement: once the customer sets the option, this returns false
|
|
211
|
+
# even while the component is still started.
|
|
212
|
+
#
|
|
213
|
+
# @return [Boolean]
|
|
214
|
+
def implicitly_enabled?
|
|
215
|
+
started? && settings.dynamic_instrumentation.using_default?(:enabled)
|
|
216
|
+
end
|
|
217
|
+
|
|
218
|
+
# Whether an APM_TRACING merge that omitted dynamic_instrumentation_enabled
|
|
219
|
+
# withdraws this component's RC enable signal, so the component must stop.
|
|
220
|
+
#
|
|
221
|
+
# Returns true when the component is implicitly enabled and no unparseable
|
|
222
|
+
# content can be the signal carrier. A content at a recorded signal path can be
|
|
223
|
+
# the carrier. When no paths are recorded, every unparseable content can be the
|
|
224
|
+
# carrier.
|
|
225
|
+
#
|
|
226
|
+
# @param unparseable_contents [Array<Core::Remote::Configuration::Content>] the APM_TRACING contents that failed to parse at this merge
|
|
227
|
+
# @return [Boolean]
|
|
228
|
+
def rc_enablement_signal_withdrawn?(unparseable_contents)
|
|
229
|
+
return false unless implicitly_enabled?
|
|
230
|
+
|
|
231
|
+
recorded_signal_paths = rc_enablement_signal_paths
|
|
232
|
+
signal_source_unparseable =
|
|
233
|
+
if recorded_signal_paths.empty?
|
|
234
|
+
unparseable_contents.any?
|
|
235
|
+
else
|
|
236
|
+
unparseable_contents.any? { |content| recorded_signal_paths.include?(content.path) }
|
|
237
|
+
end
|
|
238
|
+
if signal_source_unparseable
|
|
239
|
+
if recorded_signal_paths.empty?
|
|
240
|
+
logger.trace do
|
|
241
|
+
"APM_TRACING RC: dynamic_instrumentation_enabled absent while an APM_TRACING config " \
|
|
242
|
+
"failed to parse; the enable signal carrier is unknown (no signal paths recorded), " \
|
|
243
|
+
"keeping the DI state"
|
|
244
|
+
end
|
|
245
|
+
else
|
|
246
|
+
logger.trace do
|
|
247
|
+
"APM_TRACING RC: dynamic_instrumentation_enabled absent while the config that carried " \
|
|
248
|
+
"the enable signal failed to parse; keeping the DI state"
|
|
249
|
+
end
|
|
250
|
+
end
|
|
251
|
+
false
|
|
252
|
+
else
|
|
253
|
+
logger.trace { "APM_TRACING RC: dynamic_instrumentation_enabled withdrawn; treating as false" }
|
|
254
|
+
true
|
|
255
|
+
end
|
|
256
|
+
end
|
|
257
|
+
|
|
258
|
+
# The repository paths of the APM_TRACING contents that supplied the
|
|
259
|
+
# dynamic_instrumentation_enabled value at the last merge where the field was
|
|
260
|
+
# present. The component holds the paths so that they outlive the RC client.
|
|
261
|
+
#
|
|
262
|
+
# @return [Array<Core::Remote::Configuration::Path>]
|
|
263
|
+
attr_reader :rc_enablement_signal_paths
|
|
264
|
+
|
|
265
|
+
# Replaces the recorded enable-signal carrier paths.
|
|
266
|
+
#
|
|
267
|
+
# @param paths [Array<Core::Remote::Configuration::Path>] the carrier paths, empty when the merged field was absent
|
|
268
|
+
# @return [void]
|
|
269
|
+
def record_rc_enablement_signal_paths(paths)
|
|
270
|
+
@rc_enablement_signal_paths = paths.dup
|
|
271
|
+
nil
|
|
272
|
+
end
|
|
273
|
+
|
|
169
274
|
# Shuts down dynamic instrumentation permanently.
|
|
170
275
|
#
|
|
171
276
|
# Removes all code hooks and stops background threads.
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
+
require_relative "../core/configuration/stable_config"
|
|
4
|
+
|
|
3
5
|
module Datadog
|
|
4
6
|
module DI
|
|
5
7
|
# Configuration for DI
|
|
@@ -136,8 +138,35 @@ module Datadog
|
|
|
136
138
|
|
|
137
139
|
option :max_time_to_serialize_ms do |o|
|
|
138
140
|
o.type :int
|
|
139
|
-
o.
|
|
140
|
-
o.
|
|
141
|
+
o.env "DD_DYNAMIC_INSTRUMENTATION_CAPTURE_TIMEOUT_MS"
|
|
142
|
+
o.default do
|
|
143
|
+
legacy = Settings.legacy_capture_timeout_value
|
|
144
|
+
if legacy
|
|
145
|
+
Datadog::Core.log_deprecation(key: :di_legacy_max_time_to_serialize) do
|
|
146
|
+
"The DD_DYNAMIC_INSTRUMENTATION_MAX_TIME_TO_SERIALIZE environment variable is deprecated " \
|
|
147
|
+
"and will be removed in a future release. " \
|
|
148
|
+
"Please use DD_DYNAMIC_INSTRUMENTATION_CAPTURE_TIMEOUT_MS instead."
|
|
149
|
+
end
|
|
150
|
+
|
|
151
|
+
begin
|
|
152
|
+
Integer(legacy, 10)
|
|
153
|
+
rescue ArgumentError
|
|
154
|
+
raise ArgumentError,
|
|
155
|
+
"Expected environment variable DD_DYNAMIC_INSTRUMENTATION_MAX_TIME_TO_SERIALIZE " \
|
|
156
|
+
"to be an int, but '#{legacy}' was provided."
|
|
157
|
+
end
|
|
158
|
+
else
|
|
159
|
+
150
|
|
160
|
+
end
|
|
161
|
+
end
|
|
162
|
+
o.setter do |value, _old|
|
|
163
|
+
if value < 0
|
|
164
|
+
raise ArgumentError,
|
|
165
|
+
"The setting `dynamic_instrumentation.max_time_to_serialize_ms` must not be negative, " \
|
|
166
|
+
"but `#{value.inspect}` was provided."
|
|
167
|
+
end
|
|
168
|
+
value
|
|
169
|
+
end
|
|
141
170
|
end
|
|
142
171
|
|
|
143
172
|
# Settings in the 'internal' group are for internal Datadog
|
|
@@ -244,6 +273,28 @@ module Datadog
|
|
|
244
273
|
end
|
|
245
274
|
end
|
|
246
275
|
end
|
|
276
|
+
|
|
277
|
+
# Resolves the deprecated capture-timeout name for the setting's
|
|
278
|
+
# default. The legacy value applies only when the canonical variable
|
|
279
|
+
# is configured nowhere (environment with its registry alias, local or
|
|
280
|
+
# fleet stable configuration), and the legacy itself resolves in the
|
|
281
|
+
# option machinery's precedence order: fleet stable configuration,
|
|
282
|
+
# environment, local stable configuration.
|
|
283
|
+
def self.legacy_capture_timeout_value
|
|
284
|
+
canonical_name = "DD_DYNAMIC_INSTRUMENTATION_CAPTURE_TIMEOUT_MS"
|
|
285
|
+
legacy_name = "DD_DYNAMIC_INSTRUMENTATION_MAX_TIME_TO_SERIALIZE"
|
|
286
|
+
|
|
287
|
+
stable = Datadog::Core::Configuration::StableConfig.configuration
|
|
288
|
+
local = stable&.dig(:local, :config)
|
|
289
|
+
fleet = stable&.dig(:fleet, :config)
|
|
290
|
+
|
|
291
|
+
canonical = (fleet && DATADOG_ENV.get_environment_variable(canonical_name, source_env: fleet)) ||
|
|
292
|
+
DATADOG_ENV[canonical_name] ||
|
|
293
|
+
(local && DATADOG_ENV.get_environment_variable(canonical_name, source_env: local))
|
|
294
|
+
return nil if canonical
|
|
295
|
+
|
|
296
|
+
(fleet && fleet[legacy_name]) || DATADOG_ENV[legacy_name] || (local && local[legacy_name])
|
|
297
|
+
end
|
|
247
298
|
end
|
|
248
299
|
end
|
|
249
300
|
end
|
data/lib/datadog/di/context.rb
CHANGED
|
@@ -61,9 +61,14 @@ module Datadog
|
|
|
61
61
|
# Exception raised by the method, if any, for a method probe
|
|
62
62
|
attr_reader :exception
|
|
63
63
|
|
|
64
|
-
|
|
64
|
+
# Returns the locals captured at the probe hit in serialized form,
|
|
65
|
+
# or nil when no locals were captured.
|
|
66
|
+
#
|
|
67
|
+
# @param serialization_deadline [Float] absolute capture deadline in monotonic clock seconds
|
|
68
|
+
# @return [Hash{Symbol => Hash}, nil] serialized locals keyed by variable name
|
|
69
|
+
def serialized_locals(serialization_deadline:)
|
|
65
70
|
# TODO cache?
|
|
66
|
-
locals && serializer.serialize_vars(locals, **probe.snapshot_serializer_limits(settings))
|
|
71
|
+
locals && serializer.serialize_vars(locals, deadline: serialization_deadline, **probe.snapshot_serializer_limits(settings))
|
|
67
72
|
end
|
|
68
73
|
|
|
69
74
|
def fetch(var_name)
|
|
@@ -10,7 +10,7 @@ Datadog::DI::Serializer.register(
|
|
|
10
10
|
# logic for "instances of classes derived from X", but a condition Proc
|
|
11
11
|
# is more universal.
|
|
12
12
|
condition: lambda { |value| ActiveRecord::Base === value }
|
|
13
|
-
) do |serializer, value, name:, depth:|
|
|
13
|
+
) do |serializer, value, name:, depth:, deadline:|
|
|
14
14
|
# +serializer+ is an instance of DI::Serializer.
|
|
15
15
|
# Use it to perform the serialization to primitive values.
|
|
16
16
|
#
|
|
@@ -30,12 +30,18 @@ Datadog::DI::Serializer.register(
|
|
|
30
30
|
# nesting levels in the output.
|
|
31
31
|
# This serializer could also potentially do its own depth limiting.
|
|
32
32
|
#
|
|
33
|
+
# +deadline+ is the absolute monotonic-clock deadline (in seconds) of the
|
|
34
|
+
# capture point that is being serialized. Pass it through to
|
|
35
|
+
# +serialize_value+ so the custom-serialized subtree draws down the same
|
|
36
|
+
# capture budget as the rest of the snapshot.
|
|
37
|
+
#
|
|
33
38
|
# Steep: steep thinks all of the arguments are nil here
|
|
34
39
|
# Looks like it cannot handle kwargs in lambdas
|
|
35
40
|
# @type var depth: Integer
|
|
41
|
+
# @type var deadline: Float
|
|
36
42
|
value_to_serialize = {
|
|
37
43
|
attributes: value.attributes,
|
|
38
44
|
new_record: value.new_record?,
|
|
39
45
|
}
|
|
40
|
-
serializer.serialize_value(value_to_serialize, depth: depth, type: value.class)
|
|
46
|
+
serializer.serialize_value(value_to_serialize, depth: depth, type: value.class, deadline: deadline)
|
|
41
47
|
end
|