datadog 2.39.0 → 2.47.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +269 -44
- data/README.md +3 -0
- data/ext/datadog_profiling_native_extension/NativeExtensionDesign.md +12 -24
- data/ext/datadog_profiling_native_extension/collectors_cpu_and_wall_time_worker.c +256 -193
- data/ext/datadog_profiling_native_extension/collectors_discrete_dynamic_sampler.c +1 -5
- data/ext/datadog_profiling_native_extension/collectors_gc_profiling_helper.c +0 -2
- data/ext/datadog_profiling_native_extension/collectors_idle_sampling_helper.c +19 -20
- data/ext/datadog_profiling_native_extension/collectors_idle_sampling_helper.h +5 -1
- data/ext/datadog_profiling_native_extension/collectors_stack.c +267 -171
- data/ext/datadog_profiling_native_extension/collectors_stack.h +17 -3
- data/ext/datadog_profiling_native_extension/collectors_thread_context.c +307 -217
- data/ext/datadog_profiling_native_extension/collectors_thread_context.h +10 -5
- data/ext/datadog_profiling_native_extension/crashtracking_runtime_stacks.c +5 -4
- data/ext/datadog_profiling_native_extension/datadog_ruby_common.c +19 -11
- data/ext/datadog_profiling_native_extension/datadog_ruby_common.h +7 -10
- data/ext/datadog_profiling_native_extension/extconf.rb +67 -99
- data/ext/datadog_profiling_native_extension/heap_recorder.c +353 -257
- data/ext/datadog_profiling_native_extension/heap_recorder.h +50 -31
- data/ext/datadog_profiling_native_extension/native_extension_helpers.rb +3 -27
- data/ext/datadog_profiling_native_extension/private_vm_api_access.c +853 -496
- data/ext/datadog_profiling_native_extension/private_vm_api_access.h +42 -15
- data/ext/datadog_profiling_native_extension/profiling.c +30 -23
- data/ext/datadog_profiling_native_extension/ruby_helpers.c +4 -80
- data/ext/datadog_profiling_native_extension/ruby_helpers.h +4 -7
- data/ext/datadog_profiling_native_extension/setup_signal_handler.c +0 -2
- data/ext/datadog_profiling_native_extension/stack_recorder.c +116 -89
- data/ext/datadog_profiling_native_extension/stack_recorder.h +12 -5
- data/ext/datadog_profiling_native_extension/time_helpers.c +2 -4
- data/ext/datadog_profiling_native_extension/time_helpers.h +15 -15
- data/ext/libdatadog_api/datadog_ruby_common.c +19 -11
- data/ext/libdatadog_api/datadog_ruby_common.h +7 -10
- data/ext/libdatadog_api/di.c +43 -3
- data/ext/libdatadog_api/extconf.rb +6 -1
- data/ext/libdatadog_api/feature_flags.c +8 -0
- data/ext/libdatadog_api/init.c +9 -1
- data/ext/libdatadog_api/otel_thread_context.c +274 -0
- data/ext/libdatadog_api/otel_thread_context.h +5 -0
- data/ext/libdatadog_api/process_discovery.c +15 -1
- data/ext/libdatadog_api/trace_exporter.c +2078 -0
- data/ext/libdatadog_api/trace_exporter.h +5 -0
- data/ext/libdatadog_extconf_helpers.rb +14 -9
- data/lib/datadog/ai_guard/component.rb +17 -8
- data/lib/datadog/ai_guard/configuration/ext.rb +2 -0
- data/lib/datadog/ai_guard/configuration.rb +13 -0
- data/lib/datadog/ai_guard/contrib/ruby_llm/chat_instrumentation.rb +48 -55
- data/lib/datadog/ai_guard/contrib/ruby_llm/integration.rb +1 -1
- data/lib/datadog/ai_guard/contrib/ruby_llm/message_adapter.rb +76 -0
- data/lib/datadog/ai_guard/contrib/ruby_llm/patcher.rb +1 -0
- data/lib/datadog/ai_guard/contrib/ruby_llm/redaction_change_set.rb +135 -0
- data/lib/datadog/ai_guard/evaluation/client.rb +50 -0
- data/lib/datadog/ai_guard/evaluation/content_part.rb +12 -0
- data/lib/datadog/ai_guard/evaluation/message.rb +25 -7
- data/lib/datadog/ai_guard/evaluation/message_builder.rb +31 -0
- data/lib/datadog/ai_guard/evaluation/no_op_result.rb +6 -6
- data/lib/datadog/ai_guard/evaluation/outcome.rb +24 -0
- data/lib/datadog/ai_guard/evaluation/request.rb +8 -64
- data/lib/datadog/ai_guard/evaluation/response.rb +33 -0
- data/lib/datadog/ai_guard/evaluation/result.rb +11 -18
- data/lib/datadog/ai_guard/evaluation/tool_call.rb +15 -2
- data/lib/datadog/ai_guard/evaluation.rb +36 -14
- data/lib/datadog/ai_guard/ext.rb +4 -1
- data/lib/datadog/ai_guard/{api_client.rb → http_client.rb} +7 -5
- data/lib/datadog/ai_guard/metrics/telemetry.rb +43 -0
- data/lib/datadog/ai_guard/redaction/replacements.rb +97 -0
- data/lib/datadog/ai_guard/redaction/result.rb +29 -0
- data/lib/datadog/ai_guard/redaction.rb +80 -0
- data/lib/datadog/ai_guard.rb +58 -57
- data/lib/datadog/appsec/actions_handler/serializable_backtrace.rb +21 -42
- data/lib/datadog/appsec/api_security/endpoint_collection/grape_route_serializer.rb +1 -1
- data/lib/datadog/appsec/api_security/endpoint_collection/rails_route_serializer.rb +1 -1
- data/lib/datadog/appsec/api_security/endpoint_collection/sinatra_route_serializer.rb +1 -1
- data/lib/datadog/appsec/assets/blocked.html +1 -108
- data/lib/datadog/appsec/configuration.rb +11 -2
- data/lib/datadog/appsec/context.rb +1 -1
- data/lib/datadog/appsec/contrib/active_record/instrumentation.rb +1 -1
- data/lib/datadog/appsec/contrib/aws_lambda/waf_addresses.rb +2 -2
- data/lib/datadog/appsec/contrib/devise/configuration.rb +1 -1
- data/lib/datadog/appsec/contrib/devise/patcher.rb +1 -1
- data/lib/datadog/appsec/contrib/excon/ssrf_detection_middleware.rb +2 -2
- data/lib/datadog/appsec/contrib/faraday/ssrf_detection_middleware.rb +2 -2
- data/lib/datadog/appsec/contrib/graphql/gateway/watcher.rb +1 -1
- data/lib/datadog/appsec/contrib/rack/ext.rb +2 -2
- data/lib/datadog/appsec/contrib/rack/gateway/watcher.rb +2 -2
- data/lib/datadog/appsec/contrib/rack/patcher.rb +1 -1
- data/lib/datadog/appsec/contrib/rack/request_body_middleware.rb +6 -3
- data/lib/datadog/appsec/contrib/rails/gateway/watcher.rb +30 -3
- data/lib/datadog/appsec/contrib/rails/patches/render_to_body_patch.rb +8 -7
- data/lib/datadog/appsec/contrib/rails/request_middleware.rb +2 -1
- data/lib/datadog/appsec/contrib/rest_client/request_ssrf_detection_patch.rb +2 -2
- data/lib/datadog/appsec/contrib/sinatra/gateway/watcher.rb +15 -3
- data/lib/datadog/appsec/contrib/sinatra/patches/json_patch.rb +8 -7
- data/lib/datadog/appsec/contrib/sinatra/request_middleware.rb +2 -1
- data/lib/datadog/appsec/processor/rule_loader.rb +12 -12
- data/lib/datadog/appsec/response.rb +1 -1
- data/lib/datadog/appsec/route_normalizer/route_pattern.rb +3 -3
- data/lib/datadog/appsec/security_engine/engine.rb +5 -4
- data/lib/datadog/core/configuration/components.rb +50 -19
- data/lib/datadog/core/configuration/components_state.rb +8 -1
- data/lib/datadog/core/configuration/option_definition.rb +1 -1
- data/lib/datadog/core/configuration/options.rb +1 -1
- data/lib/datadog/core/configuration/settings.rb +38 -43
- data/lib/datadog/core/configuration/supported_configurations.rb +18 -2
- data/lib/datadog/core/crashtracking/component.rb +5 -1
- data/lib/datadog/core/diagnostics/environment_logger.rb +36 -1
- data/lib/datadog/core/environment/gc.rb +1 -1
- data/lib/datadog/core/environment/vm_cache.rb +1 -1
- data/lib/datadog/core/environment/yjit.rb +2 -2
- data/lib/datadog/core/metrics/helpers.rb +1 -1
- data/lib/datadog/core/metrics/options.rb +2 -2
- data/lib/datadog/core/process_discovery.rb +6 -2
- data/lib/datadog/core/remote/client/capabilities.rb +32 -21
- data/lib/datadog/core/remote/client.rb +45 -4
- data/lib/datadog/core/remote/component.rb +30 -7
- data/lib/datadog/core/remote/configuration/repository.rb +2 -2
- data/lib/datadog/core/remote/dispatcher.rb +47 -6
- data/lib/datadog/core/remote/worker.rb +8 -0
- data/lib/datadog/core/telemetry/configuration_value.rb +38 -0
- data/lib/datadog/core/telemetry/event/app_client_configuration_change.rb +3 -1
- data/lib/datadog/core/telemetry/event/app_endpoints_loaded.rb +1 -1
- data/lib/datadog/core/telemetry/event/app_started.rb +5 -24
- data/lib/datadog/core/telemetry/event/generate_metrics.rb +1 -1
- data/lib/datadog/core/telemetry/event/log.rb +2 -2
- data/lib/datadog/core/telemetry/event/synth_app_client_configuration_change.rb +1 -1
- data/lib/datadog/core/telemetry/metric.rb +2 -2
- data/lib/datadog/core/telemetry/request.rb +2 -2
- data/lib/datadog/core/transport/http.rb +1 -1
- data/lib/datadog/core/transport/transport.rb +1 -1
- data/lib/datadog/core/utils/at_fork_monkey_patch.rb +170 -18
- data/lib/datadog/core/utils/sequence.rb +3 -6
- data/lib/datadog/core/utils/time.rb +16 -54
- data/lib/datadog/core/workers/runtime_metrics.rb +1 -1
- data/lib/datadog/data_streams/pathway_context.rb +20 -22
- data/lib/datadog/data_streams/processor.rb +45 -14
- data/lib/datadog/di/boot.rb +1 -0
- data/lib/datadog/di/capture_expression_evaluator/result.rb +30 -0
- data/lib/datadog/di/capture_expression_evaluator.rb +39 -9
- data/lib/datadog/di/component.rb +108 -3
- data/lib/datadog/di/configuration.rb +53 -2
- data/lib/datadog/di/context.rb +7 -2
- data/lib/datadog/di/contrib/active_record.rb +8 -2
- data/lib/datadog/di/el/compiler.rb +88 -12
- data/lib/datadog/di/el/evaluator.rb +82 -2
- data/lib/datadog/di/el/expression.rb +13 -2
- data/lib/datadog/di/evaluation_failure.rb +28 -0
- data/lib/datadog/di/guardrails_telemetry/reason.rb +87 -0
- data/lib/datadog/di/guardrails_telemetry.rb +203 -0
- data/lib/datadog/di/instrumenter.rb +106 -15
- data/lib/datadog/di/logger.rb +32 -10
- data/lib/datadog/di/probe.rb +9 -1
- data/lib/datadog/di/probe_builder.rb +7 -6
- data/lib/datadog/di/probe_manager.rb +56 -8
- data/lib/datadog/di/probe_notification_builder.rb +31 -28
- data/lib/datadog/di/probe_notifier_worker.rb +56 -6
- data/lib/datadog/di/proc_responder.rb +1 -1
- data/lib/datadog/di/remote.rb +49 -5
- data/lib/datadog/di/serializer.rb +172 -55
- data/lib/datadog/di/snapshot_event.rb +38 -0
- data/lib/datadog/di/transport/http.rb +13 -3
- data/lib/datadog/di/transport/input.rb +32 -7
- data/lib/datadog/error_tracking/component.rb +1 -1
- data/lib/datadog/kit/appsec/events/v2.rb +2 -2
- data/lib/datadog/open_feature/activation.rb +268 -0
- data/lib/datadog/open_feature/agentless/configuration_source.rb +246 -0
- data/lib/datadog/open_feature/agentless/parser.rb +43 -0
- data/lib/datadog/open_feature/agentless/response.rb +19 -0
- data/lib/datadog/open_feature/agentless/transport.rb +103 -0
- data/lib/datadog/open_feature/component.rb +85 -13
- data/lib/datadog/open_feature/configuration/agentless_endpoint.rb +90 -0
- data/lib/datadog/open_feature/configuration/source/resolution.rb +22 -0
- data/lib/datadog/open_feature/configuration/source.rb +43 -0
- data/lib/datadog/open_feature/configuration.rb +124 -0
- data/lib/datadog/open_feature/evaluation_engine.rb +29 -3
- data/lib/datadog/open_feature/exposures/batch_builder.rb +1 -1
- data/lib/datadog/open_feature/exposures/event.rb +15 -8
- data/lib/datadog/open_feature/ext.rb +19 -0
- data/lib/datadog/open_feature/flag_evaluation/aggregator.rb +236 -80
- data/lib/datadog/open_feature/flag_evaluation/writer.rb +179 -68
- data/lib/datadog/open_feature/hooks/evaluation_telemetry_opt_out_hook.rb +25 -0
- data/lib/datadog/open_feature/hooks/flag_eval_evp_hook.rb +24 -21
- data/lib/datadog/open_feature/native_evaluator.rb +20 -6
- data/lib/datadog/open_feature/noop_evaluator.rb +5 -0
- data/lib/datadog/open_feature/provider.rb +315 -10
- data/lib/datadog/open_feature/remote.rb +5 -5
- data/lib/datadog/open_feature/transport.rb +5 -0
- data/lib/datadog/open_feature.rb +31 -1
- data/lib/datadog/opentelemetry/sdk/propagator.rb +1 -1
- data/lib/datadog/opentelemetry/signal_configuration.rb +13 -9
- data/lib/datadog/opentelemetry/trace.rb +3 -0
- data/lib/datadog/profiling/collectors/cpu_and_wall_time_worker.rb +10 -2
- data/lib/datadog/profiling/collectors/idle_sampling_helper.rb +5 -7
- data/lib/datadog/profiling/collectors/info.rb +40 -13
- data/lib/datadog/profiling/collectors/thread_context.rb +6 -17
- data/lib/datadog/profiling/component.rb +33 -39
- data/lib/datadog/profiling/exporter.rb +10 -10
- data/lib/datadog/profiling/tasks/exec.rb +1 -1
- data/lib/datadog/profiling.rb +4 -0
- data/lib/datadog/symbol_database/extractor.rb +89 -107
- data/lib/datadog/tracing/component.rb +44 -2
- data/lib/datadog/tracing/configuration/dynamic/option.rb +4 -0
- data/lib/datadog/tracing/configuration/dynamic.rb +5 -3
- data/lib/datadog/tracing/configuration/ext.rb +4 -0
- data/lib/datadog/tracing/configuration/settings.rb +36 -0
- data/lib/datadog/tracing/context.rb +24 -2
- data/lib/datadog/tracing/context_provider.rb +17 -5
- data/lib/datadog/tracing/contrib/action_cable/events.rb +1 -1
- data/lib/datadog/tracing/contrib/action_mailer/events.rb +1 -1
- data/lib/datadog/tracing/contrib/action_pack/action_controller/instrumentation.rb +2 -2
- data/lib/datadog/tracing/contrib/action_view/events.rb +1 -1
- data/lib/datadog/tracing/contrib/active_model_serializers/events.rb +1 -1
- data/lib/datadog/tracing/contrib/active_record/configuration/resolver.rb +1 -1
- data/lib/datadog/tracing/contrib/active_record/events/sql.rb +1 -0
- data/lib/datadog/tracing/contrib/active_record/events.rb +1 -1
- data/lib/datadog/tracing/contrib/active_support/cache/events/cache.rb +2 -2
- data/lib/datadog/tracing/contrib/aws/ext.rb +1 -1
- data/lib/datadog/tracing/contrib/aws/services.rb +1 -1
- data/lib/datadog/tracing/contrib/elasticsearch/quantize.rb +1 -1
- data/lib/datadog/tracing/contrib/ethon/easy_patch.rb +10 -5
- data/lib/datadog/tracing/contrib/excon/middleware.rb +10 -3
- data/lib/datadog/tracing/contrib/ext.rb +3 -3
- data/lib/datadog/tracing/contrib/faraday/middleware.rb +10 -4
- data/lib/datadog/tracing/contrib/grape/endpoint.rb +32 -5
- data/lib/datadog/tracing/contrib/grpc/datadog_interceptor/client.rb +1 -1
- data/lib/datadog/tracing/contrib/grpc/datadog_interceptor/server.rb +1 -1
- data/lib/datadog/tracing/contrib/grpc/distributed/propagation.rb +1 -1
- data/lib/datadog/tracing/contrib/hanami/router_tracing.rb +2 -1
- data/lib/datadog/tracing/contrib/http/instrumentation.rb +16 -1
- data/lib/datadog/tracing/contrib/httpclient/instrumentation.rb +8 -2
- data/lib/datadog/tracing/contrib/httprb/instrumentation.rb +10 -4
- data/lib/datadog/tracing/contrib/kafka/events/connection/request.rb +4 -0
- data/lib/datadog/tracing/contrib/kafka/events/produce_operation/send_messages.rb +7 -2
- data/lib/datadog/tracing/contrib/kafka/events/producer/deliver_messages.rb +7 -2
- data/lib/datadog/tracing/contrib/kafka/events.rb +1 -1
- data/lib/datadog/tracing/contrib/karafka/distributed/propagation.rb +1 -1
- data/lib/datadog/tracing/contrib/mongodb/parsers.rb +1 -1
- data/lib/datadog/tracing/contrib/opensearch/ext.rb +1 -1
- data/lib/datadog/tracing/contrib/opensearch/quantize.rb +1 -1
- data/lib/datadog/tracing/contrib/patchable.rb +1 -1
- data/lib/datadog/tracing/contrib/patcher.rb +1 -1
- data/lib/datadog/tracing/contrib/que/tracer.rb +1 -1
- data/lib/datadog/tracing/contrib/racecar/events.rb +1 -1
- data/lib/datadog/tracing/contrib/rack/configuration/settings.rb +1 -1
- data/lib/datadog/tracing/contrib/rack/header_tagging.rb +1 -1
- data/lib/datadog/tracing/contrib/rack/patcher.rb +1 -1
- data/lib/datadog/tracing/contrib/rack/trace_proxy_middleware.rb +1 -1
- data/lib/datadog/tracing/contrib/redis/configuration/resolver.rb +1 -1
- data/lib/datadog/tracing/contrib/redis/quantize.rb +36 -2
- data/lib/datadog/tracing/contrib/redis/trace_middleware.rb +9 -3
- data/lib/datadog/tracing/contrib/rest_client/request_patch.rb +10 -3
- data/lib/datadog/tracing/contrib/sequel/database.rb +1 -5
- data/lib/datadog/tracing/contrib/sequel/jdbc_connection_string.rb +140 -0
- data/lib/datadog/tracing/contrib/sequel/utils.rb +50 -63
- data/lib/datadog/tracing/contrib/sidekiq/distributed/propagation.rb +1 -1
- data/lib/datadog/tracing/contrib/sinatra/configuration/settings.rb +1 -1
- data/lib/datadog/tracing/contrib/sneakers/tracer.rb +1 -1
- data/lib/datadog/tracing/contrib/utils/quantization/hash_formatter.rb +1 -1
- data/lib/datadog/tracing/contrib/utils/quantization/http.rb +108 -3
- data/lib/datadog/tracing/contrib/waterdrop/distributed/propagation.rb +1 -1
- data/lib/datadog/tracing/correlation.rb +2 -2
- data/lib/datadog/tracing/diagnostics/environment_logger.rb +3 -2
- data/lib/datadog/tracing/distributed/baggage.rb +1 -3
- data/lib/datadog/tracing/distributed/datadog.rb +3 -3
- data/lib/datadog/tracing/distributed/propagation.rb +3 -0
- data/lib/datadog/tracing/distributed/propagation_policy.rb +5 -0
- data/lib/datadog/tracing/distributed/trace_context.rb +14 -271
- data/lib/datadog/tracing/distributed/trace_state/datadog.rb +233 -0
- data/lib/datadog/tracing/distributed/trace_state/ext.rb +44 -0
- data/lib/datadog/tracing/distributed/trace_state/open_telemetry.rb +156 -0
- data/lib/datadog/tracing/distributed/trace_state.rb +121 -0
- data/lib/datadog/tracing/metadata/ext.rb +3 -0
- data/lib/datadog/tracing/metadata/tagging.rb +1 -1
- data/lib/datadog/tracing/otel_thread_context.rb +97 -0
- data/lib/datadog/tracing/remote.rb +236 -37
- data/lib/datadog/tracing/sampling/rule_sampler.rb +2 -0
- data/lib/datadog/tracing/span.rb +1 -1
- data/lib/datadog/tracing/span_operation.rb +1 -1
- data/lib/datadog/tracing/sync_writer.rb +8 -3
- data/lib/datadog/tracing/trace_digest.rb +22 -4
- data/lib/datadog/tracing/trace_operation.rb +22 -10
- data/lib/datadog/tracing/tracer.rb +28 -7
- data/lib/datadog/tracing/transport/http/telemetry.rb +94 -0
- data/lib/datadog/tracing/transport/http/traces.rb +2 -0
- data/lib/datadog/tracing/transport/io/traces.rb +1 -1
- data/lib/datadog/tracing/transport/native/response.rb +71 -0
- data/lib/datadog/tracing/transport/native/telemetry.rb +17 -0
- data/lib/datadog/tracing/transport/native.rb +395 -0
- data/lib/datadog/tracing/transport/span_events_negotiation.rb +41 -0
- data/lib/datadog/tracing/transport/telemetry.rb +62 -0
- data/lib/datadog/tracing/transport/trace_formatter.rb +14 -4
- data/lib/datadog/tracing/transport/traces.rb +85 -38
- data/lib/datadog/tracing/writer.rb +17 -4
- data/lib/datadog/version.rb +1 -1
- metadata +51 -13
- data/lib/datadog/ai_guard/evaluation/content_builder.rb +0 -31
- data/lib/datadog/appsec/utils/hash_coercion.rb +0 -23
- data/lib/datadog/tracing/distributed/datadog_tags_codec.rb +0 -69
|
@@ -15,52 +15,265 @@ module Datadog
|
|
|
15
15
|
1 << 13, # APM_TRACING_LOGS_INJECTION: Dynamic trace logs injection configuration
|
|
16
16
|
1 << 14, # APM_TRACING_HTTP_HEADER_TAGS: Dynamic trace HTTP header tags configuration
|
|
17
17
|
1 << 29, # APM_TRACING_SAMPLE_RULES: Dynamic trace sampling rules configuration
|
|
18
|
+
1 << 45, # APM_TRACING_MULTICONFIG: merge multiple org/env-level APM_TRACING configs
|
|
18
19
|
# APM_TRACING_ENABLE_DYNAMIC_INSTRUMENTATION (bit 38) is declared in
|
|
19
20
|
# DI::Remote.capabilities, not here, so it is registered only when DI
|
|
20
21
|
# is not explicitly disabled and the runtime supports DI.
|
|
21
22
|
].freeze
|
|
22
23
|
|
|
24
|
+
# Diagnostic scope label per specificity priority.
|
|
25
|
+
SCOPE_LABELS = {
|
|
26
|
+
5 => "service+env",
|
|
27
|
+
4 => "service",
|
|
28
|
+
3 => "env",
|
|
29
|
+
2 => "cluster",
|
|
30
|
+
1 => "org",
|
|
31
|
+
}.freeze
|
|
32
|
+
|
|
33
|
+
# @return [Array[String]] the remote config products this module handles
|
|
23
34
|
def products
|
|
24
35
|
[PRODUCT]
|
|
25
36
|
end
|
|
26
37
|
|
|
38
|
+
# @return [Array[Integer]] the remote config capability bits advertised
|
|
27
39
|
def capabilities
|
|
28
40
|
CAPABILITIES
|
|
29
41
|
end
|
|
30
42
|
|
|
31
|
-
|
|
32
|
-
|
|
43
|
+
# Merges every active APM_TRACING config in the repository and applies the
|
|
44
|
+
# result once. Org/env-level (multi-config) remote enablement delivers
|
|
45
|
+
# several APM_TRACING configs in parallel (a (service, env)-specific one,
|
|
46
|
+
# an env-wide one, and/or an org-wide "*" one); for each lib_config field
|
|
47
|
+
# the value from the most-specific matching config wins. The RC repository
|
|
48
|
+
# prunes deleted configs, so this recomputes the merge from the repository's
|
|
49
|
+
# current contents on each dispatch.
|
|
50
|
+
#
|
|
51
|
+
# @param repository [Core::Remote::Configuration::Repository] the current RC repository
|
|
52
|
+
# @return [nil]
|
|
53
|
+
def merge_and_apply_configs(repository)
|
|
54
|
+
# Resolve the service identity the same way the RC client registers
|
|
55
|
+
# it with the backend (Core::Remote::Client#service_name =
|
|
56
|
+
# remote.service || service). When a customer sets remote.service,
|
|
57
|
+
# the backend delivers service_target.service values targeting that
|
|
58
|
+
# override; matching against the local service instead would drop
|
|
59
|
+
# every service-scoped config and let a less-specific org config win.
|
|
60
|
+
service = Datadog.configuration.remote.service || Datadog.configuration.service
|
|
61
|
+
env = Datadog.configuration.env
|
|
62
|
+
|
|
63
|
+
# @type var parsed: Array[[::Datadog::Core::Remote::Configuration::Content, ::Hash[::String, untyped]]]
|
|
64
|
+
parsed = []
|
|
65
|
+
# @type var unparseable_contents: Array[Datadog::Core::Remote::Configuration::Content]
|
|
66
|
+
unparseable_contents = []
|
|
67
|
+
repository.contents.each do |content|
|
|
68
|
+
next unless content.path.product == PRODUCT
|
|
69
|
+
|
|
70
|
+
begin
|
|
71
|
+
config = parse_content(content)
|
|
72
|
+
unless config.is_a?(Hash)
|
|
73
|
+
# A syntactically valid but non-object payload (null, [], 42)
|
|
74
|
+
# would later make config_matches? raise outside this per-content
|
|
75
|
+
# rescue and abort the whole merge, erroring valid configs too.
|
|
76
|
+
raise TypeError, "APM_TRACING remote config must be a JSON object, got #{config.class}"
|
|
77
|
+
end
|
|
78
|
+
# A present but non-object lib_config (e.g. {"lib_config": []}) is a
|
|
79
|
+
# schema violation the customer can fix. Acknowledging it as applied
|
|
80
|
+
# would tell the backend the config was successfully applied when it
|
|
81
|
+
# was not. Reject it per content so the malformed payload is
|
|
82
|
+
# reported errored instead. A null or absent lib_config
|
|
83
|
+
# carries no overrides and is left as a no-op.
|
|
84
|
+
lib_config = config["lib_config"]
|
|
85
|
+
if !lib_config.nil? && !lib_config.is_a?(Hash)
|
|
86
|
+
raise TypeError, "APM_TRACING lib_config must be a JSON object, got #{lib_config.class}"
|
|
87
|
+
end
|
|
88
|
+
parsed << [content, config]
|
|
89
|
+
rescue => e
|
|
90
|
+
Datadog.logger.debug { "APM_TRACING RC: skipping unparseable config: #{e.class}: #{e.message}" }
|
|
91
|
+
Datadog.send(:components, allow_initialization: false)&.telemetry&.report(
|
|
92
|
+
e,
|
|
93
|
+
description: "Failed to parse APM_TRACING remote config",
|
|
94
|
+
)
|
|
95
|
+
content.errored("#{e.class}: #{e.message}: #{Array(e.backtrace).join("\n")}")
|
|
96
|
+
unparseable_contents << content
|
|
97
|
+
end
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
Datadog.logger.debug { "APM_TRACING RC: received #{parsed.length} config(s)" }
|
|
101
|
+
|
|
102
|
+
applicable = parsed.select do |content, config|
|
|
103
|
+
if config_matches?(config, service, env)
|
|
104
|
+
Datadog.logger.debug do
|
|
105
|
+
"APM_TRACING RC: config #{content.path.config_id} " \
|
|
106
|
+
"scope=#{SCOPE_LABELS[config_priority(config)]} priority=#{config_priority(config)}"
|
|
107
|
+
end
|
|
108
|
+
true
|
|
109
|
+
else
|
|
110
|
+
Datadog.logger.debug do
|
|
111
|
+
"APM_TRACING RC: dropped config #{content.path.config_id} " \
|
|
112
|
+
"(service_target=#{config["service_target"].inspect}, self=#{service}/#{env})"
|
|
113
|
+
end
|
|
114
|
+
false
|
|
115
|
+
end
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
# Most-specific first; ties broken by config id (ascending) for a
|
|
119
|
+
# deterministic merge.
|
|
120
|
+
ordered = applicable.sort_by { |content, config| [-config_priority(config), content.path.config_id] }
|
|
121
|
+
merged = merge_lib_configs(ordered.map { |_content, config| config })
|
|
122
|
+
# The applicable configs carrying a non-null dynamic_instrumentation_enabled
|
|
123
|
+
# value: any of their paths can still supply the signal after a later
|
|
124
|
+
# replacement, so the DI component records them all.
|
|
125
|
+
# @type var enable_signal_paths: Array[Datadog::Core::Remote::Configuration::Path]
|
|
126
|
+
enable_signal_paths = Core::Utils::EnumerableCompat.filter_map(ordered) do |pair|
|
|
127
|
+
content, config = pair
|
|
128
|
+
lib_config = config["lib_config"]
|
|
129
|
+
if lib_config.is_a?(Hash) && !lib_config["dynamic_instrumentation_enabled"].nil?
|
|
130
|
+
content.path
|
|
131
|
+
end
|
|
132
|
+
end
|
|
133
|
+
|
|
134
|
+
# Applied even when the set is empty: an emptied repository (last config
|
|
135
|
+
# removed) reverts the tracing overrides to their non-RC values.
|
|
136
|
+
apply_lib_config(
|
|
137
|
+
merged,
|
|
138
|
+
repository,
|
|
139
|
+
unparseable_contents: unparseable_contents,
|
|
140
|
+
enable_signal_paths: enable_signal_paths,
|
|
141
|
+
)
|
|
142
|
+
|
|
143
|
+
parsed.each { |content, _config| content.applied }
|
|
144
|
+
nil
|
|
145
|
+
rescue => e
|
|
146
|
+
Datadog.logger.debug { "APM_TRACING RC: failed to apply configs: #{e.class}: #{e.message}" }
|
|
147
|
+
Datadog.send(:components, allow_initialization: false)&.telemetry&.report(
|
|
148
|
+
e,
|
|
149
|
+
description: "Failed to apply APM_TRACING remote configs",
|
|
150
|
+
)
|
|
151
|
+
parsed&.each do |content, _config|
|
|
152
|
+
content.errored("#{e.class}: #{e.message}: #{Array(e.backtrace).join("\n")}")
|
|
153
|
+
end
|
|
154
|
+
nil
|
|
155
|
+
end
|
|
156
|
+
|
|
157
|
+
# Whether a config targets this tracer. A concrete (non-"*") service or
|
|
158
|
+
# env that differs from ours excludes the config; "*" and an absent
|
|
159
|
+
# service_target match anything.
|
|
160
|
+
#
|
|
161
|
+
# @param config [Hash[String, untyped]] a parsed config
|
|
162
|
+
# @param service [String, nil] this tracer's service
|
|
163
|
+
# @param env [String, nil] this tracer's env
|
|
164
|
+
# @return [bool] true when the config applies to this tracer
|
|
165
|
+
def config_matches?(config, service, env)
|
|
166
|
+
target = config["service_target"]
|
|
167
|
+
return true unless target.is_a?(Hash)
|
|
33
168
|
|
|
169
|
+
target_service = target["service"]
|
|
170
|
+
target_env = target["env"]
|
|
171
|
+
return false if target_service && target_service != "*" && target_service != service
|
|
172
|
+
return false if target_env && target_env != "*" && target_env != env
|
|
173
|
+
|
|
174
|
+
true
|
|
175
|
+
end
|
|
176
|
+
|
|
177
|
+
# Specificity of a config, higher meaning more specific: service+env (5),
|
|
178
|
+
# service (4), env (3), cluster (2), org (1). A target counts as concrete
|
|
179
|
+
# only when present and not "*".
|
|
180
|
+
#
|
|
181
|
+
# @param config [Hash[String, untyped]] a parsed config
|
|
182
|
+
# @return [Integer] the specificity rank, 1 through 5
|
|
183
|
+
def config_priority(config)
|
|
184
|
+
target = config["service_target"]
|
|
185
|
+
service = target.is_a?(Hash) ? target["service"] : nil
|
|
186
|
+
env = target.is_a?(Hash) ? target["env"] : nil
|
|
187
|
+
single_service = !service.nil? && service != "*"
|
|
188
|
+
single_env = !env.nil? && env != "*"
|
|
189
|
+
|
|
190
|
+
return 5 if single_service && single_env
|
|
191
|
+
return 4 if single_service
|
|
192
|
+
return 3 if single_env
|
|
193
|
+
return 2 unless config["k8s_target_v2"].nil?
|
|
194
|
+
|
|
195
|
+
1
|
|
196
|
+
end
|
|
197
|
+
|
|
198
|
+
# Merges lib_configs from configs ordered most-specific first: for each
|
|
199
|
+
# field, the first (most-specific) non-nil value wins. Fields are
|
|
200
|
+
# independent, so a lower-priority config can supply a field the
|
|
201
|
+
# higher-priority one omits.
|
|
202
|
+
#
|
|
203
|
+
# @param configs_most_specific_first [Array[Hash[String, untyped]]] configs, most-specific first
|
|
204
|
+
# @return [Hash[String, untyped]] the merged lib_config
|
|
205
|
+
def merge_lib_configs(configs_most_specific_first)
|
|
206
|
+
merged = {}
|
|
207
|
+
configs_most_specific_first.each do |config|
|
|
208
|
+
lib_config = config["lib_config"]
|
|
209
|
+
next unless lib_config.is_a?(Hash)
|
|
210
|
+
|
|
211
|
+
lib_config.each do |key, value|
|
|
212
|
+
next if value.nil?
|
|
213
|
+
|
|
214
|
+
merged[key] = value unless merged.key?(key)
|
|
215
|
+
end
|
|
216
|
+
end
|
|
217
|
+
merged
|
|
218
|
+
end
|
|
219
|
+
|
|
220
|
+
# Applies one lib_config: maps the dynamic OPTIONS to telemetry, drives DI
|
|
221
|
+
# enablement from "dynamic_instrumentation_enabled", and reports the
|
|
222
|
+
# configuration change to telemetry.
|
|
223
|
+
#
|
|
224
|
+
# @param lib_config [Hash[String, untyped]] the lib_config to apply
|
|
225
|
+
# @param repository [Core::Remote::Configuration::Repository, nil] forwarded to DI enablement
|
|
226
|
+
# @param unparseable_contents [Array<Core::Remote::Configuration::Content>] the APM_TRACING contents that failed to parse
|
|
227
|
+
# @param enable_signal_paths [Array<Core::Remote::Configuration::Path>] the paths of the applicable configs carrying the field
|
|
228
|
+
# @return [nil]
|
|
229
|
+
def apply_lib_config(lib_config, repository, unparseable_contents:, enable_signal_paths:)
|
|
34
230
|
env_vars = Datadog::Tracing::Configuration::Dynamic::OPTIONS.map do |name, env_var, option|
|
|
35
231
|
value = lib_config[name]
|
|
36
232
|
|
|
37
233
|
# Guard for RBS/Steep
|
|
38
234
|
raise "option is a #{option.class}, expected Option" unless option.is_a?(Configuration::Dynamic::Option)
|
|
39
235
|
|
|
40
|
-
option.call(value)
|
|
236
|
+
telemetry_value = option.call(value)
|
|
237
|
+
|
|
238
|
+
[env_var, telemetry_value]
|
|
239
|
+
end
|
|
240
|
+
|
|
241
|
+
di_enabled = lib_config["dynamic_instrumentation_enabled"]
|
|
242
|
+
# allow_initialization: false because this runs on the remote-config worker
|
|
243
|
+
# thread, and the default would build the component tree from that thread.
|
|
244
|
+
components = Datadog.send(:components, allow_initialization: false)
|
|
245
|
+
di_component = components&.dynamic_instrumentation
|
|
246
|
+
if di_enabled.nil? && di_component&.rc_enablement_signal_withdrawn?(unparseable_contents)
|
|
247
|
+
di_enabled = false
|
|
248
|
+
end
|
|
41
249
|
|
|
42
|
-
|
|
250
|
+
# Records the parsed carrier paths and the previously recorded paths whose
|
|
251
|
+
# replacements remain unparseable, on every merge including merges that keep
|
|
252
|
+
# the DI state.
|
|
253
|
+
if di_component
|
|
254
|
+
unparseable_recorded_paths = di_component.rc_enablement_signal_paths.select do |path|
|
|
255
|
+
unparseable_contents.any? { |content| content.path == path }
|
|
256
|
+
end
|
|
257
|
+
di_component.record_rc_enablement_signal_paths(enable_signal_paths + unparseable_recorded_paths)
|
|
43
258
|
end
|
|
44
259
|
|
|
45
|
-
|
|
46
|
-
# repository is forwarded
|
|
47
|
-
#
|
|
48
|
-
# (see Datadog::DI::Remote.handle_rc_enablement).
|
|
260
|
+
unless di_enabled.nil?
|
|
261
|
+
# repository is forwarded for the stopped->started replay in
|
|
262
|
+
# Datadog::DI::Remote.handle_rc_enablement.
|
|
49
263
|
Datadog::DI::Remote.handle_rc_enablement(di_enabled, repository)
|
|
50
264
|
|
|
51
|
-
components = Datadog.send(:components, allow_initialization: false)
|
|
52
265
|
di_products = Datadog::DI::Remote.products +
|
|
53
266
|
Datadog::SymbolDatabase::Remote.deferred_products(Datadog.configuration)
|
|
54
267
|
|
|
55
268
|
if di_enabled
|
|
56
269
|
components&.symbol_database&.resume_pending_upload
|
|
57
270
|
# Advertise the DI products only if the component actually started.
|
|
58
|
-
# handle_rc_enablement above no-ops when DI cannot run
|
|
59
|
-
#
|
|
60
|
-
#
|
|
61
|
-
#
|
|
62
|
-
#
|
|
63
|
-
if
|
|
271
|
+
# handle_rc_enablement above no-ops when DI cannot run: the component
|
|
272
|
+
# is nil on an unsupported runtime, or the enable signal is blocked
|
|
273
|
+
# by DD_DYNAMIC_INSTRUMENTATION_ENABLED=false. Advertising then would
|
|
274
|
+
# report DI as in use when it is not and invite probe configs the
|
|
275
|
+
# tracer must refuse; withdraw the products otherwise.
|
|
276
|
+
if di_component&.started?
|
|
64
277
|
components&.remote&.add_products(*di_products)
|
|
65
278
|
else
|
|
66
279
|
components&.remote&.remove_products(*di_products)
|
|
@@ -69,39 +282,25 @@ module Datadog
|
|
|
69
282
|
components&.symbol_database&.stop_for_di_disable
|
|
70
283
|
components&.remote&.remove_products(*di_products)
|
|
71
284
|
end
|
|
72
|
-
end
|
|
73
285
|
|
|
74
|
-
|
|
286
|
+
Datadog.logger.debug { "APM_TRACING RC: merged dynamic_instrumentation_enabled=#{di_enabled}" }
|
|
287
|
+
end
|
|
75
288
|
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
# (e.g. during a teardown/reset window), the default `true` would
|
|
79
|
-
# synchronously build the entire component tree from this thread.
|
|
80
|
-
# The &. chain matches the pattern used by DI::Remote.handle_rc_enablement
|
|
81
|
-
# in the same dispatch path.
|
|
82
|
-
Datadog.send(:components, allow_initialization: false)&.telemetry&.client_configuration_change!(env_vars)
|
|
83
|
-
rescue => e
|
|
84
|
-
content.errored("#{e.class}: #{e.message}: #{Array(e.backtrace).join("\n")}")
|
|
289
|
+
components&.telemetry&.client_configuration_change!(env_vars)
|
|
290
|
+
nil
|
|
85
291
|
end
|
|
86
292
|
|
|
293
|
+
# @param _telemetry [Core::Telemetry::Component] unused; kept for the receiver contract
|
|
294
|
+
# @return [Array[Core::Remote::Dispatcher::Receiver]] the APM_TRACING receiver
|
|
87
295
|
def receivers(_telemetry)
|
|
88
296
|
receiver do |repository, _changes|
|
|
89
|
-
|
|
90
|
-
# DEV: we can filter this out before we receive the data in this method.
|
|
91
|
-
# DEV: Apply this refactor to AppSec as well if implemented.
|
|
92
|
-
repository.contents.map do |content|
|
|
93
|
-
case content.path.product
|
|
94
|
-
when PRODUCT
|
|
95
|
-
config = parse_content(content)
|
|
96
|
-
process_config(config, content, repository)
|
|
97
|
-
end
|
|
98
|
-
end
|
|
297
|
+
merge_and_apply_configs(repository)
|
|
99
298
|
end
|
|
100
299
|
end
|
|
101
300
|
|
|
102
301
|
def receiver(products = [PRODUCT], &block)
|
|
103
302
|
matcher = Core::Remote::Dispatcher::Matcher::Product.new(products)
|
|
104
|
-
[Core::Remote::Dispatcher::Receiver.new(matcher, &block)]
|
|
303
|
+
[Core::Remote::Dispatcher::Receiver.new(matcher, initial_reconcile: true, &block)]
|
|
105
304
|
end
|
|
106
305
|
|
|
107
306
|
private
|
|
@@ -192,6 +192,8 @@ module Datadog
|
|
|
192
192
|
|
|
193
193
|
def reconsider_matching_rule!(trace, rule)
|
|
194
194
|
trace.agent_sample_rate = nil
|
|
195
|
+
# Avoid mistaking a reconsidered probabilistic drop for a limiter drop.
|
|
196
|
+
trace.rate_limiter_rate = nil
|
|
195
197
|
trace.clear_tag(Tracing::Metadata::Ext::Distributed::TAG_DECISION_MAKER)
|
|
196
198
|
apply_rule!(trace, rule)
|
|
197
199
|
end
|
data/lib/datadog/tracing/span.rb
CHANGED
|
@@ -46,10 +46,15 @@ module Datadog
|
|
|
46
46
|
logger.debug(e)
|
|
47
47
|
end
|
|
48
48
|
|
|
49
|
-
#
|
|
50
|
-
# The {SyncWriter}
|
|
49
|
+
# Stops the {SyncWriter}.
|
|
50
|
+
# The {SyncWriter} holds no worker thread, but it owns its transport, so
|
|
51
|
+
# on teardown we deterministically release transports that hold native
|
|
52
|
+
# resources (e.g. the native trace exporter's Rust runtime and
|
|
53
|
+
# process-global fork hooks) rather than relying on the GC finalizer.
|
|
54
|
+
# The default HTTP transport has no `#close` and is left untouched, and
|
|
55
|
+
# `#close` is idempotent so repeated `#stop` calls are safe.
|
|
51
56
|
def stop
|
|
52
|
-
|
|
57
|
+
@transport.close if @transport.respond_to?(:close)
|
|
53
58
|
true
|
|
54
59
|
end
|
|
55
60
|
|
|
@@ -72,10 +72,7 @@ module Datadog
|
|
|
72
72
|
# @return [Integer]
|
|
73
73
|
# @see https://www.w3.org/TR/trace-context/#trace-flags
|
|
74
74
|
# @!attribute [r] trace_state
|
|
75
|
-
#
|
|
76
|
-
# This field is a string representing vendor-specific distribution data.
|
|
77
|
-
# The `dd=` entry is removed from `trace_state` as its value is dynamically calculated
|
|
78
|
-
# on every propagation injection.
|
|
75
|
+
# W3C "tracestate" members other than `dd=` and `ot=`, which are stored in parsed fields.
|
|
79
76
|
# @return [String]
|
|
80
77
|
# @see https://www.w3.org/TR/trace-context/#tracestate-header
|
|
81
78
|
# @!attribute [r] trace_state_unknown_fields
|
|
@@ -83,6 +80,15 @@ module Datadog
|
|
|
83
80
|
# This allows later propagation to include those unknown fields, as they can represent future versions of the spec
|
|
84
81
|
# sending data through this service. This value ends in a trailing `;` to facilitate serialization.
|
|
85
82
|
# @return [String]
|
|
83
|
+
# @!attribute [r] trace_otel_random_value
|
|
84
|
+
# OpenTelemetry consistent probability sampling random value.
|
|
85
|
+
# @return [String]
|
|
86
|
+
# @!attribute [r] trace_otel_threshold
|
|
87
|
+
# OpenTelemetry consistent probability sampling threshold.
|
|
88
|
+
# @return [String]
|
|
89
|
+
# @!attribute [r] trace_otel_unknown_fields
|
|
90
|
+
# Unrecognized `ot=` fields, retained with a trailing `;` for propagation.
|
|
91
|
+
# @return [String]
|
|
86
92
|
# @!attribute [r] baggage
|
|
87
93
|
# The W3C "baggage" extracted from a distributed context. This field is a hash of key/value pairs.
|
|
88
94
|
# @return [Hash<String,String>]
|
|
@@ -109,6 +115,9 @@ module Datadog
|
|
|
109
115
|
:trace_flags,
|
|
110
116
|
:trace_state,
|
|
111
117
|
:trace_state_unknown_fields,
|
|
118
|
+
:trace_otel_random_value,
|
|
119
|
+
:trace_otel_threshold,
|
|
120
|
+
:trace_otel_unknown_fields,
|
|
112
121
|
:span_remote,
|
|
113
122
|
:baggage
|
|
114
123
|
|
|
@@ -133,6 +142,9 @@ module Datadog
|
|
|
133
142
|
trace_flags: nil,
|
|
134
143
|
trace_state: nil,
|
|
135
144
|
trace_state_unknown_fields: nil,
|
|
145
|
+
trace_otel_random_value: nil,
|
|
146
|
+
trace_otel_threshold: nil,
|
|
147
|
+
trace_otel_unknown_fields: nil,
|
|
136
148
|
span_remote: true,
|
|
137
149
|
baggage: nil
|
|
138
150
|
)
|
|
@@ -156,6 +168,9 @@ module Datadog
|
|
|
156
168
|
@trace_flags = trace_flags
|
|
157
169
|
@trace_state = trace_state && trace_state.dup.freeze
|
|
158
170
|
@trace_state_unknown_fields = trace_state_unknown_fields && trace_state_unknown_fields.dup.freeze
|
|
171
|
+
@trace_otel_random_value = trace_otel_random_value && trace_otel_random_value.dup.freeze
|
|
172
|
+
@trace_otel_threshold = trace_otel_threshold && trace_otel_threshold.dup.freeze
|
|
173
|
+
@trace_otel_unknown_fields = trace_otel_unknown_fields && trace_otel_unknown_fields.dup.freeze
|
|
159
174
|
@span_remote = span_remote
|
|
160
175
|
@baggage = baggage && baggage.dup.freeze
|
|
161
176
|
freeze
|
|
@@ -188,6 +203,9 @@ module Datadog
|
|
|
188
203
|
trace_flags: trace_flags,
|
|
189
204
|
trace_state: trace_state,
|
|
190
205
|
trace_state_unknown_fields: trace_state_unknown_fields,
|
|
206
|
+
trace_otel_random_value: trace_otel_random_value,
|
|
207
|
+
trace_otel_threshold: trace_otel_threshold,
|
|
208
|
+
trace_otel_unknown_fields: trace_otel_unknown_fields,
|
|
191
209
|
span_remote: span_remote,
|
|
192
210
|
baggage: baggage, **field_value_pairs
|
|
193
211
|
)
|
|
@@ -5,6 +5,7 @@ require_relative "../core/utils"
|
|
|
5
5
|
require_relative "event"
|
|
6
6
|
require_relative "metadata/tagging"
|
|
7
7
|
require_relative "sampling/ext"
|
|
8
|
+
require_relative "distributed/trace_state"
|
|
8
9
|
require_relative "span_operation"
|
|
9
10
|
require_relative "trace_digest"
|
|
10
11
|
require_relative "correlation"
|
|
@@ -48,8 +49,7 @@ module Datadog
|
|
|
48
49
|
:id,
|
|
49
50
|
:max_length,
|
|
50
51
|
:parent_span_id,
|
|
51
|
-
:trace_state
|
|
52
|
-
:trace_state_unknown_fields
|
|
52
|
+
:trace_state
|
|
53
53
|
|
|
54
54
|
attr_writer \
|
|
55
55
|
:name,
|
|
@@ -86,8 +86,8 @@ module Datadog
|
|
|
86
86
|
tags: nil,
|
|
87
87
|
metrics: nil,
|
|
88
88
|
trace_state: nil,
|
|
89
|
-
trace_state_unknown_fields: nil,
|
|
90
89
|
remote_parent: false,
|
|
90
|
+
distributed_sampling_priority: false,
|
|
91
91
|
tracer: nil, # DEV-3.0: deprecated, remove in 3.0
|
|
92
92
|
baggage: nil,
|
|
93
93
|
auto_finish: true
|
|
@@ -100,6 +100,7 @@ module Datadog
|
|
|
100
100
|
@parent_span_id = parent_span_id
|
|
101
101
|
@sampled = sampled.nil? || sampled
|
|
102
102
|
@remote_parent = remote_parent
|
|
103
|
+
@distributed_sampling_priority = distributed_sampling_priority
|
|
103
104
|
@span_links = span_links
|
|
104
105
|
# Tags
|
|
105
106
|
@agent_sample_rate = agent_sample_rate
|
|
@@ -114,8 +115,7 @@ module Datadog
|
|
|
114
115
|
@service = service
|
|
115
116
|
@profiling_enabled = profiling_enabled
|
|
116
117
|
@apm_tracing_enabled = apm_tracing_enabled
|
|
117
|
-
@trace_state = trace_state
|
|
118
|
-
@trace_state_unknown_fields = trace_state_unknown_fields
|
|
118
|
+
@trace_state = trace_state || Distributed::TraceState.new
|
|
119
119
|
@baggage = baggage
|
|
120
120
|
|
|
121
121
|
# Generic tags
|
|
@@ -391,6 +391,15 @@ module Datadog
|
|
|
391
391
|
@propagated = true
|
|
392
392
|
events.trace_propagated.publish(self)
|
|
393
393
|
|
|
394
|
+
open_telemetry = @trace_state.open_telemetry.outbound(
|
|
395
|
+
trace_id: @id,
|
|
396
|
+
sampling_priority: @sampling_priority,
|
|
397
|
+
decision_maker: get_tag(Tracing::Metadata::Ext::Distributed::TAG_DECISION_MAKER),
|
|
398
|
+
applied_rate: @rule_sample_rate || @agent_sample_rate,
|
|
399
|
+
rate_limiter_rate: @rate_limiter_rate,
|
|
400
|
+
distributed_sampling_priority: @distributed_sampling_priority,
|
|
401
|
+
)
|
|
402
|
+
|
|
394
403
|
TraceDigest.new(
|
|
395
404
|
span_id: span_id,
|
|
396
405
|
span_name: @active_span && @active_span.name,
|
|
@@ -407,8 +416,11 @@ module Datadog
|
|
|
407
416
|
trace_runtime_id: Core::Environment::Identity.id,
|
|
408
417
|
trace_sampling_priority: @sampling_priority,
|
|
409
418
|
trace_service: service,
|
|
410
|
-
trace_state: @trace_state,
|
|
411
|
-
trace_state_unknown_fields: @
|
|
419
|
+
trace_state: @trace_state.unknown_vendors,
|
|
420
|
+
trace_state_unknown_fields: @trace_state.datadog.unknown_fields,
|
|
421
|
+
trace_otel_random_value: open_telemetry.random_value,
|
|
422
|
+
trace_otel_threshold: open_telemetry.threshold,
|
|
423
|
+
trace_otel_unknown_fields: open_telemetry.unknown_fields,
|
|
412
424
|
span_remote: @remote_parent && @active_span.nil?,
|
|
413
425
|
baggage: (@baggage.nil? || @baggage.empty?) ? nil : @baggage
|
|
414
426
|
).freeze
|
|
@@ -444,11 +456,11 @@ module Datadog
|
|
|
444
456
|
sampled: @sampled,
|
|
445
457
|
sampling_priority: @sampling_priority,
|
|
446
458
|
service: service&.dup,
|
|
447
|
-
trace_state: @trace_state
|
|
448
|
-
trace_state_unknown_fields: @trace_state_unknown_fields&.dup,
|
|
459
|
+
trace_state: @trace_state,
|
|
449
460
|
tags: meta.dup,
|
|
450
461
|
metrics: metrics.dup,
|
|
451
|
-
remote_parent: @remote_parent
|
|
462
|
+
remote_parent: @remote_parent,
|
|
463
|
+
distributed_sampling_priority: @distributed_sampling_priority
|
|
452
464
|
)
|
|
453
465
|
end
|
|
454
466
|
|
|
@@ -52,10 +52,11 @@ module Datadog
|
|
|
52
52
|
# rubocop:disable Style/KeywordParametersOrder
|
|
53
53
|
# https://github.com/rubocop/rubocop/issues/13933
|
|
54
54
|
trace_flush: Flush::Finished.new,
|
|
55
|
-
context_provider:
|
|
55
|
+
context_provider: nil,
|
|
56
56
|
default_service: Core::Environment::Ext::FALLBACK_SERVICE_NAME,
|
|
57
57
|
enabled: true,
|
|
58
58
|
logger: Datadog.logger,
|
|
59
|
+
otel_thread_context: nil,
|
|
59
60
|
sampler: Sampling::PrioritySampler.new(
|
|
60
61
|
base_sampler: Sampling::AllSampler.new,
|
|
61
62
|
post_sampler: Sampling::RuleSampler.new
|
|
@@ -71,11 +72,16 @@ module Datadog
|
|
|
71
72
|
@default_service = default_service
|
|
72
73
|
@enabled = enabled
|
|
73
74
|
@logger = logger
|
|
74
|
-
@provider = context_provider
|
|
75
75
|
@sampler = sampler
|
|
76
76
|
@span_sampler = span_sampler
|
|
77
77
|
@tags = tags
|
|
78
78
|
@writer = writer
|
|
79
|
+
|
|
80
|
+
@otel_thread_context = otel_thread_context
|
|
81
|
+
|
|
82
|
+
@provider = context_provider || DefaultContextProvider.new(
|
|
83
|
+
otel_thread_context: otel_thread_context
|
|
84
|
+
)
|
|
79
85
|
end
|
|
80
86
|
|
|
81
87
|
# Return a {Datadog::Tracing::SpanOperation span_op} and {Datadog::Tracing::TraceOperation trace_op}
|
|
@@ -341,6 +347,10 @@ module Datadog
|
|
|
341
347
|
# rubocop:enable Lint/UselessMethodDefinition
|
|
342
348
|
end
|
|
343
349
|
|
|
350
|
+
def after_fork
|
|
351
|
+
@otel_thread_context&.after_fork
|
|
352
|
+
end
|
|
353
|
+
|
|
344
354
|
# Shorthand that calls the `shutdown!` method of a registered worker.
|
|
345
355
|
# It's useful to ensure that the Trace Buffer is properly flushed before
|
|
346
356
|
# shutting down the application.
|
|
@@ -352,6 +362,7 @@ module Datadog
|
|
|
352
362
|
#
|
|
353
363
|
# tracer.shutdown!
|
|
354
364
|
def shutdown!
|
|
365
|
+
@otel_thread_context&.clear
|
|
355
366
|
return unless @enabled
|
|
356
367
|
|
|
357
368
|
@writer&.stop
|
|
@@ -375,9 +386,9 @@ module Datadog
|
|
|
375
386
|
hostname = Core::Environment::Socket.resolved_hostname(Datadog.configuration)
|
|
376
387
|
|
|
377
388
|
if digest
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
389
|
+
propagate_sampling = propagate_sampling_priority?(upstream_tags: digest.trace_distributed_tags)
|
|
390
|
+
sampling_priority = digest.trace_sampling_priority if propagate_sampling
|
|
391
|
+
trace_state = Distributed::TraceState.from_digest(digest, propagate_sampling: propagate_sampling)
|
|
381
392
|
TraceOperation.new(
|
|
382
393
|
logger: logger,
|
|
383
394
|
hostname: hostname,
|
|
@@ -390,9 +401,9 @@ module Datadog
|
|
|
390
401
|
span_links: digest.span_links,
|
|
391
402
|
# Distributed tags are just regular trace tags with special meaning to Datadog
|
|
392
403
|
tags: digest.trace_distributed_tags,
|
|
393
|
-
trace_state:
|
|
394
|
-
trace_state_unknown_fields: digest.trace_state_unknown_fields,
|
|
404
|
+
trace_state: trace_state,
|
|
395
405
|
remote_parent: digest.span_remote,
|
|
406
|
+
distributed_sampling_priority: !!sampling_priority,
|
|
396
407
|
tracer: self,
|
|
397
408
|
baggage: digest.baggage,
|
|
398
409
|
auto_finish: auto_finish
|
|
@@ -445,6 +456,8 @@ module Datadog
|
|
|
445
456
|
reconsider_trace_sampling_on_resource(event_trace_op)
|
|
446
457
|
end
|
|
447
458
|
end
|
|
459
|
+
|
|
460
|
+
@otel_thread_context&.subscribe_to_tracer_events!(events)
|
|
448
461
|
end
|
|
449
462
|
|
|
450
463
|
# Creates a new TraceOperation, with events bounds to this Tracer instance.
|
|
@@ -628,6 +641,10 @@ module Datadog
|
|
|
628
641
|
appsec_bit = upstream_tags[Tracing::Metadata::Ext::Distributed::TAG_TRACE_SOURCE].to_i(16) &
|
|
629
642
|
Datadog::AppSec::Ext::PRODUCT_BIT
|
|
630
643
|
return appsec_enabled if appsec_bit != 0
|
|
644
|
+
|
|
645
|
+
ai_guard_bit = upstream_tags[Tracing::Metadata::Ext::Distributed::TAG_TRACE_SOURCE].to_i(16) &
|
|
646
|
+
Datadog::AIGuard::Ext::PRODUCT_BIT
|
|
647
|
+
return ai_guard_enabled if ai_guard_bit != 0
|
|
631
648
|
end
|
|
632
649
|
|
|
633
650
|
false
|
|
@@ -642,6 +659,10 @@ module Datadog
|
|
|
642
659
|
@appsec_enabled ||= Datadog.configuration.appsec.enabled
|
|
643
660
|
end
|
|
644
661
|
|
|
662
|
+
def ai_guard_enabled
|
|
663
|
+
@ai_guard_enabled ||= Datadog.configuration.respond_to?(:ai_guard) && Datadog.configuration.ai_guard.enabled
|
|
664
|
+
end
|
|
665
|
+
|
|
645
666
|
# Due to APM Tracing (the product) and Tracing (the transport) being intertwined, we cannot completely disabled APM
|
|
646
667
|
# without also disabling the tracer. When setting `@apm_tracing_enabled` to `false`, it does not disable the tracer,
|
|
647
668
|
# but rather only sends heartbeat traces (1 per minutes), so that the service is considered alive in the backend.
|