datadog 2.46.0 → 2.48.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 +56 -2
- data/LICENSE-3rdparty.csv +1 -0
- data/ext/datadog_profiling_native_extension/collectors_stack.c +143 -86
- data/ext/datadog_profiling_native_extension/collectors_stack.h +9 -1
- data/ext/datadog_profiling_native_extension/collectors_thread_context.c +6 -1
- data/ext/datadog_profiling_native_extension/extconf.rb +7 -13
- data/ext/datadog_profiling_native_extension/native_extension_helpers.rb +3 -3
- data/ext/datadog_profiling_native_extension/private_vm_api_access.c +67 -14
- data/ext/datadog_profiling_native_extension/private_vm_api_access.h +8 -1
- data/ext/datadog_profiling_native_extension/profiling.c +1 -1
- data/ext/libdatadog_api/extconf.rb +9 -7
- data/ext/libdatadog_api/trace_exporter.c +34 -7
- data/ext/libdatadog_extconf_helpers.rb +2 -2
- data/lib/datadog/ai_guard/component.rb +1 -1
- data/lib/datadog/ai_guard/contrib/rack/request_middleware.rb +1 -9
- data/lib/datadog/ai_guard/contrib/rails/patcher.rb +1 -1
- data/lib/datadog/ai_guard/contrib/ruby_llm/message_adapter.rb +1 -1
- data/lib/datadog/ai_guard/contrib/ruby_llm/redaction_change_set.rb +3 -3
- data/lib/datadog/ai_guard/evaluation/client.rb +3 -3
- data/lib/datadog/ai_guard/evaluation.rb +2 -2
- data/lib/datadog/ai_guard/http_client.rb +3 -2
- data/lib/datadog/ai_guard/redaction.rb +1 -1
- data/lib/datadog/appsec/api_security/endpoint_collection/rails_collector.rb +1 -1
- data/lib/datadog/appsec/assets/waf_rules/README.md +3 -3
- data/lib/datadog/appsec/assets/waf_rules/recommended.json +5366 -1517
- data/lib/datadog/appsec/assets/waf_rules/strict.json +2 -2
- data/lib/datadog/appsec/autoload.rb +1 -1
- data/lib/datadog/appsec/component.rb +1 -1
- data/lib/datadog/appsec/compressed_json.rb +1 -1
- data/lib/datadog/appsec/configuration.rb +3 -3
- data/lib/datadog/appsec/context.rb +1 -1
- data/lib/datadog/appsec/contrib/active_record/instrumentation.rb +11 -1
- data/lib/datadog/appsec/contrib/active_record/patcher.rb +12 -4
- data/lib/datadog/appsec/contrib/aws_lambda/gateway/watcher.rb +2 -2
- data/lib/datadog/appsec/contrib/aws_lambda/waf_addresses.rb +1 -1
- data/lib/datadog/appsec/contrib/devise/configuration.rb +1 -1
- data/lib/datadog/appsec/contrib/devise/patches/signin_tracking_patch.rb +1 -1
- data/lib/datadog/appsec/contrib/devise/patches/signup_tracking_patch.rb +1 -1
- data/lib/datadog/appsec/contrib/devise/tracking_middleware.rb +1 -1
- data/lib/datadog/appsec/contrib/excon/ssrf_detection_middleware.rb +1 -1
- data/lib/datadog/appsec/contrib/faraday/ssrf_detection_middleware.rb +1 -1
- data/lib/datadog/appsec/contrib/graphql/gateway/multiplex.rb +7 -7
- data/lib/datadog/appsec/contrib/graphql/gateway/watcher.rb +1 -1
- data/lib/datadog/appsec/contrib/rack/gateway/watcher.rb +3 -3
- data/lib/datadog/appsec/contrib/rack/request_middleware.rb +5 -5
- data/lib/datadog/appsec/contrib/rails/gateway/watcher.rb +31 -4
- data/lib/datadog/appsec/contrib/rails/patcher.rb +2 -2
- data/lib/datadog/appsec/contrib/rails/patches/render_to_body_patch.rb +8 -7
- data/lib/datadog/appsec/contrib/rest_client/request_ssrf_detection_patch.rb +1 -1
- data/lib/datadog/appsec/contrib/sinatra/gateway/watcher.rb +17 -5
- data/lib/datadog/appsec/contrib/sinatra/patcher.rb +1 -1
- data/lib/datadog/appsec/contrib/sinatra/patches/json_patch.rb +8 -7
- data/lib/datadog/appsec/metrics/collector.rb +5 -5
- data/lib/datadog/appsec/metrics/telemetry_exporter.rb +3 -3
- data/lib/datadog/appsec/monitor/gateway/watcher.rb +2 -2
- data/lib/datadog/appsec/processor/rule_loader.rb +1 -1
- data/lib/datadog/appsec/response.rb +1 -1
- data/lib/datadog/appsec/security_engine/engine.rb +8 -7
- data/lib/datadog/appsec/security_engine/runner.rb +2 -2
- data/lib/datadog/appsec/trace_keeper.rb +1 -1
- data/lib/datadog/appsec.rb +1 -1
- data/lib/datadog/core/configuration/agent_settings_resolver.rb +14 -13
- data/lib/datadog/core/configuration/agentless_settings_resolver.rb +2 -2
- data/lib/datadog/core/configuration/components.rb +12 -11
- data/lib/datadog/core/configuration/components_state.rb +8 -1
- data/lib/datadog/core/configuration/settings.rb +5 -2
- data/lib/datadog/core/configuration/supported_configurations.rb +3 -0
- data/lib/datadog/core/configuration.rb +2 -2
- data/lib/datadog/core/crashtracking/component.rb +1 -1
- data/lib/datadog/core/diagnostics/environment_logger.rb +1 -1
- data/lib/datadog/core/environment/cgroup.rb +2 -2
- data/lib/datadog/core/environment/container.rb +3 -3
- data/lib/datadog/core/metrics/client.rb +6 -6
- data/lib/datadog/core/process_discovery.rb +1 -1
- data/lib/datadog/core/remote/client.rb +44 -3
- data/lib/datadog/core/remote/dispatcher.rb +34 -3
- data/lib/datadog/core/remote/tie/tracing.rb +4 -3
- data/lib/datadog/core/remote/transport/http.rb +2 -2
- data/lib/datadog/core/runtime/metrics.rb +14 -14
- data/lib/datadog/core/semaphore.rb +3 -1
- data/lib/datadog/core/telemetry/event/app_started.rb +9 -9
- data/lib/datadog/core/telemetry/logger.rb +1 -1
- data/lib/datadog/core/telemetry/logging.rb +1 -1
- data/lib/datadog/core/telemetry/request.rb +9 -3
- data/lib/datadog/core/telemetry/transport/http.rb +2 -2
- data/lib/datadog/core/telemetry/worker.rb +1 -1
- data/lib/datadog/core/transport/http/adapters/net.rb +1 -1
- data/lib/datadog/core/transport/http/adapters/unix_socket.rb +1 -1
- data/lib/datadog/core/transport/http/builder.rb +1 -1
- data/lib/datadog/core/transport/http.rb +3 -3
- data/lib/datadog/core/utils/at_fork_monkey_patch.rb +2 -2
- data/lib/datadog/core/workers/async.rb +1 -1
- data/lib/datadog/core/workers/runtime_metrics.rb +2 -2
- data/lib/datadog/data_streams/pathway_context.rb +1 -1
- data/lib/datadog/data_streams/processor.rb +48 -27
- data/lib/datadog/data_streams/transport/http.rb +1 -1
- data/lib/datadog/data_streams.rb +16 -0
- data/lib/datadog/di/capture_expression_evaluator.rb +48 -11
- data/lib/datadog/di/component.rb +73 -2
- data/lib/datadog/di/configuration.rb +19 -0
- data/lib/datadog/di/contrib/active_record.rb +1 -1
- data/lib/datadog/di/el/compiler.rb +4 -4
- data/lib/datadog/di/el/evaluator.rb +247 -43
- data/lib/datadog/di/el/expression.rb +36 -6
- data/lib/datadog/di/error.rb +16 -0
- data/lib/datadog/di/guardrails_telemetry/reason.rb +3 -2
- data/lib/datadog/di/instrumenter.rb +39 -10
- data/lib/datadog/di/probe_notification_builder.rb +58 -10
- data/lib/datadog/di/probe_notifier_worker.rb +1 -1
- data/lib/datadog/di/remote.rb +46 -2
- data/lib/datadog/di/serializer.rb +47 -13
- data/lib/datadog/di.rb +27 -0
- data/lib/datadog/error_tracking/component.rb +1 -1
- data/lib/datadog/error_tracking/configuration.rb +1 -1
- data/lib/datadog/kit/appsec/events/v2.rb +6 -6
- data/lib/datadog/kit/appsec/events.rb +1 -1
- data/lib/datadog/kit/enable_core_dumps.rb +1 -1
- data/lib/datadog/kit/identity.rb +1 -1
- data/lib/datadog/open_feature/activation.rb +26 -1
- data/lib/datadog/open_feature/agentless/configuration_source.rb +94 -15
- data/lib/datadog/open_feature/component.rb +22 -2
- data/lib/datadog/open_feature/configuration/agentless_endpoint.rb +6 -0
- data/lib/datadog/open_feature/configuration.rb +10 -4
- data/lib/datadog/open_feature/evaluation_engine.rb +62 -4
- data/lib/datadog/open_feature/exposures/buffer.rb +4 -0
- data/lib/datadog/open_feature/exposures/reporter.rb +17 -4
- data/lib/datadog/open_feature/exposures/worker.rb +37 -6
- data/lib/datadog/open_feature/flag_evaluation/aggregator.rb +5 -5
- data/lib/datadog/open_feature/flag_evaluation/writer.rb +1 -1
- data/lib/datadog/open_feature/hooks/debug_logging_hook.rb +56 -0
- data/lib/datadog/open_feature/hooks/evaluation_telemetry_opt_out_hook.rb +25 -0
- data/lib/datadog/open_feature/hooks/span_enrichment_hook.rb +2 -2
- data/lib/datadog/open_feature/metrics/flag_eval_metrics.rb +1 -1
- data/lib/datadog/open_feature/native_evaluator.rb +1 -1
- data/lib/datadog/open_feature/noop_evaluator.rb +1 -1
- data/lib/datadog/open_feature/provider.rb +69 -12
- data/lib/datadog/open_feature/remote.rb +8 -1
- data/lib/datadog/open_feature/resolution_details.rb +2 -2
- data/lib/datadog/open_feature/transport.rb +6 -6
- data/lib/datadog/opentelemetry/api/context.rb +3 -3
- data/lib/datadog/opentelemetry/logs.rb +5 -5
- data/lib/datadog/opentelemetry/metrics.rb +3 -3
- data/lib/datadog/opentelemetry/sdk/propagator.rb +3 -3
- data/lib/datadog/opentelemetry/sdk/span_processor.rb +2 -2
- data/lib/datadog/opentelemetry/sdk/trace/span.rb +1 -1
- data/lib/datadog/profiling/collectors/code_provenance.rb +3 -3
- data/lib/datadog/profiling/collectors/cpu_and_wall_time_worker.rb +4 -4
- data/lib/datadog/profiling/collectors/idle_sampling_helper.rb +1 -1
- data/lib/datadog/profiling/collectors/info.rb +37 -6
- data/lib/datadog/profiling/collectors/thread_context.rb +1 -1
- data/lib/datadog/profiling/component.rb +41 -39
- data/lib/datadog/profiling/exporter.rb +4 -6
- data/lib/datadog/profiling/http_transport.rb +3 -3
- data/lib/datadog/profiling/profiler.rb +2 -2
- data/lib/datadog/profiling/scheduler.rb +2 -2
- data/lib/datadog/profiling/tag_builder.rb +1 -1
- data/lib/datadog/symbol_database/extractor.rb +8 -8
- data/lib/datadog/symbol_database/uploader.rb +1 -1
- data/lib/datadog/tracing/buffer.rb +3 -3
- data/lib/datadog/tracing/client_ip.rb +1 -1
- data/lib/datadog/tracing/component.rb +15 -10
- data/lib/datadog/tracing/configuration/dynamic/option.rb +2 -2
- data/lib/datadog/tracing/configuration/ext.rb +2 -0
- data/lib/datadog/tracing/configuration/settings.rb +14 -3
- data/lib/datadog/tracing/context.rb +1 -1
- data/lib/datadog/tracing/context_provider.rb +8 -0
- data/lib/datadog/tracing/contrib/action_cable/instrumentation.rb +2 -2
- data/lib/datadog/tracing/contrib/active_job/data_streams.rb +27 -2
- data/lib/datadog/tracing/contrib/active_record/configuration/resolver.rb +2 -2
- data/lib/datadog/tracing/contrib/active_record/configuration/settings.rb +1 -1
- data/lib/datadog/tracing/contrib/active_record/utils.rb +1 -1
- data/lib/datadog/tracing/contrib/active_support/cache/instrumentation.rb +1 -1
- data/lib/datadog/tracing/contrib/active_support/configuration/settings.rb +1 -1
- data/lib/datadog/tracing/contrib/active_support/notifications/subscriber.rb +2 -2
- data/lib/datadog/tracing/contrib/active_support/notifications/subscription.rb +2 -2
- data/lib/datadog/tracing/contrib/aws/configuration/settings.rb +1 -1
- data/lib/datadog/tracing/contrib/aws/instrumentation.rb +1 -1
- data/lib/datadog/tracing/contrib/dalli/configuration/settings.rb +1 -1
- data/lib/datadog/tracing/contrib/dalli/instrumentation.rb +1 -1
- data/lib/datadog/tracing/contrib/delayed_job/plugin.rb +2 -2
- data/lib/datadog/tracing/contrib/elasticsearch/configuration/settings.rb +1 -1
- data/lib/datadog/tracing/contrib/elasticsearch/patcher.rb +3 -3
- data/lib/datadog/tracing/contrib/ethon/configuration/settings.rb +1 -1
- data/lib/datadog/tracing/contrib/ethon/easy_patch.rb +17 -12
- data/lib/datadog/tracing/contrib/ethon/multi_patch.rb +1 -1
- data/lib/datadog/tracing/contrib/excon/configuration/settings.rb +1 -1
- data/lib/datadog/tracing/contrib/excon/middleware.rb +16 -9
- data/lib/datadog/tracing/contrib/faraday/configuration/settings.rb +1 -1
- data/lib/datadog/tracing/contrib/faraday/middleware.rb +14 -8
- data/lib/datadog/tracing/contrib/grape/endpoint.rb +4 -4
- data/lib/datadog/tracing/contrib/graphql/patcher.rb +1 -1
- data/lib/datadog/tracing/contrib/graphql/unified_trace.rb +3 -3
- data/lib/datadog/tracing/contrib/grpc/configuration/settings.rb +1 -1
- data/lib/datadog/tracing/contrib/grpc/datadog_interceptor/client.rb +2 -2
- data/lib/datadog/tracing/contrib/grpc/datadog_interceptor/server.rb +1 -1
- data/lib/datadog/tracing/contrib/grpc.rb +1 -1
- data/lib/datadog/tracing/contrib/hanami/action_tracer.rb +1 -1
- data/lib/datadog/tracing/contrib/hanami/plugin.rb +1 -1
- data/lib/datadog/tracing/contrib/hanami/renderer_policy_tracing.rb +1 -1
- data/lib/datadog/tracing/contrib/hanami/router_tracing.rb +1 -1
- data/lib/datadog/tracing/contrib/http/configuration/settings.rb +1 -1
- data/lib/datadog/tracing/contrib/http/instrumentation.rb +21 -6
- data/lib/datadog/tracing/contrib/http.rb +1 -1
- data/lib/datadog/tracing/contrib/httpclient/configuration/settings.rb +1 -1
- data/lib/datadog/tracing/contrib/httpclient/instrumentation.rb +14 -8
- data/lib/datadog/tracing/contrib/httprb/configuration/settings.rb +1 -1
- data/lib/datadog/tracing/contrib/httprb/instrumentation.rb +14 -8
- 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/monitor.rb +1 -1
- data/lib/datadog/tracing/contrib/karafka/patcher.rb +1 -1
- data/lib/datadog/tracing/contrib/karafka.rb +1 -1
- data/lib/datadog/tracing/contrib/lograge/patcher.rb +1 -1
- data/lib/datadog/tracing/contrib/mongodb/configuration/settings.rb +1 -1
- data/lib/datadog/tracing/contrib/mongodb/parsers.rb +1 -1
- data/lib/datadog/tracing/contrib/mongodb/subscribers.rb +1 -1
- data/lib/datadog/tracing/contrib/mysql2/configuration/settings.rb +1 -1
- data/lib/datadog/tracing/contrib/mysql2/instrumentation.rb +3 -3
- data/lib/datadog/tracing/contrib/opensearch/configuration/settings.rb +2 -2
- data/lib/datadog/tracing/contrib/opensearch/patcher.rb +3 -3
- data/lib/datadog/tracing/contrib/pg/configuration/settings.rb +1 -1
- data/lib/datadog/tracing/contrib/pg/instrumentation.rb +4 -4
- data/lib/datadog/tracing/contrib/presto/configuration/settings.rb +1 -1
- data/lib/datadog/tracing/contrib/presto/instrumentation.rb +4 -4
- data/lib/datadog/tracing/contrib/propagation/sql_comment.rb +1 -1
- data/lib/datadog/tracing/contrib/que/tracer.rb +1 -1
- data/lib/datadog/tracing/contrib/racecar/configuration/settings.rb +1 -1
- data/lib/datadog/tracing/contrib/racecar/events/batch.rb +1 -1
- data/lib/datadog/tracing/contrib/racecar/events/message.rb +1 -1
- data/lib/datadog/tracing/contrib/rack/middlewares.rb +3 -3
- data/lib/datadog/tracing/contrib/rack/patcher.rb +1 -1
- data/lib/datadog/tracing/contrib/rails/framework.rb +7 -7
- data/lib/datadog/tracing/contrib/rails/log_injection.rb +1 -1
- data/lib/datadog/tracing/contrib/rails/runner.rb +4 -4
- data/lib/datadog/tracing/contrib/redis/configuration/settings.rb +1 -1
- 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/rest_client/configuration/settings.rb +1 -1
- data/lib/datadog/tracing/contrib/rest_client/request_patch.rb +17 -10
- data/lib/datadog/tracing/contrib/sequel/database.rb +1 -1
- data/lib/datadog/tracing/contrib/sequel/dataset.rb +1 -1
- data/lib/datadog/tracing/contrib/shoryuken/tracer.rb +1 -1
- data/lib/datadog/tracing/contrib/sidekiq/client_tracer.rb +2 -2
- data/lib/datadog/tracing/contrib/sidekiq/server_tracer.rb +2 -2
- data/lib/datadog/tracing/contrib/sidekiq.rb +1 -1
- data/lib/datadog/tracing/contrib/sinatra/tracer_middleware.rb +1 -1
- data/lib/datadog/tracing/contrib/status_range_env_parser.rb +1 -1
- data/lib/datadog/tracing/contrib/sucker_punch/instrumentation.rb +1 -1
- data/lib/datadog/tracing/contrib/trilogy/configuration/settings.rb +1 -1
- data/lib/datadog/tracing/contrib/trilogy/instrumentation.rb +3 -3
- data/lib/datadog/tracing/contrib/utils/quantization/http.rb +102 -0
- data/lib/datadog/tracing/contrib/waterdrop/middleware.rb +2 -2
- data/lib/datadog/tracing/contrib/waterdrop.rb +1 -1
- data/lib/datadog/tracing/diagnostics/environment_logger.rb +1 -1
- data/lib/datadog/tracing/distributed/b3_multi.rb +1 -1
- data/lib/datadog/tracing/distributed/b3_single.rb +1 -1
- data/lib/datadog/tracing/distributed/baggage.rb +3 -3
- data/lib/datadog/tracing/distributed/datadog.rb +3 -3
- data/lib/datadog/tracing/distributed/propagation.rb +7 -7
- data/lib/datadog/tracing/distributed/trace_context.rb +1 -1
- data/lib/datadog/tracing/distributed/trace_state/open_telemetry.rb +1 -1
- data/lib/datadog/tracing/otel_thread_context.rb +3 -3
- data/lib/datadog/tracing/pipeline.rb +1 -1
- data/lib/datadog/tracing/remote.rb +50 -19
- data/lib/datadog/tracing/sampling/priority_sampler.rb +1 -1
- data/lib/datadog/tracing/sampling/rule.rb +1 -1
- data/lib/datadog/tracing/sampling/rule_sampler.rb +1 -1
- data/lib/datadog/tracing/sampling/span/rule_parser.rb +2 -2
- data/lib/datadog/tracing/span_operation.rb +1 -1
- data/lib/datadog/tracing/trace_digest.rb +1 -1
- data/lib/datadog/tracing/trace_operation.rb +6 -6
- data/lib/datadog/tracing/tracer.rb +6 -6
- data/lib/datadog/tracing/transport/http/telemetry.rb +1 -1
- data/lib/datadog/tracing/transport/http.rb +2 -2
- data/lib/datadog/tracing/transport/io.rb +1 -1
- data/lib/datadog/tracing/transport/native.rb +3 -3
- data/lib/datadog/tracing/transport/statistics.rb +2 -2
- data/lib/datadog/tracing/transport/telemetry.rb +3 -1
- data/lib/datadog/tracing/transport/trace_formatter.rb +12 -12
- data/lib/datadog/tracing/transport/traces.rb +1 -1
- data/lib/datadog/tracing/utils.rb +1 -1
- data/lib/datadog/tracing/workers.rb +1 -1
- data/lib/datadog/version.rb +1 -1
- metadata +9 -8
- data/lib/datadog/appsec/utils/hash_coercion.rb +0 -23
|
@@ -27,8 +27,18 @@ module Datadog
|
|
|
27
27
|
cls = Class.new(Evaluator)
|
|
28
28
|
cls.class_exec do
|
|
29
29
|
eval(<<-RUBY, Object.new.send(:binding), __FILE__, __LINE__ + 1) # standard:disable Security/Eval
|
|
30
|
-
|
|
31
|
-
|
|
30
|
+
# Evaluates the compiled expression against +context+ within
|
|
31
|
+
# the cooperative evaluation +evaluation_deadline+.
|
|
32
|
+
#
|
|
33
|
+
# @param context [Context] evaluation context (locals, instance
|
|
34
|
+
# variables, and per-invocation special variables).
|
|
35
|
+
# @param evaluation_deadline [Float] invocation-local evaluation
|
|
36
|
+
# deadline, as CLOCK_THREAD_CPUTIME_ID float seconds.
|
|
37
|
+
# @return [Object] the value the expression evaluates to.
|
|
38
|
+
# @raise [DI::Error::ExpressionEvaluationError] the expression
|
|
39
|
+
# failed to evaluate, including the EvaluationTimeout
|
|
40
|
+
# subclass raised when the deadline is exceeded.
|
|
41
|
+
def evaluate(context, evaluation_deadline)
|
|
32
42
|
#{compiled_expr}
|
|
33
43
|
end
|
|
34
44
|
RUBY
|
|
@@ -40,12 +50,32 @@ module Datadog
|
|
|
40
50
|
attr_reader :evaluator
|
|
41
51
|
attr_reader :redaction_identifier
|
|
42
52
|
|
|
43
|
-
|
|
44
|
-
|
|
53
|
+
# Evaluates the expression against +context+.
|
|
54
|
+
#
|
|
55
|
+
# @param context [Context] evaluation context (locals, instance
|
|
56
|
+
# variables, and per-invocation special variables).
|
|
57
|
+
# @param evaluation_deadline [Float] cooperative evaluation deadline, as
|
|
58
|
+
# CLOCK_THREAD_CPUTIME_ID float seconds.
|
|
59
|
+
# @return [Object] the value the expression evaluates to.
|
|
60
|
+
# @raise [DI::Error::ExpressionEvaluationError] the expression failed
|
|
61
|
+
# to evaluate; DI::Error::EvaluationTimeout, raised when the
|
|
62
|
+
# evaluation deadline is exceeded, is a subclass.
|
|
63
|
+
def evaluate(context, evaluation_deadline:)
|
|
64
|
+
evaluator.evaluate(context, evaluation_deadline)
|
|
45
65
|
end
|
|
46
66
|
|
|
47
|
-
|
|
48
|
-
|
|
67
|
+
# Returns whether the expression evaluates to a truthy value
|
|
68
|
+
# against +context+.
|
|
69
|
+
#
|
|
70
|
+
# @param context [Context] evaluation context.
|
|
71
|
+
# @param evaluation_deadline [Float] cooperative evaluation deadline, as
|
|
72
|
+
# CLOCK_THREAD_CPUTIME_ID float seconds.
|
|
73
|
+
# @return [Boolean] whether the expression is satisfied.
|
|
74
|
+
# @raise [DI::Error::ExpressionEvaluationError] the expression failed
|
|
75
|
+
# to evaluate; DI::Error::EvaluationTimeout, raised when the
|
|
76
|
+
# evaluation deadline is exceeded, is a subclass.
|
|
77
|
+
def satisfied?(context, evaluation_deadline:)
|
|
78
|
+
!!evaluate(context, evaluation_deadline: evaluation_deadline)
|
|
49
79
|
end
|
|
50
80
|
end
|
|
51
81
|
end
|
data/lib/datadog/di/error.rb
CHANGED
|
@@ -92,6 +92,22 @@ module Datadog
|
|
|
92
92
|
# expressions.
|
|
93
93
|
class ExpressionEvaluationError < Error
|
|
94
94
|
end
|
|
95
|
+
|
|
96
|
+
# Raised when expression evaluation exceeds the configured
|
|
97
|
+
# evaluation CPU-time budget, or a `matches` operator exceeds its
|
|
98
|
+
# per-match wall-clock bound.
|
|
99
|
+
class EvaluationTimeout < ExpressionEvaluationError
|
|
100
|
+
# Default message for EvaluationTimeout exceptions.
|
|
101
|
+
DEFAULT_MESSAGE = "expression evaluation timeout"
|
|
102
|
+
|
|
103
|
+
# Builds the exception, defaulting +message+ to DEFAULT_MESSAGE.
|
|
104
|
+
#
|
|
105
|
+
# @param message [String] exception message.
|
|
106
|
+
# @return [void]
|
|
107
|
+
def initialize(message: DEFAULT_MESSAGE)
|
|
108
|
+
super(message)
|
|
109
|
+
end
|
|
110
|
+
end
|
|
95
111
|
end
|
|
96
112
|
end
|
|
97
113
|
end
|
|
@@ -16,8 +16,9 @@ module Datadog
|
|
|
16
16
|
# process-wide rate limiter.
|
|
17
17
|
RATE_LIMIT_GLOBAL = "rateLimitGlobal"
|
|
18
18
|
|
|
19
|
-
# Skip reason emitted when
|
|
20
|
-
#
|
|
19
|
+
# Skip reason emitted when an evaluation exceeds its time budget:
|
|
20
|
+
# a probe condition, a capture expression (including one skipped at
|
|
21
|
+
# the expired capture time budget), or a message template.
|
|
21
22
|
EVALUATION_TIMEOUT = "evaluationTimeout"
|
|
22
23
|
|
|
23
24
|
# Skip reason named in the +di: debug log when a condition-evaluation
|
|
@@ -83,7 +83,7 @@ module Datadog
|
|
|
83
83
|
# @param settings [Datadog::Core::Configuration::Settings] tracer settings
|
|
84
84
|
# @param serializer [Serializer] serializer for captured values
|
|
85
85
|
# @param logger [DI::Logger] logger for instrumenter diagnostics
|
|
86
|
-
# @param guardrails_telemetry [GuardrailsTelemetry] emitter for the canonical
|
|
86
|
+
# @param guardrails_telemetry [GuardrailsTelemetry] emitter for the canonical guardrail skip metrics
|
|
87
87
|
# @param capture_expression_evaluator [CaptureExpressionEvaluator] evaluator for the probe's capture expressions
|
|
88
88
|
# @param code_tracker [CodeTracker, nil] code tracker for line probe installation
|
|
89
89
|
# @param telemetry [Datadog::Core::Telemetry::Component, nil] component instrumenter errors are reported through
|
|
@@ -554,7 +554,8 @@ module Datadog
|
|
|
554
554
|
target_self: target_self,
|
|
555
555
|
probe: probe, settings: settings, serializer: serializer,
|
|
556
556
|
)
|
|
557
|
-
continue = condition.satisfied?(context
|
|
557
|
+
continue = condition.satisfied?(context,
|
|
558
|
+
evaluation_deadline: serializer.evaluation_deadline)
|
|
558
559
|
rescue Exception => exc # standard:disable Lint/RescueException
|
|
559
560
|
Datadog::DI.reraise_if_fatal(exc)
|
|
560
561
|
# Evaluation error exception can be raised for "expected"
|
|
@@ -563,6 +564,10 @@ module Datadog
|
|
|
563
564
|
raise if settings.dynamic_instrumentation.internal.propagate_all_exceptions &&
|
|
564
565
|
!exc.is_a?(DI::Error::ExpressionEvaluationError)
|
|
565
566
|
|
|
567
|
+
# An evaluation timeout is an internal budget abort, so it
|
|
568
|
+
# stays contained even under propagate_all_exceptions.
|
|
569
|
+
record_condition_evaluation_timeout(probe, exc)
|
|
570
|
+
|
|
566
571
|
if context
|
|
567
572
|
# We want to report evaluation errors for conditions
|
|
568
573
|
# as probe snapshots. However, if we failed to create
|
|
@@ -605,7 +610,7 @@ module Datadog
|
|
|
605
610
|
serialized_entry_args = if probe.capture_snapshot?
|
|
606
611
|
serializer.serialize_args(args, kwargs, target_self,
|
|
607
612
|
deadline: serializer.serialization_deadline,
|
|
608
|
-
**probe.snapshot_serializer_limits(settings)
|
|
613
|
+
**probe.snapshot_serializer_limits(settings))
|
|
609
614
|
end
|
|
610
615
|
|
|
611
616
|
entry_capture_expressions = nil
|
|
@@ -698,7 +703,7 @@ module Datadog
|
|
|
698
703
|
entry_capture_expressions: entry_capture_expressions,
|
|
699
704
|
entry_capture_evaluation_errors: entry_capture_evaluation_errors,
|
|
700
705
|
caller_locations: caller_locs,
|
|
701
|
-
return_value: rv, duration: duration, exception: exc
|
|
706
|
+
return_value: rv, duration: duration, exception: exc)
|
|
702
707
|
|
|
703
708
|
begin
|
|
704
709
|
responder.probe_executed_callback(context)
|
|
@@ -788,12 +793,16 @@ module Datadog
|
|
|
788
793
|
public :kwargs_from_splat
|
|
789
794
|
end
|
|
790
795
|
|
|
791
|
-
# Trace point callback for a line probe.
|
|
796
|
+
# Trace point callback for a line probe hit. Evaluates the probe's
|
|
797
|
+
# condition, applies the per-probe rate limiter and the global rate
|
|
798
|
+
# limiter, then invokes the responder with the built context.
|
|
792
799
|
#
|
|
793
|
-
# @param probe [Probe] the probe
|
|
794
|
-
# @param iseq [RubyVM::InstructionSequence, nil] instruction sequence
|
|
795
|
-
#
|
|
796
|
-
# @param
|
|
800
|
+
# @param probe [Probe] the probe the trace point was installed for.
|
|
801
|
+
# @param iseq [RubyVM::InstructionSequence, nil] instruction sequence of
|
|
802
|
+
# the probe's target file, when the trace point is targeted.
|
|
803
|
+
# @param responder [#probe_executed_callback, #probe_condition_evaluation_failed_callback, #probe_disabled_callback]
|
|
804
|
+
# callback target for the probe hit.
|
|
805
|
+
# @param tp [TracePoint] the trace point event that fired.
|
|
797
806
|
# @return [void]
|
|
798
807
|
def line_trace_point_callback(probe, iseq, responder, tp)
|
|
799
808
|
di_start_time = Process.clock_gettime(Process::CLOCK_THREAD_CPUTIME_ID)
|
|
@@ -832,7 +841,8 @@ module Datadog
|
|
|
832
841
|
if condition = probe.condition
|
|
833
842
|
begin
|
|
834
843
|
context = build_trace_point_context(probe, tp)
|
|
835
|
-
return unless condition.satisfied?(context
|
|
844
|
+
return unless condition.satisfied?(context,
|
|
845
|
+
evaluation_deadline: serializer.evaluation_deadline)
|
|
836
846
|
rescue Exception => exc # standard:disable Lint/RescueException
|
|
837
847
|
Datadog::DI.reraise_if_fatal(exc)
|
|
838
848
|
# Evaluation error exception can be raised for "expected"
|
|
@@ -841,6 +851,10 @@ module Datadog
|
|
|
841
851
|
raise if settings.dynamic_instrumentation.internal.propagate_all_exceptions &&
|
|
842
852
|
!exc.is_a?(DI::Error::ExpressionEvaluationError)
|
|
843
853
|
|
|
854
|
+
# An evaluation timeout is an internal budget abort, so it
|
|
855
|
+
# stays contained even under propagate_all_exceptions.
|
|
856
|
+
record_condition_evaluation_timeout(probe, exc)
|
|
857
|
+
|
|
844
858
|
if context
|
|
845
859
|
# We want to report evaluation errors for conditions
|
|
846
860
|
# as probe snapshots. However, if we failed to create
|
|
@@ -900,6 +914,21 @@ module Datadog
|
|
|
900
914
|
nil
|
|
901
915
|
end
|
|
902
916
|
|
|
917
|
+
# Records a condition evaluation timeout for +probe+ through the
|
|
918
|
+
# shared evaluation-timeout reporter. Does nothing when +exc+ is not
|
|
919
|
+
# an evaluation timeout.
|
|
920
|
+
#
|
|
921
|
+
# @param probe [Probe] the probe whose condition evaluation timed out.
|
|
922
|
+
# @param exc [Exception] the exception raised by the evaluation.
|
|
923
|
+
# @return [void]
|
|
924
|
+
def record_condition_evaluation_timeout(probe, exc)
|
|
925
|
+
DI.report_evaluation_timeout(
|
|
926
|
+
telemetry: telemetry, guardrails_telemetry: guardrails_telemetry, logger: logger,
|
|
927
|
+
probe: probe, kind: "condition", exc: exc,
|
|
928
|
+
)
|
|
929
|
+
nil
|
|
930
|
+
end
|
|
931
|
+
|
|
903
932
|
def build_trace_point_context(probe, tp)
|
|
904
933
|
stack = caller_locations
|
|
905
934
|
# We have two helper methods being invoked from the trace point
|
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
require_relative "evaluation_failure"
|
|
6
6
|
require_relative "fatal_exceptions"
|
|
7
|
+
require_relative "guardrails_telemetry"
|
|
7
8
|
|
|
8
9
|
module Datadog
|
|
9
10
|
module DI
|
|
@@ -17,12 +18,17 @@ module Datadog
|
|
|
17
18
|
# @param serializer [Serializer] serializer for captured values
|
|
18
19
|
# @param logger [DI::Logger] logger for builder diagnostics
|
|
19
20
|
# @param capture_expression_evaluator [CaptureExpressionEvaluator] evaluator for the probe's capture expressions
|
|
21
|
+
# @param guardrails_telemetry [GuardrailsTelemetry] emitter for the canonical evaluation-timeout skip metric
|
|
22
|
+
# @param telemetry [Datadog::Core::Telemetry::Component, nil] component evaluation timeouts are counted through
|
|
20
23
|
# @return [void]
|
|
21
|
-
def initialize(settings, serializer, logger, capture_expression_evaluator
|
|
24
|
+
def initialize(settings, serializer, logger, capture_expression_evaluator:, guardrails_telemetry:,
|
|
25
|
+
telemetry:)
|
|
22
26
|
@settings = settings
|
|
23
27
|
@serializer = serializer
|
|
24
28
|
@logger = logger
|
|
25
29
|
@capture_expression_evaluator = capture_expression_evaluator
|
|
30
|
+
@guardrails_telemetry = guardrails_telemetry
|
|
31
|
+
@telemetry = telemetry
|
|
26
32
|
end
|
|
27
33
|
|
|
28
34
|
attr_reader :settings
|
|
@@ -33,35 +39,43 @@ module Datadog
|
|
|
33
39
|
|
|
34
40
|
attr_reader :capture_expression_evaluator
|
|
35
41
|
|
|
42
|
+
# The guardrails metric emitter.
|
|
43
|
+
# @return [GuardrailsTelemetry]
|
|
44
|
+
attr_reader :guardrails_telemetry
|
|
45
|
+
|
|
46
|
+
# The telemetry component evaluation timeouts are counted through.
|
|
47
|
+
# @return [Datadog::Core::Telemetry::Component, nil]
|
|
48
|
+
attr_reader :telemetry
|
|
49
|
+
|
|
36
50
|
def build_received(probe)
|
|
37
51
|
build_status(probe,
|
|
38
52
|
message: "Probe #{probe.id} has been received correctly",
|
|
39
|
-
status: "RECEIVED"
|
|
53
|
+
status: "RECEIVED")
|
|
40
54
|
end
|
|
41
55
|
|
|
42
56
|
def build_installed(probe)
|
|
43
57
|
build_status(probe,
|
|
44
58
|
message: "Probe #{probe.id} has been instrumented correctly",
|
|
45
|
-
status: "INSTALLED"
|
|
59
|
+
status: "INSTALLED")
|
|
46
60
|
end
|
|
47
61
|
|
|
48
62
|
def build_emitting(probe)
|
|
49
63
|
build_status(probe,
|
|
50
64
|
message: "Probe #{probe.id} is emitting",
|
|
51
|
-
status: "EMITTING"
|
|
65
|
+
status: "EMITTING")
|
|
52
66
|
end
|
|
53
67
|
|
|
54
68
|
def build_errored(probe, exc)
|
|
55
69
|
build_status(probe,
|
|
56
70
|
message: "Instrumentation for probe #{probe.id} failed: #{exc}",
|
|
57
71
|
status: "ERROR",
|
|
58
|
-
exception: exc
|
|
72
|
+
exception: exc)
|
|
59
73
|
end
|
|
60
74
|
|
|
61
75
|
def build_disabled(probe, duration)
|
|
62
76
|
build_status(probe,
|
|
63
77
|
message: "Probe #{probe.id} was disabled because it consumed #{duration} seconds of CPU time in DI processing",
|
|
64
|
-
status: "ERROR"
|
|
78
|
+
status: "ERROR")
|
|
65
79
|
end
|
|
66
80
|
|
|
67
81
|
# Duration is in seconds.
|
|
@@ -144,12 +158,13 @@ module Datadog
|
|
|
144
158
|
message = nil
|
|
145
159
|
evaluation_errors = []
|
|
146
160
|
if segments = probe.template_segments
|
|
147
|
-
message, evaluation_errors = evaluate_template(segments, context
|
|
161
|
+
message, evaluation_errors = evaluate_template(segments, context,
|
|
162
|
+
evaluation_deadline: serializer.evaluation_deadline)
|
|
148
163
|
end
|
|
149
164
|
evaluation_errors.concat(capture_expression_evaluation_errors)
|
|
150
165
|
build_snapshot_base(context,
|
|
151
166
|
evaluation_errors: evaluation_errors, message: message,
|
|
152
|
-
captures: captures
|
|
167
|
+
captures: captures)
|
|
153
168
|
end
|
|
154
169
|
|
|
155
170
|
def build_condition_evaluation_failed(context, expression, exception)
|
|
@@ -401,23 +416,56 @@ module Datadog
|
|
|
401
416
|
end
|
|
402
417
|
end
|
|
403
418
|
|
|
404
|
-
|
|
419
|
+
# Renders the probe's message template against +context+.
|
|
420
|
+
#
|
|
421
|
+
# @param template_segments [Array<String, EL::Expression>] compiled
|
|
422
|
+
# template segments to render.
|
|
423
|
+
# @param context [Context] evaluation context for expression segments.
|
|
424
|
+
# @param evaluation_deadline [Float] cooperative evaluation deadline, as
|
|
425
|
+
# CLOCK_THREAD_CPUTIME_ID float seconds.
|
|
426
|
+
# @return [Array(String, Array<EvaluationFailure>)] the rendered message
|
|
427
|
+
# and the evaluation errors.
|
|
428
|
+
def evaluate_template(template_segments, context, evaluation_deadline:)
|
|
405
429
|
evaluation_errors = []
|
|
430
|
+
timed_out = false
|
|
406
431
|
message = template_segments.map do |segment|
|
|
432
|
+
if segment.is_a?(EL::Expression) && !timed_out &&
|
|
433
|
+
EL::Evaluator.evaluation_deadline_exceeded?(evaluation_deadline)
|
|
434
|
+
raise DI::Error::EvaluationTimeout
|
|
435
|
+
end
|
|
407
436
|
case segment
|
|
408
437
|
when String
|
|
409
438
|
segment
|
|
410
439
|
when EL::Expression
|
|
411
|
-
|
|
440
|
+
if timed_out
|
|
441
|
+
# The shared deadline already crossed and reported its
|
|
442
|
+
# timeout, so the remaining segments render as the
|
|
443
|
+
# placeholder rather than raising and re-reporting per
|
|
444
|
+
# segment.
|
|
445
|
+
"[evaluation error]"
|
|
446
|
+
else
|
|
447
|
+
serializer.serialize_value_for_message(segment.evaluate(context, evaluation_deadline: evaluation_deadline), name: segment.redaction_identifier)
|
|
448
|
+
end
|
|
412
449
|
else
|
|
413
450
|
raise ArgumentError, "Invalid template segment type: #{segment}"
|
|
414
451
|
end
|
|
415
452
|
rescue Exception => exc # standard:disable Lint/RescueException
|
|
416
453
|
Datadog::DI.reraise_if_fatal(exc)
|
|
454
|
+
DI.report_evaluation_timeout(
|
|
455
|
+
telemetry: telemetry, guardrails_telemetry: guardrails_telemetry, logger: logger,
|
|
456
|
+
probe: context.probe, kind: "template", exc: exc,
|
|
457
|
+
)
|
|
417
458
|
evaluation_errors << EvaluationFailure.new(
|
|
418
459
|
expr: segment.dsl_expr, # steep:ignore NoMethod
|
|
419
460
|
message: "#{exc.class}: #{exc.message}",
|
|
420
461
|
)
|
|
462
|
+
# The matches wall-time bound also raises EvaluationTimeout
|
|
463
|
+
# without crossing the shared deadline, and it stops only one
|
|
464
|
+
# segment, so it must not suppress the remaining ones.
|
|
465
|
+
if exc.is_a?(DI::Error::EvaluationTimeout) &&
|
|
466
|
+
EL::Evaluator.evaluation_deadline_exceeded?(evaluation_deadline)
|
|
467
|
+
timed_out = true
|
|
468
|
+
end
|
|
421
469
|
"[evaluation error]"
|
|
422
470
|
end.join
|
|
423
471
|
[message, evaluation_errors]
|
|
@@ -220,7 +220,7 @@ module Datadog
|
|
|
220
220
|
# @return [DI::Transport::Input::Transport]
|
|
221
221
|
def snapshot_transport
|
|
222
222
|
@snapshot_transport ||= DI::Transport::HTTP.input(agent_settings: agent_settings, logger: logger,
|
|
223
|
-
telemetry: telemetry, guardrails_telemetry: guardrails_telemetry
|
|
223
|
+
telemetry: telemetry, guardrails_telemetry: guardrails_telemetry)
|
|
224
224
|
end
|
|
225
225
|
|
|
226
226
|
# Sends a batch of snapshot payloads to the agent.
|
data/lib/datadog/di/remote.rb
CHANGED
|
@@ -98,6 +98,9 @@ module Datadog
|
|
|
98
98
|
# and DI.activate_tracking is defined.
|
|
99
99
|
DI.activate_tracking
|
|
100
100
|
was_started = component.started?
|
|
101
|
+
if repository && !was_started
|
|
102
|
+
remove_withdrawn_probes(repository, component)
|
|
103
|
+
end
|
|
101
104
|
component.start!
|
|
102
105
|
# A probe delivered in an earlier poll while the component was stopped
|
|
103
106
|
# was dropped by #receivers (which ignores changes while !started?) and
|
|
@@ -145,7 +148,9 @@ module Datadog
|
|
|
145
148
|
# DEV: Apply this refactor to AppSec as well if implemented.
|
|
146
149
|
|
|
147
150
|
component = DI.component
|
|
148
|
-
if
|
|
151
|
+
if changes.empty?
|
|
152
|
+
remove_withdrawn_probes(repository, component) if component
|
|
153
|
+
elsif component&.started?
|
|
149
154
|
changes.each do |change|
|
|
150
155
|
case change.type
|
|
151
156
|
when :insert
|
|
@@ -176,7 +181,7 @@ module Datadog
|
|
|
176
181
|
|
|
177
182
|
def receiver(products = [PRODUCT], &block)
|
|
178
183
|
matcher = Core::Remote::Dispatcher::Matcher::Product.new(products)
|
|
179
|
-
[Core::Remote::Dispatcher::Receiver.new(matcher, &block)]
|
|
184
|
+
[Core::Remote::Dispatcher::Receiver.new(matcher, initial_reconcile: true, &block)]
|
|
180
185
|
end
|
|
181
186
|
|
|
182
187
|
private
|
|
@@ -266,6 +271,45 @@ module Datadog
|
|
|
266
271
|
end
|
|
267
272
|
end
|
|
268
273
|
|
|
274
|
+
# Removes every probe the component tracks whose id is absent from all
|
|
275
|
+
# LIVE_DEBUGGING contents in the repository. Reconciles backend deletions that
|
|
276
|
+
# produced no delete change for {.receivers}. Skips removal while a
|
|
277
|
+
# LIVE_DEBUGGING content fails to parse, because that content can hold any
|
|
278
|
+
# tracked probe.
|
|
279
|
+
def remove_withdrawn_probes(repository, component)
|
|
280
|
+
# @type var present_probe_ids: Array[String]
|
|
281
|
+
present_probe_ids = []
|
|
282
|
+
content_failed_to_parse = false
|
|
283
|
+
repository.contents.each do |content|
|
|
284
|
+
next unless content.path.product == PRODUCT
|
|
285
|
+
|
|
286
|
+
begin
|
|
287
|
+
present_probe_ids << parse_content(content)["id"]
|
|
288
|
+
rescue => exc
|
|
289
|
+
component.logger.debug do
|
|
290
|
+
"di: skipping withdrawn-probe reconcile, a LIVE_DEBUGGING content failed to parse: " \
|
|
291
|
+
"#{exc.class}: #{exc.message}"
|
|
292
|
+
end
|
|
293
|
+
content_failed_to_parse = true
|
|
294
|
+
break
|
|
295
|
+
end
|
|
296
|
+
end
|
|
297
|
+
return if content_failed_to_parse
|
|
298
|
+
|
|
299
|
+
probe_repository = component.probe_manager.probe_repository
|
|
300
|
+
tracked_probe_ids = probe_repository.installed_probes.keys | probe_repository.pending_probes.keys
|
|
301
|
+
(tracked_probe_ids - present_probe_ids).each do |probe_id|
|
|
302
|
+
component.logger.trace { "di: removing probe #{probe_id} withdrawn from remote configuration" }
|
|
303
|
+
component.probe_manager.remove_probe(probe_id)
|
|
304
|
+
rescue Exception => exc # standard:disable Lint/RescueException
|
|
305
|
+
Datadog::DI.reraise_if_fatal(exc)
|
|
306
|
+
raise if component.settings.dynamic_instrumentation.internal.propagate_all_exceptions
|
|
307
|
+
|
|
308
|
+
component.logger.debug { "di: error removing withdrawn probe #{probe_id}: #{exc.class}: #{exc.message}" }
|
|
309
|
+
component.telemetry&.report(exc, description: "Error removing withdrawn probe")
|
|
310
|
+
end
|
|
311
|
+
end
|
|
312
|
+
|
|
269
313
|
def probe_known?(probe_id, component)
|
|
270
314
|
repo = component.probe_manager.probe_repository
|
|
271
315
|
!!(repo.find_installed(probe_id) ||
|
|
@@ -96,8 +96,25 @@ module Datadog
|
|
|
96
96
|
# hex string, or UTF-8 with replacement characters) before returning
|
|
97
97
|
# it from the custom serializer.
|
|
98
98
|
@@flat_registry = []
|
|
99
|
-
|
|
99
|
+
# Registers a custom serializer. The block serializes each value
|
|
100
|
+
# for which +condition+ returns a truthy value.
|
|
101
|
+
#
|
|
102
|
+
# @param condition [Proc] receives the value being serialized and
|
|
103
|
+
# returns whether this serializer applies to it
|
|
104
|
+
# @param block [Proc] serializer for the values +condition+ accepts
|
|
105
|
+
# @raise [ArgumentError] if +condition+ is not a Proc or +block+ is absent
|
|
106
|
+
# @return [void]
|
|
107
|
+
def self.register(condition:, &block)
|
|
108
|
+
unless condition.is_a?(Proc)
|
|
109
|
+
raise ArgumentError, "Serializer.register condition must be a Proc, got #{condition.class}"
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
unless block
|
|
113
|
+
raise ArgumentError, "Serializer.register requires a serializer block"
|
|
114
|
+
end
|
|
115
|
+
|
|
100
116
|
@@flat_registry << {condition: condition, proc: block}
|
|
117
|
+
nil
|
|
101
118
|
end
|
|
102
119
|
|
|
103
120
|
# Initializes the serializer.
|
|
@@ -114,6 +131,10 @@ module Datadog
|
|
|
114
131
|
@logger = logger
|
|
115
132
|
@guardrails_telemetry = guardrails_telemetry
|
|
116
133
|
@telemetry = telemetry
|
|
134
|
+
# Evaluation budget for one expression evaluation, as thread CPU
|
|
135
|
+
# seconds, converted from max_time_to_evaluate_ms here so that
|
|
136
|
+
# deadline resolution per probe firing traverses no settings.
|
|
137
|
+
@evaluation_budget_seconds = settings.dynamic_instrumentation.max_time_to_evaluate_ms / 1000.0
|
|
117
138
|
end
|
|
118
139
|
|
|
119
140
|
attr_reader :settings
|
|
@@ -159,7 +180,7 @@ module Datadog
|
|
|
159
180
|
# @param args [Array] positional arguments passed to the probed method
|
|
160
181
|
# @param kwargs [Hash{Symbol => Object}] keyword arguments passed to the probed method
|
|
161
182
|
# @param target_self [any] receiver of the probed method invocation
|
|
162
|
-
# @param deadline [Float] absolute capture deadline in
|
|
183
|
+
# @param deadline [Float] absolute capture deadline in thread CPU clock seconds
|
|
163
184
|
# @return [Hash{Symbol => Hash}] serialized arguments keyed by argument name
|
|
164
185
|
def serialize_args(args, kwargs, target_self,
|
|
165
186
|
deadline:,
|
|
@@ -169,7 +190,7 @@ module Datadog
|
|
|
169
190
|
collection_size: nil)
|
|
170
191
|
combined = combine_args(args, kwargs, target_self)
|
|
171
192
|
serialize_vars(combined, depth: depth, attribute_count: attribute_count,
|
|
172
|
-
length: length, collection_size: collection_size, deadline: deadline
|
|
193
|
+
length: length, collection_size: collection_size, deadline: deadline)
|
|
173
194
|
end
|
|
174
195
|
|
|
175
196
|
# Serializes variables captured by a line probe.
|
|
@@ -178,7 +199,7 @@ module Datadog
|
|
|
178
199
|
# of executed code.
|
|
179
200
|
#
|
|
180
201
|
# @param vars [Hash{Symbol => Object}] variables to serialize, keyed by variable name
|
|
181
|
-
# @param deadline [Float] absolute capture deadline in
|
|
202
|
+
# @param deadline [Float] absolute capture deadline in thread CPU clock seconds
|
|
182
203
|
# @return [Hash{Symbol => Hash}] serialized variables keyed by variable name
|
|
183
204
|
def serialize_vars(vars,
|
|
184
205
|
deadline:,
|
|
@@ -188,7 +209,7 @@ module Datadog
|
|
|
188
209
|
collection_size: nil)
|
|
189
210
|
vars.each_with_object({}) do |(k, v), agg|
|
|
190
211
|
agg[k] = serialize_value(v, name: k, depth: depth, attribute_count: attribute_count,
|
|
191
|
-
length: length, collection_size: collection_size, deadline: deadline
|
|
212
|
+
length: length, collection_size: collection_size, deadline: deadline)
|
|
192
213
|
end
|
|
193
214
|
end
|
|
194
215
|
|
|
@@ -207,7 +228,7 @@ module Datadog
|
|
|
207
228
|
#
|
|
208
229
|
# @param value [any] value to serialize
|
|
209
230
|
# @param name [Symbol, String, nil] name the value is bound to, used for redaction
|
|
210
|
-
# @param deadline [Float] absolute capture deadline in
|
|
231
|
+
# @param deadline [Float] absolute capture deadline in thread CPU clock seconds
|
|
211
232
|
# @return [Hash{Symbol => Object}] serialized value; the {type:, notCapturedReason: "timeout"} stub when the deadline is exceeded
|
|
212
233
|
def serialize_value(value, deadline:,
|
|
213
234
|
name: nil,
|
|
@@ -541,21 +562,34 @@ module Datadog
|
|
|
541
562
|
"#<#{class_name(value.class)}: serialization error>"
|
|
542
563
|
end
|
|
543
564
|
|
|
544
|
-
# Computes the absolute
|
|
545
|
-
# point from max_time_to_serialize_ms.
|
|
546
|
-
# share across all values serialized on the built-in paths so the
|
|
547
|
-
# budget is not exceeded.
|
|
565
|
+
# Computes the absolute thread CPU time deadline (in seconds) for a
|
|
566
|
+
# capture point from max_time_to_serialize_ms.
|
|
548
567
|
#
|
|
549
|
-
# @return [Float] absolute
|
|
568
|
+
# @return [Float] absolute thread CPU clock reading, in seconds, at
|
|
550
569
|
# which the capture budget is exhausted
|
|
551
570
|
def serialization_deadline
|
|
552
|
-
|
|
571
|
+
Process.clock_gettime(Process::CLOCK_THREAD_CPUTIME_ID, :float_second) +
|
|
572
|
+
settings.dynamic_instrumentation.max_time_to_serialize_ms / 1000.0
|
|
573
|
+
end
|
|
574
|
+
|
|
575
|
+
# Computes the absolute thread CPU time deadline (in seconds) for an
|
|
576
|
+
# expression evaluation by adding the evaluation budget, converted
|
|
577
|
+
# from max_time_to_evaluate_ms once at construction, to the current
|
|
578
|
+
# thread CPU clock reading.
|
|
579
|
+
#
|
|
580
|
+
# @return [Float] absolute thread CPU clock reading, in seconds, at
|
|
581
|
+
# which the evaluation budget is exhausted
|
|
582
|
+
def evaluation_deadline
|
|
583
|
+
Process.clock_gettime(Process::CLOCK_THREAD_CPUTIME_ID, :float_second) +
|
|
584
|
+
evaluation_budget_seconds
|
|
553
585
|
end
|
|
554
586
|
|
|
555
587
|
private
|
|
556
588
|
|
|
589
|
+
attr_reader :evaluation_budget_seconds
|
|
590
|
+
|
|
557
591
|
def deadline_exceeded?(deadline)
|
|
558
|
-
|
|
592
|
+
Process.clock_gettime(Process::CLOCK_THREAD_CPUTIME_ID, :float_second) >= deadline
|
|
559
593
|
end
|
|
560
594
|
|
|
561
595
|
MAX_MESSAGE_COLLECTION_SIZE = 3
|
data/lib/datadog/di.rb
CHANGED
|
@@ -173,6 +173,33 @@ module Datadog
|
|
|
173
173
|
Datadog.send(:components).dynamic_instrumentation
|
|
174
174
|
end
|
|
175
175
|
|
|
176
|
+
# Reports an evaluation timeout: increments the evaluation_timeouts
|
|
177
|
+
# telemetry counter, emits the canonical guardrail skip metric for the
|
|
178
|
+
# timeout, and logs at debug with the probe id, the evaluation kind and
|
|
179
|
+
# the exception. Returns whether +exc+ was an evaluation timeout, so
|
|
180
|
+
# callers can run timeout-specific follow-up.
|
|
181
|
+
#
|
|
182
|
+
# @param telemetry [Datadog::Core::Telemetry::Component, nil] component
|
|
183
|
+
# the counter increments through.
|
|
184
|
+
# @param guardrails_telemetry [GuardrailsTelemetry] emitter for the
|
|
185
|
+
# canonical evaluation-timeout skip metric.
|
|
186
|
+
# @param logger [DI::Logger] logger the timeout log writes through.
|
|
187
|
+
# @param probe [Probe] the probe whose evaluation timed out.
|
|
188
|
+
# @param kind [String] the evaluation kind, e.g. "condition",
|
|
189
|
+
# "capture expression" or "template".
|
|
190
|
+
# @param exc [Exception] the exception raised by the evaluation.
|
|
191
|
+
# @return [Boolean] whether the exception was an evaluation timeout.
|
|
192
|
+
def report_evaluation_timeout(telemetry:, guardrails_telemetry:, logger:, probe:, kind:, exc:)
|
|
193
|
+
return false unless exc.is_a?(DI::Error::EvaluationTimeout)
|
|
194
|
+
telemetry&.inc(TELEMETRY_NAMESPACE, "evaluation_timeouts", 1)
|
|
195
|
+
guardrails_telemetry.skipped(
|
|
196
|
+
reason: GuardrailsTelemetry::Reason::EVALUATION_TIMEOUT,
|
|
197
|
+
probe: probe,
|
|
198
|
+
)
|
|
199
|
+
logger.debug { "di: probe #{probe.id}: #{kind} evaluation timed out: #{exc.class}: #{exc.message}" }
|
|
200
|
+
true
|
|
201
|
+
end
|
|
202
|
+
|
|
176
203
|
# Track how many outstanding instrumentations are in DI.
|
|
177
204
|
#
|
|
178
205
|
# It is hard to find the actual instrumentations - there is no
|