datadog 2.47.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 +30 -1
- data/LICENSE-3rdparty.csv +1 -0
- data/ext/datadog_profiling_native_extension/collectors_stack.c +141 -101
- 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 +66 -13
- data/ext/datadog_profiling_native_extension/private_vm_api_access.h +5 -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 +1 -1
- 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 +2 -2
- data/lib/datadog/appsec/contrib/rails/patcher.rb +2 -2
- data/lib/datadog/appsec/contrib/rest_client/request_ssrf_detection_patch.rb +1 -1
- data/lib/datadog/appsec/contrib/sinatra/gateway/watcher.rb +3 -3
- data/lib/datadog/appsec/contrib/sinatra/patcher.rb +1 -1
- 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 +6 -6
- 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 +1 -1
- data/lib/datadog/core/configuration/settings.rb +5 -2
- data/lib/datadog/core/configuration/supported_configurations.rb +1 -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/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 +1 -1
- 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 +3 -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/serializer.rb +20 -2
- 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 +4 -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/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 +50 -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/thread_context.rb +1 -1
- data/lib/datadog/profiling/component.rb +19 -19
- data/lib/datadog/profiling/exporter.rb +1 -1
- 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 +8 -8
- data/lib/datadog/tracing/configuration/dynamic/option.rb +2 -2
- data/lib/datadog/tracing/configuration/settings.rb +3 -3
- data/lib/datadog/tracing/context.rb +1 -1
- 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 +8 -8
- 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 +7 -7
- data/lib/datadog/tracing/contrib/faraday/configuration/settings.rb +1 -1
- data/lib/datadog/tracing/contrib/faraday/middleware.rb +5 -5
- 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 +6 -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 +7 -7
- data/lib/datadog/tracing/contrib/httprb/configuration/settings.rb +1 -1
- data/lib/datadog/tracing/contrib/httprb/instrumentation.rb +5 -5
- 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 +8 -8
- 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/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/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 +4 -3
|
@@ -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.
|
|
@@ -131,6 +131,10 @@ module Datadog
|
|
|
131
131
|
@logger = logger
|
|
132
132
|
@guardrails_telemetry = guardrails_telemetry
|
|
133
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
|
|
134
138
|
end
|
|
135
139
|
|
|
136
140
|
attr_reader :settings
|
|
@@ -186,7 +190,7 @@ module Datadog
|
|
|
186
190
|
collection_size: nil)
|
|
187
191
|
combined = combine_args(args, kwargs, target_self)
|
|
188
192
|
serialize_vars(combined, depth: depth, attribute_count: attribute_count,
|
|
189
|
-
length: length, collection_size: collection_size, deadline: deadline
|
|
193
|
+
length: length, collection_size: collection_size, deadline: deadline)
|
|
190
194
|
end
|
|
191
195
|
|
|
192
196
|
# Serializes variables captured by a line probe.
|
|
@@ -205,7 +209,7 @@ module Datadog
|
|
|
205
209
|
collection_size: nil)
|
|
206
210
|
vars.each_with_object({}) do |(k, v), agg|
|
|
207
211
|
agg[k] = serialize_value(v, name: k, depth: depth, attribute_count: attribute_count,
|
|
208
|
-
length: length, collection_size: collection_size, deadline: deadline
|
|
212
|
+
length: length, collection_size: collection_size, deadline: deadline)
|
|
209
213
|
end
|
|
210
214
|
end
|
|
211
215
|
|
|
@@ -568,8 +572,22 @@ module Datadog
|
|
|
568
572
|
settings.dynamic_instrumentation.max_time_to_serialize_ms / 1000.0
|
|
569
573
|
end
|
|
570
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
|
|
585
|
+
end
|
|
586
|
+
|
|
571
587
|
private
|
|
572
588
|
|
|
589
|
+
attr_reader :evaluation_budget_seconds
|
|
590
|
+
|
|
573
591
|
def deadline_exceeded?(deadline)
|
|
574
592
|
Process.clock_gettime(Process::CLOCK_THREAD_CPUTIME_ID, :float_second) >= deadline
|
|
575
593
|
end
|
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
|
|
@@ -50,7 +50,7 @@ module Datadog
|
|
|
50
50
|
|
|
51
51
|
if trace.nil? || span.nil?
|
|
52
52
|
return Datadog.logger.warn(
|
|
53
|
-
"Kit::AppSec: Tracing is not enabled. Please enable tracing if you want to track events"
|
|
53
|
+
"Kit::AppSec: Tracing is not enabled. Please enable tracing if you want to track events",
|
|
54
54
|
)
|
|
55
55
|
end
|
|
56
56
|
|
|
@@ -69,7 +69,7 @@ module Datadog
|
|
|
69
69
|
record_event_telemetry_metric(LOGIN_SUCCESS_EVENT)
|
|
70
70
|
::Datadog::AppSec::Instrumentation.gateway.push("appsec.events.user_lifecycle", LOGIN_SUCCESS_EVENT)
|
|
71
71
|
|
|
72
|
-
return Kit::Identity.set_user(trace, span, **user_attributes) if user_attributes.key?(:id)
|
|
72
|
+
return Kit::Identity.set_user(trace, span, **user_attributes) if user_attributes.key?(:id) # steep:ignore InsufficientKeywordArguments
|
|
73
73
|
|
|
74
74
|
# NOTE: This is a fallback for the case when we don't have an ID,
|
|
75
75
|
# but need to trigger WAF.
|
|
@@ -102,7 +102,7 @@ module Datadog
|
|
|
102
102
|
|
|
103
103
|
if trace.nil? || span.nil?
|
|
104
104
|
return Datadog.logger.warn(
|
|
105
|
-
"Kit::AppSec: Tracing is not enabled. Please enable tracing if you want to track events"
|
|
105
|
+
"Kit::AppSec: Tracing is not enabled. Please enable tracing if you want to track events",
|
|
106
106
|
)
|
|
107
107
|
end
|
|
108
108
|
|
|
@@ -155,7 +155,7 @@ module Datadog
|
|
|
155
155
|
|
|
156
156
|
if trace.nil? || span.nil?
|
|
157
157
|
return Datadog.logger.warn(
|
|
158
|
-
"Kit::AppSec: Tracing is not enabled. Please enable tracing if you want to track events"
|
|
158
|
+
"Kit::AppSec: Tracing is not enabled. Please enable tracing if you want to track events",
|
|
159
159
|
)
|
|
160
160
|
end
|
|
161
161
|
|
|
@@ -174,7 +174,7 @@ module Datadog
|
|
|
174
174
|
record_event_telemetry_metric(SIGNUP_EVENT)
|
|
175
175
|
|
|
176
176
|
if user_attributes.key?(:id)
|
|
177
|
-
Kit::Identity.set_user(trace, span, **user_attributes)
|
|
177
|
+
Kit::Identity.set_user(trace, span, **user_attributes) # steep:ignore InsufficientKeywordArguments
|
|
178
178
|
else
|
|
179
179
|
# NOTE: {Datadog::Kit::Identity.set_user} requires an ID,
|
|
180
180
|
# but WAF can evaluate login alone
|
|
@@ -235,7 +235,7 @@ module Datadog
|
|
|
235
235
|
|
|
236
236
|
if telemetry.nil?
|
|
237
237
|
return Datadog.logger.debug(
|
|
238
|
-
"Kit::AppSec: Telemetry component is unavailable. Skip recording SDK metrics"
|
|
238
|
+
"Kit::AppSec: Telemetry component is unavailable. Skip recording SDK metrics",
|
|
239
239
|
)
|
|
240
240
|
end
|
|
241
241
|
|
data/lib/datadog/kit/identity.rb
CHANGED
|
@@ -100,6 +100,7 @@ module Datadog
|
|
|
100
100
|
return unless @providers.empty?
|
|
101
101
|
if @delivery_source == Configuration::Source::REMOTE_CONFIG && @delivery_started
|
|
102
102
|
# Remote Configuration is process-scoped and may already hold configuration needed by the next provider.
|
|
103
|
+
@logger.debug { "Feature Flags: provider detached; process-scoped Remote Configuration remains active" }
|
|
103
104
|
[nil, nil]
|
|
104
105
|
else
|
|
105
106
|
previous_source = @configuration_source
|
|
@@ -149,9 +150,14 @@ module Datadog
|
|
|
149
150
|
@activated = true
|
|
150
151
|
unless resolution.enabled?
|
|
151
152
|
@failure = "Feature Flags are disabled"
|
|
153
|
+
@logger.debug do
|
|
154
|
+
reason = @settings.feature_flags.enabled ? "the resolved configuration source is offline" : "feature_flags.enabled is false"
|
|
155
|
+
"Feature Flags: disabled because #{reason}"
|
|
156
|
+
end
|
|
152
157
|
return
|
|
153
158
|
end
|
|
154
159
|
|
|
160
|
+
@logger.debug { "Feature Flags: configuration source is #{resolution.source}" }
|
|
155
161
|
component = Component.build(
|
|
156
162
|
@settings,
|
|
157
163
|
@agent_settings,
|
|
@@ -230,6 +236,20 @@ module Datadog
|
|
|
230
236
|
end
|
|
231
237
|
|
|
232
238
|
@configuration_source = configuration_source
|
|
239
|
+
|
|
240
|
+
@logger.debug do
|
|
241
|
+
agentless = @settings.feature_flags.agentless
|
|
242
|
+
sdk_env = @settings.env ? "sdk_env=#{@settings.env.inspect}" : "sdk_env is unset"
|
|
243
|
+
requested_env = if endpoint.managed?
|
|
244
|
+
@settings.env ? "requested_env=#{@settings.env.inspect}" : "requested_env is unset"
|
|
245
|
+
else
|
|
246
|
+
"requested_env is not sent (custom endpoint)"
|
|
247
|
+
end
|
|
248
|
+
"Feature Flags: starting agentless configuration source at #{endpoint.origin} " \
|
|
249
|
+
"(#{sdk_env}, #{requested_env}, " \
|
|
250
|
+
"poll interval #{agentless.poll_interval_seconds}s, request timeout #{agentless.request_timeout_seconds}s)"
|
|
251
|
+
end
|
|
252
|
+
|
|
233
253
|
started = configuration_source.start
|
|
234
254
|
@failure = "Feature Flags agentless delivery could not start" unless started
|
|
235
255
|
started
|
|
@@ -241,7 +261,7 @@ module Datadog
|
|
|
241
261
|
@failure = "Feature Flags Remote Configuration is unavailable"
|
|
242
262
|
@logger.warn(
|
|
243
263
|
"#{@failure}. To enable Remote Configuration, " \
|
|
244
|
-
"see https://docs.datadoghq.com/remote_configuration/."
|
|
264
|
+
"see https://docs.datadoghq.com/remote_configuration/.",
|
|
245
265
|
)
|
|
246
266
|
return false
|
|
247
267
|
end
|
|
@@ -249,6 +269,7 @@ module Datadog
|
|
|
249
269
|
receivers = @remote_receivers ||= Remote.receivers(
|
|
250
270
|
@telemetry,
|
|
251
271
|
component_provider: -> { @mutex.synchronize { @component } },
|
|
272
|
+
logger: @logger,
|
|
252
273
|
)
|
|
253
274
|
remote.register(
|
|
254
275
|
capabilities: Remote.capabilities,
|
|
@@ -256,6 +277,10 @@ module Datadog
|
|
|
256
277
|
receivers: receivers,
|
|
257
278
|
)
|
|
258
279
|
remote.start
|
|
280
|
+
@logger.debug do
|
|
281
|
+
sdk_env = @settings.env ? "sdk_env=#{@settings.env.inspect}" : "sdk_env is unset"
|
|
282
|
+
"Feature Flags: started Remote Configuration source (#{sdk_env}) using Datadog Agent"
|
|
283
|
+
end
|
|
259
284
|
true
|
|
260
285
|
end
|
|
261
286
|
|
|
@@ -61,6 +61,7 @@ module Datadog
|
|
|
61
61
|
@retry_wait = retry_wait || ->(delay) { wait_for_retry(delay) }
|
|
62
62
|
@etag = nil
|
|
63
63
|
@warned = {}
|
|
64
|
+
@failed_polls = 0
|
|
64
65
|
@lifecycle_mutex = Mutex.new
|
|
65
66
|
@started = false
|
|
66
67
|
@stopped = false
|
|
@@ -91,6 +92,7 @@ module Datadog
|
|
|
91
92
|
end
|
|
92
93
|
|
|
93
94
|
super
|
|
95
|
+
@logger.debug { "Feature Flags: stopped agentless configuration polling" }
|
|
94
96
|
true
|
|
95
97
|
end
|
|
96
98
|
|
|
@@ -110,6 +112,7 @@ module Datadog
|
|
|
110
112
|
return if stopped?
|
|
111
113
|
|
|
112
114
|
response = @transport.get(@etag)
|
|
115
|
+
log_poll_attempt(response, attempt)
|
|
113
116
|
unless retryable?(response)
|
|
114
117
|
apply_response(response)
|
|
115
118
|
return
|
|
@@ -120,7 +123,9 @@ module Datadog
|
|
|
120
123
|
return
|
|
121
124
|
end
|
|
122
125
|
|
|
123
|
-
|
|
126
|
+
delay = retry_delay(attempt)
|
|
127
|
+
@logger.debug { "Feature Flags: retrying agentless configuration poll in #{delay.round(1)}s" }
|
|
128
|
+
return if wait_before_retry(delay)
|
|
124
129
|
|
|
125
130
|
attempt += 1
|
|
126
131
|
end
|
|
@@ -131,6 +136,7 @@ module Datadog
|
|
|
131
136
|
def after_fork
|
|
132
137
|
# The child must report its own failures, while the inherited ETag still matches its configuration.
|
|
133
138
|
@warned = {}
|
|
139
|
+
@failed_polls = 0
|
|
134
140
|
nil
|
|
135
141
|
end
|
|
136
142
|
|
|
@@ -140,6 +146,53 @@ module Datadog
|
|
|
140
146
|
@lifecycle_mutex.synchronize { @stopped }
|
|
141
147
|
end
|
|
142
148
|
|
|
149
|
+
def log_poll_attempt(response, attempt)
|
|
150
|
+
@logger.debug do
|
|
151
|
+
status = response.status
|
|
152
|
+
outcome = case status
|
|
153
|
+
when nil
|
|
154
|
+
"failed: #{request_error_class(response)}"
|
|
155
|
+
when 304
|
|
156
|
+
"configuration unchanged (HTTP 304)"
|
|
157
|
+
when 200
|
|
158
|
+
etag = response.etag.to_s.strip
|
|
159
|
+
etag.empty? ? "configuration received (HTTP 200)" : "configuration received (ETag #{etag}; HTTP 200)"
|
|
160
|
+
else
|
|
161
|
+
"#{http_failure_reason(status)} (HTTP #{status})"
|
|
162
|
+
end
|
|
163
|
+
"Feature Flags: agentless configuration poll attempt #{attempt}/#{MAX_ATTEMPTS}: #{outcome}"
|
|
164
|
+
end
|
|
165
|
+
end
|
|
166
|
+
|
|
167
|
+
def http_failure_reason(status)
|
|
168
|
+
case status
|
|
169
|
+
when 400
|
|
170
|
+
"configuration request rejected as invalid"
|
|
171
|
+
when 401
|
|
172
|
+
"configuration request lacks valid authentication credentials"
|
|
173
|
+
when 403
|
|
174
|
+
"access to the configuration endpoint is forbidden"
|
|
175
|
+
when 404
|
|
176
|
+
"configuration endpoint not found"
|
|
177
|
+
when 408
|
|
178
|
+
"configuration request timed out"
|
|
179
|
+
when 429
|
|
180
|
+
"configuration request rate limited"
|
|
181
|
+
when 500
|
|
182
|
+
"configuration endpoint encountered an internal error"
|
|
183
|
+
when 502
|
|
184
|
+
"configuration endpoint received an invalid upstream response"
|
|
185
|
+
when 503
|
|
186
|
+
"configuration endpoint is temporarily unavailable"
|
|
187
|
+
when 504
|
|
188
|
+
"configuration endpoint timed out waiting for an upstream response"
|
|
189
|
+
when 500..599
|
|
190
|
+
"configuration endpoint reported a server error"
|
|
191
|
+
else
|
|
192
|
+
"unexpected response from the configuration endpoint"
|
|
193
|
+
end
|
|
194
|
+
end
|
|
195
|
+
|
|
143
196
|
def retryable?(response)
|
|
144
197
|
status = response.status
|
|
145
198
|
return true unless status
|
|
@@ -181,17 +234,18 @@ module Datadog
|
|
|
181
234
|
end
|
|
182
235
|
|
|
183
236
|
def apply_response(response)
|
|
184
|
-
|
|
237
|
+
status = response.status
|
|
238
|
+
case status
|
|
185
239
|
when 200
|
|
240
|
+
log_recovery
|
|
186
241
|
apply_configuration(response)
|
|
187
242
|
when 304
|
|
188
|
-
|
|
243
|
+
log_recovery
|
|
189
244
|
when 401, 403
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
end
|
|
245
|
+
report_poll_failure(
|
|
246
|
+
:authentication,
|
|
247
|
+
"Feature Flags agentless #{http_failure_reason(status)}; verify endpoint authentication (HTTP #{status})",
|
|
248
|
+
)
|
|
195
249
|
else
|
|
196
250
|
warn_failure(response, 1)
|
|
197
251
|
end
|
|
@@ -203,6 +257,9 @@ module Datadog
|
|
|
203
257
|
warn_once(:malformed) do
|
|
204
258
|
@logger.error("Feature Flags agentless endpoint returned malformed UFC payload")
|
|
205
259
|
end
|
|
260
|
+
@logger.debug do
|
|
261
|
+
"Feature Flags: ignoring malformed agentless configuration payload"
|
|
262
|
+
end
|
|
206
263
|
return
|
|
207
264
|
end
|
|
208
265
|
|
|
@@ -224,16 +281,38 @@ module Datadog
|
|
|
224
281
|
else
|
|
225
282
|
:http_unexpected
|
|
226
283
|
end
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
284
|
+
refresh = (attempts == MAX_ATTEMPTS) ? "; next poll in #{@poll_interval_seconds}s" : ""
|
|
285
|
+
message = if status
|
|
286
|
+
"Feature Flags agentless #{http_failure_reason(status)} after #{attempts} attempt(s) (HTTP #{status})#{refresh}"
|
|
287
|
+
else
|
|
288
|
+
"Feature Flags agentless request failed after #{attempts} attempt(s): #{request_error_class(response)}#{refresh}"
|
|
289
|
+
end
|
|
290
|
+
report_poll_failure(category, message)
|
|
291
|
+
end
|
|
292
|
+
|
|
293
|
+
# Repeats are debug-only so a persistent outage does not flood warnings.
|
|
294
|
+
def report_poll_failure(category, message)
|
|
295
|
+
@failed_polls += 1
|
|
296
|
+
if @warned[category]
|
|
297
|
+
@logger.debug { message }
|
|
298
|
+
else
|
|
299
|
+
warn_once(category) { @logger.warn(message) }
|
|
234
300
|
end
|
|
235
301
|
end
|
|
236
302
|
|
|
303
|
+
def log_recovery
|
|
304
|
+
return if @failed_polls.zero?
|
|
305
|
+
|
|
306
|
+
failed_polls = @failed_polls
|
|
307
|
+
@failed_polls = 0
|
|
308
|
+
@logger.debug { "Feature Flags: agentless configuration delivery recovered after #{failed_polls} failed poll(s)" }
|
|
309
|
+
end
|
|
310
|
+
|
|
311
|
+
# Class only: transport error messages can embed endpoint details.
|
|
312
|
+
def request_error_class(response)
|
|
313
|
+
response.error ? response.error.class : StandardError
|
|
314
|
+
end
|
|
315
|
+
|
|
237
316
|
def warn_once(category)
|
|
238
317
|
return if @warned[category]
|
|
239
318
|
|
|
@@ -13,6 +13,7 @@ require_relative "flag_evaluation/writer"
|
|
|
13
13
|
require_relative "hooks/flag_eval_metrics_hook"
|
|
14
14
|
require_relative "hooks/flag_eval_evp_hook"
|
|
15
15
|
require_relative "hooks/span_enrichment_hook"
|
|
16
|
+
require_relative "hooks/debug_logging_hook"
|
|
16
17
|
|
|
17
18
|
module Datadog
|
|
18
19
|
module OpenFeature
|
|
@@ -70,12 +71,15 @@ module Datadog
|
|
|
70
71
|
@flag_eval_metrics_hook = create_flag_eval_metrics_hook
|
|
71
72
|
@flag_eval_evp_hook = create_flag_eval_evp_hook
|
|
72
73
|
@span_enrichment_hook = create_span_enrichment_hook
|
|
74
|
+
@debug_logging_hook = nil
|
|
73
75
|
|
|
74
76
|
@configuration_mutex = Mutex.new
|
|
75
77
|
@reconfiguration_mutex = Mutex.new
|
|
76
78
|
@configuration_condition = ConditionVariable.new
|
|
77
79
|
@configuration_received = false
|
|
78
80
|
@configuration_shutdown = false
|
|
81
|
+
|
|
82
|
+
@engine.warn_raw_data_logging
|
|
79
83
|
end
|
|
80
84
|
|
|
81
85
|
def reconfigure!(configuration)
|
|
@@ -102,9 +106,19 @@ module Datadog
|
|
|
102
106
|
@on_configuration_change&.call(event) if event
|
|
103
107
|
end
|
|
104
108
|
|
|
109
|
+
# Checked per evaluation so the SDK skips hook dispatch unless debug logging is on. Built lazily
|
|
110
|
+
# because Remote Configuration can build this component before the OpenFeature SDK loads.
|
|
111
|
+
def debug_logging_hook
|
|
112
|
+
return unless @logger.debug?
|
|
113
|
+
|
|
114
|
+
@engine.warn_raw_data_logging
|
|
115
|
+
@debug_logging_hook ||= create_debug_logging_hook
|
|
116
|
+
end
|
|
117
|
+
|
|
105
118
|
def wait_for_configuration(&cancelled)
|
|
106
|
-
|
|
107
|
-
|
|
119
|
+
timeout_ms = @settings.feature_flags.initialization_timeout_ms
|
|
120
|
+
@logger.debug { "Feature Flags: waiting up to #{timeout_ms}ms for configuration" }
|
|
121
|
+
deadline = Core::Utils::Time.get_time + timeout_ms / 1000.0
|
|
108
122
|
|
|
109
123
|
@configuration_mutex.synchronize do
|
|
110
124
|
loop do
|
|
@@ -176,6 +190,12 @@ module Datadog
|
|
|
176
190
|
store = Hooks::SpanEnrichmentHook::SpanEnrichmentStateStore.new
|
|
177
191
|
Hooks::SpanEnrichmentHook.new(store, logger: @logger)
|
|
178
192
|
end
|
|
193
|
+
|
|
194
|
+
def create_debug_logging_hook
|
|
195
|
+
return unless Hooks::DebugLoggingHook.available?
|
|
196
|
+
|
|
197
|
+
Hooks::DebugLoggingHook.new(@logger)
|
|
198
|
+
end
|
|
179
199
|
end
|
|
180
200
|
end
|
|
181
201
|
end
|
|
@@ -84,6 +84,12 @@ module Datadog
|
|
|
84
84
|
def managed?
|
|
85
85
|
@managed
|
|
86
86
|
end
|
|
87
|
+
|
|
88
|
+
# Excludes userinfo, path, and query, which may carry credentials.
|
|
89
|
+
def origin
|
|
90
|
+
origin = "#{uri.scheme}://#{uri.host}"
|
|
91
|
+
(uri.port == uri.default_port) ? origin : "#{origin}:#{uri.port}"
|
|
92
|
+
end
|
|
87
93
|
end
|
|
88
94
|
end
|
|
89
95
|
end
|