datadog 2.36.0 → 2.40.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 +119 -1
- data/bin/ddprofrb +4 -4
- data/ext/datadog_profiling_native_extension/clock_id_from_mach.c +5 -12
- data/ext/datadog_profiling_native_extension/collectors_cpu_and_wall_time_worker.c +105 -18
- data/ext/datadog_profiling_native_extension/collectors_idle_sampling_helper.c +17 -3
- data/ext/datadog_profiling_native_extension/collectors_stack.c +228 -162
- data/ext/datadog_profiling_native_extension/collectors_stack.h +16 -3
- data/ext/datadog_profiling_native_extension/collectors_thread_context.c +357 -217
- data/ext/datadog_profiling_native_extension/collectors_thread_context.h +3 -0
- 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 -0
- data/ext/datadog_profiling_native_extension/extconf.rb +24 -11
- data/ext/datadog_profiling_native_extension/private_vm_api_access.c +261 -62
- data/ext/datadog_profiling_native_extension/private_vm_api_access.h +17 -9
- data/ext/datadog_profiling_native_extension/ruby_helpers.c +7 -0
- data/ext/datadog_profiling_native_extension/setup_signal_handler.c +2 -0
- data/ext/datadog_profiling_native_extension/time_helpers.h +12 -7
- data/ext/libdatadog_api/datadog_ruby_common.c +19 -11
- data/ext/libdatadog_api/datadog_ruby_common.h +7 -0
- data/ext/libdatadog_api/di.c +76 -0
- data/ext/libdatadog_api/extconf.rb +29 -23
- data/ext/libdatadog_api/feature_flags.c +26 -0
- data/ext/libdatadog_api/init.c +4 -0
- data/ext/libdatadog_api/trace_exporter.c +974 -0
- data/ext/libdatadog_api/trace_exporter.h +5 -0
- data/ext/libdatadog_extconf_helpers.rb +9 -9
- data/lib/datadog/ai_guard/api_client.rb +8 -6
- data/lib/datadog/ai_guard/component.rb +10 -10
- data/lib/datadog/ai_guard/evaluation.rb +1 -0
- data/lib/datadog/ai_guard/ext.rb +2 -0
- data/lib/datadog/appsec/actions_handler/serializable_backtrace.rb +16 -16
- data/lib/datadog/appsec/actions_handler.rb +6 -6
- data/lib/datadog/appsec/anonymizer.rb +1 -1
- data/lib/datadog/appsec/api_security/endpoint_collection/grape_route_serializer.rb +1 -1
- data/lib/datadog/appsec/api_security/endpoint_collection/rails_collector.rb +6 -6
- data/lib/datadog/appsec/api_security/endpoint_collection/sinatra_route_serializer.rb +1 -1
- data/lib/datadog/appsec/api_security/route_extractor.rb +18 -15
- data/lib/datadog/appsec/api_security/sampler.rb +5 -5
- data/lib/datadog/appsec/api_security.rb +1 -1
- data/lib/datadog/appsec/assets.rb +7 -7
- data/lib/datadog/appsec/autoload.rb +3 -3
- data/lib/datadog/appsec/component.rb +15 -15
- data/lib/datadog/appsec/compressed_json.rb +6 -6
- data/lib/datadog/appsec/configuration.rb +73 -58
- data/lib/datadog/appsec/context.rb +9 -7
- data/lib/datadog/appsec/contrib/active_record/instrumentation.rb +6 -6
- data/lib/datadog/appsec/contrib/active_record/integration.rb +4 -4
- data/lib/datadog/appsec/contrib/active_record/patcher.rb +4 -4
- data/lib/datadog/appsec/contrib/aws_lambda/gateway/watcher.rb +7 -7
- data/lib/datadog/appsec/contrib/aws_lambda/integration.rb +2 -2
- data/lib/datadog/appsec/contrib/aws_lambda/patcher.rb +2 -2
- data/lib/datadog/appsec/contrib/aws_lambda/waf_addresses.rb +36 -34
- data/lib/datadog/appsec/contrib/devise/data_extractor.rb +3 -3
- data/lib/datadog/appsec/contrib/devise/ext.rb +20 -20
- data/lib/datadog/appsec/contrib/devise/integration.rb +4 -4
- data/lib/datadog/appsec/contrib/devise/patcher.rb +8 -8
- data/lib/datadog/appsec/contrib/devise/patches/signin_tracking_patch.rb +12 -12
- data/lib/datadog/appsec/contrib/devise/patches/signup_tracking_patch.rb +8 -8
- data/lib/datadog/appsec/contrib/devise/tracking_middleware.rb +24 -9
- data/lib/datadog/appsec/contrib/excon/integration.rb +4 -4
- data/lib/datadog/appsec/contrib/excon/patcher.rb +1 -1
- data/lib/datadog/appsec/contrib/excon/ssrf_detection_middleware.rb +76 -21
- data/lib/datadog/appsec/contrib/faraday/integration.rb +4 -4
- data/lib/datadog/appsec/contrib/faraday/patcher.rb +4 -4
- data/lib/datadog/appsec/contrib/faraday/ssrf_detection_middleware.rb +72 -18
- data/lib/datadog/appsec/contrib/graphql/appsec_trace.rb +4 -4
- data/lib/datadog/appsec/contrib/graphql/gateway/multiplex.rb +3 -3
- data/lib/datadog/appsec/contrib/graphql/gateway/watcher.rb +7 -7
- data/lib/datadog/appsec/contrib/graphql/integration.rb +9 -9
- data/lib/datadog/appsec/contrib/graphql/patcher.rb +3 -3
- data/lib/datadog/appsec/contrib/rack/buffered_input.rb +1 -1
- data/lib/datadog/appsec/contrib/rack/ext.rb +29 -29
- data/lib/datadog/appsec/contrib/rack/gateway/request.rb +18 -17
- data/lib/datadog/appsec/contrib/rack/gateway/response.rb +1 -1
- data/lib/datadog/appsec/contrib/rack/gateway/watcher.rb +25 -21
- data/lib/datadog/appsec/contrib/rack/input_peeker.rb +9 -22
- data/lib/datadog/appsec/contrib/rack/integration.rb +6 -6
- data/lib/datadog/appsec/contrib/rack/patcher.rb +3 -3
- data/lib/datadog/appsec/contrib/rack/request_body_middleware.rb +11 -8
- data/lib/datadog/appsec/contrib/rack/request_middleware.rb +45 -24
- data/lib/datadog/appsec/contrib/rack/response_body.rb +1 -1
- data/lib/datadog/appsec/contrib/rails/gateway/request.rb +14 -8
- data/lib/datadog/appsec/contrib/rails/gateway/watcher.rb +10 -10
- data/lib/datadog/appsec/contrib/rails/integration.rb +5 -5
- data/lib/datadog/appsec/contrib/rails/patcher.rb +17 -17
- data/lib/datadog/appsec/contrib/rails/patches/process_action_patch.rb +2 -2
- data/lib/datadog/appsec/contrib/rails/patches/render_to_body_patch.rb +3 -3
- data/lib/datadog/appsec/contrib/rails/request.rb +3 -3
- data/lib/datadog/appsec/contrib/rails/request_middleware.rb +2 -1
- data/lib/datadog/appsec/contrib/rest_client/integration.rb +5 -5
- data/lib/datadog/appsec/contrib/rest_client/patcher.rb +1 -1
- data/lib/datadog/appsec/contrib/rest_client/request_ssrf_detection_patch.rb +74 -21
- data/lib/datadog/appsec/contrib/sinatra/gateway/request.rb +1 -1
- data/lib/datadog/appsec/contrib/sinatra/gateway/route_params.rb +1 -1
- data/lib/datadog/appsec/contrib/sinatra/gateway/watcher.rb +16 -12
- data/lib/datadog/appsec/contrib/sinatra/integration.rb +5 -5
- data/lib/datadog/appsec/contrib/sinatra/patcher.rb +11 -11
- data/lib/datadog/appsec/contrib/sinatra/patches/json_patch.rb +3 -3
- data/lib/datadog/appsec/contrib/sinatra/request_middleware.rb +2 -1
- data/lib/datadog/appsec/counter_sampler.rb +1 -1
- data/lib/datadog/appsec/event.rb +14 -14
- data/lib/datadog/appsec/ext.rb +11 -10
- data/lib/datadog/appsec/extensions.rb +2 -2
- data/lib/datadog/appsec/instrumentation/gateway.rb +1 -1
- data/lib/datadog/appsec/metrics/collector.rb +18 -1
- data/lib/datadog/appsec/metrics/exporter.rb +17 -11
- data/lib/datadog/appsec/metrics/telemetry.rb +7 -7
- data/lib/datadog/appsec/metrics/telemetry_exporter.rb +4 -4
- data/lib/datadog/appsec/metrics.rb +4 -4
- data/lib/datadog/appsec/monitor/gateway/watcher.rb +16 -12
- data/lib/datadog/appsec/monitor.rb +1 -1
- data/lib/datadog/appsec/processor/rule_loader.rb +26 -26
- data/lib/datadog/appsec/rate_limiter.rb +1 -1
- data/lib/datadog/appsec/remote.rb +15 -9
- data/lib/datadog/appsec/response.rb +21 -21
- data/lib/datadog/appsec/route_normalizer/rails_route_pattern.rb +176 -0
- data/lib/datadog/appsec/route_normalizer/route_pattern.rb +378 -0
- data/lib/datadog/appsec/route_normalizer/route_text.rb +57 -0
- data/lib/datadog/appsec/route_normalizer.rb +80 -0
- data/lib/datadog/appsec/security_engine/engine.rb +37 -37
- data/lib/datadog/appsec/security_engine/runner.rb +2 -2
- data/lib/datadog/appsec/security_event.rb +2 -2
- data/lib/datadog/appsec/utils/http/body.rb +11 -8
- data/lib/datadog/appsec/utils/http/body_reader.rb +61 -0
- data/lib/datadog/appsec/utils/http/media_range.rb +15 -15
- data/lib/datadog/appsec/utils/http/media_type.rb +4 -4
- data/lib/datadog/appsec/utils/http/url_encoded.rb +80 -25
- data/lib/datadog/appsec.rb +16 -16
- data/lib/datadog/auto_instrument.rb +2 -2
- data/lib/datadog/core/buffer/cruby.rb +1 -1
- data/lib/datadog/core/buffer/thread_safe.rb +1 -1
- data/lib/datadog/core/configuration/agent_settings.rb +1 -1
- data/lib/datadog/core/configuration/agent_settings_resolver.rb +15 -15
- data/lib/datadog/core/configuration/agentless_settings_resolver.rb +2 -2
- data/lib/datadog/core/configuration/base.rb +2 -2
- data/lib/datadog/core/configuration/components.rb +115 -31
- data/lib/datadog/core/configuration/components_state.rb +6 -1
- data/lib/datadog/core/configuration/config_helper.rb +3 -3
- data/lib/datadog/core/configuration/deprecations.rb +6 -6
- data/lib/datadog/core/configuration/ext.rb +11 -11
- data/lib/datadog/core/configuration/option.rb +16 -16
- data/lib/datadog/core/configuration/option_definition.rb +4 -4
- data/lib/datadog/core/configuration/options.rb +1 -1
- data/lib/datadog/core/configuration/settings.rb +93 -104
- data/lib/datadog/core/configuration/stable_config.rb +1 -1
- data/lib/datadog/core/configuration/supported_configurations.rb +8 -1
- data/lib/datadog/core/configuration.rb +8 -8
- data/lib/datadog/core/contrib/rails/railtie.rb +3 -3
- data/lib/datadog/core/crashtracking/component.rb +9 -9
- data/lib/datadog/core/crashtracking/tag_builder.rb +5 -5
- data/lib/datadog/core/deprecations.rb +1 -1
- data/lib/datadog/core/diagnostics/environment_logger.rb +6 -6
- data/lib/datadog/core/diagnostics/health.rb +2 -2
- data/lib/datadog/core/encoding.rb +4 -4
- data/lib/datadog/core/environment/agent_info.rb +2 -2
- data/lib/datadog/core/environment/cgroup.rb +4 -4
- data/lib/datadog/core/environment/container.rb +9 -9
- data/lib/datadog/core/environment/execution.rb +3 -3
- data/lib/datadog/core/environment/ext.rb +18 -18
- data/lib/datadog/core/environment/gc.rb +1 -1
- data/lib/datadog/core/environment/git.rb +2 -2
- data/lib/datadog/core/environment/identity.rb +10 -10
- data/lib/datadog/core/environment/platform.rb +8 -8
- data/lib/datadog/core/environment/process.rb +3 -3
- data/lib/datadog/core/environment/socket.rb +2 -2
- data/lib/datadog/core/environment/variable_helpers.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/error.rb +5 -5
- data/lib/datadog/core/evp.rb +11 -0
- data/lib/datadog/core/extensions.rb +1 -1
- data/lib/datadog/core/feature_flags.rb +2 -2
- data/lib/datadog/core/git/ext.rb +4 -4
- data/lib/datadog/core/knuth_sampler.rb +3 -1
- data/lib/datadog/core/logger.rb +3 -3
- data/lib/datadog/core/logging/ext.rb +1 -1
- data/lib/datadog/core/metrics/client.rb +21 -21
- data/lib/datadog/core/metrics/ext.rb +5 -5
- data/lib/datadog/core/metrics/logging.rb +2 -2
- data/lib/datadog/core/metrics/options.rb +3 -3
- data/lib/datadog/core/pin.rb +1 -1
- data/lib/datadog/core/process_discovery.rb +8 -8
- data/lib/datadog/core/rate_limiter.rb +1 -1
- data/lib/datadog/core/remote/client/capabilities.rb +62 -19
- data/lib/datadog/core/remote/client.rb +16 -16
- data/lib/datadog/core/remote/component.rb +20 -12
- data/lib/datadog/core/remote/configuration/content.rb +3 -3
- data/lib/datadog/core/remote/configuration/digest.rb +1 -1
- data/lib/datadog/core/remote/configuration/path.rb +9 -9
- data/lib/datadog/core/remote/configuration/repository.rb +2 -2
- data/lib/datadog/core/remote/configuration/target.rb +9 -9
- data/lib/datadog/core/remote/configuration.rb +4 -4
- data/lib/datadog/core/remote/ext.rb +3 -3
- data/lib/datadog/core/remote/negotiation.rb +1 -1
- data/lib/datadog/core/remote/tie/tracing.rb +7 -7
- data/lib/datadog/core/remote/transport/config.rb +4 -4
- data/lib/datadog/core/remote/transport/http/config.rb +7 -7
- data/lib/datadog/core/remote/transport/http/negotiation.rb +4 -4
- data/lib/datadog/core/remote/transport/http.rb +10 -10
- data/lib/datadog/core/remote/transport/negotiation.rb +3 -3
- data/lib/datadog/core/remote/worker.rb +5 -5
- data/lib/datadog/core/runtime/ext.rb +22 -22
- data/lib/datadog/core/runtime/metrics.rb +9 -9
- data/lib/datadog/core/tag_builder.rb +18 -18
- data/lib/datadog/core/tag_normalizer.rb +7 -7
- data/lib/datadog/core/telemetry/component.rb +13 -13
- data/lib/datadog/core/telemetry/emitter.rb +4 -4
- data/lib/datadog/core/telemetry/event/app_client_configuration_change.rb +5 -5
- data/lib/datadog/core/telemetry/event/app_closing.rb +2 -2
- data/lib/datadog/core/telemetry/event/app_dependencies_loaded.rb +2 -2
- data/lib/datadog/core/telemetry/event/app_endpoints_loaded.rb +2 -2
- data/lib/datadog/core/telemetry/event/app_extended_heartbeat.rb +2 -2
- data/lib/datadog/core/telemetry/event/app_heartbeat.rb +2 -2
- data/lib/datadog/core/telemetry/event/app_integrations_change.rb +2 -2
- data/lib/datadog/core/telemetry/event/app_started.rb +41 -34
- data/lib/datadog/core/telemetry/event/base.rb +1 -1
- data/lib/datadog/core/telemetry/event/distributions.rb +2 -2
- data/lib/datadog/core/telemetry/event/generate_metrics.rb +2 -2
- data/lib/datadog/core/telemetry/event/log.rb +4 -4
- data/lib/datadog/core/telemetry/event/message_batch.rb +1 -1
- data/lib/datadog/core/telemetry/event/synth_app_client_configuration_change.rb +3 -3
- data/lib/datadog/core/telemetry/event.rb +16 -16
- data/lib/datadog/core/telemetry/ext.rb +11 -11
- data/lib/datadog/core/telemetry/logger.rb +1 -1
- data/lib/datadog/core/telemetry/logging.rb +5 -5
- data/lib/datadog/core/telemetry/metric.rb +7 -7
- data/lib/datadog/core/telemetry/metrics_collection.rb +2 -2
- data/lib/datadog/core/telemetry/metrics_manager.rb +1 -1
- data/lib/datadog/core/telemetry/request.rb +4 -4
- data/lib/datadog/core/telemetry/transport/http/telemetry.rb +14 -14
- data/lib/datadog/core/telemetry/transport/http.rb +7 -7
- data/lib/datadog/core/telemetry/transport/telemetry.rb +3 -3
- data/lib/datadog/core/telemetry/worker.rb +6 -6
- data/lib/datadog/core/transport/ext.rb +14 -14
- data/lib/datadog/core/transport/http/adapters/net.rb +4 -4
- data/lib/datadog/core/transport/http/adapters/test.rb +1 -1
- data/lib/datadog/core/transport/http/adapters/unix_socket.rb +4 -4
- data/lib/datadog/core/transport/http/api/endpoint.rb +1 -1
- data/lib/datadog/core/transport/http/api/map.rb +1 -1
- data/lib/datadog/core/transport/http/builder.rb +6 -6
- data/lib/datadog/core/transport/http/client.rb +2 -2
- data/lib/datadog/core/transport/http/response.rb +1 -1
- data/lib/datadog/core/transport/http.rb +8 -8
- data/lib/datadog/core/transport/transport.rb +1 -1
- data/lib/datadog/core/utils/at_fork_monkey_patch.rb +83 -15
- data/lib/datadog/core/utils/base64_codec.rb +3 -3
- data/lib/datadog/core/utils/duration.rb +1 -1
- data/lib/datadog/core/utils/forking.rb +2 -2
- data/lib/datadog/core/utils/lru_cache.rb +3 -3
- data/lib/datadog/core/utils/network.rb +11 -11
- data/lib/datadog/core/utils/only_once_successful.rb +1 -1
- data/lib/datadog/core/utils/safe_dup.rb +2 -1
- data/lib/datadog/core/utils/sequence.rb +3 -6
- data/lib/datadog/core/utils/spawn_monkey_patch.rb +2 -2
- data/lib/datadog/core/utils/time.rb +18 -52
- data/lib/datadog/core/utils/url.rb +1 -1
- data/lib/datadog/core/utils.rb +4 -4
- data/lib/datadog/core/workers/async.rb +1 -1
- data/lib/datadog/core/workers/polling.rb +2 -2
- data/lib/datadog/core/workers/runtime_metrics.rb +4 -4
- data/lib/datadog/core.rb +4 -4
- data/lib/datadog/data_streams/configuration.rb +3 -3
- data/lib/datadog/data_streams/ext.rb +1 -1
- data/lib/datadog/data_streams/extensions.rb +2 -2
- data/lib/datadog/data_streams/pathway_context.rb +5 -5
- data/lib/datadog/data_streams/processor.rb +52 -52
- data/lib/datadog/data_streams/transport/http/stats.rb +5 -5
- data/lib/datadog/data_streams/transport/http.rb +5 -5
- data/lib/datadog/data_streams/transport/stats.rb +7 -7
- data/lib/datadog/data_streams.rb +5 -5
- data/lib/datadog/di/base.rb +6 -4
- data/lib/datadog/di/boot.rb +25 -22
- data/lib/datadog/di/capture_expression.rb +21 -0
- data/lib/datadog/di/capture_expression_evaluator.rb +71 -0
- data/lib/datadog/di/capture_limits.rb +41 -0
- data/lib/datadog/di/code_tracker.rb +10 -7
- data/lib/datadog/di/component.rb +122 -40
- data/lib/datadog/di/configuration.rb +7 -1
- data/lib/datadog/di/context.rb +9 -3
- data/lib/datadog/di/contrib/railtie.rb +1 -1
- data/lib/datadog/di/contrib.rb +5 -5
- data/lib/datadog/di/el/compiler.rb +91 -38
- data/lib/datadog/di/el/evaluator.rb +82 -2
- data/lib/datadog/di/el/expression.rb +10 -2
- data/lib/datadog/di/el.rb +3 -3
- data/lib/datadog/di/error.rb +10 -0
- data/lib/datadog/di/fatal_exceptions.rb +26 -0
- data/lib/datadog/di/instrumenter.rb +426 -169
- data/lib/datadog/di/logger.rb +1 -1
- data/lib/datadog/di/preload.rb +1 -1
- data/lib/datadog/di/probe.rb +61 -2
- data/lib/datadog/di/probe_builder.rb +96 -14
- data/lib/datadog/di/probe_file_loader/railtie.rb +1 -1
- data/lib/datadog/di/probe_file_loader.rb +12 -7
- data/lib/datadog/di/probe_manager.rb +67 -9
- data/lib/datadog/di/probe_notification_builder.rb +66 -22
- data/lib/datadog/di/probe_notifier_worker.rb +57 -37
- data/lib/datadog/di/probe_repository.rb +1 -1
- data/lib/datadog/di/redactor.rb +16 -1
- data/lib/datadog/di/remote.rb +178 -17
- data/lib/datadog/di/serializer.rb +47 -28
- data/lib/datadog/di/transport/diagnostics.rb +5 -5
- data/lib/datadog/di/transport/http/diagnostics.rb +3 -3
- data/lib/datadog/di/transport/http/input.rb +2 -2
- data/lib/datadog/di/transport/http.rb +10 -10
- data/lib/datadog/di/transport/input.rb +16 -12
- data/lib/datadog/di/utils.rb +4 -4
- data/lib/datadog/di.rb +66 -3
- data/lib/datadog/error_tracking/collector.rb +2 -2
- data/lib/datadog/error_tracking/component.rb +12 -12
- data/lib/datadog/error_tracking/configuration.rb +2 -2
- data/lib/datadog/error_tracking/ext.rb +7 -7
- data/lib/datadog/error_tracking/extensions.rb +2 -2
- data/lib/datadog/error_tracking/filters.rb +4 -4
- data/lib/datadog/error_tracking.rb +6 -6
- data/lib/datadog/kit/appsec/events/v2.rb +90 -32
- data/lib/datadog/kit/appsec/events.rb +25 -25
- data/lib/datadog/kit/enable_core_dumps.rb +2 -2
- data/lib/datadog/kit/identity.rb +18 -18
- data/lib/datadog/kit/tracing/method_tracer.rb +7 -7
- data/lib/datadog/kit.rb +1 -1
- data/lib/datadog/open_feature/component.rb +53 -21
- data/lib/datadog/open_feature/configuration.rb +22 -1
- data/lib/datadog/open_feature/evaluation_engine.rb +7 -7
- data/lib/datadog/open_feature/exposures/buffer.rb +1 -1
- data/lib/datadog/open_feature/exposures/deduplicator.rb +1 -1
- data/lib/datadog/open_feature/exposures/event.rb +2 -2
- data/lib/datadog/open_feature/exposures/reporter.rb +3 -3
- data/lib/datadog/open_feature/exposures/worker.rb +6 -6
- data/lib/datadog/open_feature/ext.rb +13 -6
- data/lib/datadog/open_feature/flag_evaluation/aggregator.rb +286 -0
- data/lib/datadog/open_feature/flag_evaluation/writer.rb +433 -0
- data/lib/datadog/open_feature/hooks/flag_eval_evp_hook.rb +102 -0
- data/lib/datadog/open_feature/hooks/{flag_eval_hook.rb → flag_eval_metrics_hook.rb} +4 -2
- data/lib/datadog/open_feature/hooks/span_enrichment_hook/codec.rb +58 -0
- data/lib/datadog/open_feature/hooks/span_enrichment_hook/span_enrichment_state.rb +96 -0
- data/lib/datadog/open_feature/hooks/span_enrichment_hook/span_enrichment_state_store.rb +49 -0
- data/lib/datadog/open_feature/hooks/span_enrichment_hook.rb +184 -0
- data/lib/datadog/open_feature/metrics/flag_eval_metrics.rb +24 -24
- data/lib/datadog/open_feature/native_evaluator.rb +23 -1
- data/lib/datadog/open_feature/noop_evaluator.rb +3 -3
- data/lib/datadog/open_feature/provider.rb +97 -30
- data/lib/datadog/open_feature/remote.rb +2 -2
- data/lib/datadog/open_feature/resolution_details.rb +4 -2
- data/lib/datadog/open_feature/transport.rb +65 -11
- data/lib/datadog/open_feature.rb +2 -2
- data/lib/datadog/opentelemetry/api/baggage.rb +3 -3
- data/lib/datadog/opentelemetry/api/context.rb +4 -4
- data/lib/datadog/opentelemetry/configuration/settings.rb +41 -41
- data/lib/datadog/opentelemetry/ext.rb +1 -1
- data/lib/datadog/opentelemetry/logs.rb +5 -5
- data/lib/datadog/opentelemetry/metrics.rb +7 -7
- data/lib/datadog/opentelemetry/sdk/configurator.rb +8 -8
- data/lib/datadog/opentelemetry/sdk/id_generator.rb +2 -2
- data/lib/datadog/opentelemetry/sdk/logs_exporter.rb +10 -17
- data/lib/datadog/opentelemetry/sdk/metrics_exporter.rb +8 -15
- data/lib/datadog/opentelemetry/sdk/propagator.rb +7 -7
- data/lib/datadog/opentelemetry/sdk/span_processor.rb +15 -15
- data/lib/datadog/opentelemetry/sdk/trace/span.rb +32 -32
- data/lib/datadog/opentelemetry/sdk.rb +19 -0
- data/lib/datadog/opentelemetry/signal_configuration.rb +11 -11
- data/lib/datadog/opentelemetry/trace.rb +1 -1
- data/lib/datadog/opentelemetry.rb +8 -8
- data/lib/datadog/profiling/collectors/cpu_and_wall_time_worker.rb +6 -1
- data/lib/datadog/profiling/collectors/idle_sampling_helper.rb +5 -3
- data/lib/datadog/profiling/collectors/thread_context.rb +15 -14
- data/lib/datadog/profiling/component.rb +18 -0
- data/lib/datadog/profiling/exporter.rb +1 -1
- data/lib/datadog/profiling/http_transport.rb +1 -1
- data/lib/datadog/profiling/sequence_tracker.rb +1 -1
- data/lib/datadog/profiling/tag_builder.rb +19 -19
- data/lib/datadog/profiling.rb +31 -27
- data/lib/datadog/single_step_instrument.rb +1 -1
- data/lib/datadog/symbol_database/component.rb +177 -60
- data/lib/datadog/symbol_database/configuration.rb +15 -7
- data/lib/datadog/symbol_database/extensions.rb +19 -0
- data/lib/datadog/symbol_database/extractor.rb +167 -130
- data/lib/datadog/symbol_database/file_hash.rb +5 -3
- data/lib/datadog/symbol_database/logger.rb +1 -1
- data/lib/datadog/symbol_database/remote.rb +28 -8
- data/lib/datadog/symbol_database/scope.rb +2 -2
- data/lib/datadog/symbol_database/scope_batcher.rb +8 -4
- data/lib/datadog/symbol_database/service_version.rb +4 -4
- data/lib/datadog/symbol_database/symbol.rb +1 -1
- data/lib/datadog/symbol_database/transport/http/endpoint.rb +1 -1
- data/lib/datadog/symbol_database/transport/http.rb +6 -6
- data/lib/datadog/symbol_database/transport.rb +4 -4
- data/lib/datadog/symbol_database/uploader.rb +28 -21
- data/lib/datadog/symbol_database.rb +22 -0
- data/lib/datadog/tracing/analytics.rb +1 -1
- data/lib/datadog/tracing/buffer.rb +5 -5
- data/lib/datadog/tracing/client_ip.rb +4 -4
- data/lib/datadog/tracing/component.rb +28 -7
- data/lib/datadog/tracing/configuration/dynamic.rb +8 -8
- data/lib/datadog/tracing/configuration/ext.rb +43 -42
- data/lib/datadog/tracing/configuration/http.rb +2 -2
- data/lib/datadog/tracing/configuration/settings.rb +32 -16
- data/lib/datadog/tracing/context.rb +1 -1
- data/lib/datadog/tracing/context_provider.rb +2 -2
- data/lib/datadog/tracing/contrib/action_cable/configuration/settings.rb +2 -2
- data/lib/datadog/tracing/contrib/action_cable/event.rb +4 -4
- data/lib/datadog/tracing/contrib/action_cable/events/broadcast.rb +5 -5
- data/lib/datadog/tracing/contrib/action_cable/events/perform_action.rb +4 -4
- data/lib/datadog/tracing/contrib/action_cable/events/transmit.rb +5 -5
- data/lib/datadog/tracing/contrib/action_cable/events.rb +4 -4
- data/lib/datadog/tracing/contrib/action_cable/ext.rb +18 -18
- data/lib/datadog/tracing/contrib/action_cable/instrumentation.rb +4 -4
- data/lib/datadog/tracing/contrib/action_cable/integration.rb +7 -7
- data/lib/datadog/tracing/contrib/action_cable/patcher.rb +4 -4
- data/lib/datadog/tracing/contrib/action_mailer/configuration/settings.rb +2 -2
- data/lib/datadog/tracing/contrib/action_mailer/event.rb +3 -3
- data/lib/datadog/tracing/contrib/action_mailer/events/deliver.rb +8 -8
- data/lib/datadog/tracing/contrib/action_mailer/events/process.rb +4 -4
- data/lib/datadog/tracing/contrib/action_mailer/events.rb +2 -2
- data/lib/datadog/tracing/contrib/action_mailer/ext.rb +18 -18
- data/lib/datadog/tracing/contrib/action_mailer/integration.rb +7 -7
- data/lib/datadog/tracing/contrib/action_mailer/patcher.rb +3 -3
- data/lib/datadog/tracing/contrib/action_pack/action_controller/instrumentation.rb +8 -8
- data/lib/datadog/tracing/contrib/action_pack/action_controller/patcher.rb +2 -2
- data/lib/datadog/tracing/contrib/action_pack/action_dispatch/instrumentation.rb +4 -4
- data/lib/datadog/tracing/contrib/action_pack/action_dispatch/patcher.rb +4 -4
- data/lib/datadog/tracing/contrib/action_pack/configuration/settings.rb +3 -3
- data/lib/datadog/tracing/contrib/action_pack/ext.rb +10 -10
- data/lib/datadog/tracing/contrib/action_pack/integration.rb +7 -7
- data/lib/datadog/tracing/contrib/action_pack/patcher.rb +3 -3
- data/lib/datadog/tracing/contrib/action_pack/utils.rb +1 -1
- data/lib/datadog/tracing/contrib/action_view/configuration/settings.rb +3 -3
- data/lib/datadog/tracing/contrib/action_view/event.rb +1 -1
- data/lib/datadog/tracing/contrib/action_view/events/render_partial.rb +6 -6
- data/lib/datadog/tracing/contrib/action_view/events/render_template.rb +6 -6
- data/lib/datadog/tracing/contrib/action_view/events.rb +2 -2
- data/lib/datadog/tracing/contrib/action_view/ext.rb +10 -10
- data/lib/datadog/tracing/contrib/action_view/integration.rb +11 -11
- data/lib/datadog/tracing/contrib/action_view/patcher.rb +5 -5
- data/lib/datadog/tracing/contrib/action_view/utils.rb +2 -2
- data/lib/datadog/tracing/contrib/active_job/configuration/settings.rb +2 -2
- data/lib/datadog/tracing/contrib/active_job/data_streams.rb +62 -0
- data/lib/datadog/tracing/contrib/active_job/event.rb +3 -3
- data/lib/datadog/tracing/contrib/active_job/events/discard.rb +5 -5
- data/lib/datadog/tracing/contrib/active_job/events/enqueue.rb +5 -5
- data/lib/datadog/tracing/contrib/active_job/events/enqueue_at.rb +5 -5
- data/lib/datadog/tracing/contrib/active_job/events/enqueue_retry.rb +5 -5
- data/lib/datadog/tracing/contrib/active_job/events/perform.rb +5 -5
- data/lib/datadog/tracing/contrib/active_job/events/retry_stopped.rb +5 -5
- data/lib/datadog/tracing/contrib/active_job/events.rb +6 -6
- data/lib/datadog/tracing/contrib/active_job/ext.rb +23 -23
- data/lib/datadog/tracing/contrib/active_job/integration.rb +7 -7
- data/lib/datadog/tracing/contrib/active_job/patcher.rb +17 -5
- data/lib/datadog/tracing/contrib/active_model_serializers/configuration/settings.rb +2 -2
- data/lib/datadog/tracing/contrib/active_model_serializers/event.rb +4 -4
- data/lib/datadog/tracing/contrib/active_model_serializers/events/render.rb +6 -6
- data/lib/datadog/tracing/contrib/active_model_serializers/events/serialize.rb +7 -8
- data/lib/datadog/tracing/contrib/active_model_serializers/events.rb +2 -2
- data/lib/datadog/tracing/contrib/active_model_serializers/ext.rb +10 -10
- data/lib/datadog/tracing/contrib/active_model_serializers/integration.rb +5 -5
- data/lib/datadog/tracing/contrib/active_model_serializers/patcher.rb +3 -3
- data/lib/datadog/tracing/contrib/active_record/configuration/makara_resolver.rb +1 -1
- data/lib/datadog/tracing/contrib/active_record/configuration/resolver.rb +6 -6
- data/lib/datadog/tracing/contrib/active_record/configuration/settings.rb +4 -4
- data/lib/datadog/tracing/contrib/active_record/event.rb +1 -1
- data/lib/datadog/tracing/contrib/active_record/events/instantiation.rb +8 -8
- data/lib/datadog/tracing/contrib/active_record/events/sql.rb +9 -9
- data/lib/datadog/tracing/contrib/active_record/events.rb +2 -2
- data/lib/datadog/tracing/contrib/active_record/ext.rb +15 -15
- data/lib/datadog/tracing/contrib/active_record/integration.rb +11 -11
- data/lib/datadog/tracing/contrib/active_record/patcher.rb +2 -2
- data/lib/datadog/tracing/contrib/active_record/utils.rb +3 -3
- data/lib/datadog/tracing/contrib/active_support/cache/event.rb +1 -1
- data/lib/datadog/tracing/contrib/active_support/cache/events/cache.rb +11 -11
- data/lib/datadog/tracing/contrib/active_support/cache/events.rb +1 -1
- data/lib/datadog/tracing/contrib/active_support/cache/instrumentation.rb +4 -4
- data/lib/datadog/tracing/contrib/active_support/cache/patcher.rb +5 -5
- data/lib/datadog/tracing/contrib/active_support/cache/redis.rb +4 -4
- data/lib/datadog/tracing/contrib/active_support/configuration/settings.rb +3 -3
- data/lib/datadog/tracing/contrib/active_support/ext.rb +16 -16
- data/lib/datadog/tracing/contrib/active_support/integration.rb +8 -8
- data/lib/datadog/tracing/contrib/active_support/notifications/event.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 +1 -1
- data/lib/datadog/tracing/contrib/active_support/patcher.rb +2 -2
- data/lib/datadog/tracing/contrib/analytics.rb +1 -1
- data/lib/datadog/tracing/contrib/auto_instrument.rb +4 -4
- data/lib/datadog/tracing/contrib/aws/configuration/settings.rb +3 -3
- data/lib/datadog/tracing/contrib/aws/ext.rb +25 -25
- data/lib/datadog/tracing/contrib/aws/instrumentation.rb +5 -5
- data/lib/datadog/tracing/contrib/aws/integration.rb +9 -9
- data/lib/datadog/tracing/contrib/aws/parsed_context.rb +1 -1
- data/lib/datadog/tracing/contrib/aws/patcher.rb +5 -5
- data/lib/datadog/tracing/contrib/aws/service/dynamodb.rb +2 -2
- data/lib/datadog/tracing/contrib/aws/service/eventbridge.rb +2 -2
- data/lib/datadog/tracing/contrib/aws/service/kinesis.rb +4 -4
- data/lib/datadog/tracing/contrib/aws/service/s3.rb +2 -2
- data/lib/datadog/tracing/contrib/aws/service/sns.rb +3 -3
- data/lib/datadog/tracing/contrib/aws/service/sqs.rb +3 -3
- data/lib/datadog/tracing/contrib/aws/service/states.rb +5 -5
- data/lib/datadog/tracing/contrib/aws/services.rb +14 -14
- data/lib/datadog/tracing/contrib/concurrent_ruby/async_patch.rb +1 -1
- data/lib/datadog/tracing/contrib/concurrent_ruby/configuration/settings.rb +2 -2
- data/lib/datadog/tracing/contrib/concurrent_ruby/context_composite_executor_service.rb +1 -1
- data/lib/datadog/tracing/contrib/concurrent_ruby/ext.rb +2 -2
- data/lib/datadog/tracing/contrib/concurrent_ruby/future_patch.rb +1 -1
- data/lib/datadog/tracing/contrib/concurrent_ruby/integration.rb +6 -6
- data/lib/datadog/tracing/contrib/concurrent_ruby/patcher.rb +4 -4
- data/lib/datadog/tracing/contrib/concurrent_ruby/promises_future_patch.rb +1 -1
- data/lib/datadog/tracing/contrib/configurable.rb +2 -2
- data/lib/datadog/tracing/contrib/configuration/resolvers/pattern_resolver.rb +1 -1
- data/lib/datadog/tracing/contrib/configuration/settings.rb +2 -2
- data/lib/datadog/tracing/contrib/dalli/configuration/settings.rb +2 -2
- data/lib/datadog/tracing/contrib/dalli/ext.rb +13 -13
- data/lib/datadog/tracing/contrib/dalli/instrumentation.rb +5 -5
- data/lib/datadog/tracing/contrib/dalli/integration.rb +7 -7
- data/lib/datadog/tracing/contrib/dalli/patcher.rb +3 -3
- data/lib/datadog/tracing/contrib/dalli/quantize.rb +2 -2
- data/lib/datadog/tracing/contrib/delayed_job/configuration/settings.rb +2 -2
- data/lib/datadog/tracing/contrib/delayed_job/ext.rb +14 -14
- data/lib/datadog/tracing/contrib/delayed_job/integration.rb +5 -5
- data/lib/datadog/tracing/contrib/delayed_job/patcher.rb +3 -3
- data/lib/datadog/tracing/contrib/delayed_job/plugin.rb +5 -5
- data/lib/datadog/tracing/contrib/elasticsearch/configuration/settings.rb +2 -2
- data/lib/datadog/tracing/contrib/elasticsearch/ext.rb +15 -15
- data/lib/datadog/tracing/contrib/elasticsearch/integration.rb +6 -6
- data/lib/datadog/tracing/contrib/elasticsearch/patcher.rb +10 -10
- data/lib/datadog/tracing/contrib/elasticsearch/quantize.rb +2 -2
- data/lib/datadog/tracing/contrib/ethon/configuration/settings.rb +2 -2
- data/lib/datadog/tracing/contrib/ethon/easy_patch.rb +8 -8
- data/lib/datadog/tracing/contrib/ethon/ext.rb +13 -13
- data/lib/datadog/tracing/contrib/ethon/integration.rb +6 -6
- data/lib/datadog/tracing/contrib/ethon/multi_patch.rb +3 -3
- data/lib/datadog/tracing/contrib/ethon/patcher.rb +3 -3
- data/lib/datadog/tracing/contrib/excon/configuration/settings.rb +5 -5
- data/lib/datadog/tracing/contrib/excon/ext.rb +11 -11
- data/lib/datadog/tracing/contrib/excon/integration.rb +6 -6
- data/lib/datadog/tracing/contrib/excon/middleware.rb +8 -8
- data/lib/datadog/tracing/contrib/excon/patcher.rb +2 -2
- data/lib/datadog/tracing/contrib/ext.rb +15 -15
- data/lib/datadog/tracing/contrib/extensions.rb +2 -2
- data/lib/datadog/tracing/contrib/faraday/configuration/settings.rb +4 -4
- data/lib/datadog/tracing/contrib/faraday/ext.rb +11 -11
- data/lib/datadog/tracing/contrib/faraday/integration.rb +6 -6
- data/lib/datadog/tracing/contrib/faraday/middleware.rb +8 -8
- data/lib/datadog/tracing/contrib/faraday/patcher.rb +6 -6
- data/lib/datadog/tracing/contrib/grape/configuration/settings.rb +4 -4
- data/lib/datadog/tracing/contrib/grape/endpoint.rb +20 -20
- data/lib/datadog/tracing/contrib/grape/ext.rb +15 -15
- data/lib/datadog/tracing/contrib/grape/instrumentation.rb +3 -3
- data/lib/datadog/tracing/contrib/grape/integration.rb +5 -5
- data/lib/datadog/tracing/contrib/grape/patcher.rb +5 -5
- data/lib/datadog/tracing/contrib/graphql/configuration/error_extension_env_parser.rb +1 -1
- data/lib/datadog/tracing/contrib/graphql/configuration/settings.rb +3 -3
- data/lib/datadog/tracing/contrib/graphql/ext.rb +9 -9
- data/lib/datadog/tracing/contrib/graphql/integration.rb +9 -9
- data/lib/datadog/tracing/contrib/graphql/patcher.rb +7 -7
- data/lib/datadog/tracing/contrib/graphql/unified_trace.rb +37 -37
- data/lib/datadog/tracing/contrib/graphql/unified_trace_patcher.rb +2 -2
- data/lib/datadog/tracing/contrib/grpc/configuration/settings.rb +2 -2
- data/lib/datadog/tracing/contrib/grpc/datadog_interceptor/client.rb +7 -7
- data/lib/datadog/tracing/contrib/grpc/datadog_interceptor/server.rb +7 -7
- data/lib/datadog/tracing/contrib/grpc/datadog_interceptor.rb +6 -6
- data/lib/datadog/tracing/contrib/grpc/distributed/fetcher.rb +1 -1
- data/lib/datadog/tracing/contrib/grpc/distributed/propagation.rb +8 -8
- data/lib/datadog/tracing/contrib/grpc/ext.rb +14 -14
- data/lib/datadog/tracing/contrib/grpc/formatting.rb +7 -7
- data/lib/datadog/tracing/contrib/grpc/integration.rb +5 -5
- data/lib/datadog/tracing/contrib/grpc/intercept_with_datadog.rb +1 -1
- data/lib/datadog/tracing/contrib/grpc/patcher.rb +3 -3
- data/lib/datadog/tracing/contrib/grpc.rb +6 -6
- data/lib/datadog/tracing/contrib/hanami/action_tracer.rb +3 -3
- data/lib/datadog/tracing/contrib/hanami/configuration/settings.rb +2 -2
- data/lib/datadog/tracing/contrib/hanami/ext.rb +8 -8
- data/lib/datadog/tracing/contrib/hanami/integration.rb +6 -6
- data/lib/datadog/tracing/contrib/hanami/patcher.rb +5 -5
- data/lib/datadog/tracing/contrib/hanami/renderer_policy_tracing.rb +3 -3
- data/lib/datadog/tracing/contrib/hanami/router_tracing.rb +5 -4
- data/lib/datadog/tracing/contrib/http/circuit_breaker.rb +1 -1
- data/lib/datadog/tracing/contrib/http/configuration/settings.rb +4 -4
- data/lib/datadog/tracing/contrib/http/distributed/fetcher.rb +3 -3
- data/lib/datadog/tracing/contrib/http/distributed/propagation.rb +8 -8
- data/lib/datadog/tracing/contrib/http/ext.rb +11 -11
- data/lib/datadog/tracing/contrib/http/instrumentation.rb +6 -6
- data/lib/datadog/tracing/contrib/http/integration.rb +7 -7
- data/lib/datadog/tracing/contrib/http/patcher.rb +3 -3
- data/lib/datadog/tracing/contrib/http.rb +6 -6
- data/lib/datadog/tracing/contrib/httpclient/configuration/settings.rb +4 -4
- data/lib/datadog/tracing/contrib/httpclient/ext.rb +11 -11
- data/lib/datadog/tracing/contrib/httpclient/instrumentation.rb +5 -5
- data/lib/datadog/tracing/contrib/httpclient/integration.rb +6 -6
- data/lib/datadog/tracing/contrib/httpclient/patcher.rb +3 -3
- data/lib/datadog/tracing/contrib/httprb/configuration/settings.rb +4 -4
- data/lib/datadog/tracing/contrib/httprb/ext.rb +11 -11
- data/lib/datadog/tracing/contrib/httprb/instrumentation.rb +6 -6
- data/lib/datadog/tracing/contrib/httprb/integration.rb +7 -7
- data/lib/datadog/tracing/contrib/httprb/patcher.rb +3 -3
- data/lib/datadog/tracing/contrib/integration.rb +3 -3
- data/lib/datadog/tracing/contrib/kafka/configuration/settings.rb +2 -2
- data/lib/datadog/tracing/contrib/kafka/event.rb +3 -3
- data/lib/datadog/tracing/contrib/kafka/events/connection/request.rb +7 -3
- data/lib/datadog/tracing/contrib/kafka/events/consumer/process_batch.rb +4 -4
- data/lib/datadog/tracing/contrib/kafka/events/consumer/process_message.rb +4 -4
- data/lib/datadog/tracing/contrib/kafka/events/consumer_group/heartbeat.rb +5 -5
- data/lib/datadog/tracing/contrib/kafka/events/consumer_group/join_group.rb +5 -5
- data/lib/datadog/tracing/contrib/kafka/events/consumer_group/leave_group.rb +5 -5
- data/lib/datadog/tracing/contrib/kafka/events/consumer_group/sync_group.rb +5 -5
- data/lib/datadog/tracing/contrib/kafka/events/produce_operation/send_messages.rb +10 -5
- data/lib/datadog/tracing/contrib/kafka/events/producer/deliver_messages.rb +10 -5
- data/lib/datadog/tracing/contrib/kafka/events.rb +9 -9
- data/lib/datadog/tracing/contrib/kafka/ext.rb +40 -40
- data/lib/datadog/tracing/contrib/kafka/instrumentation/consumer.rb +2 -2
- data/lib/datadog/tracing/contrib/kafka/instrumentation/producer.rb +4 -4
- data/lib/datadog/tracing/contrib/kafka/integration.rb +6 -6
- data/lib/datadog/tracing/contrib/kafka/patcher.rb +5 -5
- data/lib/datadog/tracing/contrib/karafka/configuration/settings.rb +2 -2
- data/lib/datadog/tracing/contrib/karafka/distributed/propagation.rb +8 -8
- data/lib/datadog/tracing/contrib/karafka/ext.rb +13 -13
- data/lib/datadog/tracing/contrib/karafka/integration.rb +5 -5
- data/lib/datadog/tracing/contrib/karafka/monitor.rb +14 -14
- data/lib/datadog/tracing/contrib/karafka/patcher.rb +8 -8
- data/lib/datadog/tracing/contrib/karafka.rb +6 -6
- data/lib/datadog/tracing/contrib/lograge/configuration/settings.rb +2 -2
- data/lib/datadog/tracing/contrib/lograge/ext.rb +1 -1
- data/lib/datadog/tracing/contrib/lograge/integration.rb +5 -5
- data/lib/datadog/tracing/contrib/lograge/patcher.rb +9 -9
- data/lib/datadog/tracing/contrib/mongodb/configuration/settings.rb +2 -2
- data/lib/datadog/tracing/contrib/mongodb/ext.rb +18 -18
- data/lib/datadog/tracing/contrib/mongodb/instrumentation.rb +3 -3
- data/lib/datadog/tracing/contrib/mongodb/integration.rb +7 -7
- data/lib/datadog/tracing/contrib/mongodb/parsers.rb +5 -5
- data/lib/datadog/tracing/contrib/mongodb/patcher.rb +3 -3
- data/lib/datadog/tracing/contrib/mongodb/subscribers.rb +13 -13
- data/lib/datadog/tracing/contrib/mysql2/configuration/settings.rb +3 -3
- data/lib/datadog/tracing/contrib/mysql2/ext.rb +11 -11
- data/lib/datadog/tracing/contrib/mysql2/instrumentation.rb +6 -6
- data/lib/datadog/tracing/contrib/mysql2/integration.rb +5 -5
- data/lib/datadog/tracing/contrib/mysql2/patcher.rb +2 -2
- data/lib/datadog/tracing/contrib/opensearch/configuration/settings.rb +2 -2
- data/lib/datadog/tracing/contrib/opensearch/ext.rb +22 -22
- data/lib/datadog/tracing/contrib/opensearch/integration.rb +6 -6
- data/lib/datadog/tracing/contrib/opensearch/patcher.rb +13 -13
- data/lib/datadog/tracing/contrib/opensearch/quantize.rb +3 -3
- data/lib/datadog/tracing/contrib/patcher.rb +2 -2
- data/lib/datadog/tracing/contrib/pg/configuration/settings.rb +3 -3
- data/lib/datadog/tracing/contrib/pg/ext.rb +19 -19
- data/lib/datadog/tracing/contrib/pg/instrumentation.rb +18 -18
- data/lib/datadog/tracing/contrib/pg/integration.rb +5 -5
- data/lib/datadog/tracing/contrib/pg/patcher.rb +2 -2
- data/lib/datadog/tracing/contrib/presto/configuration/settings.rb +2 -2
- data/lib/datadog/tracing/contrib/presto/ext.rb +21 -21
- data/lib/datadog/tracing/contrib/presto/instrumentation.rb +2 -2
- data/lib/datadog/tracing/contrib/presto/integration.rb +6 -6
- data/lib/datadog/tracing/contrib/presto/patcher.rb +4 -4
- data/lib/datadog/tracing/contrib/propagation/sql_comment/comment.rb +2 -2
- data/lib/datadog/tracing/contrib/propagation/sql_comment/ext.rb +17 -17
- data/lib/datadog/tracing/contrib/propagation/sql_comment/mode.rb +1 -1
- data/lib/datadog/tracing/contrib/propagation/sql_comment.rb +5 -5
- data/lib/datadog/tracing/contrib/que/configuration/settings.rb +2 -2
- data/lib/datadog/tracing/contrib/que/ext.rb +19 -19
- data/lib/datadog/tracing/contrib/que/integration.rb +6 -6
- data/lib/datadog/tracing/contrib/que/patcher.rb +1 -1
- data/lib/datadog/tracing/contrib/que/tracer.rb +1 -1
- data/lib/datadog/tracing/contrib/racecar/configuration/settings.rb +3 -3
- data/lib/datadog/tracing/contrib/racecar/event.rb +4 -4
- data/lib/datadog/tracing/contrib/racecar/events/batch.rb +3 -3
- data/lib/datadog/tracing/contrib/racecar/events/consume.rb +3 -3
- data/lib/datadog/tracing/contrib/racecar/events/message.rb +3 -3
- data/lib/datadog/tracing/contrib/racecar/events.rb +3 -3
- data/lib/datadog/tracing/contrib/racecar/ext.rb +18 -18
- data/lib/datadog/tracing/contrib/racecar/integration.rb +5 -5
- data/lib/datadog/tracing/contrib/racecar/patcher.rb +3 -3
- data/lib/datadog/tracing/contrib/rack/configuration/settings.rb +2 -2
- data/lib/datadog/tracing/contrib/rack/ext.rb +33 -33
- data/lib/datadog/tracing/contrib/rack/header_collection.rb +3 -3
- data/lib/datadog/tracing/contrib/rack/header_tagging.rb +4 -4
- data/lib/datadog/tracing/contrib/rack/integration.rb +6 -6
- data/lib/datadog/tracing/contrib/rack/middlewares.rb +24 -24
- data/lib/datadog/tracing/contrib/rack/patcher.rb +3 -3
- data/lib/datadog/tracing/contrib/rack/request_queue.rb +3 -3
- data/lib/datadog/tracing/contrib/rack/route_inference.rb +11 -11
- data/lib/datadog/tracing/contrib/rack/trace_proxy_middleware.rb +15 -15
- data/lib/datadog/tracing/contrib/rails/auto_instrument_railtie.rb +1 -1
- data/lib/datadog/tracing/contrib/rails/configuration/settings.rb +3 -3
- data/lib/datadog/tracing/contrib/rails/ext.rb +15 -15
- data/lib/datadog/tracing/contrib/rails/framework.rb +11 -11
- data/lib/datadog/tracing/contrib/rails/integration.rb +5 -5
- data/lib/datadog/tracing/contrib/rails/middlewares.rb +1 -1
- data/lib/datadog/tracing/contrib/rails/patcher.rb +8 -8
- data/lib/datadog/tracing/contrib/rails/railtie.rb +4 -4
- data/lib/datadog/tracing/contrib/rails/runner.rb +1 -1
- data/lib/datadog/tracing/contrib/rake/configuration/settings.rb +3 -3
- data/lib/datadog/tracing/contrib/rake/ext.rb +12 -12
- data/lib/datadog/tracing/contrib/rake/instrumentation.rb +4 -4
- data/lib/datadog/tracing/contrib/rake/integration.rb +5 -5
- data/lib/datadog/tracing/contrib/rake/patcher.rb +3 -3
- data/lib/datadog/tracing/contrib/redis/configuration/resolver.rb +2 -2
- data/lib/datadog/tracing/contrib/redis/configuration/settings.rb +2 -2
- data/lib/datadog/tracing/contrib/redis/ext.rb +16 -16
- data/lib/datadog/tracing/contrib/redis/instrumentation.rb +6 -6
- data/lib/datadog/tracing/contrib/redis/integration.rb +7 -7
- data/lib/datadog/tracing/contrib/redis/patcher.rb +10 -10
- data/lib/datadog/tracing/contrib/redis/quantize.rb +4 -4
- data/lib/datadog/tracing/contrib/redis/tags.rb +5 -5
- data/lib/datadog/tracing/contrib/redis/trace_middleware.rb +5 -5
- data/lib/datadog/tracing/contrib/resque/configuration/settings.rb +2 -2
- data/lib/datadog/tracing/contrib/resque/ext.rb +7 -7
- data/lib/datadog/tracing/contrib/resque/integration.rb +5 -5
- data/lib/datadog/tracing/contrib/resque/patcher.rb +3 -3
- data/lib/datadog/tracing/contrib/resque/resque_job.rb +5 -5
- data/lib/datadog/tracing/contrib/rest_client/configuration/settings.rb +2 -2
- data/lib/datadog/tracing/contrib/rest_client/ext.rb +10 -10
- data/lib/datadog/tracing/contrib/rest_client/integration.rb +6 -6
- data/lib/datadog/tracing/contrib/rest_client/patcher.rb +2 -2
- data/lib/datadog/tracing/contrib/rest_client/request_patch.rb +5 -5
- data/lib/datadog/tracing/contrib/roda/configuration/settings.rb +2 -2
- data/lib/datadog/tracing/contrib/roda/ext.rb +6 -6
- data/lib/datadog/tracing/contrib/roda/instrumentation.rb +4 -4
- data/lib/datadog/tracing/contrib/roda/integration.rb +6 -6
- data/lib/datadog/tracing/contrib/roda/patcher.rb +3 -3
- data/lib/datadog/tracing/contrib/semantic_logger/configuration/settings.rb +2 -2
- data/lib/datadog/tracing/contrib/semantic_logger/ext.rb +1 -1
- data/lib/datadog/tracing/contrib/semantic_logger/integration.rb +5 -5
- data/lib/datadog/tracing/contrib/semantic_logger/patcher.rb +2 -2
- data/lib/datadog/tracing/contrib/sequel/configuration/settings.rb +2 -2
- data/lib/datadog/tracing/contrib/sequel/database.rb +6 -10
- data/lib/datadog/tracing/contrib/sequel/dataset.rb +5 -5
- data/lib/datadog/tracing/contrib/sequel/ext.rb +12 -8
- data/lib/datadog/tracing/contrib/sequel/integration.rb +5 -5
- data/lib/datadog/tracing/contrib/sequel/patcher.rb +3 -3
- data/lib/datadog/tracing/contrib/sequel/utils.rb +115 -10
- data/lib/datadog/tracing/contrib/shoryuken/configuration/settings.rb +2 -2
- data/lib/datadog/tracing/contrib/shoryuken/ext.rb +12 -12
- data/lib/datadog/tracing/contrib/shoryuken/integration.rb +6 -6
- data/lib/datadog/tracing/contrib/shoryuken/patcher.rb +1 -1
- data/lib/datadog/tracing/contrib/shoryuken/tracer.rb +2 -2
- data/lib/datadog/tracing/contrib/sidekiq/client_tracer.rb +8 -8
- data/lib/datadog/tracing/contrib/sidekiq/configuration/settings.rb +2 -2
- data/lib/datadog/tracing/contrib/sidekiq/distributed/propagation.rb +9 -9
- data/lib/datadog/tracing/contrib/sidekiq/ext.rb +30 -30
- data/lib/datadog/tracing/contrib/sidekiq/integration.rb +7 -7
- data/lib/datadog/tracing/contrib/sidekiq/patcher.rb +8 -8
- data/lib/datadog/tracing/contrib/sidekiq/server_tracer.rb +14 -14
- data/lib/datadog/tracing/contrib/sidekiq/utils.rb +9 -9
- data/lib/datadog/tracing/contrib/sidekiq.rb +6 -6
- data/lib/datadog/tracing/contrib/sinatra/configuration/settings.rb +2 -2
- data/lib/datadog/tracing/contrib/sinatra/env.rb +6 -6
- data/lib/datadog/tracing/contrib/sinatra/ext.rb +17 -17
- data/lib/datadog/tracing/contrib/sinatra/framework.rb +2 -2
- data/lib/datadog/tracing/contrib/sinatra/integration.rb +5 -5
- data/lib/datadog/tracing/contrib/sinatra/patcher.rb +5 -5
- data/lib/datadog/tracing/contrib/sinatra/tracer.rb +10 -10
- data/lib/datadog/tracing/contrib/sinatra/tracer_middleware.rb +8 -8
- data/lib/datadog/tracing/contrib/sneakers/configuration/settings.rb +1 -1
- data/lib/datadog/tracing/contrib/sneakers/ext.rb +12 -12
- data/lib/datadog/tracing/contrib/sneakers/integration.rb +7 -7
- data/lib/datadog/tracing/contrib/sneakers/patcher.rb +2 -2
- data/lib/datadog/tracing/contrib/sneakers/tracer.rb +3 -3
- data/lib/datadog/tracing/contrib/span_attribute_schema.rb +2 -2
- data/lib/datadog/tracing/contrib/status_range_env_parser.rb +2 -2
- data/lib/datadog/tracing/contrib/status_range_matcher.rb +1 -1
- data/lib/datadog/tracing/contrib/stripe/configuration/settings.rb +2 -2
- data/lib/datadog/tracing/contrib/stripe/ext.rb +12 -12
- data/lib/datadog/tracing/contrib/stripe/integration.rb +5 -5
- data/lib/datadog/tracing/contrib/stripe/patcher.rb +2 -2
- data/lib/datadog/tracing/contrib/stripe/request.rb +3 -3
- data/lib/datadog/tracing/contrib/sucker_punch/configuration/settings.rb +2 -2
- data/lib/datadog/tracing/contrib/sucker_punch/exception_handler.rb +1 -1
- data/lib/datadog/tracing/contrib/sucker_punch/ext.rb +13 -13
- data/lib/datadog/tracing/contrib/sucker_punch/instrumentation.rb +4 -4
- data/lib/datadog/tracing/contrib/sucker_punch/integration.rb +5 -5
- data/lib/datadog/tracing/contrib/sucker_punch/patcher.rb +4 -4
- data/lib/datadog/tracing/contrib/trilogy/configuration/settings.rb +3 -3
- data/lib/datadog/tracing/contrib/trilogy/ext.rb +11 -11
- data/lib/datadog/tracing/contrib/trilogy/instrumentation.rb +6 -6
- data/lib/datadog/tracing/contrib/trilogy/integration.rb +5 -5
- data/lib/datadog/tracing/contrib/trilogy/patcher.rb +2 -2
- data/lib/datadog/tracing/contrib/utils/database.rb +5 -5
- data/lib/datadog/tracing/contrib/utils/quantization/hash_formatter.rb +1 -1
- data/lib/datadog/tracing/contrib/utils/quantization/http.rb +10 -10
- data/lib/datadog/tracing/contrib/waterdrop/configuration/settings.rb +2 -2
- data/lib/datadog/tracing/contrib/waterdrop/distributed/propagation.rb +8 -8
- data/lib/datadog/tracing/contrib/waterdrop/ext.rb +4 -4
- data/lib/datadog/tracing/contrib/waterdrop/integration.rb +5 -5
- data/lib/datadog/tracing/contrib/waterdrop/middleware.rb +2 -2
- data/lib/datadog/tracing/contrib/waterdrop/patcher.rb +7 -7
- data/lib/datadog/tracing/contrib/waterdrop/producer.rb +3 -3
- data/lib/datadog/tracing/contrib/waterdrop.rb +6 -6
- data/lib/datadog/tracing/contrib.rb +54 -54
- data/lib/datadog/tracing/correlation.rb +10 -10
- data/lib/datadog/tracing/diagnostics/environment_logger.rb +9 -9
- data/lib/datadog/tracing/diagnostics/ext.rb +19 -19
- data/lib/datadog/tracing/diagnostics/health.rb +1 -1
- data/lib/datadog/tracing/distributed/b3_multi.rb +8 -8
- data/lib/datadog/tracing/distributed/b3_single.rb +4 -4
- data/lib/datadog/tracing/distributed/baggage.rb +28 -27
- data/lib/datadog/tracing/distributed/datadog.rb +21 -21
- data/lib/datadog/tracing/distributed/datadog_tags_codec.rb +3 -3
- data/lib/datadog/tracing/distributed/fetcher.rb +1 -1
- data/lib/datadog/tracing/distributed/helpers.rb +3 -3
- data/lib/datadog/tracing/distributed/propagation.rb +12 -12
- data/lib/datadog/tracing/distributed/propagation_policy.rb +5 -0
- data/lib/datadog/tracing/distributed/trace_context.rb +33 -33
- data/lib/datadog/tracing/event.rb +1 -1
- data/lib/datadog/tracing/ext.rb +9 -0
- data/lib/datadog/tracing/metadata/analytics.rb +2 -2
- data/lib/datadog/tracing/metadata/errors.rb +4 -4
- data/lib/datadog/tracing/metadata/ext.rb +69 -69
- data/lib/datadog/tracing/metadata/metastruct.rb +1 -1
- data/lib/datadog/tracing/metadata/metastruct_tagging.rb +1 -1
- data/lib/datadog/tracing/metadata/tagging.rb +2 -2
- data/lib/datadog/tracing/metadata.rb +4 -4
- data/lib/datadog/tracing/pipeline/span_filter.rb +2 -2
- data/lib/datadog/tracing/pipeline.rb +2 -2
- data/lib/datadog/tracing/remote.rb +45 -7
- data/lib/datadog/tracing/sampling/all_sampler.rb +1 -1
- data/lib/datadog/tracing/sampling/ext.rb +8 -8
- data/lib/datadog/tracing/sampling/matcher.rb +4 -4
- data/lib/datadog/tracing/sampling/priority_sampler.rb +4 -4
- data/lib/datadog/tracing/sampling/rate_by_key_sampler.rb +3 -3
- data/lib/datadog/tracing/sampling/rate_by_service_sampler.rb +2 -2
- data/lib/datadog/tracing/sampling/rate_sampler.rb +2 -2
- data/lib/datadog/tracing/sampling/rule.rb +4 -4
- data/lib/datadog/tracing/sampling/rule_sampler.rb +12 -12
- data/lib/datadog/tracing/sampling/sampler.rb +2 -2
- data/lib/datadog/tracing/sampling/span/ext.rb +3 -3
- data/lib/datadog/tracing/sampling/span/matcher.rb +2 -2
- data/lib/datadog/tracing/sampling/span/rule.rb +1 -1
- data/lib/datadog/tracing/sampling/span/rule_parser.rb +8 -8
- data/lib/datadog/tracing/span.rb +8 -8
- data/lib/datadog/tracing/span_event.rb +5 -5
- data/lib/datadog/tracing/span_operation.rb +21 -21
- data/lib/datadog/tracing/sync_writer.rb +12 -7
- data/lib/datadog/tracing/trace_operation.rb +11 -11
- data/lib/datadog/tracing/trace_segment.rb +10 -10
- data/lib/datadog/tracing/tracer.rb +23 -15
- data/lib/datadog/tracing/transport/http/client.rb +4 -4
- data/lib/datadog/tracing/transport/http/statistics.rb +2 -2
- data/lib/datadog/tracing/transport/http/traces.rb +8 -8
- data/lib/datadog/tracing/transport/http.rb +10 -10
- data/lib/datadog/tracing/transport/io/client.rb +2 -2
- data/lib/datadog/tracing/transport/io/response.rb +1 -1
- data/lib/datadog/tracing/transport/io/traces.rb +4 -4
- data/lib/datadog/tracing/transport/io.rb +3 -3
- data/lib/datadog/tracing/transport/native/response.rb +71 -0
- data/lib/datadog/tracing/transport/native.rb +363 -0
- data/lib/datadog/tracing/transport/serializable_trace.rb +19 -19
- data/lib/datadog/tracing/transport/statistics.rb +2 -2
- data/lib/datadog/tracing/transport/trace_formatter.rb +10 -10
- data/lib/datadog/tracing/transport/traces.rb +8 -8
- data/lib/datadog/tracing/utils.rb +2 -2
- data/lib/datadog/tracing/workers.rb +2 -2
- data/lib/datadog/tracing/writer.rb +21 -8
- data/lib/datadog/tracing.rb +3 -3
- data/lib/datadog/version.rb +4 -4
- data/lib/datadog.rb +13 -12
- metadata +33 -8
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "set"
|
|
4
|
+
require "json"
|
|
5
|
+
|
|
6
|
+
require_relative "codec"
|
|
7
|
+
|
|
8
|
+
module Datadog
|
|
9
|
+
module OpenFeature
|
|
10
|
+
module Hooks
|
|
11
|
+
class SpanEnrichmentHook
|
|
12
|
+
# Per-root-span state. Enforces the frozen limits, dedupes serial
|
|
13
|
+
# ids structurally via a Set, and renders the three `ffe_*` tag shapes.
|
|
14
|
+
#
|
|
15
|
+
# Not internally synchronized: every method is only ever called while the
|
|
16
|
+
# owning `SpanEnrichmentHook`'s mutex is held (capture, encode, cleanup),
|
|
17
|
+
# so the state stays a plain object and the lock provides the
|
|
18
|
+
# consistent snapshot at encode time.
|
|
19
|
+
class SpanEnrichmentState
|
|
20
|
+
def initialize
|
|
21
|
+
@serial_ids = Set.new
|
|
22
|
+
@subjects = {} # sha256hex => Set<int>
|
|
23
|
+
@defaults = {} # flag_key => String
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def add_serial_id(serial_id)
|
|
27
|
+
return if @serial_ids.size >= MAX_SERIAL_IDS
|
|
28
|
+
|
|
29
|
+
@serial_ids.add(serial_id)
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
# Subject serial ids are NOT required to be a subset of the flag set:
|
|
33
|
+
# the frozen cross-SDK wire contract does not mandate `subjects ⊆ flags`,
|
|
34
|
+
# so a subject may reference a serial id that the independent 200-flag cap
|
|
35
|
+
# dropped from `ffe_flags_enc`. This mirrors the reference implementation
|
|
36
|
+
# and every other SDK; the caps (200 flags, 10 subjects, 20 experiments)
|
|
37
|
+
# are applied independently on purpose.
|
|
38
|
+
def add_subject(targeting_key, serial_id)
|
|
39
|
+
hashed = Codec.hash_targeting_key(targeting_key)
|
|
40
|
+
existing = @subjects[hashed]
|
|
41
|
+
|
|
42
|
+
if existing
|
|
43
|
+
return if existing.size >= MAX_EXPERIMENTS_PER_SUBJECT
|
|
44
|
+
|
|
45
|
+
existing.add(serial_id)
|
|
46
|
+
elsif @subjects.size >= MAX_SUBJECTS
|
|
47
|
+
nil
|
|
48
|
+
else
|
|
49
|
+
@subjects[hashed] = Set[serial_id]
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
# `value` is the flag's resolved runtime-default — any OpenFeature
|
|
54
|
+
# value type (String, boolean, number, or a structured Hash/Array).
|
|
55
|
+
# Non-strings are JSON-encoded (not `to_s`) so a structured default is
|
|
56
|
+
# captured faithfully rather than as Ruby's `inspect` form (e.g.
|
|
57
|
+
# `{"a"=>1}`, which is not valid JSON). The result is a bounded
|
|
58
|
+
# diagnostic PREVIEW, not a round-trippable value: it is truncated to
|
|
59
|
+
# the frozen 64-char cap, so a long JSON string is intentionally left
|
|
60
|
+
# as a non-parseable prefix. The backend treats this field as a
|
|
61
|
+
# display string, so a clipped value is acceptable.
|
|
62
|
+
def add_default(flag_key, value)
|
|
63
|
+
return if @defaults.key?(flag_key) # first-wins
|
|
64
|
+
return if @defaults.size >= MAX_DEFAULTS
|
|
65
|
+
|
|
66
|
+
value_str = value.is_a?(String) ? value : JSON.generate(value)
|
|
67
|
+
# Slicing is by codepoint, so a multibyte UTF-8 character is never
|
|
68
|
+
# split; `|| value_str` keeps the value non-nil for the zero-start slice.
|
|
69
|
+
@defaults[flag_key] = value_str[0, MAX_DEFAULT_VALUE_LENGTH] || value_str
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
# Subjects are intentionally not checked: a subject is only ever added
|
|
73
|
+
# alongside a serial id, so serial ids cover that case.
|
|
74
|
+
def has_data?
|
|
75
|
+
@serial_ids.any? || @defaults.any?
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
def to_span_tags
|
|
79
|
+
tags = {}
|
|
80
|
+
tags[TAG_FLAGS_ENC] = Codec.encode_delta_varint(@serial_ids) if @serial_ids.any?
|
|
81
|
+
|
|
82
|
+
if @subjects.any?
|
|
83
|
+
encoded_subjects = {}
|
|
84
|
+
@subjects.each { |hashed, ids| encoded_subjects[hashed] = Codec.encode_delta_varint(ids) }
|
|
85
|
+
tags[TAG_SUBJECTS_ENC] = JSON.generate(encoded_subjects)
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
tags[TAG_RUNTIME_DEFAULTS] = JSON.generate(@defaults) if @defaults.any?
|
|
89
|
+
|
|
90
|
+
tags
|
|
91
|
+
end
|
|
92
|
+
end
|
|
93
|
+
end
|
|
94
|
+
end
|
|
95
|
+
end
|
|
96
|
+
end
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative "span_enrichment_state"
|
|
4
|
+
|
|
5
|
+
module Datadog
|
|
6
|
+
module OpenFeature
|
|
7
|
+
module Hooks
|
|
8
|
+
class SpanEnrichmentHook
|
|
9
|
+
# Maps each trace operation to its `SpanEnrichmentState`, keyed WEAKLY by
|
|
10
|
+
# object identity. Using `ObjectSpace::WeakMap` means an
|
|
11
|
+
# abandoned trace (root span never finishes) cannot pin its state:
|
|
12
|
+
# once the trace operation is unreachable the entry is collected. The
|
|
13
|
+
# state (the WeakMap *value*, which `WeakMap` would otherwise also
|
|
14
|
+
# collect once no strong ref remains) is kept alive for the trace's
|
|
15
|
+
# lifetime by the `span_before_finish` subscription closure, which is held
|
|
16
|
+
# by `trace_op.events`. So state lives exactly as long as the trace and
|
|
17
|
+
# dies with it.
|
|
18
|
+
#
|
|
19
|
+
# All access is serialized by the owning hook's mutex; the WeakMap itself
|
|
20
|
+
# is not thread-safe under concurrent mutation.
|
|
21
|
+
class SpanEnrichmentStateStore
|
|
22
|
+
def initialize
|
|
23
|
+
@states = ObjectSpace::WeakMap.new
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def [](trace_op)
|
|
27
|
+
@states[trace_op]
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def []=(trace_op, state)
|
|
31
|
+
@states[trace_op] = state
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def delete(trace_op)
|
|
35
|
+
# `ObjectSpace::WeakMap#delete` was only added in Ruby 3.3; this gem
|
|
36
|
+
# supports Ruby 2.5+, so overwrite the slot with nil instead so a stale
|
|
37
|
+
# entry is never re-read after the root finishes. The slot itself is
|
|
38
|
+
# reclaimed when the trace operation is collected.
|
|
39
|
+
@states[trace_op] = nil
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def clear!
|
|
43
|
+
@states = ObjectSpace::WeakMap.new
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
end
|
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative "span_enrichment_hook/codec"
|
|
4
|
+
require_relative "span_enrichment_hook/span_enrichment_state"
|
|
5
|
+
require_relative "span_enrichment_hook/span_enrichment_state_store"
|
|
6
|
+
|
|
7
|
+
module Datadog
|
|
8
|
+
module OpenFeature
|
|
9
|
+
module Hooks
|
|
10
|
+
# Captures feature-flag evaluation metadata and writes contract-conformant
|
|
11
|
+
# `ffe_*` tags onto the local root APM span when it finishes.
|
|
12
|
+
#
|
|
13
|
+
# The wire format is a fixed cross-SDK contract. The encoding (ULEB128
|
|
14
|
+
# delta-varint + base64), the per-trace aggregation limits, the runtime-default
|
|
15
|
+
# detection (missing variant) and the SHA256 subject hashing must be
|
|
16
|
+
# reproduced exactly so the backend decodes tags identically regardless of
|
|
17
|
+
# which language SDK emitted them.
|
|
18
|
+
#
|
|
19
|
+
# Dispatch:
|
|
20
|
+
# Enrichment is driven DIRECTLY from `Provider#evaluate` (see `#capture`),
|
|
21
|
+
# not through an OpenFeature hook. This is the only path that works on
|
|
22
|
+
# every supported SDK version, so the capture happens on the provider
|
|
23
|
+
# evaluation thread rather than a hook callback.
|
|
24
|
+
#
|
|
25
|
+
# Lifecycle:
|
|
26
|
+
# - `#capture` runs on every evaluation. It resolves the local root span
|
|
27
|
+
# off the active trace, lazily creates the per-root `SpanEnrichmentState`,
|
|
28
|
+
# and on the first capture for a trace subscribes to that trace's
|
|
29
|
+
# `span_before_finish` event. The subscription closure captures the
|
|
30
|
+
# state strongly and is held by `trace_op.events`, so the state lives
|
|
31
|
+
# exactly as long as the trace operation (the weak store key) — when the
|
|
32
|
+
# trace is GC'd both die together (no leak even if the root never finishes).
|
|
33
|
+
# - When the local root span is about to finish, the accumulated tags are
|
|
34
|
+
# written via `span.set_tag` and the per-root state is deleted.
|
|
35
|
+
# - `#shutdown` clears all accumulated state (provider-close cleanup).
|
|
36
|
+
#
|
|
37
|
+
# Thread-safety:
|
|
38
|
+
# Concurrent evaluations (on different threads) can target the same active
|
|
39
|
+
# trace. The GVL does NOT make the compound operations here safe
|
|
40
|
+
# (fetch-or-create, subscribe-once, mutate-while-encoding), so all store /
|
|
41
|
+
# subscription / state access is serialized through a single
|
|
42
|
+
# `Mutex`, and the finish-time encode takes the snapshot under that lock.
|
|
43
|
+
#
|
|
44
|
+
# When the gate is off the hook is never constructed (see
|
|
45
|
+
# `Component#create_span_enrichment_hook`), so there is zero idle per-span
|
|
46
|
+
# overhead.
|
|
47
|
+
class SpanEnrichmentHook
|
|
48
|
+
# Fixed cross-SDK contract limits. No env-var knobs.
|
|
49
|
+
MAX_SERIAL_IDS = 200
|
|
50
|
+
MAX_SUBJECTS = 10
|
|
51
|
+
MAX_EXPERIMENTS_PER_SUBJECT = 20
|
|
52
|
+
MAX_DEFAULTS = 5
|
|
53
|
+
MAX_DEFAULT_VALUE_LENGTH = 64
|
|
54
|
+
|
|
55
|
+
TAG_FLAGS_ENC = "ffe_flags_enc"
|
|
56
|
+
TAG_SUBJECTS_ENC = "ffe_subjects_enc"
|
|
57
|
+
TAG_RUNTIME_DEFAULTS = "ffe_runtime_defaults"
|
|
58
|
+
|
|
59
|
+
def initialize(span_enrichment_state_store, logger:)
|
|
60
|
+
@store = span_enrichment_state_store
|
|
61
|
+
@mutex = Mutex.new
|
|
62
|
+
@active = true
|
|
63
|
+
@logger = logger
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
# Direct dispatch from the Datadog provider evaluation path. Takes only
|
|
67
|
+
# primitives so it does not depend on any OpenFeature SDK object shape and
|
|
68
|
+
# works on every supported SDK version. Never raises — flag evaluation and
|
|
69
|
+
# the trace pipeline must not be broken by enrichment.
|
|
70
|
+
#
|
|
71
|
+
# @param flag_key [String] the evaluated flag key
|
|
72
|
+
# @param variant [String, nil] the resolved variant (nil/empty => runtime default)
|
|
73
|
+
# @param value [Object] the resolved value (used for runtime-default capture)
|
|
74
|
+
# @param serial_id [Integer, nil] the split serial id, when assigned
|
|
75
|
+
# @param do_log [Boolean] whether logging/exposure is authorized for this subject
|
|
76
|
+
# @param targeting_key [String, nil] the raw targeting key (hashed before emit)
|
|
77
|
+
def capture(flag_key:, variant:, value:, serial_id:, do_log:, targeting_key:)
|
|
78
|
+
trace_op = Datadog::Tracing.active_trace
|
|
79
|
+
return unless trace_op
|
|
80
|
+
|
|
81
|
+
@mutex.synchronize do
|
|
82
|
+
if serial_id.nil?
|
|
83
|
+
if variant.nil? || variant.empty?
|
|
84
|
+
# Runtime default: detected by a missing variant (never a reason enum).
|
|
85
|
+
state_for(trace_op).add_default(flag_key, value)
|
|
86
|
+
end
|
|
87
|
+
else
|
|
88
|
+
state = state_for(trace_op)
|
|
89
|
+
state.add_serial_id(serial_id)
|
|
90
|
+
# Skip empty targeting keys: SHA256('') would collide every
|
|
91
|
+
# anonymous/missing subject under one bogus hash, corrupting
|
|
92
|
+
# subject-level attribution.
|
|
93
|
+
state.add_subject(targeting_key, serial_id) if do_log && targeting_key && !targeting_key.empty?
|
|
94
|
+
end
|
|
95
|
+
end
|
|
96
|
+
rescue => e
|
|
97
|
+
@logger.debug { "Error capturing span enrichment: #{e.class}: #{e.message}" }
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
# Provider-close cleanup: mark the hook inactive and drop all accumulated
|
|
101
|
+
# state. State is dropped, not flushed, on purpose: each state only
|
|
102
|
+
# becomes a set of tags when ITS OWN root span finishes, and at
|
|
103
|
+
# provider-close time those roots are still open — there is no valid
|
|
104
|
+
# target to flush to, and writing partial tags onto in-flight spans
|
|
105
|
+
# would emit incomplete data (and double-write once the root finished).
|
|
106
|
+
# A trace that already subscribed still holds its state via the
|
|
107
|
+
# `span_before_finish` closure, so clearing `@active` (checked in
|
|
108
|
+
# `write_tags_on_root`) is what actually prevents a stale write after
|
|
109
|
+
# shutdown. Per-trace subscriptions die with their trace operations, so
|
|
110
|
+
# there is nothing else to unsubscribe.
|
|
111
|
+
def shutdown
|
|
112
|
+
@mutex.synchronize do
|
|
113
|
+
@active = false
|
|
114
|
+
@store.clear!
|
|
115
|
+
end
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
private
|
|
119
|
+
|
|
120
|
+
# Lazily create the per-root state and, on first capture for a trace,
|
|
121
|
+
# subscribe to that trace's span lifecycle so we can write tags when the
|
|
122
|
+
# local root span finishes. MUST be called with `@mutex` held.
|
|
123
|
+
def state_for(trace_op)
|
|
124
|
+
state = @store[trace_op]
|
|
125
|
+
return state if state
|
|
126
|
+
|
|
127
|
+
state = SpanEnrichmentState.new
|
|
128
|
+
@store[trace_op] = state
|
|
129
|
+
subscribe_root_finish(trace_op, state)
|
|
130
|
+
state
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
# MUST be called with `@mutex` held. The subscription closure captures
|
|
134
|
+
# `state` strongly; since the closure is retained by
|
|
135
|
+
# `trace_op.events`, this keeps the WeakMap value alive for the trace's
|
|
136
|
+
# lifetime (and lets both be collected together when the trace is GC'd).
|
|
137
|
+
def subscribe_root_finish(trace_op, state)
|
|
138
|
+
events = trace_op.send(:events)
|
|
139
|
+
# `span_before_finish` fires `(span_op, trace_op)` while the span can
|
|
140
|
+
# still be enriched (before it is finalized into an immutable Span).
|
|
141
|
+
# The block is the tracer-callback boundary and runs long after
|
|
142
|
+
# `#capture` returns, so it rescues on its own — enrichment must never
|
|
143
|
+
# raise into the trace pipeline. (Errors setting up the subscription
|
|
144
|
+
# here propagate to `#capture`'s rescue, since this runs under it.)
|
|
145
|
+
events.span_before_finish.subscribe do |span_op, finishing_trace_op|
|
|
146
|
+
# `span_before_finish` fires for EVERY span in the trace, and in any
|
|
147
|
+
# nested trace the child spans finish before the local root. Only the
|
|
148
|
+
# local root's finish may write tags AND clean up per-trace state:
|
|
149
|
+
# acting on a child finish would wipe the state before the root
|
|
150
|
+
# is written. Guard here so `write_tags_on_root` (and its cleanup) only
|
|
151
|
+
# ever runs for the local root.
|
|
152
|
+
next unless span_op.equal?(finishing_trace_op.send(:root_span))
|
|
153
|
+
|
|
154
|
+
write_tags_on_root(span_op, finishing_trace_op, state)
|
|
155
|
+
rescue => e
|
|
156
|
+
@logger.debug { "Error writing span enrichment tags: #{e.class}: #{e.message}" }
|
|
157
|
+
end
|
|
158
|
+
end
|
|
159
|
+
|
|
160
|
+
def write_tags_on_root(span_op, trace_op, state)
|
|
161
|
+
# Snapshot the tags under the lock so a concurrent `#capture` on another
|
|
162
|
+
# thread cannot mutate the state's Sets/Hashes while we encode.
|
|
163
|
+
tags = @mutex.synchronize do
|
|
164
|
+
# After shutdown the store is cleared, but this trace's subscription
|
|
165
|
+
# closure still holds the state; write only while active so a provider
|
|
166
|
+
# close/reconfigure never emits stale `ffe_*` tags on an open trace.
|
|
167
|
+
if @active && state.has_data?
|
|
168
|
+
state.to_span_tags
|
|
169
|
+
else
|
|
170
|
+
{}
|
|
171
|
+
end
|
|
172
|
+
ensure
|
|
173
|
+
# The caller only invokes this on the local root's finish, so cleanup
|
|
174
|
+
# runs exactly once per trace. In an `ensure` so abandoned state is
|
|
175
|
+
# still freed if encoding ever raises.
|
|
176
|
+
@store.delete(trace_op)
|
|
177
|
+
end
|
|
178
|
+
|
|
179
|
+
tags.each { |key, value| span_op.set_tag(key, value) }
|
|
180
|
+
end
|
|
181
|
+
end
|
|
182
|
+
end
|
|
183
|
+
end
|
|
184
|
+
end
|
|
@@ -5,28 +5,28 @@ module Datadog
|
|
|
5
5
|
module Metrics
|
|
6
6
|
# Records flag evaluation metrics via OpenTelemetry
|
|
7
7
|
class FlagEvalMetrics
|
|
8
|
-
METER_NAME =
|
|
9
|
-
METRIC_NAME =
|
|
10
|
-
METRIC_UNIT =
|
|
11
|
-
METRIC_DESCRIPTION =
|
|
8
|
+
METER_NAME = "ddtrace.openfeature"
|
|
9
|
+
METRIC_NAME = "feature_flag.evaluations"
|
|
10
|
+
METRIC_UNIT = "{evaluation}"
|
|
11
|
+
METRIC_DESCRIPTION = "Number of feature flag evaluations"
|
|
12
12
|
|
|
13
|
-
ATTR_FLAG_KEY =
|
|
14
|
-
ATTR_VARIANT =
|
|
15
|
-
ATTR_REASON =
|
|
16
|
-
ATTR_ALLOCATION_KEY =
|
|
17
|
-
ATTR_ERROR_TYPE =
|
|
13
|
+
ATTR_FLAG_KEY = "feature_flag.key"
|
|
14
|
+
ATTR_VARIANT = "feature_flag.result.variant"
|
|
15
|
+
ATTR_REASON = "feature_flag.result.reason"
|
|
16
|
+
ATTR_ALLOCATION_KEY = "feature_flag.result.allocation_key"
|
|
17
|
+
ATTR_ERROR_TYPE = "error.type"
|
|
18
18
|
|
|
19
|
-
DEFAULT_ERROR_TYPE =
|
|
19
|
+
DEFAULT_ERROR_TYPE = "general"
|
|
20
20
|
|
|
21
21
|
ERROR_TYPE_MAP = {
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
22
|
+
"FLAG_NOT_FOUND" => "flag_not_found",
|
|
23
|
+
"TYPE_MISMATCH" => "type_mismatch",
|
|
24
|
+
"PARSE_ERROR" => "parse_error",
|
|
25
|
+
"PROVIDER_NOT_READY" => "provider_not_ready",
|
|
26
|
+
"TARGETING_KEY_MISSING" => "targeting_key_missing",
|
|
27
|
+
"INVALID_CONTEXT" => "invalid_context",
|
|
28
|
+
"PROVIDER_FATAL" => "provider_fatal",
|
|
29
|
+
"GENERAL" => DEFAULT_ERROR_TYPE,
|
|
30
30
|
}.freeze
|
|
31
31
|
|
|
32
32
|
# Reasons that should not include allocation_key in metrics
|
|
@@ -40,7 +40,7 @@ module Datadog
|
|
|
40
40
|
@mutex = Mutex.new
|
|
41
41
|
|
|
42
42
|
unless @enabled
|
|
43
|
-
@logger.debug {
|
|
43
|
+
@logger.debug { "OpenFeature: OTel metrics not enabled (DD_METRICS_OTEL_ENABLED=false), flag evaluation metrics disabled" }
|
|
44
44
|
end
|
|
45
45
|
end
|
|
46
46
|
|
|
@@ -60,7 +60,7 @@ module Datadog
|
|
|
60
60
|
counter.add(1, attributes: attributes)
|
|
61
61
|
rescue => e
|
|
62
62
|
@logger.debug { "OpenFeature: Failed to record evaluation metric: #{e.class}: #{e.message}" }
|
|
63
|
-
@telemetry.report(e, description:
|
|
63
|
+
@telemetry.report(e, description: "OpenFeature: Failed to record evaluation metric")
|
|
64
64
|
end
|
|
65
65
|
|
|
66
66
|
private
|
|
@@ -92,9 +92,9 @@ module Datadog
|
|
|
92
92
|
meter_provider = defined?(::OpenTelemetry) ? ::OpenTelemetry.meter_provider : nil
|
|
93
93
|
return meter_provider if sdk_meter_provider?(meter_provider)
|
|
94
94
|
|
|
95
|
-
@logger.debug {
|
|
96
|
-
require
|
|
97
|
-
require
|
|
95
|
+
@logger.debug { "OpenFeature: Initializing OTel meter provider directly" }
|
|
96
|
+
require "opentelemetry-metrics-sdk"
|
|
97
|
+
require "datadog/opentelemetry/metrics"
|
|
98
98
|
Datadog::OpenTelemetry::Metrics.initialize!(Datadog.send(:components))
|
|
99
99
|
|
|
100
100
|
meter_provider = ::OpenTelemetry.meter_provider
|
|
@@ -133,7 +133,7 @@ module Datadog
|
|
|
133
133
|
|
|
134
134
|
def normalize_reason(reason)
|
|
135
135
|
reason = reason.to_s
|
|
136
|
-
reason.empty? ?
|
|
136
|
+
reason.empty? ? "unknown" : reason.downcase
|
|
137
137
|
end
|
|
138
138
|
|
|
139
139
|
def normalize_error_type(error_code)
|
|
@@ -1,11 +1,15 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require_relative
|
|
3
|
+
require_relative "../core/feature_flags"
|
|
4
|
+
require_relative "ext"
|
|
5
|
+
require_relative "resolution_details"
|
|
4
6
|
|
|
5
7
|
module Datadog
|
|
6
8
|
module OpenFeature
|
|
7
9
|
# This class is an interface of evaluation logic using native extension
|
|
8
10
|
class NativeEvaluator
|
|
11
|
+
INVALID_FLAG_CONFIGURATION_ERROR_MESSAGE = "flag configuration is invalid or unsupported"
|
|
12
|
+
|
|
9
13
|
# NOTE: In a currect implementation configuration is expected to be a raw
|
|
10
14
|
# JSON string containing feature flags (straight from the remote config)
|
|
11
15
|
# in the format expected by `libdatadog` without any modifications
|
|
@@ -27,12 +31,30 @@ module Datadog
|
|
|
27
31
|
def get_assignment(flag_key, default_value:, expected_type:, context:)
|
|
28
32
|
result = @configuration.get_assignment(flag_key, expected_type, context)
|
|
29
33
|
|
|
34
|
+
return invalid_flag_configuration_error(default_value) if invalid_flag_configuration?(result)
|
|
35
|
+
|
|
30
36
|
# NOTE: This is a special case when we need to fallback to the default
|
|
31
37
|
# value, even tho the evaluation itself doesn't produce an error
|
|
32
38
|
# resolution details
|
|
33
39
|
result.value = default_value if result.variant.nil?
|
|
34
40
|
result
|
|
35
41
|
end
|
|
42
|
+
|
|
43
|
+
private
|
|
44
|
+
|
|
45
|
+
def invalid_flag_configuration?(result)
|
|
46
|
+
result.reason == Ext::DEFAULT &&
|
|
47
|
+
result.error_code.nil? &&
|
|
48
|
+
result.error_message == INVALID_FLAG_CONFIGURATION_ERROR_MESSAGE
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
def invalid_flag_configuration_error(default_value)
|
|
52
|
+
ResolutionDetails.build_error(
|
|
53
|
+
value: default_value,
|
|
54
|
+
error_code: Ext::PARSE_ERROR,
|
|
55
|
+
error_message: INVALID_FLAG_CONFIGURATION_ERROR_MESSAGE
|
|
56
|
+
)
|
|
57
|
+
end
|
|
36
58
|
end
|
|
37
59
|
end
|
|
38
60
|
end
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require_relative
|
|
4
|
-
require_relative
|
|
3
|
+
require_relative "ext"
|
|
4
|
+
require_relative "resolution_details"
|
|
5
5
|
|
|
6
6
|
module Datadog
|
|
7
7
|
module OpenFeature
|
|
@@ -17,7 +17,7 @@ module Datadog
|
|
|
17
17
|
log?: false,
|
|
18
18
|
error?: true,
|
|
19
19
|
error_code: Ext::PROVIDER_NOT_READY,
|
|
20
|
-
error_message:
|
|
20
|
+
error_message: "Waiting for flags configuration",
|
|
21
21
|
reason: Ext::ERROR
|
|
22
22
|
)
|
|
23
23
|
end
|
|
@@ -1,13 +1,18 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require_relative
|
|
4
|
-
|
|
3
|
+
require_relative "ext"
|
|
4
|
+
require_relative "../core/utils/time"
|
|
5
|
+
require "open_feature/sdk"
|
|
5
6
|
|
|
6
7
|
module Datadog
|
|
7
8
|
module OpenFeature
|
|
8
9
|
# OpenFeature feature flagging provider backed by Datadog Remote Configuration.
|
|
9
10
|
#
|
|
10
|
-
# Requires openfeature-sdk >= 0.5.1 for flag evaluation metrics support.
|
|
11
|
+
# Requires openfeature-sdk >= 0.5.1 for flag evaluation metrics and EVP hook support.
|
|
12
|
+
#
|
|
13
|
+
# Hook lifecycle note: FlagEvalEVPHook is returned from #hooks so EVP uses the SDK-final
|
|
14
|
+
# EvaluationDetails. This matches FlagEvalMetricsHook and records defaults/errors produced
|
|
15
|
+
# by OpenFeature hook failures or post-provider type validation.
|
|
11
16
|
#
|
|
12
17
|
# Implementation follows the OpenFeature contract of Provider SDK.
|
|
13
18
|
# For details see:
|
|
@@ -53,7 +58,7 @@ module Datadog
|
|
|
53
58
|
# # => 'Welcome back!'
|
|
54
59
|
# ```
|
|
55
60
|
class Provider
|
|
56
|
-
NAME =
|
|
61
|
+
NAME = "Datadog Feature Flagging Provider"
|
|
57
62
|
|
|
58
63
|
attr_reader :metadata
|
|
59
64
|
|
|
@@ -70,8 +75,11 @@ module Datadog
|
|
|
70
75
|
end
|
|
71
76
|
|
|
72
77
|
def hooks
|
|
73
|
-
|
|
74
|
-
[
|
|
78
|
+
component = Datadog.send(:components).open_feature
|
|
79
|
+
[
|
|
80
|
+
component&.flag_eval_metrics_hook,
|
|
81
|
+
component&.flag_eval_evp_hook,
|
|
82
|
+
].compact
|
|
75
83
|
end
|
|
76
84
|
|
|
77
85
|
def fetch_boolean_value(flag_key:, default_value:, evaluation_context: nil)
|
|
@@ -101,57 +109,116 @@ module Datadog
|
|
|
101
109
|
private
|
|
102
110
|
|
|
103
111
|
def evaluate(flag_key, default_value:, expected_type:, evaluation_context:)
|
|
112
|
+
# Stamp evaluation entry time once, here on the eval thread. The EVP path uses this for
|
|
113
|
+
# accurate first/last_evaluation bounds instead of a later hook-fire clock read.
|
|
114
|
+
eval_time_ms = (Core::Utils::Time.now.to_f * 1000).to_i
|
|
115
|
+
|
|
104
116
|
engine = OpenFeature.engine
|
|
105
|
-
return component_not_configured_default(default_value) if engine.nil?
|
|
117
|
+
return component_not_configured_default(default_value, eval_time_ms) if engine.nil?
|
|
118
|
+
|
|
119
|
+
result = fetch_engine_value(engine, flag_key, default_value, expected_type, evaluation_context)
|
|
106
120
|
|
|
107
|
-
|
|
121
|
+
# Build metadata before branching so provider-returned details carry eval-entry time.
|
|
122
|
+
flag_meta = build_flag_metadata(result, eval_time_ms)
|
|
123
|
+
|
|
124
|
+
if result.error?
|
|
125
|
+
return sdk_error_details(default_value, result.error_code, result.error_message, result.reason, flag_meta)
|
|
126
|
+
end
|
|
127
|
+
|
|
128
|
+
# Drive APM span enrichment directly from the evaluation path. This is the only reliable
|
|
129
|
+
# way to attach `ffe_*` tags across all supported OpenFeature SDK versions, since older
|
|
130
|
+
# SDKs do not dispatch provider hooks. Guarded so enrichment can never break evaluation.
|
|
131
|
+
enrich_span(flag_key, result, evaluation_context)
|
|
132
|
+
|
|
133
|
+
sdk_success_details(result, flag_meta)
|
|
134
|
+
rescue => e
|
|
135
|
+
error_message = "#{e.class}: #{e.message}"
|
|
136
|
+
error_result = Datadog::OpenFeature::ResolutionDetails.build_error(
|
|
137
|
+
value: default_value,
|
|
138
|
+
error_code: Ext::GENERAL,
|
|
139
|
+
error_message: error_message
|
|
140
|
+
)
|
|
141
|
+
error_flag_meta = build_flag_metadata(error_result, eval_time_ms || (Core::Utils::Time.now.to_f * 1000).to_i)
|
|
142
|
+
|
|
143
|
+
sdk_error_details(default_value, Ext::GENERAL, error_message, Ext::ERROR, error_flag_meta)
|
|
144
|
+
end
|
|
145
|
+
|
|
146
|
+
def fetch_engine_value(engine, flag_key, default_value, expected_type, evaluation_context)
|
|
147
|
+
engine.fetch_value(
|
|
108
148
|
flag_key,
|
|
109
149
|
default_value: default_value,
|
|
110
150
|
expected_type: expected_type,
|
|
111
151
|
evaluation_context: evaluation_context
|
|
112
152
|
)
|
|
153
|
+
end
|
|
113
154
|
|
|
114
|
-
|
|
115
|
-
return ::OpenFeature::SDK::Provider::ResolutionDetails.new(
|
|
116
|
-
value: default_value,
|
|
117
|
-
error_code: result.error_code,
|
|
118
|
-
error_message: result.error_message,
|
|
119
|
-
reason: result.reason
|
|
120
|
-
)
|
|
121
|
-
end
|
|
122
|
-
|
|
155
|
+
def sdk_success_details(result, flag_meta)
|
|
123
156
|
::OpenFeature::SDK::Provider::ResolutionDetails.new(
|
|
124
157
|
value: result.value,
|
|
125
158
|
variant: result.variant,
|
|
126
159
|
reason: result.reason,
|
|
127
|
-
flag_metadata:
|
|
160
|
+
flag_metadata: flag_meta,
|
|
128
161
|
)
|
|
129
|
-
|
|
162
|
+
end
|
|
163
|
+
|
|
164
|
+
def sdk_error_details(default_value, error_code, error_message, reason, flag_meta = {})
|
|
130
165
|
::OpenFeature::SDK::Provider::ResolutionDetails.new(
|
|
131
166
|
value: default_value,
|
|
132
|
-
error_code:
|
|
133
|
-
error_message:
|
|
134
|
-
reason:
|
|
167
|
+
error_code: error_code,
|
|
168
|
+
error_message: error_message,
|
|
169
|
+
reason: reason,
|
|
170
|
+
flag_metadata: flag_meta
|
|
135
171
|
)
|
|
136
172
|
end
|
|
137
173
|
|
|
138
|
-
def build_flag_metadata(result)
|
|
139
|
-
metadata = result.flag_metadata || {}
|
|
174
|
+
def build_flag_metadata(result, eval_time_ms)
|
|
175
|
+
metadata = result.flag_metadata&.dup || {}
|
|
140
176
|
allocation_key = result.allocation_key
|
|
141
|
-
if allocation_key && !allocation_key.empty?
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
177
|
+
metadata[Ext::METADATA_ALLOCATION_KEY] = allocation_key if allocation_key && !allocation_key.empty?
|
|
178
|
+
|
|
179
|
+
# Eval-time stamped at provider entry; the EVP hook reads 'dd.eval.timestamp_ms' for
|
|
180
|
+
# accurate first/last_evaluation bounds (it falls back to hook-fire time when absent).
|
|
181
|
+
metadata["dd.eval.timestamp_ms"] = eval_time_ms
|
|
145
182
|
|
|
146
183
|
metadata
|
|
147
184
|
end
|
|
148
185
|
|
|
149
|
-
|
|
186
|
+
# Dispatch span enrichment from the evaluation path in a never-throw
|
|
187
|
+
# wrapper. Reads the split serial id / do-log flag directly off the Datadog
|
|
188
|
+
# `ResolutionDetails` struct and the targeting key off the built evaluation
|
|
189
|
+
# context. A nil hook (gate off or component absent) is a no-op.
|
|
190
|
+
def enrich_span(flag_key, result, evaluation_context)
|
|
191
|
+
hook = span_enrichment_hook
|
|
192
|
+
return unless hook
|
|
193
|
+
|
|
194
|
+
# Hook resolved first so the common gate-off path short-circuits without
|
|
195
|
+
# resolving the tracer. With the gate on but no active trace there is
|
|
196
|
+
# nowhere to attach tags, so skip before building the capture call.
|
|
197
|
+
return unless Datadog::Tracing.active_trace
|
|
198
|
+
|
|
199
|
+
hook.capture(
|
|
200
|
+
flag_key: flag_key,
|
|
201
|
+
variant: result.variant,
|
|
202
|
+
value: result.value,
|
|
203
|
+
serial_id: result.serial_id,
|
|
204
|
+
do_log: result.log? || false,
|
|
205
|
+
targeting_key: evaluation_context&.targeting_key,
|
|
206
|
+
)
|
|
207
|
+
rescue => e
|
|
208
|
+
Datadog.logger.debug { "OpenFeature: span enrichment dispatch failed: #{e.class}: #{e.message}" }
|
|
209
|
+
end
|
|
210
|
+
|
|
211
|
+
def span_enrichment_hook
|
|
212
|
+
Datadog.send(:components).open_feature&.span_enrichment_hook
|
|
213
|
+
end
|
|
214
|
+
|
|
215
|
+
def component_not_configured_default(value, eval_time_ms)
|
|
150
216
|
::OpenFeature::SDK::Provider::ResolutionDetails.new(
|
|
151
217
|
value: value,
|
|
152
218
|
error_code: Ext::PROVIDER_FATAL,
|
|
153
219
|
error_message: "Datadog's OpenFeature component must be configured",
|
|
154
|
-
reason: Ext::ERROR
|
|
220
|
+
reason: Ext::ERROR,
|
|
221
|
+
flag_metadata: {"dd.eval.timestamp_ms" => eval_time_ms}
|
|
155
222
|
)
|
|
156
223
|
end
|
|
157
224
|
end
|