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
|
@@ -43,7 +43,7 @@ module Datadog
|
|
|
43
43
|
# These are expected failures — no logging needed.
|
|
44
44
|
#
|
|
45
45
|
# 2. **Method-level rescues** (`rescue => e` with logging):
|
|
46
|
-
# Catch failures in
|
|
46
|
+
# Catch failures in build_class_method_scopes, find_source_file, etc. Log at debug
|
|
47
47
|
# for post-hoc diagnosis, return nil or empty array. One bad method/module
|
|
48
48
|
# doesn't kill the entire class extraction.
|
|
49
49
|
#
|
|
@@ -133,16 +133,16 @@ module Datadog
|
|
|
133
133
|
return nil unless Module === mod
|
|
134
134
|
mod_name = safe_mod_name(mod)
|
|
135
135
|
return nil unless mod_name
|
|
136
|
-
|
|
137
|
-
return nil unless user_code_module?(mod)
|
|
136
|
+
return nil unless user_code_module_name?(mod)
|
|
138
137
|
|
|
139
138
|
source_file = find_source_file(mod)
|
|
140
139
|
return nil unless source_file
|
|
140
|
+
return nil unless user_code_path?(source_file)
|
|
141
141
|
|
|
142
142
|
inner_scope = if Class === mod
|
|
143
|
-
extract_class_scope(mod)
|
|
143
|
+
extract_class_scope(mod, source_file)
|
|
144
144
|
else
|
|
145
|
-
extract_module_scope(mod)
|
|
145
|
+
extract_module_scope(mod, source_file)
|
|
146
146
|
end
|
|
147
147
|
|
|
148
148
|
wrap_in_file_scope(source_file, [inner_scope])
|
|
@@ -275,10 +275,12 @@ module Datadog
|
|
|
275
275
|
false
|
|
276
276
|
end
|
|
277
277
|
|
|
278
|
-
#
|
|
279
|
-
#
|
|
280
|
-
#
|
|
281
|
-
|
|
278
|
+
# Return whether +mod+ passes the name-based user-code exclusions
|
|
279
|
+
# (named, outside Datadog, not a Ruby root class). Does not resolve
|
|
280
|
+
# a source file.
|
|
281
|
+
# @param mod [Module]
|
|
282
|
+
# @return [Boolean]
|
|
283
|
+
def user_code_module_name?(mod)
|
|
282
284
|
mod_name = safe_mod_name(mod)
|
|
283
285
|
return false unless mod_name
|
|
284
286
|
|
|
@@ -297,6 +299,15 @@ module Datadog
|
|
|
297
299
|
return false if mod.equal?(Object) || mod.equal?(BasicObject) ||
|
|
298
300
|
mod.equal?(Kernel) || mod.equal?(Module) || mod.equal?(Class)
|
|
299
301
|
|
|
302
|
+
true
|
|
303
|
+
end
|
|
304
|
+
|
|
305
|
+
# Check if module is from user code (not gems or stdlib)
|
|
306
|
+
# @param mod [Module] The module to check
|
|
307
|
+
# @return [Boolean] true if user code
|
|
308
|
+
def user_code_module?(mod)
|
|
309
|
+
return false unless user_code_module_name?(mod)
|
|
310
|
+
|
|
300
311
|
source_file = find_source_file(mod)
|
|
301
312
|
return false unless source_file
|
|
302
313
|
|
|
@@ -331,6 +342,25 @@ module Datadog
|
|
|
331
342
|
true
|
|
332
343
|
end
|
|
333
344
|
|
|
345
|
+
# Resolve the UnboundMethod +mod+ itself declares for +method_name+,
|
|
346
|
+
# skipping prepended wrapper modules (e.g. a DI method-logpoint wrapper)
|
|
347
|
+
# that shadow it.
|
|
348
|
+
#
|
|
349
|
+
# @param mod [Module] Module or class expected to declare the method
|
|
350
|
+
# @param method_name [Symbol] Name of the method to resolve
|
|
351
|
+
# @return [UnboundMethod] Method whose owner is +mod+, or the
|
|
352
|
+
# prepend-resolved method when +mod+ owns no method in the super chain
|
|
353
|
+
def declared_instance_method(mod, method_name)
|
|
354
|
+
original_method = mod.instance_method(method_name)
|
|
355
|
+
method = original_method
|
|
356
|
+
until method.owner.equal?(mod)
|
|
357
|
+
super_method = method.super_method
|
|
358
|
+
return original_method unless super_method
|
|
359
|
+
method = super_method
|
|
360
|
+
end
|
|
361
|
+
method
|
|
362
|
+
end
|
|
363
|
+
|
|
334
364
|
# Find source file for a module.
|
|
335
365
|
# Prefers user code paths over gem/stdlib paths. ActiveRecord models have
|
|
336
366
|
# generated methods (autosave callbacks) whose source is in the gem, but
|
|
@@ -349,7 +379,7 @@ module Datadog
|
|
|
349
379
|
|
|
350
380
|
# Try instance methods first
|
|
351
381
|
mod.instance_methods(false).each do |method_name|
|
|
352
|
-
method = mod
|
|
382
|
+
method = declared_instance_method(mod, method_name)
|
|
353
383
|
location = method.source_location
|
|
354
384
|
next unless location
|
|
355
385
|
|
|
@@ -357,10 +387,15 @@ module Datadog
|
|
|
357
387
|
return path if user_code_path?(path)
|
|
358
388
|
|
|
359
389
|
fallback ||= path # steep:ignore
|
|
390
|
+
rescue Exception => e # standard:disable Lint/RescueException
|
|
391
|
+
Datadog::DI.reraise_if_fatal(e)
|
|
392
|
+
@logger.debug { "symdb: error resolving #{safe_mod_name(mod)}##{method_name}: #{e.class}: #{e.message}" }
|
|
360
393
|
end
|
|
361
394
|
|
|
362
395
|
# Try singleton methods
|
|
363
396
|
mod.singleton_methods(false).each do |method_name|
|
|
397
|
+
# Method-logpoint probes prepend instance methods only, so singleton
|
|
398
|
+
# methods are never shadowed by a DI wrapper.
|
|
364
399
|
method = mod.method(method_name)
|
|
365
400
|
location = method.source_location
|
|
366
401
|
next unless location
|
|
@@ -369,6 +404,9 @@ module Datadog
|
|
|
369
404
|
return path if user_code_path?(path)
|
|
370
405
|
|
|
371
406
|
fallback ||= path # steep:ignore
|
|
407
|
+
rescue Exception => e # standard:disable Lint/RescueException
|
|
408
|
+
Datadog::DI.reraise_if_fatal(e)
|
|
409
|
+
@logger.debug { "symdb: error resolving #{safe_mod_name(mod)}.#{method_name}: #{e.class}: #{e.message}" }
|
|
372
410
|
end
|
|
373
411
|
|
|
374
412
|
# Use const_source_location to find where this class/module is declared.
|
|
@@ -460,10 +498,9 @@ module Datadog
|
|
|
460
498
|
# Extract MODULE scope (without file_hash — that belongs on the FILE root scope).
|
|
461
499
|
# Does not include nested classes — nesting is handled by extract_all via FQN splitting.
|
|
462
500
|
# @param mod [Module] The module
|
|
501
|
+
# @param source_file [String] Source file resolved by the caller
|
|
463
502
|
# @return [Scope] The module scope
|
|
464
|
-
def extract_module_scope(mod)
|
|
465
|
-
source_file = find_source_file(mod)
|
|
466
|
-
|
|
503
|
+
def extract_module_scope(mod, source_file)
|
|
467
504
|
Scope.new(
|
|
468
505
|
scope_type: "MODULE",
|
|
469
506
|
name: safe_mod_name(mod),
|
|
@@ -476,11 +513,11 @@ module Datadog
|
|
|
476
513
|
|
|
477
514
|
# Extract CLASS scope
|
|
478
515
|
# @param klass [Class] The class
|
|
516
|
+
# @param source_file [String] Source file resolved by the caller
|
|
479
517
|
# @return [Scope] The class scope
|
|
480
|
-
def extract_class_scope(klass)
|
|
481
|
-
|
|
482
|
-
start_line, end_line =
|
|
483
|
-
source_file = find_source_file(klass)
|
|
518
|
+
def extract_class_scope(klass, source_file)
|
|
519
|
+
method_scopes = build_class_method_scopes(klass)
|
|
520
|
+
start_line, end_line = line_range_from_scopes(method_scopes)
|
|
484
521
|
|
|
485
522
|
Scope.new(
|
|
486
523
|
scope_type: "CLASS",
|
|
@@ -489,36 +526,20 @@ module Datadog
|
|
|
489
526
|
start_line: start_line,
|
|
490
527
|
end_line: end_line,
|
|
491
528
|
language_specifics: build_class_language_specifics(klass),
|
|
492
|
-
scopes:
|
|
529
|
+
scopes: method_scopes,
|
|
493
530
|
symbols: extract_scope_symbols(klass)
|
|
494
531
|
)
|
|
495
532
|
end
|
|
496
533
|
|
|
497
|
-
#
|
|
498
|
-
#
|
|
499
|
-
#
|
|
500
|
-
# @param
|
|
501
|
-
# @param methods [Array<Symbol>] Method names
|
|
534
|
+
# Derive a [start_line, end_line] range from method scopes, ignoring
|
|
535
|
+
# UNKNOWN sentinel values. The end is the max of method end_lines so a
|
|
536
|
+
# multi-line method's last line is not truncated to its start_line.
|
|
537
|
+
# @param method_scopes [Array<Scope>]
|
|
502
538
|
# @return [Array<Integer, Integer>] [start_line, end_line]
|
|
503
|
-
def
|
|
504
|
-
starts =
|
|
505
|
-
ends =
|
|
506
|
-
|
|
507
|
-
method = klass.instance_method(method_name)
|
|
508
|
-
location = method.source_location
|
|
509
|
-
next unless location && location[0]
|
|
510
|
-
starts << location[1]
|
|
511
|
-
_ranges, method_end = extract_targetable_lines(method, location[1])
|
|
512
|
-
ends << method_end
|
|
513
|
-
end
|
|
514
|
-
|
|
515
|
-
return [UNKNOWN_MIN_LINE, UNKNOWN_MAX_LINE] if starts.empty?
|
|
516
|
-
|
|
517
|
-
[starts.min, ends.max]
|
|
518
|
-
rescue Exception => e # standard:disable Lint/RescueException
|
|
519
|
-
Datadog::DI.reraise_if_fatal(e)
|
|
520
|
-
@logger.debug { "symdb: error calculating line range for #{safe_mod_name(klass)}: #{e.class}: #{e.message}" }
|
|
521
|
-
[UNKNOWN_MIN_LINE, UNKNOWN_MAX_LINE]
|
|
539
|
+
def line_range_from_scopes(method_scopes)
|
|
540
|
+
starts = method_scopes.map(&:start_line).reject { |line| line == UNKNOWN_MIN_LINE }
|
|
541
|
+
ends = method_scopes.map(&:end_line).reject { |line| line == UNKNOWN_MAX_LINE }
|
|
542
|
+
[starts.min || UNKNOWN_MIN_LINE, ends.max || UNKNOWN_MAX_LINE]
|
|
522
543
|
end
|
|
523
544
|
|
|
524
545
|
# Build language specifics for CLASS
|
|
@@ -566,66 +587,33 @@ module Datadog
|
|
|
566
587
|
{}
|
|
567
588
|
end
|
|
568
589
|
|
|
569
|
-
#
|
|
570
|
-
#
|
|
571
|
-
# @
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
# Get all instance methods (public, protected, private)
|
|
576
|
-
all_instance_methods = klass.instance_methods(false) +
|
|
590
|
+
# Build a METHOD scope for each user-code instance method +klass+
|
|
591
|
+
# declares.
|
|
592
|
+
# @param klass [Class]
|
|
593
|
+
# @return [Array<Scope>]
|
|
594
|
+
def build_class_method_scopes(klass)
|
|
595
|
+
method_names = (klass.instance_methods(false) +
|
|
577
596
|
klass.protected_instance_methods(false) +
|
|
578
|
-
klass.private_instance_methods(false)
|
|
579
|
-
all_instance_methods.uniq!
|
|
597
|
+
klass.private_instance_methods(false)).uniq
|
|
580
598
|
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
599
|
+
Core::Utils::EnumerableCompat.filter_map(method_names) do |method_name|
|
|
600
|
+
method = declared_instance_method(klass, method_name)
|
|
601
|
+
location = method.source_location
|
|
602
|
+
next unless location
|
|
603
|
+
next unless user_code_path?(location[0])
|
|
585
604
|
|
|
586
|
-
|
|
605
|
+
build_instance_method_scope(klass, method_name, method)
|
|
606
|
+
rescue Exception => e # standard:disable Lint/RescueException
|
|
607
|
+
Datadog::DI.reraise_if_fatal(e)
|
|
608
|
+
@logger.debug { "symdb: error resolving #{safe_mod_name(klass)}##{method_name}: #{e.class}: #{e.message}" }
|
|
609
|
+
nil
|
|
610
|
+
end
|
|
587
611
|
rescue Exception => e # standard:disable Lint/RescueException
|
|
588
612
|
Datadog::DI.reraise_if_fatal(e)
|
|
589
613
|
@logger.debug { "symdb: failed to extract methods from #{safe_mod_name(klass)}: #{e.class}: #{e.message}" }
|
|
590
614
|
[]
|
|
591
615
|
end
|
|
592
616
|
|
|
593
|
-
# Extract a single method scope
|
|
594
|
-
# @param klass [Class] The class
|
|
595
|
-
# @param method_name [Symbol] Method name
|
|
596
|
-
# @param method_type [Symbol] :instance or :class
|
|
597
|
-
# @return [Scope, nil] Method scope or nil
|
|
598
|
-
def extract_method_scope(klass, method_name, method_type)
|
|
599
|
-
method = klass.instance_method(method_name)
|
|
600
|
-
location = method.source_location
|
|
601
|
-
|
|
602
|
-
return nil unless location # Skip methods without source location
|
|
603
|
-
|
|
604
|
-
source_file, line = location
|
|
605
|
-
return nil unless user_code_path?(source_file) # Skip gem/stdlib methods
|
|
606
|
-
|
|
607
|
-
targetable_lines, end_line = extract_targetable_lines(method, line)
|
|
608
|
-
|
|
609
|
-
Scope.new(
|
|
610
|
-
scope_type: "METHOD",
|
|
611
|
-
name: method_name.to_s,
|
|
612
|
-
source_file: source_file,
|
|
613
|
-
start_line: line,
|
|
614
|
-
end_line: end_line,
|
|
615
|
-
targetable_lines: targetable_lines,
|
|
616
|
-
language_specifics: {
|
|
617
|
-
visibility: method_visibility(klass, method_name),
|
|
618
|
-
method_type: method_type.to_s,
|
|
619
|
-
arity: method.arity
|
|
620
|
-
},
|
|
621
|
-
symbols: extract_method_parameters(method)
|
|
622
|
-
)
|
|
623
|
-
rescue Exception => e # standard:disable Lint/RescueException
|
|
624
|
-
Datadog::DI.reraise_if_fatal(e)
|
|
625
|
-
@logger.debug { "symdb: failed to extract method #{safe_mod_name(klass)}##{method_name}: #{e.class}: #{e.message}" }
|
|
626
|
-
nil
|
|
627
|
-
end
|
|
628
|
-
|
|
629
617
|
# Get method visibility
|
|
630
618
|
# @param klass [Class] The class
|
|
631
619
|
# @param method_name [Symbol] Method name
|
|
@@ -647,7 +635,7 @@ module Datadog
|
|
|
647
635
|
# @param start_line [Integer] Fallback end_line if iseq unavailable
|
|
648
636
|
# @return [Array(Array<Hash>, Integer), Array(nil, Integer)]
|
|
649
637
|
def extract_targetable_lines(method, start_line)
|
|
650
|
-
iseq = RubyVM::InstructionSequence.of(method)
|
|
638
|
+
iseq = RubyVM::InstructionSequence.of(method)
|
|
651
639
|
unless iseq
|
|
652
640
|
@logger.debug { "symdb: no iseq for #{method.name} (C extension or native), skipping targetable lines" }
|
|
653
641
|
return [nil, start_line]
|
|
@@ -801,14 +789,14 @@ module Datadog
|
|
|
801
789
|
# objects allocated to read `source_location` are not retained between
|
|
802
790
|
# passes, so they can be GC'd as soon as the inner loop ends.
|
|
803
791
|
def collect_method_names_by_file(mod)
|
|
804
|
-
result = Hash.new { |h, k| h[k] = [] }
|
|
792
|
+
result = Hash.new { |h, k| h[k] = [] }
|
|
805
793
|
|
|
806
794
|
# Module#instance_methods(false) already returns both public and protected
|
|
807
795
|
# methods, so iterating it plus private_instance_methods covers all three
|
|
808
796
|
# visibilities without an intermediate merged array.
|
|
809
797
|
[mod.instance_methods(false), mod.private_instance_methods(false)].each do |method_names|
|
|
810
798
|
method_names.each do |method_name|
|
|
811
|
-
method = mod
|
|
799
|
+
method = declared_instance_method(mod, method_name)
|
|
812
800
|
loc = method.source_location
|
|
813
801
|
next unless loc
|
|
814
802
|
next unless user_code_path?(loc[0])
|
|
@@ -852,7 +840,7 @@ module Datadog
|
|
|
852
840
|
# live only as long as the tree node holds them; they are released when
|
|
853
841
|
# convert_tree_to_scope finishes building the file's Scope.
|
|
854
842
|
method_infos = Core::Utils::EnumerableCompat.filter_map(method_names) do |name|
|
|
855
|
-
method = mod
|
|
843
|
+
method = declared_instance_method(mod, name)
|
|
856
844
|
# Pass 1 (build_per_file_index) recorded this method under file_path.
|
|
857
845
|
# If the method has been redefined in another file between the two
|
|
858
846
|
# passes (e.g. a class reopened during a Rails reload while extract_all
|
|
@@ -905,7 +893,7 @@ module Datadog
|
|
|
905
893
|
current[:children][part] ||= {
|
|
906
894
|
name: fqn, type: resolve_scope_type(fqn),
|
|
907
895
|
children: {}, methods: [], mod: nil,
|
|
908
|
-
source_file: file_path, fqn: fqn
|
|
896
|
+
source_file: file_path, fqn: fqn,
|
|
909
897
|
}
|
|
910
898
|
current = current[:children][part]
|
|
911
899
|
end
|
|
@@ -924,7 +912,7 @@ module Datadog
|
|
|
924
912
|
type: (Class === mod) ? "CLASS" : "MODULE",
|
|
925
913
|
children: {}, methods: [],
|
|
926
914
|
mod: mod, source_file: file_path,
|
|
927
|
-
fqn: mod_name
|
|
915
|
+
fqn: mod_name,
|
|
928
916
|
}
|
|
929
917
|
current[:children][leaf_name] = leaf
|
|
930
918
|
end
|
|
@@ -989,13 +977,7 @@ module Datadog
|
|
|
989
977
|
# Recurse into child scopes (nested modules/classes)
|
|
990
978
|
child_scopes = node[:children].values.map { |child| convert_node_to_scope(child) }
|
|
991
979
|
|
|
992
|
-
|
|
993
|
-
# method end. Using max(start_line) would underreport the class's end_line for
|
|
994
|
-
# classes whose last method spans multiple lines.
|
|
995
|
-
starts = method_scopes.map(&:start_line).reject { |l| l == UNKNOWN_MIN_LINE } # steep:ignore
|
|
996
|
-
ends = method_scopes.map(&:end_line).reject { |l| l == UNKNOWN_MAX_LINE } # steep:ignore
|
|
997
|
-
start_line = starts.empty? ? UNKNOWN_MIN_LINE : starts.min
|
|
998
|
-
end_line = ends.empty? ? UNKNOWN_MAX_LINE : ends.max
|
|
980
|
+
start_line, end_line = line_range_from_scopes(method_scopes)
|
|
999
981
|
|
|
1000
982
|
# Extract symbols (constants, class variables) if we have the actual module object
|
|
1001
983
|
symbols = node[:mod] ? extract_scope_symbols(node[:mod]) : []
|
|
@@ -1043,7 +1025,7 @@ module Datadog
|
|
|
1043
1025
|
language_specifics: {
|
|
1044
1026
|
visibility: klass ? method_visibility(klass, method_name) : "public", # steep:ignore
|
|
1045
1027
|
method_type: "instance",
|
|
1046
|
-
arity: method.arity
|
|
1028
|
+
arity: method.arity,
|
|
1047
1029
|
},
|
|
1048
1030
|
symbols: extract_method_parameters(method)
|
|
1049
1031
|
)
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
+
require_relative "otel_thread_context"
|
|
3
4
|
require_relative "tracer"
|
|
4
5
|
require_relative "flush"
|
|
5
6
|
require_relative "sync_writer"
|
|
@@ -20,14 +21,14 @@ module Datadog
|
|
|
20
21
|
tracer = settings.tracing.instance
|
|
21
22
|
return tracer unless tracer.nil?
|
|
22
23
|
|
|
24
|
+
sampler = build_sampler(settings)
|
|
25
|
+
|
|
23
26
|
# Apply test mode settings if test mode is activated
|
|
24
27
|
if settings.tracing.test_mode.enabled
|
|
25
28
|
trace_flush = build_test_mode_trace_flush(settings)
|
|
26
|
-
sampler = build_test_mode_sampler
|
|
27
29
|
writer = build_test_mode_writer(settings, agent_settings)
|
|
28
30
|
else
|
|
29
31
|
trace_flush = build_trace_flush(settings)
|
|
30
|
-
sampler = build_sampler(settings)
|
|
31
32
|
writer = build_writer(settings, agent_settings)
|
|
32
33
|
end
|
|
33
34
|
|
|
@@ -42,6 +43,7 @@ module Datadog
|
|
|
42
43
|
default_service: settings.service,
|
|
43
44
|
enabled: settings.tracing.enabled,
|
|
44
45
|
logger: logger,
|
|
46
|
+
otel_thread_context: OTelThreadContext.build(settings.tracing),
|
|
45
47
|
trace_flush: trace_flush,
|
|
46
48
|
sampler: sampler_delegator,
|
|
47
49
|
span_sampler: build_span_sampler(settings),
|
|
@@ -60,7 +62,26 @@ module Datadog
|
|
|
60
62
|
end
|
|
61
63
|
end
|
|
62
64
|
|
|
65
|
+
def bind_transport_telemetry(tracer, telemetry)
|
|
66
|
+
return unless tracer.is_a?(Tracing::Tracer)
|
|
67
|
+
|
|
68
|
+
writer = tracer.writer
|
|
69
|
+
return unless writer.respond_to?(:transport)
|
|
70
|
+
|
|
71
|
+
transport = writer.transport
|
|
72
|
+
if transport.is_a?(Transport::Traces::Transport) ||
|
|
73
|
+
(defined?(Transport::Native::Transport) && transport.is_a?(Transport::Native::Transport))
|
|
74
|
+
transport.telemetry = telemetry
|
|
75
|
+
end
|
|
76
|
+
nil
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
# Builds the sampler for the given settings: the sampler that keeps
|
|
80
|
+
# every trace when test mode is enabled, otherwise the sampler built
|
|
81
|
+
# from the custom sampler, sampling rules and rates.
|
|
63
82
|
def build_sampler(settings)
|
|
83
|
+
return build_test_mode_sampler if settings.tracing.test_mode.enabled
|
|
84
|
+
|
|
64
85
|
# A custom sampler is provided
|
|
65
86
|
if (sampler = settings.tracing.sampler)
|
|
66
87
|
return sampler
|
|
@@ -104,9 +125,30 @@ module Datadog
|
|
|
104
125
|
return writer
|
|
105
126
|
end
|
|
106
127
|
|
|
128
|
+
if !options.key?(:transport) && settings.tracing.native_transport && (transport = build_native_transport(agent_settings))
|
|
129
|
+
options = options.merge(transport: transport)
|
|
130
|
+
end
|
|
131
|
+
|
|
107
132
|
Tracing::Writer.new(agent_settings: agent_settings, **options)
|
|
108
133
|
end
|
|
109
134
|
|
|
135
|
+
def build_native_transport(agent_settings)
|
|
136
|
+
require_relative "transport/native"
|
|
137
|
+
|
|
138
|
+
unless Transport::Native.supported?
|
|
139
|
+
Datadog.logger.warn(
|
|
140
|
+
"Native transport requested but not available: #{Transport::Native::UNSUPPORTED_REASON}. " \
|
|
141
|
+
"Falling back to default HTTP transport."
|
|
142
|
+
)
|
|
143
|
+
return nil
|
|
144
|
+
end
|
|
145
|
+
|
|
146
|
+
Transport::Native::Transport.new(
|
|
147
|
+
agent_settings: agent_settings,
|
|
148
|
+
logger: Datadog.logger
|
|
149
|
+
)
|
|
150
|
+
end
|
|
151
|
+
|
|
110
152
|
def subscribe_to_writer_events!(writer, sampler_delegator, test_mode)
|
|
111
153
|
return unless writer.respond_to?(:events) # Check if it's a custom, external writer
|
|
112
154
|
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
+
require_relative "../../../core/telemetry/configuration_value"
|
|
4
|
+
|
|
3
5
|
module Datadog
|
|
4
6
|
module Tracing
|
|
5
7
|
module Configuration
|
|
@@ -56,6 +58,8 @@ module Datadog
|
|
|
56
58
|
precedence: Core::Configuration::Option::Precedence::REMOTE_CONFIGURATION
|
|
57
59
|
)
|
|
58
60
|
end
|
|
61
|
+
|
|
62
|
+
Core::Telemetry::ConfigurationValue.convert(value)
|
|
59
63
|
end
|
|
60
64
|
|
|
61
65
|
protected
|
|
@@ -24,11 +24,11 @@ module Datadog
|
|
|
24
24
|
def call(tracing_header_tags)
|
|
25
25
|
# Modify the remote configuration value that it matches the
|
|
26
26
|
# environment variable it configures.
|
|
27
|
-
tracing_header_tags&.map
|
|
27
|
+
parsed_header_tags = tracing_header_tags&.map do |hash|
|
|
28
28
|
"#{hash["header"]}:#{hash["tag_name"]}"
|
|
29
29
|
end
|
|
30
30
|
|
|
31
|
-
super
|
|
31
|
+
super(parsed_header_tags)
|
|
32
32
|
end
|
|
33
33
|
end
|
|
34
34
|
|
|
@@ -42,6 +42,7 @@ module Datadog
|
|
|
42
42
|
def call(tracing_sampling_rate)
|
|
43
43
|
super
|
|
44
44
|
Datadog.send(:components).reconfigure_sampler
|
|
45
|
+
tracing_sampling_rate
|
|
45
46
|
end
|
|
46
47
|
|
|
47
48
|
protected
|
|
@@ -78,8 +79,9 @@ module Datadog
|
|
|
78
79
|
tracing_sampling_rules = tracing_sampling_rules.to_json
|
|
79
80
|
end
|
|
80
81
|
|
|
81
|
-
super
|
|
82
|
+
telemetry_value = super
|
|
82
83
|
Datadog.send(:components).reconfigure_sampler
|
|
84
|
+
telemetry_value
|
|
83
85
|
end
|
|
84
86
|
|
|
85
87
|
protected
|
|
@@ -13,9 +13,11 @@ module Datadog
|
|
|
13
13
|
ENV_BAGGAGE_TAG_KEYS = "DD_TRACE_BAGGAGE_TAG_KEYS"
|
|
14
14
|
ENV_TRACE_ID_128_BIT_GENERATION_ENABLED = "DD_TRACE_128_BIT_TRACEID_GENERATION_ENABLED"
|
|
15
15
|
ENV_NATIVE_SPAN_EVENTS = "DD_TRACE_NATIVE_SPAN_EVENTS"
|
|
16
|
+
ENV_OTEL_CONTEXT_ENABLED = "DD_TRACE_OTEL_CTX_ENABLED"
|
|
16
17
|
ENV_RESOURCE_RENAMING_ENABLED = "DD_TRACE_RESOURCE_RENAMING_ENABLED"
|
|
17
18
|
ENV_RESOURCE_RENAMING_ALWAYS_SIMPLIFIED_ENDPOINT = "DD_TRACE_RESOURCE_RENAMING_ALWAYS_SIMPLIFIED_ENDPOINT"
|
|
18
19
|
ENV_EXPERIMENTAL_PROPAGATE_PROCESS_TAGS_ENABLED = "DD_EXPERIMENTAL_PROPAGATE_PROCESS_TAGS_ENABLED"
|
|
20
|
+
ENV_EXPERIMENTAL_NATIVE_TRANSPORT_ENABLED = "DD_EXPERIMENTAL_NATIVE_TRANSPORT_ENABLED"
|
|
19
21
|
|
|
20
22
|
# @public_api
|
|
21
23
|
module SpanAttributeSchema
|
|
@@ -126,6 +128,8 @@ module Datadog
|
|
|
126
128
|
ENV_SERVER_ERROR_STATUSES = "DD_TRACE_HTTP_SERVER_ERROR_STATUSES"
|
|
127
129
|
ENV_CLIENT_ERROR_STATUSES = "DD_TRACE_HTTP_CLIENT_ERROR_STATUSES"
|
|
128
130
|
end
|
|
131
|
+
|
|
132
|
+
ENV_HTTP_CLIENT_RESOURCE_NAME_QUANTIZE = "DD_TRACE_HTTP_CLIENT_RESOURCE_NAME_QUANTIZE"
|
|
129
133
|
end
|
|
130
134
|
end
|
|
131
135
|
end
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
require_relative "../../tracing/configuration/ext"
|
|
4
4
|
require_relative "../../core/environment/variable_helpers"
|
|
5
|
+
require_relative "../../ruby_version"
|
|
5
6
|
require_relative "../contrib/status_range_matcher"
|
|
6
7
|
require_relative "../contrib/status_range_env_parser"
|
|
7
8
|
require_relative "http"
|
|
@@ -255,6 +256,14 @@ module Datadog
|
|
|
255
256
|
o.type :bool
|
|
256
257
|
end
|
|
257
258
|
|
|
259
|
+
option :otel_thread_context_enabled do |o|
|
|
260
|
+
o.env Tracing::Configuration::Ext::ENV_OTEL_CONTEXT_ENABLED
|
|
261
|
+
o.default do
|
|
262
|
+
RUBY_ENGINE == "ruby" && RUBY_PLATFORM.include?("linux")
|
|
263
|
+
end
|
|
264
|
+
o.type :bool
|
|
265
|
+
end
|
|
266
|
+
|
|
258
267
|
# Configures an alternative trace transport behavior, where
|
|
259
268
|
# traces can be sent to the agent and backend before all spans
|
|
260
269
|
# have finished.
|
|
@@ -482,6 +491,22 @@ module Datadog
|
|
|
482
491
|
end
|
|
483
492
|
end
|
|
484
493
|
|
|
494
|
+
# Use the native trace transport (Rust via C FFI) instead of
|
|
495
|
+
# the default pure-Ruby HTTP transport.
|
|
496
|
+
#
|
|
497
|
+
# The native transport delegates serialization, stats
|
|
498
|
+
# computation, and HTTP sending to the Rust data pipeline.
|
|
499
|
+
#
|
|
500
|
+
# This option is recommended for internal use only.
|
|
501
|
+
#
|
|
502
|
+
# @default `true` on CRuby 4.0.0 and later, otherwise `false`
|
|
503
|
+
# @return [Boolean]
|
|
504
|
+
option :native_transport do |o|
|
|
505
|
+
o.env Configuration::Ext::ENV_EXPERIMENTAL_NATIVE_TRANSPORT_ENABLED
|
|
506
|
+
o.default { RUBY_ENGINE == "ruby" && RubyVersion.is?(">= 4.0.0") }
|
|
507
|
+
o.type :bool
|
|
508
|
+
end
|
|
509
|
+
|
|
485
510
|
# A custom writer instance.
|
|
486
511
|
# The object must respect the {Datadog::Tracing::Writer} interface.
|
|
487
512
|
#
|
|
@@ -543,6 +568,17 @@ module Datadog
|
|
|
543
568
|
o.default 512
|
|
544
569
|
end
|
|
545
570
|
|
|
571
|
+
# Whether outbound HTTP client resource names include a quantized request path.
|
|
572
|
+
# URL tags and outgoing requests are unchanged.
|
|
573
|
+
#
|
|
574
|
+
# @default `DD_TRACE_HTTP_CLIENT_RESOURCE_NAME_QUANTIZE` environment variable, otherwise `false`.
|
|
575
|
+
# @return [Boolean]
|
|
576
|
+
option :http_client_resource_name_quantize do |o|
|
|
577
|
+
o.env Tracing::Configuration::Ext::ENV_HTTP_CLIENT_RESOURCE_NAME_QUANTIZE
|
|
578
|
+
o.default false
|
|
579
|
+
o.type :bool
|
|
580
|
+
end
|
|
581
|
+
|
|
546
582
|
# HTTP error statuses configuration
|
|
547
583
|
# @public_api
|
|
548
584
|
settings :http_error_statuses do
|
|
@@ -20,9 +20,15 @@ module Datadog
|
|
|
20
20
|
attr_reader \
|
|
21
21
|
:active_trace
|
|
22
22
|
|
|
23
|
+
attr_writer \
|
|
24
|
+
:otel_thread_context
|
|
25
|
+
|
|
23
26
|
def initialize(
|
|
24
|
-
trace: nil
|
|
27
|
+
trace: nil,
|
|
28
|
+
otel_thread_context: nil
|
|
25
29
|
)
|
|
30
|
+
@otel_thread_context = otel_thread_context
|
|
31
|
+
@active_trace = nil
|
|
26
32
|
activate!(trace)
|
|
27
33
|
end
|
|
28
34
|
|
|
@@ -54,14 +60,30 @@ module Datadog
|
|
|
54
60
|
# Creates a copy of the context, when forked.
|
|
55
61
|
def fork_clone
|
|
56
62
|
forked_trace = @active_trace&.fork_clone
|
|
57
|
-
|
|
63
|
+
|
|
64
|
+
self.class.new(
|
|
65
|
+
trace: forked_trace,
|
|
66
|
+
otel_thread_context: @otel_thread_context
|
|
67
|
+
)
|
|
58
68
|
end
|
|
59
69
|
|
|
60
70
|
private
|
|
61
71
|
|
|
62
72
|
def set_active_trace!(trace)
|
|
73
|
+
previous_trace = @active_trace
|
|
74
|
+
|
|
63
75
|
# Don't retain finished traces
|
|
64
76
|
@active_trace = (trace && !trace.finished?) ? trace : nil
|
|
77
|
+
|
|
78
|
+
return @active_trace if previous_trace == @active_trace
|
|
79
|
+
|
|
80
|
+
if @active_trace
|
|
81
|
+
@otel_thread_context&.update_from_trace_op(@active_trace)
|
|
82
|
+
elsif previous_trace
|
|
83
|
+
@otel_thread_context&.clear
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
@active_trace
|
|
65
87
|
end
|
|
66
88
|
end
|
|
67
89
|
end
|
|
@@ -12,12 +12,23 @@ module Datadog
|
|
|
12
12
|
# @see https://ruby-doc.org/core-3.1.2/Thread.html#method-i-5B-5D Thread attributes are fiber-local
|
|
13
13
|
class DefaultContextProvider
|
|
14
14
|
# Initializes the default context provider with a fiber-bound context.
|
|
15
|
-
def initialize
|
|
16
|
-
@
|
|
15
|
+
def initialize(otel_thread_context: nil)
|
|
16
|
+
@otel_thread_context = otel_thread_context
|
|
17
|
+
@context = FiberLocalContext.new(otel_thread_context: otel_thread_context)
|
|
17
18
|
end
|
|
18
19
|
|
|
19
20
|
# Sets the current context.
|
|
20
21
|
def context=(ctx)
|
|
22
|
+
ctx.otel_thread_context = @otel_thread_context if ctx.respond_to?(:otel_thread_context=)
|
|
23
|
+
|
|
24
|
+
if (otel_thread_context = @otel_thread_context)
|
|
25
|
+
if (trace = ctx&.active_trace)
|
|
26
|
+
otel_thread_context.update_from_trace_op(trace)
|
|
27
|
+
else
|
|
28
|
+
otel_thread_context.clear
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
|
|
21
32
|
@context.local = ctx
|
|
22
33
|
end
|
|
23
34
|
|
|
@@ -48,10 +59,11 @@ module Datadog
|
|
|
48
59
|
class FiberLocalContext
|
|
49
60
|
# To support multiple tracers simultaneously, each {Datadog::Tracing::FiberLocalContext}
|
|
50
61
|
# instance has its own fiber-local variable.
|
|
51
|
-
def initialize
|
|
62
|
+
def initialize(otel_thread_context: nil)
|
|
63
|
+
@otel_thread_context = otel_thread_context
|
|
52
64
|
@key = :"datadog_context_#{FiberLocalContext.next_instance_id}"
|
|
53
65
|
|
|
54
|
-
self.local = Context.new
|
|
66
|
+
self.local = Context.new(otel_thread_context: otel_thread_context)
|
|
55
67
|
end
|
|
56
68
|
|
|
57
69
|
# Override the fiber-local context with a new context.
|
|
@@ -61,7 +73,7 @@ module Datadog
|
|
|
61
73
|
|
|
62
74
|
# Return the fiber-local context.
|
|
63
75
|
def local(storage = Thread.current)
|
|
64
|
-
storage[@key] ||= Context.new
|
|
76
|
+
storage[@key] ||= Context.new(otel_thread_context: @otel_thread_context)
|
|
65
77
|
end
|
|
66
78
|
|
|
67
79
|
# Ensure two instances of {FiberLocalContext} do not conflict.
|