datadog 2.28.0 → 2.41.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 +412 -1
- data/bin/ddprofrb +4 -4
- data/ext/datadog_profiling_native_extension/clock_id.h +9 -1
- data/ext/datadog_profiling_native_extension/clock_id_from_mach.c +66 -0
- data/ext/datadog_profiling_native_extension/clock_id_from_pthread.c +1 -1
- data/ext/datadog_profiling_native_extension/collectors_cpu_and_wall_time_worker.c +281 -57
- data/ext/datadog_profiling_native_extension/collectors_discrete_dynamic_sampler.c +1 -1
- data/ext/datadog_profiling_native_extension/collectors_idle_sampling_helper.c +18 -4
- data/ext/datadog_profiling_native_extension/collectors_stack.c +245 -160
- data/ext/datadog_profiling_native_extension/collectors_stack.h +23 -4
- data/ext/datadog_profiling_native_extension/collectors_thread_context.c +725 -432
- data/ext/datadog_profiling_native_extension/collectors_thread_context.h +19 -6
- data/ext/datadog_profiling_native_extension/crashtracking_runtime_stacks.c +5 -4
- data/ext/datadog_profiling_native_extension/datadog_ruby_common.c +44 -19
- data/ext/datadog_profiling_native_extension/datadog_ruby_common.h +17 -12
- data/ext/datadog_profiling_native_extension/extconf.rb +44 -40
- data/ext/datadog_profiling_native_extension/gvl_profiling_helper.c +4 -43
- data/ext/datadog_profiling_native_extension/gvl_profiling_helper.h +15 -47
- data/ext/datadog_profiling_native_extension/heap_recorder.c +230 -81
- data/ext/datadog_profiling_native_extension/heap_recorder.h +12 -1
- data/ext/datadog_profiling_native_extension/http_transport.c +61 -69
- data/ext/datadog_profiling_native_extension/macos_sampler_thread.h +55 -0
- data/ext/datadog_profiling_native_extension/native_extension_helpers.rb +3 -16
- data/ext/datadog_profiling_native_extension/private_vm_api_access.c +300 -108
- data/ext/datadog_profiling_native_extension/private_vm_api_access.h +17 -9
- data/ext/datadog_profiling_native_extension/profiling.c +44 -5
- data/ext/datadog_profiling_native_extension/ruby_helpers.c +40 -34
- data/ext/datadog_profiling_native_extension/setup_signal_handler.c +26 -8
- data/ext/datadog_profiling_native_extension/setup_signal_handler.h +1 -3
- data/ext/datadog_profiling_native_extension/stack_recorder.c +94 -69
- data/ext/datadog_profiling_native_extension/stack_recorder.h +3 -1
- data/ext/datadog_profiling_native_extension/time_helpers.h +13 -7
- data/ext/datadog_profiling_native_extension/unsafe_api_calls_check.h +4 -2
- data/ext/libdatadog_api/crashtracker.c +12 -8
- data/ext/libdatadog_api/crashtracker_report_exception.c +126 -0
- data/ext/libdatadog_api/datadog_ruby_common.c +44 -19
- data/ext/libdatadog_api/datadog_ruby_common.h +17 -12
- data/ext/libdatadog_api/di.c +203 -0
- data/ext/libdatadog_api/extconf.rb +38 -44
- data/ext/libdatadog_api/feature_flags.c +26 -0
- data/ext/libdatadog_api/init.c +9 -2
- data/ext/libdatadog_api/trace_exporter.c +1312 -0
- data/ext/libdatadog_api/trace_exporter.h +5 -0
- data/ext/libdatadog_extconf_helpers.rb +98 -15
- data/lib/datadog/ai_guard/api_client.rb +9 -7
- data/lib/datadog/ai_guard/autoload.rb +10 -0
- data/lib/datadog/ai_guard/component.rb +11 -9
- data/lib/datadog/ai_guard/configuration.rb +106 -2
- data/lib/datadog/ai_guard/contrib/auto_instrument.rb +24 -0
- data/lib/datadog/ai_guard/contrib/rack/integration.rb +42 -0
- data/lib/datadog/ai_guard/contrib/rack/patcher.rb +26 -0
- data/lib/datadog/ai_guard/contrib/rack/request_middleware.rb +97 -0
- data/lib/datadog/ai_guard/contrib/rails/integration.rb +41 -0
- data/lib/datadog/ai_guard/contrib/rails/patcher.rb +97 -0
- data/lib/datadog/ai_guard/contrib/ruby_llm/chat_instrumentation.rb +41 -3
- data/lib/datadog/ai_guard/evaluation/content_builder.rb +31 -0
- data/lib/datadog/ai_guard/evaluation/content_part.rb +36 -0
- data/lib/datadog/ai_guard/evaluation/no_op_result.rb +3 -1
- data/lib/datadog/ai_guard/evaluation/request.rb +22 -17
- data/lib/datadog/ai_guard/evaluation/result.rb +3 -1
- data/lib/datadog/ai_guard/evaluation.rb +51 -7
- data/lib/datadog/ai_guard/ext.rb +15 -0
- data/lib/datadog/ai_guard.rb +34 -8
- data/lib/datadog/appsec/actions_handler/serializable_backtrace.rb +22 -43
- data/lib/datadog/appsec/actions_handler.rb +6 -6
- data/lib/datadog/appsec/anonymizer.rb +1 -1
- data/lib/datadog/appsec/api_security/endpoint_collection/grape_route_serializer.rb +2 -2
- data/lib/datadog/appsec/api_security/endpoint_collection/rails_collector.rb +6 -6
- 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 +2 -2
- data/lib/datadog/appsec/api_security/route_extractor.rb +26 -14
- data/lib/datadog/appsec/api_security/sampler.rb +5 -5
- data/lib/datadog/appsec/api_security.rb +1 -1
- data/lib/datadog/appsec/assets/blocked.html +2 -1
- data/lib/datadog/appsec/assets.rb +7 -7
- data/lib/datadog/appsec/autoload.rb +4 -4
- data/lib/datadog/appsec/component.rb +29 -22
- data/lib/datadog/appsec/compressed_json.rb +7 -7
- data/lib/datadog/appsec/configuration.rb +436 -1
- data/lib/datadog/appsec/context.rb +49 -12
- data/lib/datadog/appsec/contrib/active_record/instrumentation.rb +6 -6
- data/lib/datadog/appsec/contrib/active_record/integration.rb +4 -4
- data/lib/datadog/appsec/contrib/active_record/patcher.rb +7 -4
- data/lib/datadog/appsec/contrib/aws_lambda/gateway/watcher.rb +75 -0
- data/lib/datadog/appsec/contrib/aws_lambda/integration.rb +39 -0
- data/lib/datadog/appsec/contrib/aws_lambda/patcher.rb +30 -0
- data/lib/datadog/appsec/contrib/aws_lambda/waf_addresses.rb +146 -0
- data/lib/datadog/appsec/contrib/devise/configuration.rb +1 -1
- data/lib/datadog/appsec/contrib/devise/data_extractor.rb +3 -3
- data/lib/datadog/appsec/contrib/devise/ext.rb +20 -20
- data/lib/datadog/appsec/contrib/devise/integration.rb +5 -5
- data/lib/datadog/appsec/contrib/devise/patcher.rb +8 -8
- data/lib/datadog/appsec/contrib/devise/patches/signin_tracking_patch.rb +14 -13
- data/lib/datadog/appsec/contrib/devise/patches/signup_tracking_patch.rb +8 -8
- data/lib/datadog/appsec/contrib/devise/tracking_middleware.rb +24 -9
- data/lib/datadog/appsec/contrib/excon/integration.rb +4 -4
- data/lib/datadog/appsec/contrib/excon/patcher.rb +3 -1
- data/lib/datadog/appsec/contrib/excon/ssrf_detection_middleware.rb +118 -14
- data/lib/datadog/appsec/contrib/faraday/integration.rb +5 -5
- data/lib/datadog/appsec/contrib/faraday/patcher.rb +4 -4
- data/lib/datadog/appsec/contrib/faraday/ssrf_detection_middleware.rb +119 -12
- data/lib/datadog/appsec/contrib/graphql/appsec_trace.rb +4 -4
- data/lib/datadog/appsec/contrib/graphql/gateway/multiplex.rb +76 -26
- data/lib/datadog/appsec/contrib/graphql/gateway/watcher.rb +7 -7
- data/lib/datadog/appsec/contrib/graphql/integration.rb +10 -9
- data/lib/datadog/appsec/contrib/graphql/patcher.rb +3 -3
- data/lib/datadog/appsec/contrib/rack/buffered_input.rb +83 -0
- data/lib/datadog/appsec/contrib/rack/ext.rb +29 -29
- data/lib/datadog/appsec/contrib/rack/gateway/request.rb +56 -21
- data/lib/datadog/appsec/contrib/rack/gateway/response.rb +1 -1
- data/lib/datadog/appsec/contrib/rack/gateway/watcher.rb +46 -30
- data/lib/datadog/appsec/contrib/rack/input_peeker.rb +79 -0
- data/lib/datadog/appsec/contrib/rack/integration.rb +7 -7
- data/lib/datadog/appsec/contrib/rack/patcher.rb +3 -3
- data/lib/datadog/appsec/contrib/rack/request_body_middleware.rb +11 -8
- data/lib/datadog/appsec/contrib/rack/request_middleware.rb +63 -52
- data/lib/datadog/appsec/contrib/rack/response_body.rb +36 -0
- data/lib/datadog/appsec/contrib/rails/gateway/request.rb +43 -4
- data/lib/datadog/appsec/contrib/rails/gateway/watcher.rb +25 -9
- data/lib/datadog/appsec/contrib/rails/integration.rb +6 -6
- data/lib/datadog/appsec/contrib/rails/patcher.rb +17 -17
- data/lib/datadog/appsec/contrib/rails/patches/process_action_patch.rb +3 -1
- data/lib/datadog/appsec/contrib/rails/patches/render_to_body_patch.rb +3 -3
- data/lib/datadog/appsec/contrib/rails/request.rb +3 -3
- data/lib/datadog/appsec/contrib/rails/request_middleware.rb +2 -1
- data/lib/datadog/appsec/contrib/rest_client/integration.rb +5 -5
- data/lib/datadog/appsec/contrib/rest_client/patcher.rb +3 -1
- data/lib/datadog/appsec/contrib/rest_client/request_ssrf_detection_patch.rb +131 -13
- data/lib/datadog/appsec/contrib/sinatra/gateway/request.rb +1 -1
- data/lib/datadog/appsec/contrib/sinatra/gateway/route_params.rb +1 -1
- data/lib/datadog/appsec/contrib/sinatra/gateway/watcher.rb +35 -12
- data/lib/datadog/appsec/contrib/sinatra/integration.rb +5 -5
- data/lib/datadog/appsec/contrib/sinatra/patcher.rb +11 -11
- data/lib/datadog/appsec/contrib/sinatra/patches/json_patch.rb +3 -3
- data/lib/datadog/appsec/contrib/sinatra/request_middleware.rb +2 -1
- data/lib/datadog/appsec/counter_sampler.rb +25 -0
- data/lib/datadog/appsec/default_header_tags.rb +52 -0
- data/lib/datadog/appsec/event.rb +15 -31
- data/lib/datadog/appsec/ext.rb +11 -10
- data/lib/datadog/appsec/extensions.rb +2 -2
- data/lib/datadog/appsec/instrumentation/gateway/middleware.rb +2 -3
- data/lib/datadog/appsec/instrumentation/gateway.rb +3 -16
- data/lib/datadog/appsec/metrics/collector.rb +18 -1
- data/lib/datadog/appsec/metrics/exporter.rb +17 -11
- data/lib/datadog/appsec/metrics/telemetry.rb +15 -3
- data/lib/datadog/appsec/metrics/telemetry_exporter.rb +20 -2
- data/lib/datadog/appsec/metrics.rb +4 -4
- data/lib/datadog/appsec/monitor/gateway/watcher.rb +18 -12
- data/lib/datadog/appsec/monitor.rb +1 -1
- data/lib/datadog/appsec/processor/rule_loader.rb +32 -32
- data/lib/datadog/appsec/rate_limiter.rb +1 -1
- data/lib/datadog/appsec/remote.rb +15 -9
- data/lib/datadog/appsec/response.rb +22 -22
- data/lib/datadog/appsec/route_normalizer/rails_route_pattern.rb +176 -0
- data/lib/datadog/appsec/route_normalizer/route_pattern.rb +378 -0
- data/lib/datadog/appsec/route_normalizer/route_text.rb +57 -0
- data/lib/datadog/appsec/route_normalizer.rb +80 -0
- data/lib/datadog/appsec/security_engine/engine.rb +54 -33
- data/lib/datadog/appsec/security_engine/runner.rb +3 -3
- data/lib/datadog/appsec/security_event.rb +2 -2
- data/lib/datadog/appsec/trace_keeper.rb +18 -6
- data/lib/datadog/appsec/utils/http/body.rb +41 -0
- data/lib/datadog/appsec/utils/http/body_reader.rb +61 -0
- data/lib/datadog/appsec/utils/http/media_range.rb +17 -16
- data/lib/datadog/appsec/utils/http/media_type.rb +28 -36
- data/lib/datadog/appsec/utils/http/url_encoded.rb +107 -0
- data/lib/datadog/appsec.rb +21 -24
- data/lib/datadog/auto_instrument.rb +2 -2
- data/lib/datadog/core/buffer/cruby.rb +1 -1
- data/lib/datadog/core/buffer/thread_safe.rb +1 -1
- data/lib/datadog/core/configuration/agent_settings.rb +1 -1
- data/lib/datadog/core/configuration/agent_settings_resolver.rb +15 -15
- data/lib/datadog/core/configuration/agentless_settings_resolver.rb +2 -2
- data/lib/datadog/core/configuration/base.rb +19 -7
- data/lib/datadog/core/configuration/components.rb +166 -36
- data/lib/datadog/core/configuration/components_state.rb +6 -1
- data/lib/datadog/core/configuration/config_helper.rb +12 -3
- data/lib/datadog/core/configuration/deprecations.rb +6 -6
- data/lib/datadog/core/configuration/ext.rb +11 -11
- data/lib/datadog/core/configuration/option.rb +48 -22
- data/lib/datadog/core/configuration/option_definition.rb +43 -17
- data/lib/datadog/core/configuration/options.rb +43 -9
- data/lib/datadog/core/configuration/settings.rb +155 -106
- data/lib/datadog/core/configuration/stable_config.rb +1 -1
- data/lib/datadog/core/configuration/supported_configurations.rb +44 -1
- data/lib/datadog/core/configuration.rb +11 -11
- data/lib/datadog/core/contrib/rails/railtie.rb +32 -0
- data/lib/datadog/core/contrib/rails/utils.rb +7 -3
- data/lib/datadog/core/crashtracking/component.rb +78 -26
- data/lib/datadog/core/crashtracking/tag_builder.rb +5 -5
- data/lib/datadog/core/deprecations.rb +1 -1
- data/lib/datadog/core/diagnostics/environment_logger.rb +45 -8
- data/lib/datadog/core/diagnostics/health.rb +2 -2
- data/lib/datadog/core/encoding.rb +4 -4
- data/lib/datadog/core/environment/agent_info.rb +65 -1
- data/lib/datadog/core/environment/cgroup.rb +4 -4
- data/lib/datadog/core/environment/container.rb +11 -11
- data/lib/datadog/core/environment/execution.rb +3 -3
- data/lib/datadog/core/environment/ext.rb +21 -15
- data/lib/datadog/core/environment/gc.rb +1 -1
- data/lib/datadog/core/environment/git.rb +2 -2
- data/lib/datadog/core/environment/identity.rb +47 -11
- data/lib/datadog/core/environment/platform.rb +8 -8
- data/lib/datadog/core/environment/process.rb +54 -19
- data/lib/datadog/core/environment/socket.rb +15 -2
- data/lib/datadog/core/environment/variable_helpers.rb +1 -1
- data/lib/datadog/core/environment/vm_cache.rb +1 -1
- data/lib/datadog/core/environment/yjit.rb +2 -2
- data/lib/datadog/core/error.rb +5 -5
- data/lib/datadog/core/evp.rb +11 -0
- data/lib/datadog/core/extensions.rb +1 -1
- data/lib/datadog/core/feature_flags.rb +3 -3
- data/lib/datadog/core/git/ext.rb +4 -4
- data/lib/datadog/core/knuth_sampler.rb +3 -1
- data/lib/datadog/core/logger.rb +4 -4
- data/lib/datadog/core/logging/ext.rb +1 -1
- data/lib/datadog/core/metrics/client.rb +26 -26
- data/lib/datadog/core/metrics/ext.rb +5 -5
- data/lib/datadog/core/metrics/helpers.rb +1 -1
- data/lib/datadog/core/metrics/logging.rb +3 -3
- data/lib/datadog/core/metrics/options.rb +5 -5
- data/lib/datadog/core/pin.rb +1 -1
- data/lib/datadog/core/process_discovery.rb +23 -22
- data/lib/datadog/core/rate_limiter.rb +3 -1
- data/lib/datadog/core/remote/client/capabilities.rb +67 -15
- data/lib/datadog/core/remote/client.rb +18 -18
- data/lib/datadog/core/remote/component.rb +70 -34
- data/lib/datadog/core/remote/configuration/content.rb +3 -3
- data/lib/datadog/core/remote/configuration/digest.rb +1 -1
- data/lib/datadog/core/remote/configuration/path.rb +9 -9
- data/lib/datadog/core/remote/configuration/repository.rb +4 -4
- data/lib/datadog/core/remote/configuration/target.rb +9 -9
- data/lib/datadog/core/remote/configuration.rb +4 -4
- data/lib/datadog/core/remote/ext.rb +3 -3
- data/lib/datadog/core/remote/negotiation.rb +1 -1
- data/lib/datadog/core/remote/tie/tracing.rb +7 -7
- data/lib/datadog/core/remote/transport/config.rb +9 -15
- data/lib/datadog/core/remote/transport/http/config.rb +10 -10
- data/lib/datadog/core/remote/transport/http/negotiation.rb +4 -4
- data/lib/datadog/core/remote/transport/http.rb +10 -10
- data/lib/datadog/core/remote/transport/negotiation.rb +3 -3
- data/lib/datadog/core/remote/worker.rb +5 -5
- data/lib/datadog/core/runtime/ext.rb +22 -22
- data/lib/datadog/core/runtime/metrics.rb +11 -12
- data/lib/datadog/core/tag_builder.rb +18 -18
- data/lib/datadog/core/tag_normalizer.rb +7 -7
- data/lib/datadog/core/telemetry/component.rb +16 -26
- data/lib/datadog/core/telemetry/configuration_value.rb +38 -0
- data/lib/datadog/core/telemetry/emitter.rb +5 -5
- data/lib/datadog/core/telemetry/event/app_client_configuration_change.rb +10 -9
- data/lib/datadog/core/telemetry/event/app_closing.rb +2 -2
- data/lib/datadog/core/telemetry/event/app_dependencies_loaded.rb +2 -2
- data/lib/datadog/core/telemetry/event/app_endpoints_loaded.rb +3 -3
- data/lib/datadog/core/telemetry/event/app_extended_heartbeat.rb +32 -0
- data/lib/datadog/core/telemetry/event/app_heartbeat.rb +2 -2
- data/lib/datadog/core/telemetry/event/app_integrations_change.rb +2 -2
- data/lib/datadog/core/telemetry/event/app_started.rb +142 -193
- data/lib/datadog/core/telemetry/event/base.rb +1 -1
- data/lib/datadog/core/telemetry/event/distributions.rb +2 -2
- data/lib/datadog/core/telemetry/event/generate_metrics.rb +3 -3
- data/lib/datadog/core/telemetry/event/log.rb +6 -6
- data/lib/datadog/core/telemetry/event/message_batch.rb +1 -1
- data/lib/datadog/core/telemetry/event/synth_app_client_configuration_change.rb +3 -3
- data/lib/datadog/core/telemetry/event.rb +16 -22
- data/lib/datadog/core/telemetry/ext.rb +11 -10
- data/lib/datadog/core/telemetry/logger.rb +1 -1
- data/lib/datadog/core/telemetry/logging.rb +5 -5
- data/lib/datadog/core/telemetry/metric.rb +9 -9
- data/lib/datadog/core/telemetry/metrics_collection.rb +2 -2
- data/lib/datadog/core/telemetry/metrics_manager.rb +1 -1
- data/lib/datadog/core/telemetry/request.rb +6 -8
- data/lib/datadog/core/telemetry/transport/http/telemetry.rb +16 -11
- data/lib/datadog/core/telemetry/transport/http.rb +7 -7
- data/lib/datadog/core/telemetry/transport/telemetry.rb +8 -9
- data/lib/datadog/core/telemetry/worker.rb +26 -6
- data/lib/datadog/core/transport/ext.rb +14 -13
- data/lib/datadog/core/transport/http/adapters/net.rb +4 -4
- data/lib/datadog/core/transport/http/adapters/test.rb +1 -1
- data/lib/datadog/core/transport/http/adapters/unix_socket.rb +4 -4
- data/lib/datadog/core/transport/http/api/endpoint.rb +1 -1
- data/lib/datadog/core/transport/http/api/map.rb +1 -1
- data/lib/datadog/core/transport/http/builder.rb +6 -6
- data/lib/datadog/core/transport/http/client.rb +2 -2
- data/lib/datadog/core/transport/http/response.rb +5 -1
- data/lib/datadog/core/transport/http.rb +9 -7
- data/lib/datadog/core/transport/parcel.rb +61 -9
- data/lib/datadog/core/transport/response.rb +1 -1
- data/lib/datadog/core/transport/transport.rb +2 -2
- data/lib/datadog/core/utils/at_fork_monkey_patch.rb +172 -20
- data/lib/datadog/core/utils/base64_codec.rb +23 -0
- data/lib/datadog/core/utils/duration.rb +1 -1
- data/lib/datadog/core/utils/{array.rb → enumerable_compat.rb} +2 -2
- data/lib/datadog/core/utils/fnv.rb +26 -0
- data/lib/datadog/core/utils/forking.rb +3 -1
- data/lib/datadog/core/utils/hash.rb +0 -23
- data/lib/datadog/core/utils/lru_cache.rb +3 -3
- data/lib/datadog/core/utils/network.rb +11 -11
- data/lib/datadog/core/utils/only_once.rb +1 -1
- data/lib/datadog/core/utils/only_once_successful.rb +1 -1
- data/lib/datadog/core/utils/safe_dup.rb +2 -1
- data/lib/datadog/core/utils/sequence.rb +3 -6
- data/lib/datadog/core/utils/spawn_monkey_patch.rb +68 -0
- data/lib/datadog/core/utils/time.rb +18 -52
- data/lib/datadog/core/utils/url.rb +1 -1
- data/lib/datadog/core/utils.rb +5 -5
- data/lib/datadog/core/workers/async.rb +2 -2
- data/lib/datadog/core/workers/interval_loop.rb +13 -6
- data/lib/datadog/core/workers/polling.rb +2 -2
- data/lib/datadog/core/workers/queue.rb +0 -4
- data/lib/datadog/core/workers/runtime_metrics.rb +13 -5
- data/lib/datadog/core.rb +13 -6
- data/lib/datadog/data_streams/configuration.rb +40 -1
- data/lib/datadog/data_streams/ext.rb +1 -1
- data/lib/datadog/data_streams/extensions.rb +2 -2
- data/lib/datadog/data_streams/pathway_context.rb +8 -8
- data/lib/datadog/data_streams/processor.rb +87 -85
- data/lib/datadog/data_streams/transport/http/stats.rb +9 -3
- data/lib/datadog/data_streams/transport/http.rb +5 -9
- data/lib/datadog/data_streams/transport/stats.rb +10 -17
- data/lib/datadog/data_streams.rb +5 -5
- data/lib/datadog/di/base.rb +16 -8
- data/lib/datadog/di/boot.rb +25 -23
- data/lib/datadog/di/capture_expression.rb +21 -0
- data/lib/datadog/di/capture_expression_evaluator.rb +71 -0
- data/lib/datadog/di/capture_limits.rb +41 -0
- data/lib/datadog/di/code_tracker.rb +218 -16
- data/lib/datadog/di/component.rb +137 -39
- data/lib/datadog/di/configuration.rb +241 -2
- data/lib/datadog/di/context.rb +15 -3
- data/lib/datadog/di/contrib/active_record.rb +6 -2
- data/lib/datadog/di/contrib/railtie.rb +1 -1
- data/lib/datadog/di/contrib.rb +5 -5
- data/lib/datadog/di/el/compiler.rb +114 -38
- data/lib/datadog/di/el/evaluator.rb +82 -2
- data/lib/datadog/di/el/expression.rb +13 -2
- data/lib/datadog/di/el.rb +3 -3
- data/lib/datadog/di/error.rb +10 -0
- data/lib/datadog/di/fatal_exceptions.rb +26 -0
- data/lib/datadog/di/instrumenter.rb +608 -255
- data/lib/datadog/di/logger.rb +1 -1
- data/lib/datadog/di/preload.rb +1 -1
- data/lib/datadog/di/probe.rb +71 -3
- data/lib/datadog/di/probe_builder.rb +98 -15
- data/lib/datadog/di/probe_file_loader/railtie.rb +1 -1
- data/lib/datadog/di/probe_file_loader.rb +16 -11
- data/lib/datadog/di/probe_manager.rb +153 -73
- data/lib/datadog/di/probe_notification_builder.rb +218 -38
- data/lib/datadog/di/probe_notifier_worker.rb +111 -35
- data/lib/datadog/di/probe_repository.rb +198 -0
- data/lib/datadog/di/proc_responder.rb +4 -0
- data/lib/datadog/di/redactor.rb +16 -1
- data/lib/datadog/di/remote.rb +193 -33
- data/lib/datadog/di/serializer.rb +201 -39
- data/lib/datadog/di/transport/diagnostics.rb +10 -12
- data/lib/datadog/di/transport/http/diagnostics.rb +5 -3
- data/lib/datadog/di/transport/http/input.rb +3 -3
- data/lib/datadog/di/transport/http.rb +22 -13
- data/lib/datadog/di/transport/input.rb +65 -24
- data/lib/datadog/di/utils.rb +43 -15
- data/lib/datadog/di.rb +147 -3
- data/lib/datadog/error_tracking/collector.rb +3 -2
- data/lib/datadog/error_tracking/component.rb +12 -12
- data/lib/datadog/error_tracking/configuration.rb +55 -2
- data/lib/datadog/error_tracking/ext.rb +7 -7
- data/lib/datadog/error_tracking/extensions.rb +2 -2
- data/lib/datadog/error_tracking/filters.rb +4 -4
- data/lib/datadog/error_tracking.rb +6 -6
- data/lib/datadog/kit/appsec/events/v2.rb +91 -33
- data/lib/datadog/kit/appsec/events.rb +25 -25
- data/lib/datadog/kit/enable_core_dumps.rb +3 -3
- data/lib/datadog/kit/identity.rb +18 -18
- data/lib/datadog/kit/tracing/method_tracer.rb +135 -0
- data/lib/datadog/kit.rb +1 -1
- data/lib/datadog/open_feature/component.rb +62 -13
- data/lib/datadog/open_feature/configuration.rb +24 -1
- data/lib/datadog/open_feature/evaluation_engine.rb +9 -9
- data/lib/datadog/open_feature/exposures/batch_builder.rb +1 -1
- data/lib/datadog/open_feature/exposures/buffer.rb +1 -1
- data/lib/datadog/open_feature/exposures/deduplicator.rb +1 -1
- data/lib/datadog/open_feature/exposures/event.rb +7 -7
- data/lib/datadog/open_feature/exposures/reporter.rb +3 -3
- data/lib/datadog/open_feature/exposures/worker.rb +6 -6
- data/lib/datadog/open_feature/ext.rb +13 -6
- data/lib/datadog/open_feature/flag_evaluation/aggregator.rb +286 -0
- data/lib/datadog/open_feature/flag_evaluation/writer.rb +433 -0
- data/lib/datadog/open_feature/hooks/flag_eval_evp_hook.rb +102 -0
- data/lib/datadog/open_feature/hooks/flag_eval_metrics_hook.rb +51 -0
- data/lib/datadog/open_feature/hooks/span_enrichment_hook/codec.rb +58 -0
- data/lib/datadog/open_feature/hooks/span_enrichment_hook/span_enrichment_state.rb +96 -0
- data/lib/datadog/open_feature/hooks/span_enrichment_hook/span_enrichment_state_store.rb +49 -0
- data/lib/datadog/open_feature/hooks/span_enrichment_hook.rb +184 -0
- data/lib/datadog/open_feature/metrics/flag_eval_metrics.rb +149 -0
- data/lib/datadog/open_feature/native_evaluator.rb +23 -1
- data/lib/datadog/open_feature/noop_evaluator.rb +3 -3
- data/lib/datadog/open_feature/provider.rb +106 -21
- data/lib/datadog/open_feature/remote.rb +3 -3
- data/lib/datadog/open_feature/resolution_details.rb +4 -2
- data/lib/datadog/open_feature/transport.rb +73 -22
- data/lib/datadog/open_feature.rb +2 -2
- data/lib/datadog/opentelemetry/api/baggage.rb +3 -3
- data/lib/datadog/opentelemetry/api/context.rb +4 -4
- data/lib/datadog/opentelemetry/configuration/settings.rb +95 -28
- data/lib/datadog/opentelemetry/ext.rb +9 -0
- data/lib/datadog/opentelemetry/logs.rb +98 -0
- data/lib/datadog/opentelemetry/metrics.rb +17 -44
- data/lib/datadog/opentelemetry/sdk/configurator.rb +46 -6
- data/lib/datadog/opentelemetry/sdk/id_generator.rb +16 -10
- data/lib/datadog/opentelemetry/sdk/logs_exporter.rb +30 -0
- data/lib/datadog/opentelemetry/sdk/metrics_exporter.rb +9 -16
- data/lib/datadog/opentelemetry/sdk/propagator.rb +16 -10
- data/lib/datadog/opentelemetry/sdk/span_processor.rb +18 -15
- data/lib/datadog/opentelemetry/sdk/trace/span.rb +32 -32
- data/lib/datadog/opentelemetry/sdk.rb +19 -0
- data/lib/datadog/opentelemetry/signal_configuration.rb +53 -0
- data/lib/datadog/opentelemetry/trace.rb +1 -1
- data/lib/datadog/opentelemetry.rb +8 -7
- data/lib/datadog/profiling/collectors/code_provenance.rb +36 -11
- data/lib/datadog/profiling/collectors/cpu_and_wall_time_worker.rb +50 -3
- data/lib/datadog/profiling/collectors/idle_sampling_helper.rb +12 -4
- data/lib/datadog/profiling/collectors/info.rb +17 -4
- data/lib/datadog/profiling/collectors/thread_context.rb +16 -18
- data/lib/datadog/profiling/component.rb +62 -33
- data/lib/datadog/profiling/exporter.rb +38 -13
- data/lib/datadog/profiling/ext/dir_monkey_patches.rb +6 -5
- data/lib/datadog/profiling/ext.rb +0 -2
- data/lib/datadog/profiling/flush.rb +21 -12
- data/lib/datadog/profiling/http_transport.rb +18 -8
- data/lib/datadog/profiling/load_native_extension.rb +2 -2
- data/lib/datadog/profiling/profiler.rb +28 -13
- data/lib/datadog/profiling/scheduler.rb +2 -2
- data/lib/datadog/profiling/sequence_tracker.rb +1 -1
- data/lib/datadog/profiling/stack_recorder.rb +0 -8
- data/lib/datadog/profiling/tag_builder.rb +19 -19
- data/lib/datadog/profiling/tasks/exec.rb +9 -4
- data/lib/datadog/profiling/tasks/help.rb +1 -0
- data/lib/datadog/profiling/tasks/setup.rb +2 -2
- data/lib/datadog/profiling.rb +32 -29
- data/lib/datadog/ruby_version.rb +25 -0
- data/lib/datadog/single_step_instrument.rb +2 -2
- data/lib/datadog/symbol_database/component.rb +734 -0
- data/lib/datadog/symbol_database/configuration.rb +73 -0
- data/lib/datadog/symbol_database/extensions.rb +19 -0
- data/lib/datadog/symbol_database/extractor.rb +1110 -0
- data/lib/datadog/symbol_database/file_hash.rb +48 -0
- data/lib/datadog/symbol_database/logger.rb +43 -0
- data/lib/datadog/symbol_database/remote.rb +195 -0
- data/lib/datadog/symbol_database/scope.rb +102 -0
- data/lib/datadog/symbol_database/scope_batcher.rb +292 -0
- data/lib/datadog/symbol_database/service_version.rb +66 -0
- data/lib/datadog/symbol_database/symbol.rb +69 -0
- data/lib/datadog/symbol_database/transport/http/endpoint.rb +28 -0
- data/lib/datadog/symbol_database/transport/http.rb +45 -0
- data/lib/datadog/symbol_database/transport.rb +54 -0
- data/lib/datadog/symbol_database/uploader.rb +230 -0
- data/lib/datadog/symbol_database.rb +71 -0
- data/lib/datadog/tracing/analytics.rb +1 -1
- data/lib/datadog/tracing/buffer.rb +8 -8
- data/lib/datadog/tracing/client_ip.rb +4 -4
- data/lib/datadog/tracing/component.rb +39 -7
- data/lib/datadog/tracing/configuration/dynamic/option.rb +4 -0
- data/lib/datadog/tracing/configuration/dynamic.rb +13 -11
- data/lib/datadog/tracing/configuration/ext.rb +52 -38
- data/lib/datadog/tracing/configuration/http.rb +2 -2
- data/lib/datadog/tracing/configuration/settings.rb +51 -17
- data/lib/datadog/tracing/context.rb +1 -1
- data/lib/datadog/tracing/context_provider.rb +2 -2
- data/lib/datadog/tracing/contrib/action_cable/configuration/settings.rb +2 -2
- data/lib/datadog/tracing/contrib/action_cable/event.rb +4 -4
- data/lib/datadog/tracing/contrib/action_cable/events/broadcast.rb +9 -6
- data/lib/datadog/tracing/contrib/action_cable/events/perform_action.rb +8 -5
- data/lib/datadog/tracing/contrib/action_cable/events/transmit.rb +9 -6
- data/lib/datadog/tracing/contrib/action_cable/events.rb +5 -5
- data/lib/datadog/tracing/contrib/action_cable/ext.rb +18 -18
- data/lib/datadog/tracing/contrib/action_cable/instrumentation.rb +8 -5
- data/lib/datadog/tracing/contrib/action_cable/integration.rb +7 -7
- data/lib/datadog/tracing/contrib/action_cable/patcher.rb +4 -4
- data/lib/datadog/tracing/contrib/action_mailer/configuration/settings.rb +2 -2
- data/lib/datadog/tracing/contrib/action_mailer/event.rb +7 -4
- data/lib/datadog/tracing/contrib/action_mailer/events/deliver.rb +8 -8
- data/lib/datadog/tracing/contrib/action_mailer/events/process.rb +4 -4
- data/lib/datadog/tracing/contrib/action_mailer/events.rb +3 -3
- data/lib/datadog/tracing/contrib/action_mailer/ext.rb +18 -18
- data/lib/datadog/tracing/contrib/action_mailer/integration.rb +7 -7
- data/lib/datadog/tracing/contrib/action_mailer/patcher.rb +3 -3
- data/lib/datadog/tracing/contrib/action_pack/action_controller/instrumentation.rb +15 -12
- data/lib/datadog/tracing/contrib/action_pack/action_controller/patcher.rb +2 -2
- data/lib/datadog/tracing/contrib/action_pack/action_dispatch/instrumentation.rb +31 -3
- data/lib/datadog/tracing/contrib/action_pack/action_dispatch/patcher.rb +5 -3
- data/lib/datadog/tracing/contrib/action_pack/configuration/settings.rb +3 -3
- data/lib/datadog/tracing/contrib/action_pack/ext.rb +10 -10
- data/lib/datadog/tracing/contrib/action_pack/integration.rb +7 -7
- data/lib/datadog/tracing/contrib/action_pack/patcher.rb +3 -3
- data/lib/datadog/tracing/contrib/action_pack/utils.rb +1 -1
- data/lib/datadog/tracing/contrib/action_view/configuration/settings.rb +3 -3
- data/lib/datadog/tracing/contrib/action_view/event.rb +1 -1
- data/lib/datadog/tracing/contrib/action_view/events/render_partial.rb +10 -7
- data/lib/datadog/tracing/contrib/action_view/events/render_template.rb +11 -8
- data/lib/datadog/tracing/contrib/action_view/events.rb +3 -3
- data/lib/datadog/tracing/contrib/action_view/ext.rb +10 -10
- data/lib/datadog/tracing/contrib/action_view/integration.rb +11 -11
- data/lib/datadog/tracing/contrib/action_view/patcher.rb +5 -5
- data/lib/datadog/tracing/contrib/action_view/utils.rb +2 -2
- data/lib/datadog/tracing/contrib/active_job/configuration/settings.rb +2 -2
- data/lib/datadog/tracing/contrib/active_job/data_streams.rb +62 -0
- data/lib/datadog/tracing/contrib/active_job/event.rb +3 -3
- data/lib/datadog/tracing/contrib/active_job/events/discard.rb +10 -7
- data/lib/datadog/tracing/contrib/active_job/events/enqueue.rb +10 -7
- data/lib/datadog/tracing/contrib/active_job/events/enqueue_at.rb +10 -7
- data/lib/datadog/tracing/contrib/active_job/events/enqueue_retry.rb +10 -7
- data/lib/datadog/tracing/contrib/active_job/events/perform.rb +10 -7
- data/lib/datadog/tracing/contrib/active_job/events/retry_stopped.rb +10 -7
- data/lib/datadog/tracing/contrib/active_job/events.rb +6 -6
- data/lib/datadog/tracing/contrib/active_job/ext.rb +23 -23
- data/lib/datadog/tracing/contrib/active_job/integration.rb +7 -7
- data/lib/datadog/tracing/contrib/active_job/patcher.rb +17 -5
- data/lib/datadog/tracing/contrib/active_model_serializers/configuration/settings.rb +2 -2
- data/lib/datadog/tracing/contrib/active_model_serializers/event.rb +4 -4
- data/lib/datadog/tracing/contrib/active_model_serializers/events/render.rb +7 -7
- data/lib/datadog/tracing/contrib/active_model_serializers/events/serialize.rb +8 -9
- data/lib/datadog/tracing/contrib/active_model_serializers/events.rb +3 -3
- data/lib/datadog/tracing/contrib/active_model_serializers/ext.rb +10 -10
- data/lib/datadog/tracing/contrib/active_model_serializers/integration.rb +5 -5
- data/lib/datadog/tracing/contrib/active_model_serializers/patcher.rb +3 -3
- data/lib/datadog/tracing/contrib/active_record/configuration/makara_resolver.rb +1 -1
- data/lib/datadog/tracing/contrib/active_record/configuration/resolver.rb +9 -9
- data/lib/datadog/tracing/contrib/active_record/configuration/settings.rb +4 -4
- data/lib/datadog/tracing/contrib/active_record/event.rb +1 -1
- data/lib/datadog/tracing/contrib/active_record/events/instantiation.rb +9 -9
- data/lib/datadog/tracing/contrib/active_record/events/sql.rb +11 -14
- data/lib/datadog/tracing/contrib/active_record/events.rb +3 -3
- data/lib/datadog/tracing/contrib/active_record/ext.rb +15 -15
- data/lib/datadog/tracing/contrib/active_record/integration.rb +11 -11
- data/lib/datadog/tracing/contrib/active_record/patcher.rb +2 -2
- data/lib/datadog/tracing/contrib/active_record/utils.rb +4 -4
- data/lib/datadog/tracing/contrib/active_support/cache/event.rb +1 -1
- data/lib/datadog/tracing/contrib/active_support/cache/events/cache.rb +14 -17
- data/lib/datadog/tracing/contrib/active_support/cache/events.rb +1 -1
- data/lib/datadog/tracing/contrib/active_support/cache/instrumentation.rb +5 -8
- data/lib/datadog/tracing/contrib/active_support/cache/patcher.rb +5 -5
- data/lib/datadog/tracing/contrib/active_support/cache/redis.rb +4 -4
- data/lib/datadog/tracing/contrib/active_support/configuration/settings.rb +3 -3
- data/lib/datadog/tracing/contrib/active_support/ext.rb +16 -16
- data/lib/datadog/tracing/contrib/active_support/integration.rb +8 -8
- data/lib/datadog/tracing/contrib/active_support/notifications/event.rb +1 -1
- data/lib/datadog/tracing/contrib/active_support/notifications/subscriber.rb +2 -2
- data/lib/datadog/tracing/contrib/active_support/notifications/subscription.rb +3 -3
- data/lib/datadog/tracing/contrib/active_support/patcher.rb +2 -2
- data/lib/datadog/tracing/contrib/analytics.rb +1 -1
- data/lib/datadog/tracing/contrib/auto_instrument.rb +4 -4
- data/lib/datadog/tracing/contrib/aws/configuration/settings.rb +3 -3
- data/lib/datadog/tracing/contrib/aws/ext.rb +26 -26
- data/lib/datadog/tracing/contrib/aws/instrumentation.rb +7 -11
- data/lib/datadog/tracing/contrib/aws/integration.rb +9 -9
- data/lib/datadog/tracing/contrib/aws/parsed_context.rb +1 -1
- data/lib/datadog/tracing/contrib/aws/patcher.rb +5 -5
- data/lib/datadog/tracing/contrib/aws/service/dynamodb.rb +2 -2
- data/lib/datadog/tracing/contrib/aws/service/eventbridge.rb +2 -2
- data/lib/datadog/tracing/contrib/aws/service/kinesis.rb +4 -4
- data/lib/datadog/tracing/contrib/aws/service/s3.rb +2 -2
- data/lib/datadog/tracing/contrib/aws/service/sns.rb +3 -3
- data/lib/datadog/tracing/contrib/aws/service/sqs.rb +3 -3
- data/lib/datadog/tracing/contrib/aws/service/states.rb +5 -5
- data/lib/datadog/tracing/contrib/aws/services.rb +14 -14
- data/lib/datadog/tracing/contrib/component.rb +1 -1
- data/lib/datadog/tracing/contrib/concurrent_ruby/async_patch.rb +1 -1
- data/lib/datadog/tracing/contrib/concurrent_ruby/configuration/settings.rb +2 -2
- data/lib/datadog/tracing/contrib/concurrent_ruby/context_composite_executor_service.rb +1 -1
- data/lib/datadog/tracing/contrib/concurrent_ruby/ext.rb +2 -2
- data/lib/datadog/tracing/contrib/concurrent_ruby/future_patch.rb +1 -1
- data/lib/datadog/tracing/contrib/concurrent_ruby/integration.rb +6 -6
- data/lib/datadog/tracing/contrib/concurrent_ruby/patcher.rb +4 -4
- data/lib/datadog/tracing/contrib/concurrent_ruby/promises_future_patch.rb +1 -1
- data/lib/datadog/tracing/contrib/configurable.rb +20 -5
- data/lib/datadog/tracing/contrib/configuration/resolver.rb +14 -4
- data/lib/datadog/tracing/contrib/configuration/resolvers/pattern_resolver.rb +1 -1
- data/lib/datadog/tracing/contrib/configuration/settings.rb +2 -2
- data/lib/datadog/tracing/contrib/dalli/configuration/settings.rb +2 -2
- data/lib/datadog/tracing/contrib/dalli/ext.rb +13 -13
- data/lib/datadog/tracing/contrib/dalli/instrumentation.rb +6 -10
- data/lib/datadog/tracing/contrib/dalli/integration.rb +10 -7
- data/lib/datadog/tracing/contrib/dalli/patcher.rb +3 -3
- data/lib/datadog/tracing/contrib/dalli/quantize.rb +3 -3
- data/lib/datadog/tracing/contrib/delayed_job/configuration/settings.rb +2 -2
- data/lib/datadog/tracing/contrib/delayed_job/ext.rb +14 -14
- data/lib/datadog/tracing/contrib/delayed_job/integration.rb +5 -5
- data/lib/datadog/tracing/contrib/delayed_job/patcher.rb +3 -3
- data/lib/datadog/tracing/contrib/delayed_job/plugin.rb +7 -5
- data/lib/datadog/tracing/contrib/delayed_job/server_internal_tracer/worker.rb +1 -0
- data/lib/datadog/tracing/contrib/elasticsearch/configuration/settings.rb +2 -2
- data/lib/datadog/tracing/contrib/elasticsearch/ext.rb +15 -15
- data/lib/datadog/tracing/contrib/elasticsearch/integration.rb +6 -6
- data/lib/datadog/tracing/contrib/elasticsearch/patcher.rb +12 -16
- data/lib/datadog/tracing/contrib/elasticsearch/quantize.rb +4 -4
- data/lib/datadog/tracing/contrib/ethon/configuration/settings.rb +7 -3
- data/lib/datadog/tracing/contrib/ethon/easy_patch.rb +9 -13
- data/lib/datadog/tracing/contrib/ethon/ext.rb +13 -12
- data/lib/datadog/tracing/contrib/ethon/integration.rb +6 -6
- data/lib/datadog/tracing/contrib/ethon/multi_patch.rb +4 -11
- data/lib/datadog/tracing/contrib/ethon/patcher.rb +3 -3
- data/lib/datadog/tracing/contrib/excon/configuration/settings.rb +10 -7
- data/lib/datadog/tracing/contrib/excon/ext.rb +11 -10
- data/lib/datadog/tracing/contrib/excon/integration.rb +6 -6
- data/lib/datadog/tracing/contrib/excon/middleware.rb +10 -14
- data/lib/datadog/tracing/contrib/excon/patcher.rb +2 -2
- data/lib/datadog/tracing/contrib/ext.rb +20 -18
- data/lib/datadog/tracing/contrib/extensions.rb +11 -2
- data/lib/datadog/tracing/contrib/faraday/configuration/settings.rb +9 -6
- data/lib/datadog/tracing/contrib/faraday/ext.rb +11 -10
- data/lib/datadog/tracing/contrib/faraday/integration.rb +6 -6
- data/lib/datadog/tracing/contrib/faraday/middleware.rb +10 -14
- data/lib/datadog/tracing/contrib/faraday/patcher.rb +6 -6
- data/lib/datadog/tracing/contrib/grape/configuration/settings.rb +4 -4
- data/lib/datadog/tracing/contrib/grape/endpoint.rb +30 -27
- data/lib/datadog/tracing/contrib/grape/ext.rb +15 -15
- data/lib/datadog/tracing/contrib/grape/instrumentation.rb +15 -10
- data/lib/datadog/tracing/contrib/grape/integration.rb +5 -5
- data/lib/datadog/tracing/contrib/grape/patcher.rb +10 -5
- data/lib/datadog/tracing/contrib/graphql/configuration/error_extension_env_parser.rb +1 -1
- data/lib/datadog/tracing/contrib/graphql/configuration/settings.rb +3 -3
- data/lib/datadog/tracing/contrib/graphql/ext.rb +9 -9
- data/lib/datadog/tracing/contrib/graphql/integration.rb +9 -9
- data/lib/datadog/tracing/contrib/graphql/patcher.rb +7 -7
- data/lib/datadog/tracing/contrib/graphql/unified_trace.rb +38 -37
- data/lib/datadog/tracing/contrib/graphql/unified_trace_patcher.rb +2 -2
- data/lib/datadog/tracing/contrib/grpc/configuration/settings.rb +7 -4
- data/lib/datadog/tracing/contrib/grpc/datadog_interceptor/client.rb +11 -15
- data/lib/datadog/tracing/contrib/grpc/datadog_interceptor/server.rb +11 -15
- data/lib/datadog/tracing/contrib/grpc/datadog_interceptor.rb +6 -6
- data/lib/datadog/tracing/contrib/grpc/distributed/fetcher.rb +1 -1
- data/lib/datadog/tracing/contrib/grpc/distributed/propagation.rb +11 -9
- data/lib/datadog/tracing/contrib/grpc/ext.rb +14 -13
- data/lib/datadog/tracing/contrib/grpc/formatting.rb +7 -7
- data/lib/datadog/tracing/contrib/grpc/integration.rb +5 -5
- data/lib/datadog/tracing/contrib/grpc/intercept_with_datadog.rb +1 -1
- data/lib/datadog/tracing/contrib/grpc/patcher.rb +3 -3
- data/lib/datadog/tracing/contrib/grpc.rb +7 -6
- data/lib/datadog/tracing/contrib/hanami/action_tracer.rb +4 -3
- data/lib/datadog/tracing/contrib/hanami/configuration/settings.rb +2 -2
- data/lib/datadog/tracing/contrib/hanami/ext.rb +8 -8
- data/lib/datadog/tracing/contrib/hanami/integration.rb +6 -6
- data/lib/datadog/tracing/contrib/hanami/patcher.rb +5 -5
- data/lib/datadog/tracing/contrib/hanami/renderer_policy_tracing.rb +4 -3
- data/lib/datadog/tracing/contrib/hanami/router_tracing.rb +6 -4
- data/lib/datadog/tracing/contrib/http/circuit_breaker.rb +1 -1
- data/lib/datadog/tracing/contrib/http/configuration/settings.rb +9 -6
- data/lib/datadog/tracing/contrib/http/distributed/fetcher.rb +3 -3
- data/lib/datadog/tracing/contrib/http/distributed/propagation.rb +10 -8
- data/lib/datadog/tracing/contrib/http/ext.rb +11 -10
- data/lib/datadog/tracing/contrib/http/instrumentation.rb +10 -14
- data/lib/datadog/tracing/contrib/http/integration.rb +7 -9
- data/lib/datadog/tracing/contrib/http/patcher.rb +3 -3
- data/lib/datadog/tracing/contrib/http.rb +7 -6
- data/lib/datadog/tracing/contrib/httpclient/configuration/settings.rb +9 -6
- data/lib/datadog/tracing/contrib/httpclient/ext.rb +11 -10
- data/lib/datadog/tracing/contrib/httpclient/instrumentation.rb +12 -12
- data/lib/datadog/tracing/contrib/httpclient/integration.rb +6 -6
- data/lib/datadog/tracing/contrib/httpclient/patcher.rb +3 -3
- data/lib/datadog/tracing/contrib/httprb/configuration/settings.rb +9 -6
- data/lib/datadog/tracing/contrib/httprb/ext.rb +11 -10
- data/lib/datadog/tracing/contrib/httprb/instrumentation.rb +10 -14
- data/lib/datadog/tracing/contrib/httprb/integration.rb +7 -7
- data/lib/datadog/tracing/contrib/httprb/patcher.rb +3 -3
- data/lib/datadog/tracing/contrib/integration.rb +3 -3
- data/lib/datadog/tracing/contrib/kafka/configuration/settings.rb +2 -2
- data/lib/datadog/tracing/contrib/kafka/event.rb +4 -3
- data/lib/datadog/tracing/contrib/kafka/events/connection/request.rb +7 -3
- data/lib/datadog/tracing/contrib/kafka/events/consumer/process_batch.rb +4 -4
- data/lib/datadog/tracing/contrib/kafka/events/consumer/process_message.rb +4 -4
- data/lib/datadog/tracing/contrib/kafka/events/consumer_group/heartbeat.rb +5 -5
- data/lib/datadog/tracing/contrib/kafka/events/consumer_group/join_group.rb +5 -5
- data/lib/datadog/tracing/contrib/kafka/events/consumer_group/leave_group.rb +5 -5
- data/lib/datadog/tracing/contrib/kafka/events/consumer_group/sync_group.rb +5 -5
- data/lib/datadog/tracing/contrib/kafka/events/produce_operation/send_messages.rb +10 -5
- data/lib/datadog/tracing/contrib/kafka/events/producer/deliver_messages.rb +10 -5
- data/lib/datadog/tracing/contrib/kafka/events.rb +10 -10
- data/lib/datadog/tracing/contrib/kafka/ext.rb +40 -40
- data/lib/datadog/tracing/contrib/kafka/instrumentation/consumer.rb +4 -4
- data/lib/datadog/tracing/contrib/kafka/instrumentation/producer.rb +6 -6
- data/lib/datadog/tracing/contrib/kafka/integration.rb +6 -6
- data/lib/datadog/tracing/contrib/kafka/patcher.rb +5 -5
- data/lib/datadog/tracing/contrib/karafka/configuration/settings.rb +7 -3
- data/lib/datadog/tracing/contrib/karafka/distributed/propagation.rb +11 -9
- data/lib/datadog/tracing/contrib/karafka/ext.rb +13 -12
- data/lib/datadog/tracing/contrib/karafka/integration.rb +5 -5
- data/lib/datadog/tracing/contrib/karafka/monitor.rb +14 -14
- data/lib/datadog/tracing/contrib/karafka/patcher.rb +9 -9
- data/lib/datadog/tracing/contrib/karafka.rb +7 -6
- data/lib/datadog/tracing/contrib/lograge/configuration/settings.rb +2 -2
- data/lib/datadog/tracing/contrib/lograge/ext.rb +1 -1
- data/lib/datadog/tracing/contrib/lograge/integration.rb +5 -5
- data/lib/datadog/tracing/contrib/lograge/patcher.rb +9 -9
- data/lib/datadog/tracing/contrib/mongodb/configuration/settings.rb +2 -2
- data/lib/datadog/tracing/contrib/mongodb/ext.rb +18 -18
- data/lib/datadog/tracing/contrib/mongodb/instrumentation.rb +3 -3
- data/lib/datadog/tracing/contrib/mongodb/integration.rb +7 -7
- data/lib/datadog/tracing/contrib/mongodb/parsers.rb +9 -9
- data/lib/datadog/tracing/contrib/mongodb/patcher.rb +3 -3
- data/lib/datadog/tracing/contrib/mongodb/subscribers.rb +18 -21
- data/lib/datadog/tracing/contrib/mysql2/configuration/settings.rb +9 -3
- data/lib/datadog/tracing/contrib/mysql2/ext.rb +11 -11
- data/lib/datadog/tracing/contrib/mysql2/instrumentation.rb +9 -12
- data/lib/datadog/tracing/contrib/mysql2/integration.rb +5 -5
- data/lib/datadog/tracing/contrib/mysql2/patcher.rb +2 -2
- data/lib/datadog/tracing/contrib/opensearch/configuration/settings.rb +2 -2
- data/lib/datadog/tracing/contrib/opensearch/ext.rb +23 -23
- data/lib/datadog/tracing/contrib/opensearch/integration.rb +6 -6
- data/lib/datadog/tracing/contrib/opensearch/patcher.rb +15 -19
- data/lib/datadog/tracing/contrib/opensearch/quantize.rb +5 -5
- data/lib/datadog/tracing/contrib/patchable.rb +1 -1
- data/lib/datadog/tracing/contrib/patcher.rb +3 -3
- data/lib/datadog/tracing/contrib/pg/configuration/settings.rb +9 -3
- data/lib/datadog/tracing/contrib/pg/ext.rb +19 -19
- data/lib/datadog/tracing/contrib/pg/instrumentation.rb +21 -24
- data/lib/datadog/tracing/contrib/pg/integration.rb +5 -5
- data/lib/datadog/tracing/contrib/pg/patcher.rb +2 -2
- data/lib/datadog/tracing/contrib/presto/configuration/settings.rb +2 -2
- data/lib/datadog/tracing/contrib/presto/ext.rb +21 -21
- data/lib/datadog/tracing/contrib/presto/instrumentation.rb +8 -10
- data/lib/datadog/tracing/contrib/presto/integration.rb +6 -6
- data/lib/datadog/tracing/contrib/presto/patcher.rb +4 -4
- data/lib/datadog/tracing/contrib/propagation/sql_comment/comment.rb +2 -2
- data/lib/datadog/tracing/contrib/propagation/sql_comment/ext.rb +26 -13
- data/lib/datadog/tracing/contrib/propagation/sql_comment/mode.rb +7 -3
- data/lib/datadog/tracing/contrib/propagation/sql_comment.rb +29 -5
- data/lib/datadog/tracing/contrib/que/configuration/settings.rb +7 -4
- data/lib/datadog/tracing/contrib/que/ext.rb +19 -18
- data/lib/datadog/tracing/contrib/que/integration.rb +6 -6
- data/lib/datadog/tracing/contrib/que/patcher.rb +1 -1
- data/lib/datadog/tracing/contrib/que/tracer.rb +3 -2
- data/lib/datadog/tracing/contrib/racecar/configuration/settings.rb +3 -3
- data/lib/datadog/tracing/contrib/racecar/event.rb +5 -9
- data/lib/datadog/tracing/contrib/racecar/events/batch.rb +3 -3
- data/lib/datadog/tracing/contrib/racecar/events/consume.rb +3 -3
- data/lib/datadog/tracing/contrib/racecar/events/message.rb +3 -3
- data/lib/datadog/tracing/contrib/racecar/events.rb +4 -4
- data/lib/datadog/tracing/contrib/racecar/ext.rb +18 -18
- data/lib/datadog/tracing/contrib/racecar/integration.rb +5 -5
- data/lib/datadog/tracing/contrib/racecar/patcher.rb +3 -3
- data/lib/datadog/tracing/contrib/rack/configuration/settings.rb +14 -4
- data/lib/datadog/tracing/contrib/rack/ext.rb +43 -15
- data/lib/datadog/tracing/contrib/rack/header_collection.rb +3 -3
- data/lib/datadog/tracing/contrib/rack/header_tagging.rb +24 -1
- data/lib/datadog/tracing/contrib/rack/integration.rb +6 -6
- data/lib/datadog/tracing/contrib/rack/middlewares.rb +28 -25
- data/lib/datadog/tracing/contrib/rack/patcher.rb +5 -5
- data/lib/datadog/tracing/contrib/rack/request_queue.rb +4 -4
- data/lib/datadog/tracing/contrib/rack/route_inference.rb +27 -13
- data/lib/datadog/tracing/contrib/rack/trace_proxy_middleware.rb +124 -6
- data/lib/datadog/tracing/contrib/rails/auto_instrument_railtie.rb +1 -1
- data/lib/datadog/tracing/contrib/rails/configuration/settings.rb +8 -5
- data/lib/datadog/tracing/contrib/rails/ext.rb +15 -14
- data/lib/datadog/tracing/contrib/rails/framework.rb +11 -11
- data/lib/datadog/tracing/contrib/rails/integration.rb +5 -5
- data/lib/datadog/tracing/contrib/rails/log_injection.rb +1 -1
- data/lib/datadog/tracing/contrib/rails/middlewares.rb +1 -1
- data/lib/datadog/tracing/contrib/rails/patcher.rb +8 -9
- data/lib/datadog/tracing/contrib/rails/railtie.rb +4 -4
- data/lib/datadog/tracing/contrib/rails/runner.rb +4 -2
- data/lib/datadog/tracing/contrib/rake/configuration/settings.rb +3 -3
- data/lib/datadog/tracing/contrib/rake/ext.rb +12 -12
- data/lib/datadog/tracing/contrib/rake/instrumentation.rb +9 -7
- data/lib/datadog/tracing/contrib/rake/integration.rb +5 -5
- data/lib/datadog/tracing/contrib/rake/patcher.rb +3 -3
- data/lib/datadog/tracing/contrib/redis/configuration/resolver.rb +3 -3
- data/lib/datadog/tracing/contrib/redis/configuration/settings.rb +2 -2
- data/lib/datadog/tracing/contrib/redis/ext.rb +16 -16
- data/lib/datadog/tracing/contrib/redis/instrumentation.rb +6 -6
- data/lib/datadog/tracing/contrib/redis/integration.rb +7 -7
- data/lib/datadog/tracing/contrib/redis/patcher.rb +10 -10
- data/lib/datadog/tracing/contrib/redis/quantize.rb +40 -6
- data/lib/datadog/tracing/contrib/redis/tags.rb +6 -11
- data/lib/datadog/tracing/contrib/redis/trace_middleware.rb +16 -8
- data/lib/datadog/tracing/contrib/registerable.rb +11 -0
- data/lib/datadog/tracing/contrib/resque/configuration/settings.rb +2 -2
- data/lib/datadog/tracing/contrib/resque/ext.rb +7 -7
- data/lib/datadog/tracing/contrib/resque/integration.rb +5 -5
- data/lib/datadog/tracing/contrib/resque/patcher.rb +3 -3
- data/lib/datadog/tracing/contrib/resque/resque_job.rb +6 -5
- data/lib/datadog/tracing/contrib/rest_client/configuration/settings.rb +7 -4
- data/lib/datadog/tracing/contrib/rest_client/ext.rb +10 -9
- data/lib/datadog/tracing/contrib/rest_client/integration.rb +6 -6
- data/lib/datadog/tracing/contrib/rest_client/patcher.rb +2 -2
- data/lib/datadog/tracing/contrib/rest_client/request_patch.rb +6 -10
- data/lib/datadog/tracing/contrib/roda/configuration/settings.rb +2 -2
- data/lib/datadog/tracing/contrib/roda/ext.rb +6 -5
- data/lib/datadog/tracing/contrib/roda/instrumentation.rb +8 -5
- data/lib/datadog/tracing/contrib/roda/integration.rb +6 -6
- data/lib/datadog/tracing/contrib/roda/patcher.rb +3 -3
- data/lib/datadog/tracing/contrib/semantic_logger/configuration/settings.rb +2 -2
- data/lib/datadog/tracing/contrib/semantic_logger/ext.rb +1 -1
- data/lib/datadog/tracing/contrib/semantic_logger/integration.rb +5 -5
- data/lib/datadog/tracing/contrib/semantic_logger/patcher.rb +2 -2
- data/lib/datadog/tracing/contrib/sequel/configuration/settings.rb +2 -2
- data/lib/datadog/tracing/contrib/sequel/database.rb +7 -10
- data/lib/datadog/tracing/contrib/sequel/dataset.rb +6 -5
- data/lib/datadog/tracing/contrib/sequel/ext.rb +12 -8
- data/lib/datadog/tracing/contrib/sequel/integration.rb +5 -5
- data/lib/datadog/tracing/contrib/sequel/patcher.rb +3 -3
- data/lib/datadog/tracing/contrib/sequel/utils.rb +116 -16
- data/lib/datadog/tracing/contrib/shoryuken/configuration/settings.rb +2 -2
- data/lib/datadog/tracing/contrib/shoryuken/ext.rb +12 -12
- data/lib/datadog/tracing/contrib/shoryuken/integration.rb +6 -6
- data/lib/datadog/tracing/contrib/shoryuken/patcher.rb +1 -1
- data/lib/datadog/tracing/contrib/shoryuken/tracer.rb +3 -2
- data/lib/datadog/tracing/contrib/sidekiq/client_tracer.rb +9 -8
- data/lib/datadog/tracing/contrib/sidekiq/configuration/settings.rb +7 -3
- data/lib/datadog/tracing/contrib/sidekiq/distributed/propagation.rb +12 -10
- data/lib/datadog/tracing/contrib/sidekiq/ext.rb +30 -29
- data/lib/datadog/tracing/contrib/sidekiq/integration.rb +7 -7
- data/lib/datadog/tracing/contrib/sidekiq/patcher.rb +8 -8
- data/lib/datadog/tracing/contrib/sidekiq/server_internal_tracer/heartbeat.rb +2 -0
- data/lib/datadog/tracing/contrib/sidekiq/server_internal_tracer/job_fetch.rb +1 -0
- data/lib/datadog/tracing/contrib/sidekiq/server_internal_tracer/redis_info.rb +1 -0
- data/lib/datadog/tracing/contrib/sidekiq/server_internal_tracer/scheduled_poller.rb +2 -0
- data/lib/datadog/tracing/contrib/sidekiq/server_internal_tracer/stop.rb +1 -0
- data/lib/datadog/tracing/contrib/sidekiq/server_tracer.rb +15 -14
- data/lib/datadog/tracing/contrib/sidekiq/utils.rb +10 -10
- data/lib/datadog/tracing/contrib/sidekiq.rb +7 -6
- data/lib/datadog/tracing/contrib/sinatra/configuration/settings.rb +8 -4
- data/lib/datadog/tracing/contrib/sinatra/env.rb +6 -6
- data/lib/datadog/tracing/contrib/sinatra/ext.rb +17 -16
- data/lib/datadog/tracing/contrib/sinatra/framework.rb +2 -2
- data/lib/datadog/tracing/contrib/sinatra/integration.rb +5 -5
- data/lib/datadog/tracing/contrib/sinatra/patcher.rb +5 -5
- data/lib/datadog/tracing/contrib/sinatra/tracer.rb +11 -10
- data/lib/datadog/tracing/contrib/sinatra/tracer_middleware.rb +9 -8
- data/lib/datadog/tracing/contrib/sneakers/configuration/settings.rb +1 -1
- data/lib/datadog/tracing/contrib/sneakers/ext.rb +12 -12
- data/lib/datadog/tracing/contrib/sneakers/integration.rb +19 -8
- data/lib/datadog/tracing/contrib/sneakers/patcher.rb +2 -2
- data/lib/datadog/tracing/contrib/sneakers/tracer.rb +5 -4
- data/lib/datadog/tracing/contrib/span_attribute_schema.rb +2 -2
- data/lib/datadog/tracing/contrib/status_range_env_parser.rb +2 -2
- data/lib/datadog/tracing/contrib/status_range_matcher.rb +4 -0
- data/lib/datadog/tracing/contrib/stripe/configuration/settings.rb +2 -2
- data/lib/datadog/tracing/contrib/stripe/ext.rb +12 -12
- data/lib/datadog/tracing/contrib/stripe/integration.rb +5 -5
- data/lib/datadog/tracing/contrib/stripe/patcher.rb +2 -2
- data/lib/datadog/tracing/contrib/stripe/request.rb +4 -4
- data/lib/datadog/tracing/contrib/sucker_punch/configuration/settings.rb +2 -2
- data/lib/datadog/tracing/contrib/sucker_punch/exception_handler.rb +1 -1
- data/lib/datadog/tracing/contrib/sucker_punch/ext.rb +13 -13
- data/lib/datadog/tracing/contrib/sucker_punch/instrumentation.rb +5 -4
- data/lib/datadog/tracing/contrib/sucker_punch/integration.rb +5 -5
- data/lib/datadog/tracing/contrib/sucker_punch/patcher.rb +4 -4
- data/lib/datadog/tracing/contrib/trilogy/configuration/settings.rb +9 -3
- data/lib/datadog/tracing/contrib/trilogy/ext.rb +11 -11
- data/lib/datadog/tracing/contrib/trilogy/instrumentation.rb +10 -12
- data/lib/datadog/tracing/contrib/trilogy/integration.rb +5 -5
- data/lib/datadog/tracing/contrib/trilogy/patcher.rb +2 -2
- data/lib/datadog/tracing/contrib/utils/database.rb +5 -5
- data/lib/datadog/tracing/contrib/utils/quantization/{hash.rb → hash_formatter.rb} +3 -3
- data/lib/datadog/tracing/contrib/utils/quantization/http.rb +10 -10
- data/lib/datadog/tracing/contrib/waterdrop/configuration/settings.rb +7 -3
- data/lib/datadog/tracing/contrib/waterdrop/distributed/propagation.rb +11 -9
- data/lib/datadog/tracing/contrib/waterdrop/ext.rb +4 -3
- data/lib/datadog/tracing/contrib/waterdrop/integration.rb +5 -5
- data/lib/datadog/tracing/contrib/waterdrop/middleware.rb +2 -2
- data/lib/datadog/tracing/contrib/waterdrop/patcher.rb +7 -7
- data/lib/datadog/tracing/contrib/waterdrop/producer.rb +3 -3
- data/lib/datadog/tracing/contrib/waterdrop.rb +7 -6
- data/lib/datadog/tracing/contrib.rb +62 -54
- data/lib/datadog/tracing/correlation.rb +12 -12
- data/lib/datadog/tracing/diagnostics/environment_logger.rb +14 -12
- data/lib/datadog/tracing/diagnostics/ext.rb +19 -19
- data/lib/datadog/tracing/diagnostics/health.rb +1 -1
- data/lib/datadog/tracing/distributed/b3_multi.rb +8 -8
- data/lib/datadog/tracing/distributed/b3_single.rb +4 -4
- data/lib/datadog/tracing/distributed/baggage.rb +82 -28
- data/lib/datadog/tracing/distributed/datadog.rb +32 -30
- data/lib/datadog/tracing/distributed/datadog_tags_codec.rb +4 -17
- data/lib/datadog/tracing/distributed/fetcher.rb +1 -1
- data/lib/datadog/tracing/distributed/helpers.rb +3 -3
- data/lib/datadog/tracing/distributed/propagation.rb +43 -11
- data/lib/datadog/tracing/distributed/propagation_policy.rb +5 -0
- data/lib/datadog/tracing/distributed/trace_context.rb +108 -85
- data/lib/datadog/tracing/event.rb +2 -2
- data/lib/datadog/tracing/ext.rb +9 -0
- data/lib/datadog/tracing/metadata/analytics.rb +2 -2
- data/lib/datadog/tracing/metadata/errors.rb +4 -4
- data/lib/datadog/tracing/metadata/ext.rb +79 -65
- data/lib/datadog/tracing/metadata/metastruct.rb +1 -1
- data/lib/datadog/tracing/metadata/metastruct_tagging.rb +1 -1
- data/lib/datadog/tracing/metadata/tagging.rb +5 -5
- data/lib/datadog/tracing/metadata.rb +4 -4
- data/lib/datadog/tracing/pipeline/span_filter.rb +2 -2
- data/lib/datadog/tracing/pipeline.rb +3 -3
- data/lib/datadog/tracing/remote.rb +48 -10
- data/lib/datadog/tracing/sampling/all_sampler.rb +1 -1
- data/lib/datadog/tracing/sampling/ext.rb +9 -7
- data/lib/datadog/tracing/sampling/matcher.rb +4 -4
- data/lib/datadog/tracing/sampling/priority_sampler.rb +17 -4
- data/lib/datadog/tracing/sampling/rate_by_key_sampler.rb +3 -3
- data/lib/datadog/tracing/sampling/rate_by_service_sampler.rb +2 -2
- data/lib/datadog/tracing/sampling/rate_sampler.rb +2 -2
- data/lib/datadog/tracing/sampling/rule.rb +5 -5
- data/lib/datadog/tracing/sampling/rule_sampler.rb +66 -37
- data/lib/datadog/tracing/sampling/sampler.rb +2 -2
- data/lib/datadog/tracing/sampling/span/ext.rb +3 -3
- data/lib/datadog/tracing/sampling/span/matcher.rb +2 -2
- data/lib/datadog/tracing/sampling/span/rule.rb +1 -1
- data/lib/datadog/tracing/sampling/span/rule_parser.rb +10 -10
- data/lib/datadog/tracing/span.rb +9 -9
- data/lib/datadog/tracing/span_event.rb +5 -5
- data/lib/datadog/tracing/span_operation.rb +39 -26
- data/lib/datadog/tracing/sync_writer.rb +12 -8
- data/lib/datadog/tracing/trace_digest.rb +7 -0
- data/lib/datadog/tracing/trace_operation.rb +90 -21
- data/lib/datadog/tracing/trace_segment.rb +10 -10
- data/lib/datadog/tracing/tracer.rb +63 -22
- data/lib/datadog/tracing/transport/http/client.rb +4 -4
- data/lib/datadog/tracing/transport/http/statistics.rb +2 -2
- data/lib/datadog/tracing/transport/http/traces.rb +8 -8
- data/lib/datadog/tracing/transport/http.rb +10 -10
- data/lib/datadog/tracing/transport/io/client.rb +8 -11
- data/lib/datadog/tracing/transport/io/response.rb +1 -1
- data/lib/datadog/tracing/transport/io/traces.rb +33 -39
- data/lib/datadog/tracing/transport/io.rb +3 -3
- data/lib/datadog/tracing/transport/native/response.rb +71 -0
- data/lib/datadog/tracing/transport/native.rb +387 -0
- data/lib/datadog/tracing/transport/serializable_trace.rb +19 -19
- data/lib/datadog/tracing/transport/statistics.rb +2 -2
- data/lib/datadog/tracing/transport/trace_formatter.rb +20 -9
- data/lib/datadog/tracing/transport/traces.rb +13 -19
- data/lib/datadog/tracing/utils.rb +2 -2
- data/lib/datadog/tracing/workers.rb +4 -3
- data/lib/datadog/tracing/writer.rb +22 -10
- data/lib/datadog/tracing.rb +3 -3
- data/lib/datadog/version.rb +4 -4
- data/lib/datadog.rb +15 -11
- metadata +91 -23
- data/ext/datadog_profiling_native_extension/clock_id_noop.c +0 -21
- data/lib/datadog/ai_guard/configuration/settings.rb +0 -110
- data/lib/datadog/appsec/configuration/settings.rb +0 -409
- data/lib/datadog/appsec/contrib/rails/ext.rb +0 -13
- data/lib/datadog/core/utils/base64.rb +0 -22
- data/lib/datadog/data_streams/configuration/settings.rb +0 -49
- data/lib/datadog/di/configuration/settings.rb +0 -234
- data/lib/datadog/error_tracking/configuration/settings.rb +0 -63
- data/lib/datadog/tracing/workers/trace_writer.rb +0 -204
|
@@ -0,0 +1,1312 @@
|
|
|
1
|
+
#include <ruby.h>
|
|
2
|
+
#ifdef __GNUC__
|
|
3
|
+
#pragma GCC diagnostic push
|
|
4
|
+
#pragma GCC diagnostic ignored "-Wunused-parameter"
|
|
5
|
+
#endif
|
|
6
|
+
#include <ruby/encoding.h>
|
|
7
|
+
#ifdef __GNUC__
|
|
8
|
+
#pragma GCC diagnostic pop
|
|
9
|
+
#endif
|
|
10
|
+
#include <ruby/thread.h>
|
|
11
|
+
#include <limits.h>
|
|
12
|
+
#include <stdbool.h>
|
|
13
|
+
#include <string.h>
|
|
14
|
+
#include <datadog/data-pipeline.h>
|
|
15
|
+
#include <datadog/shared-runtime.h>
|
|
16
|
+
|
|
17
|
+
#include "datadog_ruby_common.h"
|
|
18
|
+
#include "helpers.h"
|
|
19
|
+
#include "trace_exporter.h"
|
|
20
|
+
|
|
21
|
+
/* ========================================================================
|
|
22
|
+
* Forward declarations
|
|
23
|
+
* ======================================================================== */
|
|
24
|
+
|
|
25
|
+
typedef struct {
|
|
26
|
+
ddog_TracerSpan *span;
|
|
27
|
+
} raw_span_owner;
|
|
28
|
+
|
|
29
|
+
/* Internal: convert a Ruby Span into the supplied raw Rust span owner */
|
|
30
|
+
static void convert_ruby_span_to_rust(VALUE span, raw_span_owner *owner);
|
|
31
|
+
|
|
32
|
+
/* TracerSpan methods */
|
|
33
|
+
static VALUE _native_from_span(VALUE klass, VALUE span);
|
|
34
|
+
|
|
35
|
+
/* TraceExporter methods */
|
|
36
|
+
static VALUE _native_exporter_new(int argc, VALUE *argv, VALUE klass);
|
|
37
|
+
static VALUE _native_send_traces(VALUE self, VALUE traces);
|
|
38
|
+
static VALUE _native_before_fork(VALUE self);
|
|
39
|
+
static VALUE _native_after_fork_in_parent(VALUE self);
|
|
40
|
+
static VALUE _native_after_fork_in_child(VALUE self);
|
|
41
|
+
|
|
42
|
+
/* Response helpers */
|
|
43
|
+
static VALUE create_ok_response(long trace_count, VALUE payload);
|
|
44
|
+
static VALUE create_error_response(ddog_TraceExporterErrorCode code,
|
|
45
|
+
long trace_count);
|
|
46
|
+
|
|
47
|
+
/* GC / TypedData */
|
|
48
|
+
static void tracer_span_dfree(void *ptr);
|
|
49
|
+
static void trace_exporter_dfree(void *ptr);
|
|
50
|
+
|
|
51
|
+
/* ========================================================================
|
|
52
|
+
* Cached Ruby intern IDs
|
|
53
|
+
* ======================================================================== */
|
|
54
|
+
|
|
55
|
+
/* Instance variable IDs on Datadog::Tracing::Span */
|
|
56
|
+
static ID at_name_id;
|
|
57
|
+
static ID at_service_id;
|
|
58
|
+
static ID at_resource_id;
|
|
59
|
+
static ID at_type_id;
|
|
60
|
+
static ID at_id_id;
|
|
61
|
+
static ID at_parent_id_id;
|
|
62
|
+
static ID at_trace_id_id;
|
|
63
|
+
static ID at_start_time_id;
|
|
64
|
+
static ID at_duration_id;
|
|
65
|
+
static ID at_status_id;
|
|
66
|
+
static ID at_meta_id;
|
|
67
|
+
static ID at_metrics_id;
|
|
68
|
+
static ID at_metastruct_id;
|
|
69
|
+
|
|
70
|
+
/* Method IDs for time / integer operations */
|
|
71
|
+
static ID id_duration_method;
|
|
72
|
+
static ID id_to_h;
|
|
73
|
+
static ID id_negative_p;
|
|
74
|
+
|
|
75
|
+
/* Resolved lazily because AppSec may load after this extension. */
|
|
76
|
+
static VALUE serializable_backtrace_class = Qnil;
|
|
77
|
+
|
|
78
|
+
/* Response class (loaded from Ruby) */
|
|
79
|
+
static VALUE response_class = Qnil;
|
|
80
|
+
static ID id_new;
|
|
81
|
+
|
|
82
|
+
/* Response keyword-argument IDs, cached to avoid re-interning per send */
|
|
83
|
+
static ID kw_ok;
|
|
84
|
+
static ID kw_internal_error;
|
|
85
|
+
static ID kw_server_error;
|
|
86
|
+
static ID kw_client_error;
|
|
87
|
+
static ID kw_trace_count;
|
|
88
|
+
static ID kw_payload;
|
|
89
|
+
|
|
90
|
+
/* ========================================================================
|
|
91
|
+
* Ruby class references (marked as GC roots)
|
|
92
|
+
* ======================================================================== */
|
|
93
|
+
|
|
94
|
+
static VALUE tracer_span_class = Qnil;
|
|
95
|
+
static VALUE trace_exporter_class = Qnil;
|
|
96
|
+
|
|
97
|
+
/* ========================================================================
|
|
98
|
+
* TypedData definitions
|
|
99
|
+
* ======================================================================== */
|
|
100
|
+
|
|
101
|
+
static const rb_data_type_t tracer_span_typed_data = {
|
|
102
|
+
.wrap_struct_name = "Datadog::Tracing::Transport::Native::TracerSpan",
|
|
103
|
+
.function = {
|
|
104
|
+
.dmark = NULL,
|
|
105
|
+
.dfree = tracer_span_dfree,
|
|
106
|
+
.dsize = NULL,
|
|
107
|
+
},
|
|
108
|
+
.flags = RUBY_TYPED_FREE_IMMEDIATELY
|
|
109
|
+
};
|
|
110
|
+
|
|
111
|
+
static void tracer_span_dfree(void *ptr) {
|
|
112
|
+
if (ptr != NULL) {
|
|
113
|
+
ddog_tracer_span_free((ddog_TracerSpan *)ptr);
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
/*
|
|
118
|
+
* The TraceExporter wrapper owns both the Rust exporter and the SharedRuntime
|
|
119
|
+
* that drives its background workers. Fork-safety hooks operate on the
|
|
120
|
+
* runtime, while send/receive operate on the exporter.
|
|
121
|
+
*/
|
|
122
|
+
typedef struct {
|
|
123
|
+
ddog_TraceExporter *exporter;
|
|
124
|
+
const ddog_ForkSafeRuntime *runtime;
|
|
125
|
+
} trace_exporter_t;
|
|
126
|
+
|
|
127
|
+
static const rb_data_type_t trace_exporter_typed_data = {
|
|
128
|
+
.wrap_struct_name = "Datadog::Tracing::Transport::Native::TraceExporter",
|
|
129
|
+
.function = {
|
|
130
|
+
.dmark = NULL,
|
|
131
|
+
.dfree = trace_exporter_dfree,
|
|
132
|
+
.dsize = NULL,
|
|
133
|
+
},
|
|
134
|
+
.flags = RUBY_TYPED_FREE_IMMEDIATELY
|
|
135
|
+
};
|
|
136
|
+
|
|
137
|
+
static void trace_exporter_dfree(void *ptr) {
|
|
138
|
+
if (ptr != NULL) {
|
|
139
|
+
trace_exporter_t *wrapper = (trace_exporter_t *)ptr;
|
|
140
|
+
if (wrapper->exporter != NULL) {
|
|
141
|
+
ddog_trace_exporter_free(wrapper->exporter);
|
|
142
|
+
}
|
|
143
|
+
if (wrapper->runtime != NULL) {
|
|
144
|
+
ddog_shared_runtime_free(wrapper->runtime);
|
|
145
|
+
}
|
|
146
|
+
ruby_xfree(wrapper);
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
/* ========================================================================
|
|
151
|
+
* Error handling
|
|
152
|
+
* ======================================================================== */
|
|
153
|
+
|
|
154
|
+
/*
|
|
155
|
+
* If +err+ is non-NULL, copies the message, frees the error struct, and
|
|
156
|
+
* raises a Ruby RuntimeError. Does not return on error.
|
|
157
|
+
*/
|
|
158
|
+
static inline void check_exporter_error(const char *context,
|
|
159
|
+
ddog_TraceExporterError *err) {
|
|
160
|
+
if (err == NULL) return;
|
|
161
|
+
|
|
162
|
+
char buf[MAX_RAISE_MESSAGE_SIZE];
|
|
163
|
+
if (err->msg != NULL) {
|
|
164
|
+
snprintf(buf, sizeof(buf), "%s: %s", context, err->msg);
|
|
165
|
+
} else {
|
|
166
|
+
snprintf(buf, sizeof(buf), "%s: (unknown error)", context);
|
|
167
|
+
}
|
|
168
|
+
ddog_trace_exporter_error_free(err);
|
|
169
|
+
raise_error(rb_eRuntimeError, "%s", buf);
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
/*
|
|
173
|
+
* If +err+ is non-NULL, copies the message, frees the error struct, and
|
|
174
|
+
* raises a Ruby RuntimeError. Does not return on error.
|
|
175
|
+
*/
|
|
176
|
+
static inline void check_shared_runtime_error(const char *context,
|
|
177
|
+
ddog_SharedRuntimeFFIError *err) {
|
|
178
|
+
if (err == NULL) return;
|
|
179
|
+
|
|
180
|
+
char buf[MAX_RAISE_MESSAGE_SIZE];
|
|
181
|
+
if (err->msg != NULL) {
|
|
182
|
+
snprintf(buf, sizeof(buf), "%s: %s", context, err->msg);
|
|
183
|
+
} else {
|
|
184
|
+
snprintf(buf, sizeof(buf), "%s: (unknown error)", context);
|
|
185
|
+
}
|
|
186
|
+
ddog_shared_runtime_error_free(err);
|
|
187
|
+
raise_error(rb_eRuntimeError, "%s", buf);
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
/* ========================================================================
|
|
191
|
+
* Config helpers
|
|
192
|
+
* ======================================================================== */
|
|
193
|
+
|
|
194
|
+
typedef ddog_TraceExporterError *(*config_setter_fn)(
|
|
195
|
+
ddog_TraceExporterConfig *, ddog_CharSlice);
|
|
196
|
+
|
|
197
|
+
/*
|
|
198
|
+
* Set a single string-valued config field. `rb_val` MUST be a Ruby String
|
|
199
|
+
* (or nil, which is skipped): it is passed to char_slice_from_ruby_string,
|
|
200
|
+
* which enforces the String type. This helper does not handle numeric or
|
|
201
|
+
* other non-string config settings.
|
|
202
|
+
*/
|
|
203
|
+
static inline void set_config_field(
|
|
204
|
+
ddog_TraceExporterConfig *config,
|
|
205
|
+
config_setter_fn setter,
|
|
206
|
+
VALUE rb_val,
|
|
207
|
+
const char *label) {
|
|
208
|
+
if (rb_val == Qnil) return;
|
|
209
|
+
|
|
210
|
+
ddog_TraceExporterError *err =
|
|
211
|
+
setter(config, char_slice_from_ruby_string(rb_val));
|
|
212
|
+
if (err) {
|
|
213
|
+
ddog_trace_exporter_config_free(config);
|
|
214
|
+
check_exporter_error(label, err);
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
/* ========================================================================
|
|
219
|
+
* Conversion helpers (Ruby -> C, require the GVL)
|
|
220
|
+
* ======================================================================== */
|
|
221
|
+
|
|
222
|
+
/* Nullable Ruby String -> ddog_CharSlice (nil -> empty slice) */
|
|
223
|
+
static inline ddog_CharSlice nullable_char_slice(VALUE str) {
|
|
224
|
+
if (str == Qnil) {
|
|
225
|
+
return (ddog_CharSlice){.ptr = "", .len = 0};
|
|
226
|
+
}
|
|
227
|
+
return char_slice_from_ruby_string(str);
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
/* Ruby Time -> int64_t nanoseconds since Unix epoch */
|
|
231
|
+
static inline int64_t time_to_nanos(VALUE time) {
|
|
232
|
+
struct timespec ts = rb_time_timespec(time);
|
|
233
|
+
return (int64_t)ts.tv_sec * 1000000000LL + (int64_t)ts.tv_nsec;
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
/* 128-bit trace ID split into two 64-bit halves */
|
|
237
|
+
typedef struct {
|
|
238
|
+
uint64_t low;
|
|
239
|
+
uint64_t high;
|
|
240
|
+
} trace_id_t;
|
|
241
|
+
|
|
242
|
+
/* Ruby 128-bit Integer -> trace_id_t */
|
|
243
|
+
static inline trace_id_t split_trace_id(VALUE trace_id) {
|
|
244
|
+
/* Fast path: Fixnum fits in 63 bits, no high half */
|
|
245
|
+
if (FIXNUM_P(trace_id)) {
|
|
246
|
+
return (trace_id_t){
|
|
247
|
+
.low = (uint64_t)FIX2LONG(trace_id),
|
|
248
|
+
.high = 0,
|
|
249
|
+
};
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
/* Bignum path: extract raw bytes into two 64-bit words */
|
|
253
|
+
unsigned long words[2] = {0, 0};
|
|
254
|
+
rb_big_pack(trace_id, words, 2);
|
|
255
|
+
return (trace_id_t){
|
|
256
|
+
.low = (uint64_t)words[0],
|
|
257
|
+
.high = (uint64_t)words[1],
|
|
258
|
+
};
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
/* ========================================================================
|
|
262
|
+
* Hash iteration callbacks for meta / metrics
|
|
263
|
+
*
|
|
264
|
+
* The libdatadog setters return owned errors rather than raising. Stash the
|
|
265
|
+
* first error in a context struct and stop iteration with ST_STOP so the
|
|
266
|
+
* caller can free the still-unowned Rust span before turning the error into
|
|
267
|
+
* a Ruby exception. (This is about span ownership, not hash iteration: MRI
|
|
268
|
+
* restores rb_hash_foreach's iteration state via rb_ensure if a callback
|
|
269
|
+
* exits non-locally.)
|
|
270
|
+
* ======================================================================== */
|
|
271
|
+
|
|
272
|
+
typedef struct {
|
|
273
|
+
ddog_TracerSpan *span;
|
|
274
|
+
ddog_TraceExporterError *error; /* first error, if any */
|
|
275
|
+
long skipped; /* entries skipped due to wrong type */
|
|
276
|
+
} hash_iter_ctx;
|
|
277
|
+
|
|
278
|
+
static int meta_iter_cb(VALUE key, VALUE value, VALUE arg) {
|
|
279
|
+
hash_iter_ctx *ctx = (hash_iter_ctx *)arg;
|
|
280
|
+
|
|
281
|
+
/*
|
|
282
|
+
* The types are checked below, so build the ddog_CharSlice directly instead
|
|
283
|
+
* of repeating char_slice_from_ruby_string()'s ENFORCE_TYPE check.
|
|
284
|
+
* libdatadog copies both slices before the FFI call returns and retains no
|
|
285
|
+
* pointer into the Ruby-owned string storage.
|
|
286
|
+
*/
|
|
287
|
+
if (!RB_TYPE_P(key, T_STRING) || !RB_TYPE_P(value, T_STRING)) {
|
|
288
|
+
ctx->skipped++;
|
|
289
|
+
return ST_CONTINUE;
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
ddog_CharSlice ks = {.ptr = RSTRING_PTR(key), .len = RSTRING_LEN(key)};
|
|
293
|
+
ddog_CharSlice vs = {.ptr = RSTRING_PTR(value), .len = RSTRING_LEN(value)};
|
|
294
|
+
|
|
295
|
+
ddog_TraceExporterError *err = ddog_tracer_span_set_meta(ctx->span, ks, vs);
|
|
296
|
+
if (err != NULL) {
|
|
297
|
+
ctx->error = err;
|
|
298
|
+
return ST_STOP;
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
return ST_CONTINUE;
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
static int metrics_iter_cb(VALUE key, VALUE value, VALUE arg) {
|
|
305
|
+
hash_iter_ctx *ctx = (hash_iter_ctx *)arg;
|
|
306
|
+
|
|
307
|
+
if (!RB_TYPE_P(key, T_STRING) ||
|
|
308
|
+
(!RB_TYPE_P(value, T_FLOAT) && !RB_TYPE_P(value, T_FIXNUM) &&
|
|
309
|
+
!RB_TYPE_P(value, T_BIGNUM))) {
|
|
310
|
+
ctx->skipped++;
|
|
311
|
+
return ST_CONTINUE;
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
/* See meta_iter_cb: the key type is checked above, so build the slice
|
|
315
|
+
* directly. */
|
|
316
|
+
ddog_CharSlice ks = {.ptr = RSTRING_PTR(key), .len = RSTRING_LEN(key)};
|
|
317
|
+
|
|
318
|
+
ddog_TraceExporterError *err =
|
|
319
|
+
ddog_tracer_span_set_metric(ctx->span, ks, NUM2DBL(value));
|
|
320
|
+
if (err != NULL) {
|
|
321
|
+
ctx->error = err;
|
|
322
|
+
return ST_STOP;
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
return ST_CONTINUE;
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
typedef struct {
|
|
329
|
+
ddog_TracerValueToken *tokens;
|
|
330
|
+
size_t len;
|
|
331
|
+
size_t capacity;
|
|
332
|
+
st_table *active;
|
|
333
|
+
uint8_t **scratch;
|
|
334
|
+
size_t scratch_len;
|
|
335
|
+
size_t scratch_capacity;
|
|
336
|
+
} structured_value_ctx;
|
|
337
|
+
|
|
338
|
+
static ddog_TracerValueToken *append_structured_value_token(
|
|
339
|
+
structured_value_ctx *ctx, uint8_t kind) {
|
|
340
|
+
if (ctx->len == ctx->capacity) {
|
|
341
|
+
size_t capacity = ctx->capacity == 0 ? 16 : ctx->capacity * 2;
|
|
342
|
+
if (capacity < ctx->capacity || capacity > SIZE_MAX / sizeof(*ctx->tokens)) {
|
|
343
|
+
rb_raise(rb_eNoMemError, "meta_struct token buffer is too large");
|
|
344
|
+
}
|
|
345
|
+
REALLOC_N(ctx->tokens, ddog_TracerValueToken, capacity);
|
|
346
|
+
ctx->capacity = capacity;
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
ddog_TracerValueToken *token = &ctx->tokens[ctx->len++];
|
|
350
|
+
*token = (ddog_TracerValueToken){0};
|
|
351
|
+
token->kind = kind;
|
|
352
|
+
return token;
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
static const uint8_t *copy_structured_value_bytes(
|
|
356
|
+
structured_value_ctx *ctx, VALUE string, size_t len) {
|
|
357
|
+
if (len == 0) return (const uint8_t *)"";
|
|
358
|
+
|
|
359
|
+
if (ctx->scratch_len == ctx->scratch_capacity) {
|
|
360
|
+
size_t capacity = ctx->scratch_capacity == 0 ? 8 : ctx->scratch_capacity * 2;
|
|
361
|
+
if (capacity < ctx->scratch_capacity || capacity > SIZE_MAX / sizeof(*ctx->scratch)) {
|
|
362
|
+
rb_raise(rb_eNoMemError, "meta_struct scratch buffer is too large");
|
|
363
|
+
}
|
|
364
|
+
REALLOC_N(ctx->scratch, uint8_t *, capacity);
|
|
365
|
+
ctx->scratch_capacity = capacity;
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
uint8_t *copy = ruby_xmalloc(len);
|
|
369
|
+
ctx->scratch[ctx->scratch_len++] = copy;
|
|
370
|
+
/* ruby_xmalloc may trigger GC, so retrieve the Ruby buffer only after it
|
|
371
|
+
* returns and do not call Ruby again before the copy completes. */
|
|
372
|
+
memcpy(copy, RSTRING_PTR(string), len);
|
|
373
|
+
return copy;
|
|
374
|
+
}
|
|
375
|
+
|
|
376
|
+
static void free_structured_value_ctx(structured_value_ctx *ctx) {
|
|
377
|
+
if (ctx->active != NULL) st_free_table(ctx->active);
|
|
378
|
+
for (size_t i = 0; i < ctx->scratch_len; i++) {
|
|
379
|
+
ruby_xfree(ctx->scratch[i]);
|
|
380
|
+
}
|
|
381
|
+
ruby_xfree(ctx->scratch);
|
|
382
|
+
ruby_xfree(ctx->tokens);
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
static VALUE resolve_serializable_backtrace_class(void) {
|
|
386
|
+
if (serializable_backtrace_class != Qnil) return serializable_backtrace_class;
|
|
387
|
+
|
|
388
|
+
ID datadog_id = rb_intern("Datadog");
|
|
389
|
+
ID appsec_id = rb_intern("AppSec");
|
|
390
|
+
ID actions_handler_id = rb_intern("ActionsHandler");
|
|
391
|
+
ID backtrace_id = rb_intern("SerializableBacktrace");
|
|
392
|
+
if (!rb_const_defined(rb_cObject, datadog_id)) return Qnil;
|
|
393
|
+
VALUE datadog = rb_const_get(rb_cObject, datadog_id);
|
|
394
|
+
if (!rb_const_defined(datadog, appsec_id)) return Qnil;
|
|
395
|
+
VALUE appsec = rb_const_get(datadog, appsec_id);
|
|
396
|
+
if (!rb_const_defined(appsec, actions_handler_id)) return Qnil;
|
|
397
|
+
VALUE actions_handler = rb_const_get(appsec, actions_handler_id);
|
|
398
|
+
if (!rb_const_defined(actions_handler, backtrace_id)) return Qnil;
|
|
399
|
+
|
|
400
|
+
serializable_backtrace_class = rb_const_get(actions_handler, backtrace_id);
|
|
401
|
+
rb_global_variable(&serializable_backtrace_class);
|
|
402
|
+
return serializable_backtrace_class;
|
|
403
|
+
}
|
|
404
|
+
|
|
405
|
+
static void append_structured_value(VALUE value, unsigned int depth,
|
|
406
|
+
structured_value_ctx *ctx);
|
|
407
|
+
|
|
408
|
+
typedef struct {
|
|
409
|
+
structured_value_ctx *ctx;
|
|
410
|
+
unsigned int depth;
|
|
411
|
+
} structured_hash_ctx;
|
|
412
|
+
|
|
413
|
+
static int append_structured_hash_entry(VALUE key, VALUE value, VALUE arg) {
|
|
414
|
+
structured_hash_ctx *hash_ctx = (structured_hash_ctx *)arg;
|
|
415
|
+
append_structured_value(key, hash_ctx->depth, hash_ctx->ctx);
|
|
416
|
+
append_structured_value(value, hash_ctx->depth, hash_ctx->ctx);
|
|
417
|
+
return ST_CONTINUE;
|
|
418
|
+
}
|
|
419
|
+
|
|
420
|
+
static VALUE utf8_string(VALUE value) {
|
|
421
|
+
VALUE string = RB_TYPE_P(value, T_SYMBOL) ? rb_sym2str(value) : value;
|
|
422
|
+
string = rb_str_export_to_enc(string, rb_utf8_encoding());
|
|
423
|
+
if (rb_enc_str_coderange(string) == ENC_CODERANGE_BROKEN) {
|
|
424
|
+
rb_raise(rb_eEncodingError, "meta_struct string is not valid UTF-8");
|
|
425
|
+
}
|
|
426
|
+
return string;
|
|
427
|
+
}
|
|
428
|
+
|
|
429
|
+
static void append_structured_value(VALUE value, unsigned int depth,
|
|
430
|
+
structured_value_ctx *ctx) {
|
|
431
|
+
if (value == Qnil) {
|
|
432
|
+
append_structured_value_token(ctx, DDOG_TRACER_VALUE_NIL);
|
|
433
|
+
return;
|
|
434
|
+
}
|
|
435
|
+
if (value == Qtrue || value == Qfalse) {
|
|
436
|
+
ddog_TracerValueToken *token =
|
|
437
|
+
append_structured_value_token(ctx, DDOG_TRACER_VALUE_BOOL);
|
|
438
|
+
token->bool_value = value == Qtrue ? 1 : 0;
|
|
439
|
+
return;
|
|
440
|
+
}
|
|
441
|
+
if (RB_TYPE_P(value, T_FIXNUM) || RB_TYPE_P(value, T_BIGNUM)) {
|
|
442
|
+
if (RTEST(rb_funcall(value, id_negative_p, 0))) {
|
|
443
|
+
ddog_TracerValueToken *token =
|
|
444
|
+
append_structured_value_token(ctx, DDOG_TRACER_VALUE_I64);
|
|
445
|
+
token->i64_value = NUM2LL(value);
|
|
446
|
+
} else {
|
|
447
|
+
ddog_TracerValueToken *token =
|
|
448
|
+
append_structured_value_token(ctx, DDOG_TRACER_VALUE_U64);
|
|
449
|
+
token->u64_value = NUM2ULL(value);
|
|
450
|
+
}
|
|
451
|
+
return;
|
|
452
|
+
}
|
|
453
|
+
if (RB_TYPE_P(value, T_FLOAT)) {
|
|
454
|
+
ddog_TracerValueToken *token =
|
|
455
|
+
append_structured_value_token(ctx, DDOG_TRACER_VALUE_F64);
|
|
456
|
+
token->f64_value = RFLOAT_VALUE(value);
|
|
457
|
+
return;
|
|
458
|
+
}
|
|
459
|
+
if (RB_TYPE_P(value, T_STRING) || RB_TYPE_P(value, T_SYMBOL)) {
|
|
460
|
+
bool binary = RB_TYPE_P(value, T_STRING) &&
|
|
461
|
+
rb_enc_get_index(value) == rb_ascii8bit_encindex();
|
|
462
|
+
VALUE string = binary ? value : utf8_string(value);
|
|
463
|
+
size_t len = (size_t)RSTRING_LEN(string);
|
|
464
|
+
ddog_TracerValueToken *token = append_structured_value_token(
|
|
465
|
+
ctx, binary ? DDOG_TRACER_VALUE_BINARY : DDOG_TRACER_VALUE_STRING);
|
|
466
|
+
token->bytes = (ddog_ByteSlice){
|
|
467
|
+
.ptr = copy_structured_value_bytes(ctx, string, len),
|
|
468
|
+
.len = len,
|
|
469
|
+
};
|
|
470
|
+
return;
|
|
471
|
+
}
|
|
472
|
+
|
|
473
|
+
VALUE backtrace_class = resolve_serializable_backtrace_class();
|
|
474
|
+
if (backtrace_class != Qnil && rb_obj_is_kind_of(value, backtrace_class)) {
|
|
475
|
+
append_structured_value(rb_funcall(value, id_to_h, 0), depth, ctx);
|
|
476
|
+
return;
|
|
477
|
+
}
|
|
478
|
+
|
|
479
|
+
if (!RB_TYPE_P(value, T_ARRAY) && !RB_TYPE_P(value, T_HASH)) {
|
|
480
|
+
rb_raise(rb_eTypeError, "unsupported meta_struct value type: %s",
|
|
481
|
+
rb_obj_classname(value));
|
|
482
|
+
}
|
|
483
|
+
if (depth >= 64) {
|
|
484
|
+
rb_raise(rb_eArgError, "meta_struct value exceeds maximum depth of 64");
|
|
485
|
+
}
|
|
486
|
+
if (st_lookup(ctx->active, (st_data_t)value, NULL)) {
|
|
487
|
+
rb_raise(rb_eArgError, "meta_struct value contains a cycle");
|
|
488
|
+
}
|
|
489
|
+
st_insert(ctx->active, (st_data_t)value, 1);
|
|
490
|
+
|
|
491
|
+
size_t length = RB_TYPE_P(value, T_ARRAY) ? (size_t)RARRAY_LEN(value) : RHASH_SIZE(value);
|
|
492
|
+
if (length > UINT32_MAX) {
|
|
493
|
+
rb_raise(rb_eArgError, "meta_struct container exceeds u32::MAX entries");
|
|
494
|
+
}
|
|
495
|
+
ddog_TracerValueToken *token = append_structured_value_token(
|
|
496
|
+
ctx, RB_TYPE_P(value, T_ARRAY) ? DDOG_TRACER_VALUE_ARRAY : DDOG_TRACER_VALUE_MAP);
|
|
497
|
+
token->child_count = (uint32_t)length;
|
|
498
|
+
|
|
499
|
+
if (RB_TYPE_P(value, T_ARRAY)) {
|
|
500
|
+
for (size_t i = 0; i < length; i++) {
|
|
501
|
+
append_structured_value(rb_ary_entry(value, (long)i), depth + 1, ctx);
|
|
502
|
+
}
|
|
503
|
+
} else {
|
|
504
|
+
structured_hash_ctx hash_ctx = {.ctx = ctx, .depth = depth + 1};
|
|
505
|
+
rb_hash_foreach(value, append_structured_hash_entry, (VALUE)&hash_ctx);
|
|
506
|
+
}
|
|
507
|
+
st_delete(ctx->active, (st_data_t *)&value, NULL);
|
|
508
|
+
}
|
|
509
|
+
|
|
510
|
+
typedef struct {
|
|
511
|
+
const uint8_t *key;
|
|
512
|
+
size_t key_len;
|
|
513
|
+
structured_value_ctx value;
|
|
514
|
+
} prepared_metastruct_entry;
|
|
515
|
+
|
|
516
|
+
typedef struct {
|
|
517
|
+
prepared_metastruct_entry *entries;
|
|
518
|
+
size_t len;
|
|
519
|
+
size_t capacity;
|
|
520
|
+
} prepared_metastruct;
|
|
521
|
+
|
|
522
|
+
static void free_prepared_metastruct(prepared_metastruct *prepared) {
|
|
523
|
+
for (size_t i = 0; i < prepared->len; i++) {
|
|
524
|
+
free_structured_value_ctx(&prepared->entries[i].value);
|
|
525
|
+
}
|
|
526
|
+
ruby_xfree(prepared->entries);
|
|
527
|
+
*prepared = (prepared_metastruct){0};
|
|
528
|
+
}
|
|
529
|
+
|
|
530
|
+
static prepared_metastruct_entry *append_prepared_metastruct_entry(
|
|
531
|
+
prepared_metastruct *prepared) {
|
|
532
|
+
if (prepared->len == prepared->capacity) {
|
|
533
|
+
size_t capacity = prepared->capacity == 0 ? 4 : prepared->capacity * 2;
|
|
534
|
+
if (capacity < prepared->capacity || capacity > SIZE_MAX / sizeof(*prepared->entries)) {
|
|
535
|
+
rb_raise(rb_eNoMemError, "meta_struct entry buffer is too large");
|
|
536
|
+
}
|
|
537
|
+
REALLOC_N(prepared->entries, prepared_metastruct_entry, capacity);
|
|
538
|
+
prepared->capacity = capacity;
|
|
539
|
+
}
|
|
540
|
+
|
|
541
|
+
prepared_metastruct_entry *entry = &prepared->entries[prepared->len++];
|
|
542
|
+
*entry = (prepared_metastruct_entry){0};
|
|
543
|
+
entry->value.active = st_init_numtable();
|
|
544
|
+
return entry;
|
|
545
|
+
}
|
|
546
|
+
|
|
547
|
+
typedef struct {
|
|
548
|
+
prepared_metastruct *prepared;
|
|
549
|
+
long skipped;
|
|
550
|
+
} metastruct_prepare_ctx;
|
|
551
|
+
|
|
552
|
+
static int prepare_metastruct_iter_cb(VALUE key, VALUE value, VALUE arg) {
|
|
553
|
+
metastruct_prepare_ctx *ctx = (metastruct_prepare_ctx *)arg;
|
|
554
|
+
|
|
555
|
+
/* The agent meta_struct contract requires string keys. Accept symbols as a
|
|
556
|
+
* Ruby convenience, but do not encode other key types differently from the
|
|
557
|
+
* native tracer implementations. */
|
|
558
|
+
if (RB_TYPE_P(key, T_SYMBOL)) {
|
|
559
|
+
key = rb_sym2str(key);
|
|
560
|
+
} else if (!RB_TYPE_P(key, T_STRING)) {
|
|
561
|
+
ctx->skipped++;
|
|
562
|
+
return ST_CONTINUE;
|
|
563
|
+
}
|
|
564
|
+
|
|
565
|
+
key = utf8_string(key);
|
|
566
|
+
prepared_metastruct_entry *entry =
|
|
567
|
+
append_prepared_metastruct_entry(ctx->prepared);
|
|
568
|
+
entry->key_len = (size_t)RSTRING_LEN(key);
|
|
569
|
+
entry->key = copy_structured_value_bytes(
|
|
570
|
+
&entry->value, key, entry->key_len);
|
|
571
|
+
append_structured_value(value, 0, &entry->value);
|
|
572
|
+
|
|
573
|
+
return ST_CONTINUE;
|
|
574
|
+
}
|
|
575
|
+
|
|
576
|
+
typedef struct {
|
|
577
|
+
VALUE span;
|
|
578
|
+
prepared_metastruct *prepared;
|
|
579
|
+
} prepare_metastruct_call;
|
|
580
|
+
|
|
581
|
+
static VALUE prepare_metastruct_body(VALUE arg) {
|
|
582
|
+
prepare_metastruct_call *call = (prepare_metastruct_call *)arg;
|
|
583
|
+
VALUE metastruct = rb_ivar_get(call->span, at_metastruct_id);
|
|
584
|
+
if (metastruct == Qnil) return Qnil;
|
|
585
|
+
|
|
586
|
+
VALUE values = rb_funcall(metastruct, id_to_h, 0);
|
|
587
|
+
Check_Type(values, T_HASH);
|
|
588
|
+
if (RHASH_SIZE(values) == 0) return Qnil;
|
|
589
|
+
|
|
590
|
+
metastruct_prepare_ctx ctx = {.prepared = call->prepared, .skipped = 0};
|
|
591
|
+
rb_hash_foreach(values, prepare_metastruct_iter_cb, (VALUE)&ctx);
|
|
592
|
+
if (ctx.skipped > 0) {
|
|
593
|
+
log_warning(rb_sprintf(
|
|
594
|
+
"Native trace exporter: skipped %ld meta_struct entries with non-string keys",
|
|
595
|
+
ctx.skipped));
|
|
596
|
+
}
|
|
597
|
+
return Qnil;
|
|
598
|
+
}
|
|
599
|
+
|
|
600
|
+
/* Prepare stable token storage before allocating the Rust span. Any Ruby
|
|
601
|
+
* callback or non-local exit is contained here, where deterministic cleanup
|
|
602
|
+
* does not need to account for Rust span ownership. */
|
|
603
|
+
static void prepare_metastruct(VALUE span, prepared_metastruct *prepared) {
|
|
604
|
+
prepare_metastruct_call call = {.span = span, .prepared = prepared};
|
|
605
|
+
int state = 0;
|
|
606
|
+
rb_protect(prepare_metastruct_body, (VALUE)&call, &state);
|
|
607
|
+
if (state) {
|
|
608
|
+
free_prepared_metastruct(prepared);
|
|
609
|
+
rb_jump_tag(state);
|
|
610
|
+
}
|
|
611
|
+
}
|
|
612
|
+
|
|
613
|
+
static void set_prepared_metastruct(
|
|
614
|
+
ddog_TracerSpan *span, prepared_metastruct *prepared) {
|
|
615
|
+
for (size_t i = 0; i < prepared->len; i++) {
|
|
616
|
+
prepared_metastruct_entry *entry = &prepared->entries[i];
|
|
617
|
+
ddog_Slice_TracerValueToken tokens = {
|
|
618
|
+
.ptr = entry->value.tokens,
|
|
619
|
+
.len = entry->value.len,
|
|
620
|
+
};
|
|
621
|
+
ddog_CharSlice key = {
|
|
622
|
+
.ptr = (const char *)entry->key,
|
|
623
|
+
.len = entry->key_len,
|
|
624
|
+
};
|
|
625
|
+
ddog_TraceExporterError *err =
|
|
626
|
+
ddog_tracer_span_set_meta_struct(span, key, tokens);
|
|
627
|
+
if (err != NULL) {
|
|
628
|
+
free_prepared_metastruct(prepared);
|
|
629
|
+
check_exporter_error("Failed to set span meta_struct", err);
|
|
630
|
+
}
|
|
631
|
+
}
|
|
632
|
+
free_prepared_metastruct(prepared);
|
|
633
|
+
}
|
|
634
|
+
/* ========================================================================
|
|
635
|
+
* Internal: convert a Ruby Span into a raw_span_owner
|
|
636
|
+
*
|
|
637
|
+
* The caller keeps its ensure handler active until the span is either wrapped
|
|
638
|
+
* in TypedData or consumed by a trace chunk.
|
|
639
|
+
* ======================================================================== */
|
|
640
|
+
|
|
641
|
+
static void convert_ruby_span_to_rust(VALUE span, raw_span_owner *owner) {
|
|
642
|
+
/* 1. Read Ruby ivars */
|
|
643
|
+
VALUE rb_name = rb_ivar_get(span, at_name_id);
|
|
644
|
+
VALUE rb_service = rb_ivar_get(span, at_service_id);
|
|
645
|
+
VALUE rb_resource = rb_ivar_get(span, at_resource_id);
|
|
646
|
+
VALUE rb_type = rb_ivar_get(span, at_type_id);
|
|
647
|
+
VALUE rb_span_id = rb_ivar_get(span, at_id_id);
|
|
648
|
+
VALUE rb_parent_id = rb_ivar_get(span, at_parent_id_id);
|
|
649
|
+
VALUE rb_trace_id = rb_ivar_get(span, at_trace_id_id);
|
|
650
|
+
VALUE rb_status = rb_ivar_get(span, at_status_id);
|
|
651
|
+
|
|
652
|
+
ENFORCE_TYPE(rb_name, T_STRING);
|
|
653
|
+
if (rb_service != Qnil) ENFORCE_TYPE(rb_service, T_STRING);
|
|
654
|
+
if (rb_resource != Qnil) ENFORCE_TYPE(rb_resource, T_STRING);
|
|
655
|
+
if (rb_type != Qnil) ENFORCE_TYPE(rb_type, T_STRING);
|
|
656
|
+
|
|
657
|
+
/* 2. Convert scalars that may call Ruby. */
|
|
658
|
+
uint64_t span_id = NUM2ULL(rb_span_id);
|
|
659
|
+
uint64_t parent_id = NUM2ULL(rb_parent_id);
|
|
660
|
+
int32_t error_val = NUM2INT(rb_status);
|
|
661
|
+
|
|
662
|
+
trace_id_t trace_id = split_trace_id(rb_trace_id);
|
|
663
|
+
|
|
664
|
+
/* start (ns) */
|
|
665
|
+
int64_t start_ns = 0;
|
|
666
|
+
VALUE rb_start_time = rb_ivar_get(span, at_start_time_id);
|
|
667
|
+
if (rb_start_time != Qnil) {
|
|
668
|
+
start_ns = time_to_nanos(rb_start_time);
|
|
669
|
+
}
|
|
670
|
+
|
|
671
|
+
/* duration (ns) */
|
|
672
|
+
int64_t duration_ns = 0;
|
|
673
|
+
VALUE rb_duration_ivar = rb_ivar_get(span, at_duration_id);
|
|
674
|
+
if (rb_duration_ivar != Qnil) {
|
|
675
|
+
duration_ns = (int64_t)(NUM2DBL(rb_duration_ivar) * 1e9);
|
|
676
|
+
} else {
|
|
677
|
+
VALUE dur = rb_funcall(span, id_duration_method, 0);
|
|
678
|
+
if (dur != Qnil) duration_ns = (int64_t)(NUM2DBL(dur) * 1e9);
|
|
679
|
+
}
|
|
680
|
+
|
|
681
|
+
/* Structured-value normalisation can call Ruby code. Snapshot it before
|
|
682
|
+
* borrowing scalar string pointers or allocating the Rust span. */
|
|
683
|
+
prepared_metastruct metastruct = {0};
|
|
684
|
+
prepare_metastruct(span, &metastruct);
|
|
685
|
+
|
|
686
|
+
/* No Ruby calls may occur between borrowing these pointers and span_new. */
|
|
687
|
+
ddog_CharSlice name_s = char_slice_from_ruby_string(rb_name);
|
|
688
|
+
ddog_CharSlice service_s = nullable_char_slice(rb_service);
|
|
689
|
+
ddog_CharSlice resource_s = nullable_char_slice(rb_resource);
|
|
690
|
+
ddog_CharSlice type_s = nullable_char_slice(rb_type);
|
|
691
|
+
|
|
692
|
+
/* 3. Create Rust span and immediately consume the stable prepared values. */
|
|
693
|
+
ddog_TracerSpanFields fields = {
|
|
694
|
+
.service = service_s,
|
|
695
|
+
.name = name_s,
|
|
696
|
+
.resource = resource_s,
|
|
697
|
+
.span_type = type_s,
|
|
698
|
+
.trace_id_low = trace_id.low,
|
|
699
|
+
.trace_id_high = trace_id.high,
|
|
700
|
+
.span_id = span_id,
|
|
701
|
+
.parent_id = parent_id,
|
|
702
|
+
.start = start_ns,
|
|
703
|
+
.duration = duration_ns,
|
|
704
|
+
.error = error_val,
|
|
705
|
+
};
|
|
706
|
+
|
|
707
|
+
ddog_TraceExporterError *err = ddog_tracer_span_new(&owner->span, &fields);
|
|
708
|
+
if (err != NULL) free_prepared_metastruct(&metastruct);
|
|
709
|
+
check_exporter_error("Failed to create TracerSpan", err);
|
|
710
|
+
set_prepared_metastruct(owner->span, &metastruct);
|
|
711
|
+
|
|
712
|
+
/* 4. Populate meta and metrics */
|
|
713
|
+
hash_iter_ctx ctx = {.span = owner->span, .error = NULL, .skipped = 0};
|
|
714
|
+
|
|
715
|
+
VALUE rb_meta = rb_ivar_get(span, at_meta_id);
|
|
716
|
+
if (RB_TYPE_P(rb_meta, T_HASH) && RHASH_SIZE(rb_meta) > 0) {
|
|
717
|
+
rb_hash_foreach(rb_meta, meta_iter_cb, (VALUE)&ctx);
|
|
718
|
+
check_exporter_error("Failed to set span meta", ctx.error);
|
|
719
|
+
if (ctx.skipped > 0) {
|
|
720
|
+
log_warning(rb_sprintf(
|
|
721
|
+
"Native trace exporter: skipped %ld non-string meta entries",
|
|
722
|
+
ctx.skipped));
|
|
723
|
+
ctx.skipped = 0;
|
|
724
|
+
}
|
|
725
|
+
}
|
|
726
|
+
|
|
727
|
+
VALUE rb_metrics = rb_ivar_get(span, at_metrics_id);
|
|
728
|
+
if (RB_TYPE_P(rb_metrics, T_HASH) && RHASH_SIZE(rb_metrics) > 0) {
|
|
729
|
+
rb_hash_foreach(rb_metrics, metrics_iter_cb, (VALUE)&ctx);
|
|
730
|
+
check_exporter_error("Failed to set span metric", ctx.error);
|
|
731
|
+
if (ctx.skipped > 0) {
|
|
732
|
+
log_warning(rb_sprintf(
|
|
733
|
+
"Native trace exporter: skipped %ld non-numeric metrics entries",
|
|
734
|
+
ctx.skipped));
|
|
735
|
+
}
|
|
736
|
+
}
|
|
737
|
+
|
|
738
|
+
}
|
|
739
|
+
|
|
740
|
+
static VALUE free_raw_span(VALUE arg) {
|
|
741
|
+
raw_span_owner *owner = (raw_span_owner *)arg;
|
|
742
|
+
if (owner->span != NULL) {
|
|
743
|
+
ddog_tracer_span_free(owner->span);
|
|
744
|
+
owner->span = NULL;
|
|
745
|
+
}
|
|
746
|
+
return Qnil;
|
|
747
|
+
}
|
|
748
|
+
|
|
749
|
+
/* ========================================================================
|
|
750
|
+
* TracerSpan._native_from_span
|
|
751
|
+
* ======================================================================== */
|
|
752
|
+
|
|
753
|
+
typedef struct {
|
|
754
|
+
VALUE span;
|
|
755
|
+
raw_span_owner owner;
|
|
756
|
+
} wrap_span_ctx;
|
|
757
|
+
|
|
758
|
+
static VALUE convert_and_wrap_span(VALUE arg) {
|
|
759
|
+
wrap_span_ctx *ctx = (wrap_span_ctx *)arg;
|
|
760
|
+
convert_ruby_span_to_rust(ctx->span, &ctx->owner);
|
|
761
|
+
|
|
762
|
+
VALUE wrapped = TypedData_Wrap_Struct(
|
|
763
|
+
tracer_span_class, &tracer_span_typed_data, ctx->owner.span);
|
|
764
|
+
ctx->owner.span = NULL;
|
|
765
|
+
return wrapped;
|
|
766
|
+
}
|
|
767
|
+
|
|
768
|
+
static VALUE _native_from_span(DDTRACE_UNUSED VALUE klass, VALUE span) {
|
|
769
|
+
wrap_span_ctx ctx = {.span = span, .owner = {.span = NULL}};
|
|
770
|
+
return rb_ensure(
|
|
771
|
+
convert_and_wrap_span, (VALUE)&ctx,
|
|
772
|
+
free_raw_span, (VALUE)&ctx.owner);
|
|
773
|
+
}
|
|
774
|
+
|
|
775
|
+
/* ========================================================================
|
|
776
|
+
* Response class helpers
|
|
777
|
+
* ======================================================================== */
|
|
778
|
+
|
|
779
|
+
/*
|
|
780
|
+
* Build an error response, classifying the error code into the
|
|
781
|
+
* Transport::Response categories:
|
|
782
|
+
*
|
|
783
|
+
* HTTP_CLIENT -> client_error? (4xx family)
|
|
784
|
+
* HTTP_SERVER -> server_error? (5xx family)
|
|
785
|
+
* everything else -> internal_error?
|
|
786
|
+
*/
|
|
787
|
+
static VALUE create_error_response(ddog_TraceExporterErrorCode code,
|
|
788
|
+
long trace_count) {
|
|
789
|
+
VALUE kwargs = rb_hash_new();
|
|
790
|
+
rb_hash_aset(kwargs, ID2SYM(kw_ok), Qfalse);
|
|
791
|
+
rb_hash_aset(kwargs, ID2SYM(kw_internal_error), (code != DDOG_TRACE_EXPORTER_ERROR_CODE_HTTP_CLIENT &&
|
|
792
|
+
code != DDOG_TRACE_EXPORTER_ERROR_CODE_HTTP_SERVER) ? Qtrue : Qfalse);
|
|
793
|
+
rb_hash_aset(kwargs, ID2SYM(kw_server_error), code == DDOG_TRACE_EXPORTER_ERROR_CODE_HTTP_SERVER ? Qtrue : Qfalse);
|
|
794
|
+
rb_hash_aset(kwargs, ID2SYM(kw_client_error), code == DDOG_TRACE_EXPORTER_ERROR_CODE_HTTP_CLIENT ? Qtrue : Qfalse);
|
|
795
|
+
rb_hash_aset(kwargs, ID2SYM(kw_trace_count), LONG2NUM(trace_count));
|
|
796
|
+
return rb_funcallv_kw(response_class, id_new, 1, &kwargs, RB_PASS_KEYWORDS);
|
|
797
|
+
}
|
|
798
|
+
|
|
799
|
+
/*
|
|
800
|
+
* Build a success response, optionally carrying the agent's response body
|
|
801
|
+
* as +payload+.
|
|
802
|
+
*
|
|
803
|
+
* +payload+ is the raw HTTP response body returned by the Datadog Agent
|
|
804
|
+
* (typically JSON containing +rate_by_service+). It is surfaced here so
|
|
805
|
+
* that callers matching the +Datadog::Core::Transport::Response+ interface
|
|
806
|
+
* can parse service sampling rates, just as the Net::HTTP transport does.
|
|
807
|
+
*/
|
|
808
|
+
static VALUE create_ok_response(long trace_count, VALUE payload) {
|
|
809
|
+
VALUE kwargs = rb_hash_new();
|
|
810
|
+
rb_hash_aset(kwargs, ID2SYM(kw_ok), Qtrue);
|
|
811
|
+
rb_hash_aset(kwargs, ID2SYM(kw_trace_count), LONG2NUM(trace_count));
|
|
812
|
+
rb_hash_aset(kwargs, ID2SYM(kw_payload), payload);
|
|
813
|
+
return rb_funcallv_kw(response_class, id_new, 1, &kwargs, RB_PASS_KEYWORDS);
|
|
814
|
+
}
|
|
815
|
+
|
|
816
|
+
/* ========================================================================
|
|
817
|
+
* TraceExporter._native_new
|
|
818
|
+
*
|
|
819
|
+
* Creates a Rust TraceExporter with the given configuration.
|
|
820
|
+
*
|
|
821
|
+
* Ruby signature:
|
|
822
|
+
* TraceExporter._native_new(
|
|
823
|
+
* url:, tracer_version: nil, language: nil, language_version: nil,
|
|
824
|
+
* language_interpreter: nil, hostname: nil, env: nil,
|
|
825
|
+
* service: nil, version: nil) -> TraceExporter
|
|
826
|
+
*
|
|
827
|
+
* +url+ is required (String). All other arguments may be nil.
|
|
828
|
+
* ======================================================================== */
|
|
829
|
+
|
|
830
|
+
static VALUE _native_exporter_new(
|
|
831
|
+
int argc, VALUE *argv, DDTRACE_UNUSED VALUE klass
|
|
832
|
+
) {
|
|
833
|
+
VALUE options;
|
|
834
|
+
rb_scan_args(argc, argv, "0:", &options);
|
|
835
|
+
if (options == Qnil) options = rb_hash_new();
|
|
836
|
+
|
|
837
|
+
VALUE rb_url = rb_hash_fetch(options, ID2SYM(rb_intern("url")));
|
|
838
|
+
VALUE rb_tracer_version = rb_hash_fetch(options, ID2SYM(rb_intern("tracer_version")));
|
|
839
|
+
VALUE rb_language = rb_hash_fetch(options, ID2SYM(rb_intern("language")));
|
|
840
|
+
VALUE rb_language_version = rb_hash_fetch(options, ID2SYM(rb_intern("language_version")));
|
|
841
|
+
VALUE rb_language_interpreter = rb_hash_fetch(options, ID2SYM(rb_intern("language_interpreter")));
|
|
842
|
+
VALUE rb_hostname = rb_hash_fetch(options, ID2SYM(rb_intern("hostname")));
|
|
843
|
+
VALUE rb_env = rb_hash_fetch(options, ID2SYM(rb_intern("env")));
|
|
844
|
+
VALUE rb_service = rb_hash_fetch(options, ID2SYM(rb_intern("service")));
|
|
845
|
+
VALUE rb_version = rb_hash_fetch(options, ID2SYM(rb_intern("version")));
|
|
846
|
+
|
|
847
|
+
/* Phase 1: validate types (may raise, no Rust resources yet) */
|
|
848
|
+
ENFORCE_TYPE(rb_url, T_STRING);
|
|
849
|
+
if (rb_tracer_version != Qnil) ENFORCE_TYPE(rb_tracer_version, T_STRING);
|
|
850
|
+
if (rb_language != Qnil) ENFORCE_TYPE(rb_language, T_STRING);
|
|
851
|
+
if (rb_language_version != Qnil) ENFORCE_TYPE(rb_language_version, T_STRING);
|
|
852
|
+
if (rb_language_interpreter != Qnil) ENFORCE_TYPE(rb_language_interpreter, T_STRING);
|
|
853
|
+
if (rb_hostname != Qnil) ENFORCE_TYPE(rb_hostname, T_STRING);
|
|
854
|
+
if (rb_env != Qnil) ENFORCE_TYPE(rb_env, T_STRING);
|
|
855
|
+
if (rb_service != Qnil) ENFORCE_TYPE(rb_service, T_STRING);
|
|
856
|
+
if (rb_version != Qnil) ENFORCE_TYPE(rb_version, T_STRING);
|
|
857
|
+
|
|
858
|
+
/* Phase 2: configure before creating the separately-owned runtime. */
|
|
859
|
+
ddog_TraceExporterConfig *config = NULL;
|
|
860
|
+
ddog_trace_exporter_config_new(&config);
|
|
861
|
+
|
|
862
|
+
set_config_field(config, ddog_trace_exporter_config_set_url, rb_url, "url");
|
|
863
|
+
set_config_field(config, ddog_trace_exporter_config_set_tracer_version, rb_tracer_version, "tracer_version");
|
|
864
|
+
set_config_field(config, ddog_trace_exporter_config_set_language, rb_language, "language");
|
|
865
|
+
set_config_field(config, ddog_trace_exporter_config_set_lang_version, rb_language_version, "language_version");
|
|
866
|
+
set_config_field(config, ddog_trace_exporter_config_set_lang_interpreter, rb_language_interpreter, "language_interpreter");
|
|
867
|
+
set_config_field(config, ddog_trace_exporter_config_set_hostname, rb_hostname, "hostname");
|
|
868
|
+
set_config_field(config, ddog_trace_exporter_config_set_env, rb_env, "env");
|
|
869
|
+
set_config_field(config, ddog_trace_exporter_config_set_service, rb_service, "service");
|
|
870
|
+
set_config_field(config, ddog_trace_exporter_config_set_version, rb_version, "version");
|
|
871
|
+
|
|
872
|
+
/*
|
|
873
|
+
* Create a SharedRuntime and attach it to the config before building the
|
|
874
|
+
* exporter. The exporter holds a clone of the runtime's Arc; we keep our
|
|
875
|
+
* own handle in the wrapper to drive fork-safety hooks and to free it when
|
|
876
|
+
* the exporter is collected.
|
|
877
|
+
*/
|
|
878
|
+
const ddog_ForkSafeRuntime *runtime = NULL;
|
|
879
|
+
ddog_SharedRuntimeFFIError *rt_err = ddog_shared_runtime_new(&runtime);
|
|
880
|
+
if (rt_err != NULL) {
|
|
881
|
+
ddog_trace_exporter_config_free(config);
|
|
882
|
+
check_shared_runtime_error("Failed to create SharedRuntime", rt_err);
|
|
883
|
+
}
|
|
884
|
+
|
|
885
|
+
/*
|
|
886
|
+
* Const asymmetry: ddog_shared_runtime_new yields a `const ddog_ForkSafeRuntime *`
|
|
887
|
+
* but the setter takes a non-const pointer. The setter only clones the Arc,
|
|
888
|
+
* so casting away const here is safe.
|
|
889
|
+
*/
|
|
890
|
+
{
|
|
891
|
+
ddog_TraceExporterError *attach_err = ddog_trace_exporter_config_set_shared_runtime(
|
|
892
|
+
config, (ddog_ForkSafeRuntime *)runtime);
|
|
893
|
+
if (attach_err != NULL) {
|
|
894
|
+
ddog_trace_exporter_config_free(config);
|
|
895
|
+
ddog_shared_runtime_free(runtime);
|
|
896
|
+
check_exporter_error("Failed to attach SharedRuntime to config", attach_err);
|
|
897
|
+
}
|
|
898
|
+
}
|
|
899
|
+
|
|
900
|
+
/* Phase 3: build the exporter from the config */
|
|
901
|
+
ddog_TraceExporter *exporter = NULL;
|
|
902
|
+
ddog_TraceExporterError *err = ddog_trace_exporter_new(&exporter, config);
|
|
903
|
+
ddog_trace_exporter_config_free(config);
|
|
904
|
+
config = NULL;
|
|
905
|
+
|
|
906
|
+
if (err) {
|
|
907
|
+
ddog_shared_runtime_free(runtime);
|
|
908
|
+
check_exporter_error("Failed to create TraceExporter", err);
|
|
909
|
+
}
|
|
910
|
+
|
|
911
|
+
trace_exporter_t *wrapper = ruby_xmalloc(sizeof(trace_exporter_t));
|
|
912
|
+
wrapper->exporter = exporter;
|
|
913
|
+
wrapper->runtime = runtime;
|
|
914
|
+
|
|
915
|
+
return TypedData_Wrap_Struct(trace_exporter_class, &trace_exporter_typed_data,
|
|
916
|
+
wrapper);
|
|
917
|
+
}
|
|
918
|
+
|
|
919
|
+
/* ========================================================================
|
|
920
|
+
* Fork safety hooks
|
|
921
|
+
*
|
|
922
|
+
* These coordinate the tokio runtime lifecycle around process forks
|
|
923
|
+
* (Puma, Unicorn, Passenger).
|
|
924
|
+
* ======================================================================== */
|
|
925
|
+
|
|
926
|
+
static VALUE _native_before_fork(VALUE self) {
|
|
927
|
+
trace_exporter_t *wrapper;
|
|
928
|
+
TypedData_Get_Struct(self, trace_exporter_t, &trace_exporter_typed_data, wrapper);
|
|
929
|
+
if (wrapper == NULL || wrapper->runtime == NULL) {
|
|
930
|
+
raise_error(rb_eRuntimeError, "TraceExporter has not been initialized or was already freed");
|
|
931
|
+
}
|
|
932
|
+
ddog_SharedRuntimeFFIError *err = ddog_shared_runtime_before_fork(wrapper->runtime);
|
|
933
|
+
check_shared_runtime_error("Failed to prepare for fork", err);
|
|
934
|
+
return Qnil;
|
|
935
|
+
}
|
|
936
|
+
|
|
937
|
+
static VALUE _native_after_fork_in_parent(VALUE self) {
|
|
938
|
+
trace_exporter_t *wrapper;
|
|
939
|
+
TypedData_Get_Struct(self, trace_exporter_t, &trace_exporter_typed_data, wrapper);
|
|
940
|
+
if (wrapper == NULL || wrapper->runtime == NULL) {
|
|
941
|
+
raise_error(rb_eRuntimeError, "TraceExporter has not been initialized or was already freed");
|
|
942
|
+
}
|
|
943
|
+
ddog_SharedRuntimeFFIError *err = ddog_shared_runtime_after_fork_parent(wrapper->runtime);
|
|
944
|
+
check_shared_runtime_error("Failed to restore after fork in parent", err);
|
|
945
|
+
return Qnil;
|
|
946
|
+
}
|
|
947
|
+
|
|
948
|
+
static VALUE _native_after_fork_in_child(VALUE self) {
|
|
949
|
+
trace_exporter_t *wrapper;
|
|
950
|
+
TypedData_Get_Struct(self, trace_exporter_t, &trace_exporter_typed_data, wrapper);
|
|
951
|
+
if (wrapper == NULL || wrapper->runtime == NULL) {
|
|
952
|
+
raise_error(rb_eRuntimeError, "TraceExporter has not been initialized or was already freed");
|
|
953
|
+
}
|
|
954
|
+
ddog_SharedRuntimeFFIError *err = ddog_shared_runtime_after_fork_child(wrapper->runtime);
|
|
955
|
+
check_shared_runtime_error("Failed to restore after fork in child", err);
|
|
956
|
+
return Qnil;
|
|
957
|
+
}
|
|
958
|
+
|
|
959
|
+
/* ========================================================================
|
|
960
|
+
* GVL-release helper for ddog_trace_exporter_send_trace_chunks
|
|
961
|
+
*
|
|
962
|
+
* The send call performs blocking network I/O. Releasing the GVL lets
|
|
963
|
+
* other Ruby threads (application code, test mock servers, etc.) run
|
|
964
|
+
* while we wait for the agent's response.
|
|
965
|
+
* ======================================================================== */
|
|
966
|
+
|
|
967
|
+
typedef struct {
|
|
968
|
+
const ddog_TraceExporter *exporter;
|
|
969
|
+
ddog_TracerTraceChunks *chunks;
|
|
970
|
+
ddog_TraceExporterResponse *response;
|
|
971
|
+
ddog_TraceExporterCancelToken *cancel_token; /* borrowed, not owned */
|
|
972
|
+
ddog_TraceExporterErrorCode error_code;
|
|
973
|
+
bool failed;
|
|
974
|
+
bool send_ran;
|
|
975
|
+
} send_chunks_args_t;
|
|
976
|
+
|
|
977
|
+
static void *send_chunks_without_gvl(void *data) {
|
|
978
|
+
send_chunks_args_t *args = (send_chunks_args_t *)data;
|
|
979
|
+
ddog_TraceExporterError *err = ddog_trace_exporter_send_trace_chunks(
|
|
980
|
+
args->exporter, args->chunks, &args->response, args->cancel_token);
|
|
981
|
+
if (err != NULL) {
|
|
982
|
+
args->error_code = err->code;
|
|
983
|
+
args->failed = true;
|
|
984
|
+
ddog_trace_exporter_error_free(err);
|
|
985
|
+
}
|
|
986
|
+
args->send_ran = true;
|
|
987
|
+
return NULL;
|
|
988
|
+
}
|
|
989
|
+
|
|
990
|
+
/*
|
|
991
|
+
* Unblock function: cooperatively cancel an in-flight send.
|
|
992
|
+
*
|
|
993
|
+
* Called by Ruby when an interrupt (Thread#kill, shutdown) fires while
|
|
994
|
+
* the thread is inside rb_thread_call_without_gvl2. Cancelling the
|
|
995
|
+
* token causes the Rust HTTP pipeline to abort the in-flight request
|
|
996
|
+
* and return promptly, which is not possible with RUBY_UBF_IO's
|
|
997
|
+
* signal-based approach.
|
|
998
|
+
*/
|
|
999
|
+
static void interrupt_exporter_call(void *cancel_token) {
|
|
1000
|
+
ddog_trace_exporter_cancel_token_cancel(
|
|
1001
|
+
(const ddog_TraceExporterCancelToken *)cancel_token);
|
|
1002
|
+
}
|
|
1003
|
+
|
|
1004
|
+
/*
|
|
1005
|
+
* Check for a pending Ruby exception without raising it.
|
|
1006
|
+
* Mirrors the profiling extension's check_if_pending_exception().
|
|
1007
|
+
*/
|
|
1008
|
+
static VALUE process_pending_interruptions(DDTRACE_UNUSED VALUE _) {
|
|
1009
|
+
rb_thread_check_ints();
|
|
1010
|
+
return Qnil;
|
|
1011
|
+
}
|
|
1012
|
+
|
|
1013
|
+
__attribute__((warn_unused_result))
|
|
1014
|
+
static int check_if_pending_exception(void) {
|
|
1015
|
+
int pending_exception;
|
|
1016
|
+
rb_protect(process_pending_interruptions, Qnil, &pending_exception);
|
|
1017
|
+
return pending_exception;
|
|
1018
|
+
}
|
|
1019
|
+
|
|
1020
|
+
/* ========================================================================
|
|
1021
|
+
* TraceExporter#_native_send_traces
|
|
1022
|
+
*
|
|
1023
|
+
* Ruby signature:
|
|
1024
|
+
* exporter._native_send_traces(traces) -> Array[Response]
|
|
1025
|
+
*
|
|
1026
|
+
* +traces+ is an Array of Arrays of Spans:
|
|
1027
|
+
* [[span, span, ...], [span, ...], ...]
|
|
1028
|
+
*
|
|
1029
|
+
* Each inner array maps to one trace chunk (Vec<Span> in Rust).
|
|
1030
|
+
*
|
|
1031
|
+
* On success returns [Response(ok: true, trace_count: N)].
|
|
1032
|
+
* On error returns [Response(ok: false, ...)].
|
|
1033
|
+
*
|
|
1034
|
+
* The chunk-building loop calls into Ruby (ENFORCE_TYPE,
|
|
1035
|
+
* convert_ruby_span_to_rust) which may raise. We use rb_ensure so
|
|
1036
|
+
* that the Rust-allocated chunks are freed if an exception fires
|
|
1037
|
+
* before the send consumes them.
|
|
1038
|
+
* ======================================================================== */
|
|
1039
|
+
|
|
1040
|
+
/* Context shared between the body and ensure callbacks. */
|
|
1041
|
+
typedef struct {
|
|
1042
|
+
const ddog_TraceExporter *exporter;
|
|
1043
|
+
VALUE traces;
|
|
1044
|
+
long trace_count;
|
|
1045
|
+
raw_span_owner span_owner;
|
|
1046
|
+
ddog_TracerTraceChunks *chunks; /* NULL after send consumes it */
|
|
1047
|
+
} send_traces_ctx;
|
|
1048
|
+
|
|
1049
|
+
/*
|
|
1050
|
+
* Body: build trace chunks from Ruby spans, then send them.
|
|
1051
|
+
* Passed to rb_ensure as the "try" block.
|
|
1052
|
+
*/
|
|
1053
|
+
static VALUE build_and_send_traces(VALUE arg) {
|
|
1054
|
+
send_traces_ctx *ctx = (send_traces_ctx *)arg;
|
|
1055
|
+
|
|
1056
|
+
for (long i = 0; i < ctx->trace_count; i++) {
|
|
1057
|
+
VALUE chunk_spans = rb_ary_entry(ctx->traces, i);
|
|
1058
|
+
ENFORCE_TYPE(chunk_spans, T_ARRAY);
|
|
1059
|
+
|
|
1060
|
+
long span_count = RARRAY_LEN(chunk_spans);
|
|
1061
|
+
/* Propagate a begin_chunk failure instead of swallowing it: continuing
|
|
1062
|
+
* would build an incomplete payload and still report success. rb_ensure
|
|
1063
|
+
* frees chunks on the raise. Today this only fails for an absurd
|
|
1064
|
+
* span_count, but a future libdatadog change (e.g. a fallible allocator)
|
|
1065
|
+
* could make it reachable. */
|
|
1066
|
+
ddog_TraceExporterError *begin_err =
|
|
1067
|
+
ddog_tracer_trace_chunks_begin_chunk(ctx->chunks, (size_t)span_count);
|
|
1068
|
+
check_exporter_error("Failed to begin trace chunk", begin_err);
|
|
1069
|
+
for (long j = 0; j < span_count; j++) {
|
|
1070
|
+
convert_ruby_span_to_rust(
|
|
1071
|
+
rb_ary_entry(chunk_spans, j), &ctx->span_owner);
|
|
1072
|
+
|
|
1073
|
+
ddog_TraceExporterError *push_err =
|
|
1074
|
+
ddog_tracer_trace_chunks_push_span(ctx->chunks, ctx->span_owner.span);
|
|
1075
|
+
/* push_span consumes the span on every path. */
|
|
1076
|
+
ctx->span_owner.span = NULL;
|
|
1077
|
+
check_exporter_error("Failed to push span into trace chunk", push_err);
|
|
1078
|
+
}
|
|
1079
|
+
}
|
|
1080
|
+
|
|
1081
|
+
/*
|
|
1082
|
+
* Send with the GVL released so other Ruby threads run during I/O.
|
|
1083
|
+
*
|
|
1084
|
+
* Custom behaviour of this call site:
|
|
1085
|
+
* - We use the gvl2 variant precisely because it does NOT auto-raise a
|
|
1086
|
+
* pending interrupt on return: the send consumes chunks and allocates
|
|
1087
|
+
* a Rust response, so we must inspect/free those before letting any
|
|
1088
|
+
* exception propagate (otherwise they leak).
|
|
1089
|
+
* - The unblock function cancels a per-send cancellation token, which
|
|
1090
|
+
* cooperatively aborts the in-flight Rust HTTP request (RUBY_UBF_IO
|
|
1091
|
+
* could not cancel the Rust pipeline).
|
|
1092
|
+
* - An interrupt can make gvl2 return before send_chunks_without_gvl
|
|
1093
|
+
* runs, so we loop until the send actually executes or an exception
|
|
1094
|
+
* is pending.
|
|
1095
|
+
*/
|
|
1096
|
+
ddog_TraceExporterCancelToken *cancel_token =
|
|
1097
|
+
ddog_trace_exporter_cancel_token_new();
|
|
1098
|
+
|
|
1099
|
+
send_chunks_args_t args = {
|
|
1100
|
+
.exporter = ctx->exporter,
|
|
1101
|
+
.chunks = ctx->chunks,
|
|
1102
|
+
.response = NULL,
|
|
1103
|
+
.cancel_token = cancel_token,
|
|
1104
|
+
.failed = false,
|
|
1105
|
+
.send_ran = false,
|
|
1106
|
+
};
|
|
1107
|
+
|
|
1108
|
+
int pending_exception = 0;
|
|
1109
|
+
while (!args.send_ran && !pending_exception) {
|
|
1110
|
+
rb_thread_call_without_gvl2(
|
|
1111
|
+
send_chunks_without_gvl, &args,
|
|
1112
|
+
interrupt_exporter_call, cancel_token);
|
|
1113
|
+
|
|
1114
|
+
if (!args.send_ran) {
|
|
1115
|
+
pending_exception = check_if_pending_exception();
|
|
1116
|
+
}
|
|
1117
|
+
}
|
|
1118
|
+
|
|
1119
|
+
ddog_trace_exporter_cancel_token_drop(cancel_token);
|
|
1120
|
+
/* Only null chunks when the send actually ran and consumed them.
|
|
1121
|
+
* If an interrupt fired before the send executed, chunks are still
|
|
1122
|
+
* live and the ensure handler must free them. */
|
|
1123
|
+
if (args.send_ran) {
|
|
1124
|
+
ctx->chunks = NULL;
|
|
1125
|
+
}
|
|
1126
|
+
|
|
1127
|
+
/* Extract the response body as a Ruby string before freeing. */
|
|
1128
|
+
VALUE payload = Qnil;
|
|
1129
|
+
if (args.response != NULL) {
|
|
1130
|
+
ddog_ByteSlice body =
|
|
1131
|
+
ddog_trace_exporter_response_get_body(args.response);
|
|
1132
|
+
if (body.len > 0) {
|
|
1133
|
+
payload = rb_str_new((const char *)body.ptr, (long)body.len);
|
|
1134
|
+
}
|
|
1135
|
+
ddog_trace_exporter_response_free(args.response);
|
|
1136
|
+
args.response = NULL;
|
|
1137
|
+
}
|
|
1138
|
+
|
|
1139
|
+
/*
|
|
1140
|
+
* Re-check for a pending interrupt unconditionally before deciding the
|
|
1141
|
+
* outcome. In a race, the unblock function (interrupt_exporter_call) can
|
|
1142
|
+
* fire -- cancelling the token -- while the send still completes, so
|
|
1143
|
+
* rb_thread_call_without_gvl2 returns with args.send_ran == true. In that
|
|
1144
|
+
* case the loop above exits without ever calling check_if_pending_exception(),
|
|
1145
|
+
* leaving the interrupt pending. If we did not check here, the cancelled
|
|
1146
|
+
* send would fall through and be reported as an ordinary transport error
|
|
1147
|
+
* response, swallowing the interrupt (e.g. Thread#kill / shutdown).
|
|
1148
|
+
*
|
|
1149
|
+
* This runs after the response has already been extracted and freed and
|
|
1150
|
+
* after chunks have been handed off to the ensure handler, so re-raising
|
|
1151
|
+
* here leaks nothing.
|
|
1152
|
+
*/
|
|
1153
|
+
if (!pending_exception) {
|
|
1154
|
+
pending_exception = check_if_pending_exception();
|
|
1155
|
+
}
|
|
1156
|
+
if (pending_exception) {
|
|
1157
|
+
rb_jump_tag(pending_exception);
|
|
1158
|
+
}
|
|
1159
|
+
|
|
1160
|
+
if (args.failed) {
|
|
1161
|
+
VALUE err_resp = create_error_response(args.error_code, ctx->trace_count);
|
|
1162
|
+
return rb_ary_new_from_args(1, err_resp);
|
|
1163
|
+
}
|
|
1164
|
+
|
|
1165
|
+
VALUE ok_resp = create_ok_response(ctx->trace_count, payload);
|
|
1166
|
+
return rb_ary_new_from_args(1, ok_resp);
|
|
1167
|
+
}
|
|
1168
|
+
|
|
1169
|
+
/*
|
|
1170
|
+
* Ensure: free the current raw span and any chunks not consumed by the send.
|
|
1171
|
+
* This runs whether build_and_send_traces returned normally or raised.
|
|
1172
|
+
*/
|
|
1173
|
+
static VALUE free_send_resources(VALUE arg) {
|
|
1174
|
+
send_traces_ctx *ctx = (send_traces_ctx *)arg;
|
|
1175
|
+
free_raw_span((VALUE)&ctx->span_owner);
|
|
1176
|
+
if (ctx->chunks != NULL) {
|
|
1177
|
+
ddog_tracer_trace_chunks_free(ctx->chunks);
|
|
1178
|
+
ctx->chunks = NULL;
|
|
1179
|
+
}
|
|
1180
|
+
return Qnil;
|
|
1181
|
+
}
|
|
1182
|
+
|
|
1183
|
+
static VALUE _native_send_traces(VALUE self, VALUE traces) {
|
|
1184
|
+
ENFORCE_TYPE(traces, T_ARRAY);
|
|
1185
|
+
|
|
1186
|
+
trace_exporter_t *wrapper;
|
|
1187
|
+
TypedData_Get_Struct(self, trace_exporter_t, &trace_exporter_typed_data,
|
|
1188
|
+
wrapper);
|
|
1189
|
+
if (wrapper == NULL || wrapper->exporter == NULL) {
|
|
1190
|
+
raise_error(rb_eRuntimeError,
|
|
1191
|
+
"TraceExporter has not been initialized or was already freed");
|
|
1192
|
+
}
|
|
1193
|
+
|
|
1194
|
+
long trace_count = RARRAY_LEN(traces);
|
|
1195
|
+
|
|
1196
|
+
/* Empty batch -> empty response (matches existing transport behaviour) */
|
|
1197
|
+
if (trace_count == 0) {
|
|
1198
|
+
return rb_ary_new();
|
|
1199
|
+
}
|
|
1200
|
+
|
|
1201
|
+
/* Allocate trace chunks */
|
|
1202
|
+
ddog_TracerTraceChunks *chunks = NULL;
|
|
1203
|
+
ddog_TraceExporterError *chunks_err =
|
|
1204
|
+
ddog_tracer_trace_chunks_new((size_t)trace_count, &chunks);
|
|
1205
|
+
if (chunks_err != NULL) {
|
|
1206
|
+
ddog_trace_exporter_error_free(chunks_err);
|
|
1207
|
+
raise_error(rb_eRuntimeError, "Failed to allocate trace chunks");
|
|
1208
|
+
}
|
|
1209
|
+
|
|
1210
|
+
send_traces_ctx ctx = {
|
|
1211
|
+
.exporter = wrapper->exporter,
|
|
1212
|
+
.traces = traces,
|
|
1213
|
+
.trace_count = trace_count,
|
|
1214
|
+
.span_owner = {.span = NULL},
|
|
1215
|
+
.chunks = chunks,
|
|
1216
|
+
};
|
|
1217
|
+
|
|
1218
|
+
return rb_ensure(
|
|
1219
|
+
build_and_send_traces, (VALUE)&ctx,
|
|
1220
|
+
free_send_resources, (VALUE)&ctx);
|
|
1221
|
+
}
|
|
1222
|
+
|
|
1223
|
+
/* ========================================================================
|
|
1224
|
+
* Initialization
|
|
1225
|
+
* ======================================================================== */
|
|
1226
|
+
|
|
1227
|
+
void trace_exporter_init(VALUE tracing_module) {
|
|
1228
|
+
/* -- Module hierarchy -- */
|
|
1229
|
+
VALUE transport_module = rb_define_module_under(tracing_module, "Transport");
|
|
1230
|
+
VALUE native_module =
|
|
1231
|
+
rb_define_module_under(transport_module, "Native");
|
|
1232
|
+
|
|
1233
|
+
/* ----------------------------------------------------------------
|
|
1234
|
+
* TracerSpan class
|
|
1235
|
+
* ---------------------------------------------------------------- */
|
|
1236
|
+
tracer_span_class =
|
|
1237
|
+
rb_define_class_under(native_module, "TracerSpan", rb_cObject);
|
|
1238
|
+
rb_undef_alloc_func(tracer_span_class);
|
|
1239
|
+
|
|
1240
|
+
/* Factory */
|
|
1241
|
+
rb_define_singleton_method(tracer_span_class, "_native_from_span",
|
|
1242
|
+
_native_from_span, 1);
|
|
1243
|
+
|
|
1244
|
+
/* ----------------------------------------------------------------
|
|
1245
|
+
* TraceExporter class
|
|
1246
|
+
* ---------------------------------------------------------------- */
|
|
1247
|
+
trace_exporter_class =
|
|
1248
|
+
rb_define_class_under(native_module, "TraceExporter", rb_cObject);
|
|
1249
|
+
rb_undef_alloc_func(trace_exporter_class);
|
|
1250
|
+
|
|
1251
|
+
/* Factory: _native_new(url:, tracer_version:, ...) */
|
|
1252
|
+
rb_define_singleton_method(trace_exporter_class, "_native_new",
|
|
1253
|
+
_native_exporter_new, -1);
|
|
1254
|
+
|
|
1255
|
+
/* Instance: _native_send_traces(traces) -> Array[Response] */
|
|
1256
|
+
rb_define_method(trace_exporter_class, "_native_send_traces",
|
|
1257
|
+
_native_send_traces, 1);
|
|
1258
|
+
|
|
1259
|
+
/* Instance: fork safety hooks */
|
|
1260
|
+
rb_define_method(trace_exporter_class, "_native_before_fork",
|
|
1261
|
+
_native_before_fork, 0);
|
|
1262
|
+
rb_define_method(trace_exporter_class, "_native_after_fork_in_parent",
|
|
1263
|
+
_native_after_fork_in_parent, 0);
|
|
1264
|
+
rb_define_method(trace_exporter_class, "_native_after_fork_in_child",
|
|
1265
|
+
_native_after_fork_in_child, 0);
|
|
1266
|
+
|
|
1267
|
+
/* ----------------------------------------------------------------
|
|
1268
|
+
* Response class (defined in Ruby, loaded lazily)
|
|
1269
|
+
*
|
|
1270
|
+
* We resolve it here so create_ok_response / create_error_response
|
|
1271
|
+
* can call Response.new without repeated const lookups.
|
|
1272
|
+
* ---------------------------------------------------------------- */
|
|
1273
|
+
rb_require("datadog/tracing/transport/native/response");
|
|
1274
|
+
response_class =
|
|
1275
|
+
rb_const_get(native_module, rb_intern("Response"));
|
|
1276
|
+
rb_global_variable(&response_class);
|
|
1277
|
+
|
|
1278
|
+
/* ----------------------------------------------------------------
|
|
1279
|
+
* Cache Ruby intern IDs
|
|
1280
|
+
* ---------------------------------------------------------------- */
|
|
1281
|
+
|
|
1282
|
+
/* Span ivars */
|
|
1283
|
+
at_name_id = rb_intern("@name");
|
|
1284
|
+
at_service_id = rb_intern("@service");
|
|
1285
|
+
at_resource_id = rb_intern("@resource");
|
|
1286
|
+
at_type_id = rb_intern("@type");
|
|
1287
|
+
at_id_id = rb_intern("@id");
|
|
1288
|
+
at_parent_id_id = rb_intern("@parent_id");
|
|
1289
|
+
at_trace_id_id = rb_intern("@trace_id");
|
|
1290
|
+
at_start_time_id = rb_intern("@start_time");
|
|
1291
|
+
at_duration_id = rb_intern("@duration");
|
|
1292
|
+
at_status_id = rb_intern("@status");
|
|
1293
|
+
at_meta_id = rb_intern("@meta");
|
|
1294
|
+
at_metrics_id = rb_intern("@metrics");
|
|
1295
|
+
at_metastruct_id = rb_intern("@metastruct");
|
|
1296
|
+
|
|
1297
|
+
/* Methods */
|
|
1298
|
+
id_duration_method = rb_intern("duration");
|
|
1299
|
+
id_to_h = rb_intern("to_h");
|
|
1300
|
+
id_negative_p = rb_intern("negative?");
|
|
1301
|
+
|
|
1302
|
+
/* Response.new */
|
|
1303
|
+
id_new = rb_intern("new");
|
|
1304
|
+
|
|
1305
|
+
/* Response keyword-argument IDs */
|
|
1306
|
+
kw_ok = rb_intern("ok");
|
|
1307
|
+
kw_internal_error = rb_intern("internal_error");
|
|
1308
|
+
kw_server_error = rb_intern("server_error");
|
|
1309
|
+
kw_client_error = rb_intern("client_error");
|
|
1310
|
+
kw_trace_count = rb_intern("trace_count");
|
|
1311
|
+
kw_payload = rb_intern("payload");
|
|
1312
|
+
}
|