datadog 2.21.0 → 2.38.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 +574 -1
- data/ext/LIBDATADOG_DEVELOPMENT.md +3 -0
- 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 +3 -2
- data/ext/datadog_profiling_native_extension/collectors_cpu_and_wall_time_worker.c +301 -82
- data/ext/datadog_profiling_native_extension/collectors_discrete_dynamic_sampler.c +4 -4
- data/ext/datadog_profiling_native_extension/collectors_gc_profiling_helper.c +3 -2
- data/ext/datadog_profiling_native_extension/collectors_idle_sampling_helper.c +18 -4
- data/ext/datadog_profiling_native_extension/collectors_stack.c +63 -32
- data/ext/datadog_profiling_native_extension/collectors_stack.h +7 -2
- data/ext/datadog_profiling_native_extension/collectors_thread_context.c +728 -436
- data/ext/datadog_profiling_native_extension/collectors_thread_context.h +19 -6
- data/ext/datadog_profiling_native_extension/crashtracking_runtime_stacks.c +239 -0
- data/ext/datadog_profiling_native_extension/datadog_ruby_common.c +65 -1
- data/ext/datadog_profiling_native_extension/datadog_ruby_common.h +40 -1
- data/ext/datadog_profiling_native_extension/encoded_profile.c +2 -1
- data/ext/datadog_profiling_native_extension/extconf.rb +41 -37
- 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 +252 -103
- data/ext/datadog_profiling_native_extension/heap_recorder.h +12 -1
- data/ext/datadog_profiling_native_extension/http_transport.c +66 -68
- data/ext/datadog_profiling_native_extension/libdatadog_helpers.c +3 -22
- data/ext/datadog_profiling_native_extension/libdatadog_helpers.h +0 -5
- data/ext/datadog_profiling_native_extension/macos_sampler_thread.h +55 -0
- data/ext/datadog_profiling_native_extension/native_extension_helpers.rb +0 -13
- data/ext/datadog_profiling_native_extension/private_vm_api_access.c +40 -43
- data/ext/datadog_profiling_native_extension/private_vm_api_access.h +6 -0
- data/ext/datadog_profiling_native_extension/profiling.c +65 -19
- data/ext/datadog_profiling_native_extension/ruby_helpers.c +63 -46
- data/ext/datadog_profiling_native_extension/ruby_helpers.h +17 -5
- data/ext/datadog_profiling_native_extension/setup_signal_handler.c +32 -10
- data/ext/datadog_profiling_native_extension/setup_signal_handler.h +2 -1
- data/ext/datadog_profiling_native_extension/stack_recorder.c +110 -85
- 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.c +2 -1
- data/ext/datadog_profiling_native_extension/unsafe_api_calls_check.h +9 -4
- data/ext/libdatadog_api/crashtracker.c +16 -15
- data/ext/libdatadog_api/crashtracker_report_exception.c +126 -0
- data/ext/libdatadog_api/datadog_ruby_common.c +65 -1
- data/ext/libdatadog_api/datadog_ruby_common.h +40 -1
- data/ext/libdatadog_api/ddsketch.c +102 -0
- data/ext/libdatadog_api/di.c +203 -0
- data/ext/libdatadog_api/extconf.rb +18 -24
- data/ext/libdatadog_api/feature_flags.c +554 -0
- data/ext/libdatadog_api/feature_flags.h +5 -0
- data/ext/libdatadog_api/helpers.h +27 -0
- data/ext/libdatadog_api/init.c +13 -1
- data/ext/libdatadog_api/library_config.c +34 -25
- data/ext/libdatadog_api/process_discovery.c +19 -13
- data/ext/libdatadog_extconf_helpers.rb +94 -11
- data/lib/datadog/ai_guard/api_client.rb +84 -0
- data/lib/datadog/ai_guard/autoload.rb +10 -0
- data/lib/datadog/ai_guard/component.rb +44 -0
- data/lib/datadog/ai_guard/configuration/ext.rb +17 -0
- data/lib/datadog/ai_guard/configuration.rb +115 -0
- data/lib/datadog/ai_guard/contrib/auto_instrument.rb +24 -0
- data/lib/datadog/ai_guard/contrib/integration.rb +37 -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 +80 -0
- data/lib/datadog/ai_guard/contrib/ruby_llm/integration.rb +41 -0
- data/lib/datadog/ai_guard/contrib/ruby_llm/patcher.rb +30 -0
- 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/message.rb +25 -0
- data/lib/datadog/ai_guard/evaluation/no_op_result.rb +36 -0
- data/lib/datadog/ai_guard/evaluation/request.rb +86 -0
- data/lib/datadog/ai_guard/evaluation/result.rb +45 -0
- data/lib/datadog/ai_guard/evaluation/tool_call.rb +18 -0
- data/lib/datadog/ai_guard/evaluation.rb +108 -0
- data/lib/datadog/ai_guard/ext.rb +29 -0
- data/lib/datadog/ai_guard.rb +181 -0
- data/lib/datadog/appsec/api_security/endpoint_collection/grape_route_serializer.rb +26 -0
- data/lib/datadog/appsec/api_security/endpoint_collection/rails_collector.rb +66 -0
- data/lib/datadog/appsec/api_security/endpoint_collection/rails_route_serializer.rb +36 -0
- data/lib/datadog/appsec/api_security/endpoint_collection/sinatra_route_serializer.rb +26 -0
- data/lib/datadog/appsec/api_security/endpoint_collection.rb +10 -0
- data/lib/datadog/appsec/api_security/route_extractor.rb +38 -9
- data/lib/datadog/appsec/api_security/sampler.rb +7 -4
- data/lib/datadog/appsec/assets/blocked.html +10 -1
- data/lib/datadog/appsec/assets/blocked.json +1 -1
- data/lib/datadog/appsec/assets/blocked.text +3 -1
- data/lib/datadog/appsec/assets/waf_rules/README.md +30 -36
- data/lib/datadog/appsec/assets/waf_rules/recommended.json +359 -4
- data/lib/datadog/appsec/assets/waf_rules/strict.json +43 -2
- data/lib/datadog/appsec/assets.rb +1 -1
- data/lib/datadog/appsec/autoload.rb +1 -1
- data/lib/datadog/appsec/component.rb +16 -9
- data/lib/datadog/appsec/compressed_json.rb +3 -3
- data/lib/datadog/appsec/configuration.rb +427 -1
- data/lib/datadog/appsec/context.rb +51 -13
- data/lib/datadog/appsec/contrib/active_record/instrumentation.rb +3 -1
- data/lib/datadog/appsec/contrib/active_record/integration.rb +1 -1
- data/lib/datadog/appsec/contrib/active_record/patcher.rb +4 -1
- 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 +144 -0
- data/lib/datadog/appsec/contrib/devise/integration.rb +1 -1
- data/lib/datadog/appsec/contrib/devise/patches/signin_tracking_patch.rb +2 -1
- data/lib/datadog/appsec/contrib/excon/integration.rb +1 -1
- data/lib/datadog/appsec/contrib/excon/patcher.rb +3 -1
- data/lib/datadog/appsec/contrib/excon/ssrf_detection_middleware.rb +152 -12
- data/lib/datadog/appsec/contrib/faraday/integration.rb +1 -1
- data/lib/datadog/appsec/contrib/faraday/patcher.rb +1 -1
- data/lib/datadog/appsec/contrib/faraday/ssrf_detection_middleware.rb +138 -12
- data/lib/datadog/appsec/contrib/graphql/gateway/multiplex.rb +74 -24
- data/lib/datadog/appsec/contrib/graphql/gateway/watcher.rb +4 -2
- data/lib/datadog/appsec/contrib/graphql/integration.rb +2 -1
- data/lib/datadog/appsec/contrib/rack/buffered_input.rb +83 -0
- data/lib/datadog/appsec/contrib/rack/ext.rb +1 -1
- data/lib/datadog/appsec/contrib/rack/gateway/request.rb +52 -13
- data/lib/datadog/appsec/contrib/rack/gateway/watcher.rb +40 -19
- data/lib/datadog/appsec/contrib/rack/input_peeker.rb +79 -0
- data/lib/datadog/appsec/contrib/rack/integration.rb +1 -1
- data/lib/datadog/appsec/contrib/rack/request_middleware.rb +48 -33
- data/lib/datadog/appsec/contrib/rack/response_body.rb +36 -0
- data/lib/datadog/appsec/contrib/rails/gateway/request.rb +40 -1
- data/lib/datadog/appsec/contrib/rails/gateway/watcher.rb +26 -5
- data/lib/datadog/appsec/contrib/rails/integration.rb +1 -1
- data/lib/datadog/appsec/contrib/rails/patcher.rb +38 -0
- data/lib/datadog/appsec/contrib/rails/patches/process_action_patch.rb +2 -0
- data/lib/datadog/appsec/contrib/rest_client/integration.rb +1 -1
- data/lib/datadog/appsec/contrib/rest_client/patcher.rb +3 -1
- data/lib/datadog/appsec/contrib/rest_client/request_ssrf_detection_patch.rb +167 -11
- data/lib/datadog/appsec/contrib/sinatra/gateway/watcher.rb +43 -13
- data/lib/datadog/appsec/contrib/sinatra/integration.rb +1 -1
- data/lib/datadog/appsec/contrib/sinatra/patcher.rb +4 -4
- data/lib/datadog/appsec/contrib/sinatra/patches/json_patch.rb +1 -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 +13 -31
- data/lib/datadog/appsec/ext.rb +3 -0
- data/lib/datadog/appsec/instrumentation/gateway/middleware.rb +2 -3
- data/lib/datadog/appsec/instrumentation/gateway.rb +2 -15
- data/lib/datadog/appsec/metrics/collector.rb +43 -5
- data/lib/datadog/appsec/metrics/exporter.rb +16 -3
- data/lib/datadog/appsec/metrics/telemetry.rb +20 -3
- data/lib/datadog/appsec/metrics/telemetry_exporter.rb +20 -1
- data/lib/datadog/appsec/metrics.rb +5 -5
- data/lib/datadog/appsec/monitor/gateway/watcher.rb +8 -6
- data/lib/datadog/appsec/remote.rb +44 -29
- data/lib/datadog/appsec/response.rb +18 -4
- 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 +26 -5
- data/lib/datadog/appsec/security_engine/result.rb +29 -9
- data/lib/datadog/appsec/security_engine/runner.rb +20 -10
- data/lib/datadog/appsec/security_event.rb +5 -7
- data/lib/datadog/appsec/trace_keeper.rb +18 -6
- data/lib/datadog/appsec/utils/http/body.rb +38 -0
- data/lib/datadog/appsec/utils/http/body_reader.rb +61 -0
- data/lib/datadog/appsec/utils/http/media_range.rb +2 -1
- data/lib/datadog/appsec/utils/http/media_type.rb +32 -26
- data/lib/datadog/appsec/utils/http/url_encoded.rb +52 -0
- data/lib/datadog/appsec.rb +6 -3
- data/lib/datadog/core/configuration/agentless_settings_resolver.rb +2 -2
- data/lib/datadog/core/configuration/base.rb +17 -5
- data/lib/datadog/core/configuration/components.rb +185 -17
- data/lib/datadog/core/configuration/components_state.rb +6 -1
- data/lib/datadog/core/configuration/config_helper.rb +11 -2
- data/lib/datadog/core/configuration/deprecations.rb +2 -2
- data/lib/datadog/core/configuration/option.rb +32 -6
- data/lib/datadog/core/configuration/option_definition.rb +42 -14
- data/lib/datadog/core/configuration/options.rb +49 -12
- data/lib/datadog/core/configuration/settings.rb +115 -16
- data/lib/datadog/core/configuration/stable_config.rb +10 -0
- data/lib/datadog/core/configuration/supported_configurations.rb +379 -300
- data/lib/datadog/core/configuration.rb +3 -3
- 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 +73 -21
- data/lib/datadog/core/crashtracking/tag_builder.rb +6 -0
- data/lib/datadog/core/ddsketch.rb +19 -0
- data/lib/datadog/core/diagnostics/environment_logger.rb +3 -1
- data/lib/datadog/core/environment/agent_info.rb +65 -1
- data/lib/datadog/core/environment/cgroup.rb +52 -25
- data/lib/datadog/core/environment/container.rb +140 -46
- data/lib/datadog/core/environment/ext.rb +13 -0
- data/lib/datadog/core/environment/identity.rb +40 -4
- data/lib/datadog/core/environment/process.rb +122 -0
- data/lib/datadog/core/environment/socket.rb +13 -0
- data/lib/datadog/core/environment/yjit.rb +2 -1
- data/lib/datadog/core/error.rb +6 -6
- data/lib/datadog/core/evp.rb +11 -0
- data/lib/datadog/core/feature_flags.rb +61 -0
- data/lib/datadog/core/knuth_sampler.rb +59 -0
- data/lib/datadog/core/logger.rb +1 -1
- data/lib/datadog/core/metrics/client.rb +6 -6
- data/lib/datadog/core/metrics/logging.rb +1 -1
- data/lib/datadog/core/pin.rb +8 -8
- data/lib/datadog/core/process_discovery.rb +21 -18
- data/lib/datadog/core/rate_limiter.rb +11 -1
- data/lib/datadog/core/remote/client/capabilities.rb +49 -6
- data/lib/datadog/core/remote/client.rb +15 -7
- data/lib/datadog/core/remote/component.rb +64 -36
- data/lib/datadog/core/remote/configuration/content.rb +15 -2
- data/lib/datadog/core/remote/configuration/digest.rb +14 -7
- data/lib/datadog/core/remote/configuration/repository.rb +1 -1
- data/lib/datadog/core/remote/configuration/target.rb +13 -6
- data/lib/datadog/core/remote/transport/config.rb +9 -36
- data/lib/datadog/core/remote/transport/http/config.rb +15 -55
- data/lib/datadog/core/remote/transport/http/negotiation.rb +14 -44
- data/lib/datadog/core/remote/transport/http.rb +15 -24
- data/lib/datadog/core/remote/transport/negotiation.rb +8 -33
- data/lib/datadog/core/remote/worker.rb +25 -37
- data/lib/datadog/core/runtime/metrics.rb +11 -2
- data/lib/datadog/core/semaphore.rb +1 -4
- data/lib/datadog/core/tag_builder.rb +0 -4
- data/lib/datadog/core/tag_normalizer.rb +84 -0
- data/lib/datadog/core/telemetry/component.rb +59 -15
- data/lib/datadog/core/telemetry/emitter.rb +6 -6
- data/lib/datadog/core/telemetry/event/app_client_configuration_change.rb +2 -3
- data/lib/datadog/core/telemetry/event/app_endpoints_loaded.rb +30 -0
- data/lib/datadog/core/telemetry/event/app_extended_heartbeat.rb +32 -0
- data/lib/datadog/core/telemetry/event/app_started.rb +177 -171
- data/lib/datadog/core/telemetry/event/synth_app_client_configuration_change.rb +27 -4
- data/lib/datadog/core/telemetry/event.rb +2 -7
- data/lib/datadog/core/telemetry/ext.rb +1 -0
- data/lib/datadog/core/telemetry/logger.rb +4 -2
- data/lib/datadog/core/telemetry/logging.rb +17 -5
- data/lib/datadog/core/telemetry/metrics_manager.rb +9 -0
- data/lib/datadog/core/telemetry/request.rb +17 -5
- data/lib/datadog/core/telemetry/transport/http/telemetry.rb +8 -34
- data/lib/datadog/core/telemetry/transport/http.rb +21 -16
- data/lib/datadog/core/telemetry/transport/telemetry.rb +8 -17
- data/lib/datadog/core/telemetry/worker.rb +108 -32
- data/lib/datadog/core/transport/ext.rb +3 -0
- data/lib/datadog/core/transport/http/api/endpoint.rb +9 -4
- data/lib/datadog/core/transport/http/api/instance.rb +4 -21
- data/lib/datadog/core/transport/http/builder.rb +10 -6
- data/lib/datadog/core/transport/http/client.rb +80 -0
- data/lib/datadog/core/transport/http/response.rb +4 -0
- data/lib/datadog/core/transport/http.rb +24 -19
- data/lib/datadog/core/transport/parcel.rb +61 -9
- data/lib/datadog/core/transport/response.rb +16 -2
- data/lib/datadog/core/transport/transport.rb +90 -0
- data/lib/datadog/core/utils/at_fork_monkey_patch.rb +2 -2
- data/lib/datadog/core/utils/{base64.rb → base64_codec.rb} +4 -3
- data/lib/datadog/core/utils/enumerable_compat.rb +29 -0
- 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/{appsec/api_security → core/utils}/lru_cache.rb +10 -21
- data/lib/datadog/core/utils/network.rb +22 -1
- data/lib/datadog/core/utils/only_once.rb +1 -1
- data/lib/datadog/core/utils/only_once_successful.rb +8 -2
- data/lib/datadog/core/utils/safe_dup.rb +2 -2
- data/lib/datadog/core/utils/sequence.rb +2 -0
- data/lib/datadog/core/utils/spawn_monkey_patch.rb +68 -0
- data/lib/datadog/core/utils/time.rb +6 -2
- data/lib/datadog/core/utils.rb +3 -1
- data/lib/datadog/core/workers/async.rb +11 -2
- data/lib/datadog/core/workers/interval_loop.rb +51 -3
- data/lib/datadog/core/workers/polling.rb +2 -0
- data/lib/datadog/core/workers/queue.rb +96 -1
- data/lib/datadog/core/workers/runtime_metrics.rb +9 -1
- data/lib/datadog/core.rb +10 -3
- data/lib/datadog/data_streams/configuration.rb +50 -0
- data/lib/datadog/data_streams/ext.rb +11 -0
- data/lib/datadog/data_streams/extensions.rb +16 -0
- data/lib/datadog/data_streams/pathway_context.rb +169 -0
- data/lib/datadog/data_streams/processor.rb +511 -0
- data/lib/datadog/data_streams/transport/http/stats.rb +58 -0
- data/lib/datadog/data_streams/transport/http.rb +36 -0
- data/lib/datadog/data_streams/transport/stats.rb +39 -0
- data/lib/datadog/data_streams.rb +100 -0
- data/lib/datadog/di/base.rb +15 -7
- data/lib/datadog/di/boot.rb +7 -2
- 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 +217 -15
- data/lib/datadog/di/component.rb +139 -51
- data/lib/datadog/di/configuration.rb +241 -2
- data/lib/datadog/di/context.rb +82 -0
- data/lib/datadog/di/contrib/active_record.rb +34 -5
- data/lib/datadog/di/el/compiler.rb +168 -0
- data/lib/datadog/di/el/evaluator.rb +159 -0
- data/lib/datadog/di/el/expression.rb +42 -0
- data/lib/datadog/di/el.rb +5 -0
- data/lib/datadog/di/error.rb +44 -0
- data/lib/datadog/di/fatal_exceptions.rb +26 -0
- data/lib/datadog/di/instrumenter.rb +623 -147
- data/lib/datadog/di/logger.rb +2 -2
- data/lib/datadog/di/probe.rb +122 -14
- data/lib/datadog/di/probe_builder.rb +124 -3
- data/lib/datadog/di/probe_file_loader/railtie.rb +1 -1
- data/lib/datadog/di/probe_file_loader.rb +12 -7
- data/lib/datadog/di/probe_manager.rb +195 -100
- data/lib/datadog/di/probe_notification_builder.rb +321 -90
- data/lib/datadog/di/probe_notifier_worker.rb +112 -36
- data/lib/datadog/di/probe_repository.rb +198 -0
- data/lib/datadog/di/proc_responder.rb +36 -0
- data/lib/datadog/di/redactor.rb +24 -2
- data/lib/datadog/di/remote.rb +258 -93
- data/lib/datadog/di/serializer.rb +310 -29
- data/lib/datadog/di/transport/diagnostics.rb +12 -42
- data/lib/datadog/di/transport/http/diagnostics.rb +4 -34
- data/lib/datadog/di/transport/http/input.rb +2 -34
- data/lib/datadog/di/transport/http.rb +43 -19
- data/lib/datadog/di/transport/input.rb +112 -38
- data/lib/datadog/di/utils.rb +42 -14
- data/lib/datadog/di.rb +204 -4
- data/lib/datadog/error_tracking/collector.rb +2 -1
- data/lib/datadog/error_tracking/component.rb +2 -2
- data/lib/datadog/error_tracking/configuration.rb +55 -2
- data/lib/datadog/error_tracking/filters.rb +2 -2
- data/lib/datadog/kit/appsec/events/v2.rb +60 -3
- data/lib/datadog/kit/enable_core_dumps.rb +1 -1
- data/lib/datadog/kit/tracing/method_tracer.rb +135 -0
- data/lib/datadog/open_feature/component.rb +100 -0
- data/lib/datadog/open_feature/configuration.rb +37 -0
- data/lib/datadog/open_feature/evaluation_engine.rb +70 -0
- data/lib/datadog/open_feature/exposures/batch_builder.rb +32 -0
- data/lib/datadog/open_feature/exposures/buffer.rb +43 -0
- data/lib/datadog/open_feature/exposures/deduplicator.rb +30 -0
- data/lib/datadog/open_feature/exposures/event.rb +60 -0
- data/lib/datadog/open_feature/exposures/reporter.rb +40 -0
- data/lib/datadog/open_feature/exposures/worker.rb +116 -0
- data/lib/datadog/open_feature/ext.rb +16 -0
- 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 +101 -0
- data/lib/datadog/open_feature/hooks/flag_eval_metrics_hook.rb +49 -0
- data/lib/datadog/open_feature/metrics/flag_eval_metrics.rb +149 -0
- data/lib/datadog/open_feature/native_evaluator.rb +60 -0
- data/lib/datadog/open_feature/noop_evaluator.rb +26 -0
- data/lib/datadog/open_feature/provider.rb +191 -0
- data/lib/datadog/open_feature/remote.rb +67 -0
- data/lib/datadog/open_feature/resolution_details.rb +35 -0
- data/lib/datadog/open_feature/transport.rb +121 -0
- data/lib/datadog/open_feature.rb +19 -0
- data/lib/datadog/opentelemetry/api/baggage.rb +1 -1
- data/lib/datadog/opentelemetry/configuration/settings.rb +226 -0
- data/lib/datadog/opentelemetry/ext.rb +9 -0
- data/lib/datadog/opentelemetry/logs.rb +98 -0
- data/lib/datadog/opentelemetry/metrics.rb +90 -0
- data/lib/datadog/opentelemetry/sdk/configurator.rb +65 -1
- 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 +28 -0
- data/lib/datadog/opentelemetry/sdk/propagator.rb +9 -3
- data/lib/datadog/opentelemetry/sdk/span_processor.rb +4 -1
- data/lib/datadog/opentelemetry/sdk.rb +19 -0
- data/lib/datadog/opentelemetry/signal_configuration.rb +53 -0
- data/lib/datadog/opentelemetry.rb +4 -0
- data/lib/datadog/profiling/collectors/code_provenance.rb +71 -12
- data/lib/datadog/profiling/collectors/cpu_and_wall_time_worker.rb +52 -4
- data/lib/datadog/profiling/collectors/idle_sampling_helper.rb +13 -5
- data/lib/datadog/profiling/collectors/info.rb +18 -4
- data/lib/datadog/profiling/collectors/thread_context.rb +10 -5
- data/lib/datadog/profiling/component.rb +82 -40
- data/lib/datadog/profiling/exporter.rb +41 -12
- data/lib/datadog/profiling/ext/dir_monkey_patches.rb +24 -5
- data/lib/datadog/profiling/ext/exec_monkey_patch.rb +32 -0
- data/lib/datadog/profiling/ext.rb +0 -2
- data/lib/datadog/profiling/flush.rb +23 -11
- data/lib/datadog/profiling/http_transport.rb +21 -8
- data/lib/datadog/profiling/load_native_extension.rb +2 -2
- data/lib/datadog/profiling/profiler.rb +31 -14
- data/lib/datadog/profiling/scheduler.rb +10 -9
- data/lib/datadog/profiling/stack_recorder.rb +0 -8
- data/lib/datadog/profiling/tag_builder.rb +37 -3
- data/lib/datadog/profiling/tasks/exec.rb +8 -3
- data/lib/datadog/profiling/tasks/help.rb +1 -0
- data/lib/datadog/profiling/tasks/setup.rb +2 -2
- data/lib/datadog/profiling.rb +1 -3
- 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 +180 -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/buffer.rb +3 -3
- data/lib/datadog/tracing/component.rb +17 -17
- data/lib/datadog/tracing/configuration/dynamic.rb +2 -2
- data/lib/datadog/tracing/configuration/ext.rb +22 -0
- data/lib/datadog/tracing/configuration/settings.rb +96 -4
- data/lib/datadog/tracing/contrib/action_cable/events/broadcast.rb +4 -1
- data/lib/datadog/tracing/contrib/action_cable/events/perform_action.rb +4 -1
- data/lib/datadog/tracing/contrib/action_cable/events/transmit.rb +4 -1
- data/lib/datadog/tracing/contrib/action_cable/instrumentation.rb +4 -1
- data/lib/datadog/tracing/contrib/action_mailer/event.rb +4 -1
- data/lib/datadog/tracing/contrib/action_pack/action_controller/instrumentation.rb +10 -7
- data/lib/datadog/tracing/contrib/action_pack/action_dispatch/instrumentation.rb +28 -0
- data/lib/datadog/tracing/contrib/action_pack/action_dispatch/patcher.rb +3 -1
- data/lib/datadog/tracing/contrib/action_pack/utils.rb +1 -2
- data/lib/datadog/tracing/contrib/action_view/events/render_partial.rb +4 -1
- data/lib/datadog/tracing/contrib/action_view/events/render_template.rb +5 -2
- data/lib/datadog/tracing/contrib/active_job/data_streams.rb +62 -0
- data/lib/datadog/tracing/contrib/active_job/events/discard.rb +5 -2
- data/lib/datadog/tracing/contrib/active_job/events/enqueue.rb +5 -2
- data/lib/datadog/tracing/contrib/active_job/events/enqueue_at.rb +5 -2
- data/lib/datadog/tracing/contrib/active_job/events/enqueue_retry.rb +5 -2
- data/lib/datadog/tracing/contrib/active_job/events/perform.rb +5 -2
- data/lib/datadog/tracing/contrib/active_job/events/retry_stopped.rb +5 -2
- data/lib/datadog/tracing/contrib/active_job/log_injection.rb +21 -7
- data/lib/datadog/tracing/contrib/active_job/patcher.rb +17 -1
- data/lib/datadog/tracing/contrib/active_model_serializers/events/render.rb +1 -1
- data/lib/datadog/tracing/contrib/active_model_serializers/events/serialize.rb +3 -4
- data/lib/datadog/tracing/contrib/active_record/configuration/resolver.rb +2 -2
- data/lib/datadog/tracing/contrib/active_record/events/instantiation.rb +1 -1
- data/lib/datadog/tracing/contrib/active_record/events/sql.rb +2 -5
- data/lib/datadog/tracing/contrib/active_record/utils.rb +1 -1
- data/lib/datadog/tracing/contrib/active_support/cache/events/cache.rb +2 -5
- data/lib/datadog/tracing/contrib/active_support/cache/instrumentation.rb +1 -4
- data/lib/datadog/tracing/contrib/active_support/notifications/subscription.rb +2 -2
- data/lib/datadog/tracing/contrib/aws/instrumentation.rb +6 -8
- data/lib/datadog/tracing/contrib/component.rb +3 -3
- data/lib/datadog/tracing/contrib/configurable.rb +18 -3
- data/lib/datadog/tracing/contrib/configuration/resolver.rb +14 -4
- data/lib/datadog/tracing/contrib/dalli/instrumentation.rb +1 -5
- data/lib/datadog/tracing/contrib/dalli/integration.rb +4 -1
- data/lib/datadog/tracing/contrib/dalli/quantize.rb +1 -1
- data/lib/datadog/tracing/contrib/delayed_job/plugin.rb +2 -0
- data/lib/datadog/tracing/contrib/delayed_job/server_internal_tracer/worker.rb +1 -0
- data/lib/datadog/tracing/contrib/elasticsearch/patcher.rb +2 -6
- data/lib/datadog/tracing/contrib/elasticsearch/quantize.rb +2 -2
- data/lib/datadog/tracing/contrib/ethon/configuration/settings.rb +5 -1
- data/lib/datadog/tracing/contrib/ethon/easy_patch.rb +5 -6
- data/lib/datadog/tracing/contrib/ethon/ext.rb +1 -0
- data/lib/datadog/tracing/contrib/ethon/multi_patch.rb +1 -8
- data/lib/datadog/tracing/contrib/excon/configuration/settings.rb +16 -5
- data/lib/datadog/tracing/contrib/excon/ext.rb +1 -0
- data/lib/datadog/tracing/contrib/excon/middleware.rb +3 -7
- data/lib/datadog/tracing/contrib/ext.rb +3 -1
- data/lib/datadog/tracing/contrib/extensions.rb +19 -2
- data/lib/datadog/tracing/contrib/faraday/configuration/settings.rb +16 -9
- data/lib/datadog/tracing/contrib/faraday/ext.rb +1 -0
- data/lib/datadog/tracing/contrib/faraday/middleware.rb +3 -7
- data/lib/datadog/tracing/contrib/grape/configuration/settings.rb +7 -3
- data/lib/datadog/tracing/contrib/grape/endpoint.rb +10 -7
- data/lib/datadog/tracing/contrib/grape/instrumentation.rb +13 -8
- data/lib/datadog/tracing/contrib/grape/patcher.rb +6 -1
- data/lib/datadog/tracing/contrib/graphql/configuration/settings.rb +7 -0
- data/lib/datadog/tracing/contrib/graphql/ext.rb +1 -0
- data/lib/datadog/tracing/contrib/graphql/unified_trace.rb +75 -44
- data/lib/datadog/tracing/contrib/grpc/configuration/settings.rb +5 -2
- data/lib/datadog/tracing/contrib/grpc/datadog_interceptor/client.rb +3 -7
- data/lib/datadog/tracing/contrib/grpc/datadog_interceptor/server.rb +3 -7
- data/lib/datadog/tracing/contrib/grpc/distributed/propagation.rb +2 -0
- data/lib/datadog/tracing/contrib/grpc/ext.rb +1 -0
- data/lib/datadog/tracing/contrib/grpc.rb +1 -0
- data/lib/datadog/tracing/contrib/hanami/action_tracer.rb +1 -0
- data/lib/datadog/tracing/contrib/hanami/renderer_policy_tracing.rb +1 -0
- data/lib/datadog/tracing/contrib/hanami/router_tracing.rb +1 -0
- data/lib/datadog/tracing/contrib/http/configuration/settings.rb +16 -5
- data/lib/datadog/tracing/contrib/http/distributed/propagation.rb +2 -0
- data/lib/datadog/tracing/contrib/http/ext.rb +1 -0
- data/lib/datadog/tracing/contrib/http/instrumentation.rb +4 -8
- data/lib/datadog/tracing/contrib/http/integration.rb +0 -2
- data/lib/datadog/tracing/contrib/http.rb +1 -0
- data/lib/datadog/tracing/contrib/httpclient/configuration/settings.rb +16 -5
- data/lib/datadog/tracing/contrib/httpclient/ext.rb +1 -0
- data/lib/datadog/tracing/contrib/httpclient/instrumentation.rb +7 -7
- data/lib/datadog/tracing/contrib/httprb/configuration/settings.rb +16 -5
- data/lib/datadog/tracing/contrib/httprb/ext.rb +1 -0
- data/lib/datadog/tracing/contrib/httprb/instrumentation.rb +4 -8
- data/lib/datadog/tracing/contrib/kafka/event.rb +1 -0
- data/lib/datadog/tracing/contrib/kafka/instrumentation/consumer.rb +66 -0
- data/lib/datadog/tracing/contrib/kafka/instrumentation/producer.rb +66 -0
- data/lib/datadog/tracing/contrib/kafka/patcher.rb +14 -0
- data/lib/datadog/tracing/contrib/karafka/configuration/settings.rb +5 -1
- data/lib/datadog/tracing/contrib/karafka/distributed/propagation.rb +2 -0
- data/lib/datadog/tracing/contrib/karafka/ext.rb +1 -0
- data/lib/datadog/tracing/contrib/karafka/framework.rb +30 -0
- data/lib/datadog/tracing/contrib/karafka/monitor.rb +11 -0
- data/lib/datadog/tracing/contrib/karafka/patcher.rb +35 -4
- data/lib/datadog/tracing/contrib/karafka.rb +1 -0
- data/lib/datadog/tracing/contrib/mongodb/parsers.rb +5 -5
- data/lib/datadog/tracing/contrib/mongodb/subscribers.rb +5 -8
- data/lib/datadog/tracing/contrib/mysql2/configuration/settings.rb +6 -0
- data/lib/datadog/tracing/contrib/mysql2/instrumentation.rb +3 -6
- data/lib/datadog/tracing/contrib/opensearch/patcher.rb +2 -6
- data/lib/datadog/tracing/contrib/opensearch/quantize.rb +2 -2
- data/lib/datadog/tracing/contrib/pg/configuration/settings.rb +6 -0
- data/lib/datadog/tracing/contrib/pg/instrumentation.rb +15 -18
- data/lib/datadog/tracing/contrib/presto/instrumentation.rb +6 -8
- data/lib/datadog/tracing/contrib/propagation/sql_comment/ext.rb +13 -0
- data/lib/datadog/tracing/contrib/propagation/sql_comment/mode.rb +6 -2
- data/lib/datadog/tracing/contrib/propagation/sql_comment.rb +24 -0
- data/lib/datadog/tracing/contrib/que/configuration/settings.rb +5 -2
- data/lib/datadog/tracing/contrib/que/ext.rb +1 -0
- data/lib/datadog/tracing/contrib/que/tracer.rb +1 -0
- data/lib/datadog/tracing/contrib/racecar/event.rb +1 -5
- data/lib/datadog/tracing/contrib/rack/configuration/settings.rb +11 -1
- data/lib/datadog/tracing/contrib/rack/ext.rb +28 -0
- data/lib/datadog/tracing/contrib/rack/header_tagging.rb +23 -0
- data/lib/datadog/tracing/contrib/rack/middlewares.rb +62 -27
- data/lib/datadog/tracing/contrib/rack/patcher.rb +2 -2
- data/lib/datadog/tracing/contrib/rack/request_queue.rb +1 -1
- data/lib/datadog/tracing/contrib/rack/route_inference.rb +67 -0
- data/lib/datadog/tracing/contrib/rack/trace_proxy_middleware.rb +119 -1
- data/lib/datadog/tracing/contrib/rails/configuration/settings.rb +5 -2
- data/lib/datadog/tracing/contrib/rails/ext.rb +1 -0
- data/lib/datadog/tracing/contrib/rails/log_injection.rb +1 -1
- data/lib/datadog/tracing/contrib/rails/middlewares.rb +2 -2
- data/lib/datadog/tracing/contrib/rails/patcher.rb +0 -1
- data/lib/datadog/tracing/contrib/rails/runner.rb +3 -1
- data/lib/datadog/tracing/contrib/rake/instrumentation.rb +6 -4
- data/lib/datadog/tracing/contrib/redis/quantize.rb +1 -1
- data/lib/datadog/tracing/contrib/redis/tags.rb +1 -6
- data/lib/datadog/tracing/contrib/redis/trace_middleware.rb +2 -0
- data/lib/datadog/tracing/contrib/registerable.rb +11 -0
- data/lib/datadog/tracing/contrib/resque/resque_job.rb +1 -0
- data/lib/datadog/tracing/contrib/rest_client/configuration/settings.rb +5 -2
- data/lib/datadog/tracing/contrib/rest_client/ext.rb +1 -0
- data/lib/datadog/tracing/contrib/rest_client/request_patch.rb +5 -6
- data/lib/datadog/tracing/contrib/roda/ext.rb +1 -0
- data/lib/datadog/tracing/contrib/roda/instrumentation.rb +7 -2
- data/lib/datadog/tracing/contrib/sequel/database.rb +1 -0
- data/lib/datadog/tracing/contrib/sequel/dataset.rb +1 -0
- data/lib/datadog/tracing/contrib/sequel/utils.rb +2 -7
- data/lib/datadog/tracing/contrib/shoryuken/tracer.rb +1 -0
- data/lib/datadog/tracing/contrib/sidekiq/client_tracer.rb +1 -0
- data/lib/datadog/tracing/contrib/sidekiq/configuration/settings.rb +5 -1
- data/lib/datadog/tracing/contrib/sidekiq/distributed/propagation.rb +2 -0
- data/lib/datadog/tracing/contrib/sidekiq/ext.rb +1 -0
- 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 +3 -2
- data/lib/datadog/tracing/contrib/sidekiq/utils.rb +1 -1
- data/lib/datadog/tracing/contrib/sidekiq.rb +1 -0
- data/lib/datadog/tracing/contrib/sinatra/configuration/settings.rb +5 -1
- data/lib/datadog/tracing/contrib/sinatra/ext.rb +1 -0
- data/lib/datadog/tracing/contrib/sinatra/framework.rb +1 -1
- data/lib/datadog/tracing/contrib/sinatra/tracer.rb +1 -0
- data/lib/datadog/tracing/contrib/sinatra/tracer_middleware.rb +4 -1
- data/lib/datadog/tracing/contrib/sneakers/integration.rb +15 -4
- data/lib/datadog/tracing/contrib/sneakers/tracer.rb +1 -0
- data/lib/datadog/tracing/contrib/status_range_matcher.rb +13 -1
- data/lib/datadog/tracing/contrib/stripe/request.rb +1 -1
- data/lib/datadog/tracing/contrib/sucker_punch/instrumentation.rb +1 -0
- data/lib/datadog/tracing/contrib/trilogy/configuration/settings.rb +6 -0
- data/lib/datadog/tracing/contrib/trilogy/instrumentation.rb +4 -6
- data/lib/datadog/tracing/contrib/utils/quantization/{hash.rb → hash_formatter.rb} +4 -2
- data/lib/datadog/tracing/contrib/waterdrop/configuration/settings.rb +31 -0
- data/lib/datadog/tracing/contrib/waterdrop/distributed/propagation.rb +50 -0
- data/lib/datadog/tracing/contrib/waterdrop/ext.rb +18 -0
- data/lib/datadog/tracing/contrib/waterdrop/integration.rb +43 -0
- data/lib/datadog/tracing/contrib/waterdrop/middleware.rb +46 -0
- data/lib/datadog/tracing/contrib/waterdrop/patcher.rb +49 -0
- data/lib/datadog/tracing/contrib/waterdrop/producer.rb +50 -0
- data/lib/datadog/tracing/contrib/waterdrop.rb +42 -0
- data/lib/datadog/tracing/contrib.rb +9 -0
- data/lib/datadog/tracing/diagnostics/environment_logger.rb +4 -2
- data/lib/datadog/tracing/distributed/baggage.rb +64 -8
- data/lib/datadog/tracing/distributed/datadog.rb +13 -11
- data/lib/datadog/tracing/distributed/datadog_tags_codec.rb +1 -14
- data/lib/datadog/tracing/distributed/propagation.rb +35 -3
- data/lib/datadog/tracing/distributed/trace_context.rb +85 -62
- data/lib/datadog/tracing/event.rb +1 -1
- data/lib/datadog/tracing/ext.rb +9 -0
- data/lib/datadog/tracing/metadata/ext.rb +23 -1
- data/lib/datadog/tracing/metadata/tagging.rb +2 -2
- data/lib/datadog/tracing/pipeline.rb +1 -1
- data/lib/datadog/tracing/remote.rb +36 -13
- data/lib/datadog/tracing/sampling/ext.rb +2 -0
- data/lib/datadog/tracing/sampling/priority_sampler.rb +16 -1
- data/lib/datadog/tracing/sampling/rate_sampler.rb +8 -19
- data/lib/datadog/tracing/sampling/rule.rb +1 -1
- data/lib/datadog/tracing/sampling/rule_sampler.rb +54 -25
- data/lib/datadog/tracing/sampling/span/rule_parser.rb +2 -2
- data/lib/datadog/tracing/span.rb +1 -1
- data/lib/datadog/tracing/span_event.rb +2 -2
- data/lib/datadog/tracing/span_operation.rb +34 -10
- data/lib/datadog/tracing/sync_writer.rb +0 -1
- data/lib/datadog/tracing/trace_digest.rb +7 -0
- data/lib/datadog/tracing/trace_operation.rb +123 -16
- data/lib/datadog/tracing/tracer.rb +82 -23
- data/lib/datadog/tracing/transport/http/client.rb +12 -26
- data/lib/datadog/tracing/transport/http/traces.rb +2 -50
- data/lib/datadog/tracing/transport/http.rb +15 -9
- data/lib/datadog/tracing/transport/io/client.rb +6 -9
- data/lib/datadog/tracing/transport/io/traces.rb +28 -34
- data/lib/datadog/tracing/transport/trace_formatter.rb +22 -0
- data/lib/datadog/tracing/transport/traces.rb +13 -81
- data/lib/datadog/tracing/workers.rb +2 -1
- data/lib/datadog/tracing/writer.rb +1 -1
- data/lib/datadog/version.rb +2 -2
- data/lib/datadog.rb +8 -1
- metadata +185 -36
- data/ext/datadog_profiling_native_extension/clock_id_noop.c +0 -21
- data/ext/libdatadog_api/macos_development.md +0 -26
- data/lib/datadog/appsec/configuration/settings.rb +0 -400
- data/lib/datadog/appsec/contrib/rails/ext.rb +0 -13
- data/lib/datadog/core/remote/transport/http/api.rb +0 -53
- data/lib/datadog/core/remote/transport/http/client.rb +0 -49
- data/lib/datadog/core/telemetry/transport/http/api.rb +0 -43
- data/lib/datadog/core/telemetry/transport/http/client.rb +0 -49
- data/lib/datadog/core/transport/http/api/spec.rb +0 -36
- data/lib/datadog/di/configuration/settings.rb +0 -212
- data/lib/datadog/di/transport/http/api.rb +0 -42
- data/lib/datadog/di/transport/http/client.rb +0 -47
- data/lib/datadog/error_tracking/configuration/settings.rb +0 -63
- data/lib/datadog/opentelemetry/api/baggage.rbs +0 -26
- data/lib/datadog/tracing/transport/http/api.rb +0 -44
- data/lib/datadog/tracing/workers/trace_writer.rb +0 -199
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative '../../ruby_version'
|
|
4
|
+
|
|
5
|
+
module Datadog
|
|
6
|
+
module Core
|
|
7
|
+
module Utils
|
|
8
|
+
# Applies the Process.spawn wrapper used to merge additional environment variables
|
|
9
|
+
# into child processes.
|
|
10
|
+
module SpawnMonkeyPatch
|
|
11
|
+
# @param env_provider [#call] returns a Hash of env vars to merge into the child process
|
|
12
|
+
def self.apply!(env_provider:)
|
|
13
|
+
@env_provider = env_provider
|
|
14
|
+
|
|
15
|
+
# Idempotent: tests, reloads, or repeated Components init must not stack prepends.
|
|
16
|
+
return if ::Process.singleton_class.ancestors.include?(ProcessSpawnPatch)
|
|
17
|
+
|
|
18
|
+
::Process.singleton_class.prepend(ProcessSpawnPatch)
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
# Prepends `Process.spawn` to merge `env_provider` output into the child's environment hash.
|
|
22
|
+
module ProcessSpawnPatch
|
|
23
|
+
# The One and Only Correct Delegation Pattern
|
|
24
|
+
if RubyVersion.is?('>= 3')
|
|
25
|
+
def spawn(*args, **kwargs) # steep:ignore DifferentMethodParameterKind
|
|
26
|
+
super(*SpawnMonkeyPatch.inject_envs(args), **kwargs)
|
|
27
|
+
end
|
|
28
|
+
else
|
|
29
|
+
def spawn(*args)
|
|
30
|
+
super(*SpawnMonkeyPatch.inject_envs(args))
|
|
31
|
+
end
|
|
32
|
+
ruby2_keywords :spawn if respond_to?(:ruby2_keywords, true)
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
# Merge the env vars from `env_provider` with the optional env `Hash` from {Process.spawn}.
|
|
37
|
+
#
|
|
38
|
+
# `env` is the first argument when it is a {Hash}; see MRI `spawn([env, ] *args, options)`:
|
|
39
|
+
# https://docs.ruby-lang.org/en/master/Process.html#method-c-spawn
|
|
40
|
+
#
|
|
41
|
+
# When there is **no** leading env Hash, MRI inherits the parent's `ENV`; we prepend only the
|
|
42
|
+
# `env_provider` hash so spawned children see parent env plus injections.
|
|
43
|
+
#
|
|
44
|
+
# When callers pass `unsetenv_others: true`, MRI only forwards the explicitly passed env Hash;
|
|
45
|
+
# replacing a missing hash with DATADOG_ENV.to_h would wrongly carry over parent variables.
|
|
46
|
+
# Prepending only the provider hash preserves `unsetenv_others` semantics.
|
|
47
|
+
#
|
|
48
|
+
# See https://docs.ruby-lang.org/en/master/Process.html#module-Process-label-Environment+Variables+-28-3Aunsetenv_others-29
|
|
49
|
+
#
|
|
50
|
+
# NOTE: `::Hash` (not bare `Hash`) is required because this module is nested under
|
|
51
|
+
# `Datadog::Core::Utils`, and `Datadog::Core::Utils::Hash` exists.
|
|
52
|
+
# Bare `Hash` resolves to that module via Module.nesting, making `Hash === some_hash`
|
|
53
|
+
# silently return `false`. See https://github.com/DataDog/dd-trace-rb/issues/5621.
|
|
54
|
+
def self.inject_envs(args)
|
|
55
|
+
provided_env = @env_provider.call
|
|
56
|
+
|
|
57
|
+
if ::Hash === args.first
|
|
58
|
+
args[0] = args.first.merge(provided_env)
|
|
59
|
+
else
|
|
60
|
+
args.unshift(provided_env)
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
args
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
end
|
|
@@ -8,11 +8,15 @@ module Datadog
|
|
|
8
8
|
module_function
|
|
9
9
|
|
|
10
10
|
# Current monotonic time
|
|
11
|
+
# On macOS, CLOCK_MONOTONIC only has microsecond precision,
|
|
12
|
+
# so we use CLOCK_MONOTONIC_RAW which has nanosecond precision instead.
|
|
11
13
|
#
|
|
12
14
|
# @param unit [Symbol] unit for the resulting value, same as ::Process#clock_gettime, defaults to :float_second
|
|
13
|
-
# @return [
|
|
15
|
+
# @return [Float|Integer] timestamp in the requested unit, since some unspecified starting point
|
|
16
|
+
MONOTONIC_CLOCK_ID = RUBY_PLATFORM.include?("darwin") ? Process::CLOCK_MONOTONIC_RAW : Process::CLOCK_MONOTONIC
|
|
17
|
+
|
|
14
18
|
def get_time(unit = :float_second)
|
|
15
|
-
Process.clock_gettime(
|
|
19
|
+
Process.clock_gettime(MONOTONIC_CLOCK_ID, unit)
|
|
16
20
|
end
|
|
17
21
|
|
|
18
22
|
# Current wall time.
|
data/lib/datadog/core/utils.rb
CHANGED
|
@@ -38,6 +38,8 @@ module Datadog
|
|
|
38
38
|
|
|
39
39
|
# Ensure `str` is a valid UTF-8, ready to be
|
|
40
40
|
# sent through the tracer transport.
|
|
41
|
+
# DEV-3.0: This method should unconditionally handle invalid byte sequences
|
|
42
|
+
# DEV-3.0: and return a safe string to display.
|
|
41
43
|
#
|
|
42
44
|
# @param [String,#to_s] str object to be converted to a UTF-8 string
|
|
43
45
|
# @param [Boolean] binary whether to expect binary data in the `str` parameter
|
|
@@ -61,7 +63,7 @@ module Datadog
|
|
|
61
63
|
str.encode(::Encoding::UTF_8)
|
|
62
64
|
end
|
|
63
65
|
rescue => e
|
|
64
|
-
Datadog.logger.debug("Error encoding string in UTF-8: #{e}")
|
|
66
|
+
Datadog.logger.debug("Error encoding string in UTF-8: #{e.class}: #{e.message}")
|
|
65
67
|
|
|
66
68
|
placeholder
|
|
67
69
|
end
|
|
@@ -8,6 +8,11 @@ module Datadog
|
|
|
8
8
|
module Async
|
|
9
9
|
# Adds threading behavior to workers
|
|
10
10
|
# to run tasks asynchronously.
|
|
11
|
+
#
|
|
12
|
+
# This module is included in Polling module, and has no other
|
|
13
|
+
# direct users.
|
|
14
|
+
#
|
|
15
|
+
# @api private
|
|
11
16
|
module Thread
|
|
12
17
|
FORK_POLICY_STOP = :stop
|
|
13
18
|
FORK_POLICY_RESTART = :restart
|
|
@@ -24,7 +29,11 @@ module Datadog
|
|
|
24
29
|
# Methods that must be prepended
|
|
25
30
|
module PrependedMethods
|
|
26
31
|
def perform(*args)
|
|
27
|
-
|
|
32
|
+
unless started?
|
|
33
|
+
start_async do
|
|
34
|
+
self.result = super(*args)
|
|
35
|
+
end
|
|
36
|
+
end
|
|
28
37
|
end
|
|
29
38
|
end
|
|
30
39
|
|
|
@@ -159,7 +168,7 @@ module Datadog
|
|
|
159
168
|
rescue Exception => e
|
|
160
169
|
@error = e
|
|
161
170
|
Datadog.logger.debug(
|
|
162
|
-
"Worker thread error. Cause: #{e.class
|
|
171
|
+
"Worker thread error. Cause: #{e.class}: #{e.message} Location: #{Array(e.backtrace).first}"
|
|
163
172
|
)
|
|
164
173
|
raise
|
|
165
174
|
|
|
@@ -5,6 +5,11 @@ module Datadog
|
|
|
5
5
|
module Workers
|
|
6
6
|
# Adds looping behavior to workers, with a sleep
|
|
7
7
|
# interval between each loop.
|
|
8
|
+
#
|
|
9
|
+
# This module is included in Polling module, and has no other
|
|
10
|
+
# direct users.
|
|
11
|
+
#
|
|
12
|
+
# @api private
|
|
8
13
|
module IntervalLoop
|
|
9
14
|
BACK_OFF_RATIO = 1.2
|
|
10
15
|
BACK_OFF_MAX = 5
|
|
@@ -38,19 +43,50 @@ module Datadog
|
|
|
38
43
|
|
|
39
44
|
def stop_loop
|
|
40
45
|
mutex.synchronize do
|
|
41
|
-
|
|
42
|
-
|
|
46
|
+
# Do not call run_loop? from this method to see if the loop
|
|
47
|
+
# is running, because @run_loop is normally initialized by
|
|
48
|
+
# the background thread and if the stop is requested right
|
|
49
|
+
# after the worker starts, the background thread may be created
|
|
50
|
+
# (and scheduled) but hasn't run yet, thus skipping the
|
|
51
|
+
# write to @run_loop here would leave the thread running forever.
|
|
43
52
|
@run_loop = false
|
|
53
|
+
|
|
54
|
+
# It is possible that we don't need to signal shutdown if
|
|
55
|
+
# @run_loop was not initialized (i.e. we changed it from not
|
|
56
|
+
# defined to false above). But let's be safe and signal the
|
|
57
|
+
# shutdown anyway, I don't see what harm it can cause.
|
|
44
58
|
shutdown.signal
|
|
45
59
|
end
|
|
46
60
|
|
|
61
|
+
# Previously, this method would return false (and do nothing)
|
|
62
|
+
# if the worker was not running the loop. However, this was racy -
|
|
63
|
+
# see https://github.com/DataDog/ruby-guild/issues/279.
|
|
64
|
+
# stop_loop now always sets the state to "stop requested" and,
|
|
65
|
+
# correspondingly, always returns true.
|
|
66
|
+
#
|
|
67
|
+
# There is some test code that returns false when mocking this
|
|
68
|
+
# method - most likely this method should be treated as a void one
|
|
69
|
+
# and the caller should assume that the stop was always requested.
|
|
47
70
|
true
|
|
48
71
|
end
|
|
49
72
|
|
|
73
|
+
# TODO: This method carries two semantics today:
|
|
74
|
+
# 1. Is there work available to process?
|
|
75
|
+
# 2. Should the main loop keep running?
|
|
76
|
+
# Things get messy when `Queue` is mixed in,
|
|
77
|
+
# wanting to override semantic 1 but not 2.
|
|
78
|
+
# This should probably be split into two methods:
|
|
79
|
+
# `work_pending?` (semantic 1) and `continue_loop?` (semantic 2).
|
|
80
|
+
# Today, `run_loop?` performs semantic 2, but should probably be
|
|
81
|
+
# renamed to `continue_loop?`, since that would make it clear that
|
|
82
|
+
# we're just checking if we can "keep going inside the loop",
|
|
83
|
+
# and not checking if we should run the loop right now.
|
|
84
|
+
# Clean up {Workers::Queue} after this.
|
|
50
85
|
def work_pending?
|
|
51
86
|
run_loop?
|
|
52
87
|
end
|
|
53
88
|
|
|
89
|
+
# TODO: Probably should be renamed to `continue_loop?`, see `work_pending?` TODO.
|
|
54
90
|
def run_loop?
|
|
55
91
|
return false unless instance_variable_defined?(:@run_loop)
|
|
56
92
|
|
|
@@ -104,7 +140,19 @@ module Datadog
|
|
|
104
140
|
|
|
105
141
|
def perform_loop
|
|
106
142
|
mutex.synchronize do
|
|
107
|
-
@run_loop
|
|
143
|
+
unless defined?(@run_loop)
|
|
144
|
+
# This write must only happen if @run_loop is not defined
|
|
145
|
+
# (i.e., not initialized). In the case when the worker is
|
|
146
|
+
# asked to stop right after it is created, the thread may not
|
|
147
|
+
# have run yet by the time +stop_loop+ is invoked and
|
|
148
|
+
# we need to preserve the stop-requested state from
|
|
149
|
+
# +stop_loop+ to +perform_loop+.
|
|
150
|
+
#
|
|
151
|
+
# If the workers are refactored to use classes and inheritance
|
|
152
|
+
# and their state, such as @run_loop, is initialized in
|
|
153
|
+
# constructors, the write can be made unconditional.
|
|
154
|
+
@run_loop = true
|
|
155
|
+
end
|
|
108
156
|
|
|
109
157
|
shutdown.wait(mutex, loop_wait_time) if loop_wait_before_first_iteration?
|
|
110
158
|
end
|
|
@@ -5,6 +5,17 @@ module Datadog
|
|
|
5
5
|
module Workers
|
|
6
6
|
# Adds queue behavior to workers, with a buffer
|
|
7
7
|
# to which items can be queued then dequeued.
|
|
8
|
+
#
|
|
9
|
+
# This module is included in some but not all workers.
|
|
10
|
+
# Notably, Data Streams Processor uses a queue but implements it
|
|
11
|
+
# inline rather than using this module.
|
|
12
|
+
#
|
|
13
|
+
# The workers that do include Queue also include Polling, which
|
|
14
|
+
# in turn includes Async::Thread and IntervalLoop. This means
|
|
15
|
+
# we have e.g. +in_iteration?+ always available in any worker
|
|
16
|
+
# that includes Queue.
|
|
17
|
+
#
|
|
18
|
+
# @api private
|
|
8
19
|
module Queue
|
|
9
20
|
def self.included(base)
|
|
10
21
|
base.prepend(PrependedMethods)
|
|
@@ -13,11 +24,16 @@ module Datadog
|
|
|
13
24
|
# Methods that must be prepended
|
|
14
25
|
module PrependedMethods
|
|
15
26
|
def perform(*args)
|
|
16
|
-
|
|
27
|
+
if work_pending?
|
|
28
|
+
work = dequeue
|
|
29
|
+
super(*work)
|
|
30
|
+
end
|
|
17
31
|
end
|
|
18
32
|
end
|
|
19
33
|
|
|
20
34
|
def buffer
|
|
35
|
+
# Why is this an unsynchronized Array and not a Core::Buffer
|
|
36
|
+
# instance?
|
|
21
37
|
@buffer ||= []
|
|
22
38
|
end
|
|
23
39
|
|
|
@@ -34,10 +50,89 @@ module Datadog
|
|
|
34
50
|
!buffer.empty?
|
|
35
51
|
end
|
|
36
52
|
|
|
53
|
+
# Wait for the worker to finish handling all work that has already
|
|
54
|
+
# been submitted to it.
|
|
55
|
+
#
|
|
56
|
+
# If the worker is not enabled, returns nil.
|
|
57
|
+
# If the worker is enabled, returns whether, at the point of return,
|
|
58
|
+
# there was no pending or in progress work.
|
|
59
|
+
#
|
|
60
|
+
# Flushing can time out because there is a constant stream of work
|
|
61
|
+
# submitted at the same or higher rate than it is processed.
|
|
62
|
+
# Flushing can also fail if the worker thread is not running -
|
|
63
|
+
# this method will not flush from the calling thread.
|
|
64
|
+
def flush(timeout: nil)
|
|
65
|
+
# Default timeout is 5 seconds.
|
|
66
|
+
# Specific workers can override it to be more or less
|
|
67
|
+
timeout ||= 5
|
|
68
|
+
|
|
69
|
+
# Nothing needs to be done if the worker is not enabled.
|
|
70
|
+
return nil unless enabled?
|
|
71
|
+
|
|
72
|
+
unless running?
|
|
73
|
+
unless buffer.empty?
|
|
74
|
+
# If we are asked to flush but the worker is not running,
|
|
75
|
+
# do not flush from the caller thread. If the buffer is not
|
|
76
|
+
# empty, it will not be flushed. Log a warning to this effect.
|
|
77
|
+
#
|
|
78
|
+
# We are not guaranteed to have a logger as an instance method,
|
|
79
|
+
# reference the global for now - all other worker methods
|
|
80
|
+
# also reference the logger globally.
|
|
81
|
+
# TODO inject it into worker instances.
|
|
82
|
+
Datadog.logger.debug { "Asked to flush #{self} when the worker is not running" }
|
|
83
|
+
return false
|
|
84
|
+
end
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
started = Utils::Time.get_time
|
|
88
|
+
loop do
|
|
89
|
+
# The AppStarted event is triggered by the worker itself,
|
|
90
|
+
# from the worker thread. As such the main thread has no way
|
|
91
|
+
# to delay itself until that event is queued and we need some
|
|
92
|
+
# way to wait until that event is sent out to assert on it in
|
|
93
|
+
# the test suite. Check the run once flag which *should*
|
|
94
|
+
# indicate the event has been queued (at which point our queue
|
|
95
|
+
# depth check should wait until it's sent).
|
|
96
|
+
# This is still a hack because the flag can be overridden
|
|
97
|
+
# either way with or without the event being sent out.
|
|
98
|
+
# Note that if the AppStarted sending fails, this check
|
|
99
|
+
# will return false and flushing will be blocked until the
|
|
100
|
+
# 15 second timeout.
|
|
101
|
+
# Note that the first wait interval between telemetry event
|
|
102
|
+
# sending is 10 seconds, the timeout needs to be strictly
|
|
103
|
+
# greater than that.
|
|
104
|
+
return true if idle?
|
|
105
|
+
|
|
106
|
+
return false if Utils::Time.get_time - started > timeout
|
|
107
|
+
|
|
108
|
+
sleep 0.5
|
|
109
|
+
end
|
|
110
|
+
end
|
|
111
|
+
|
|
37
112
|
protected
|
|
38
113
|
|
|
39
114
|
attr_writer \
|
|
40
115
|
:buffer
|
|
116
|
+
|
|
117
|
+
# Returns whether this worker has no pending work and is not actively
|
|
118
|
+
# working.
|
|
119
|
+
#
|
|
120
|
+
# The reason why "actively working" is considered is that we use
|
|
121
|
+
# flushing to ensure all work is completed before asserting on the
|
|
122
|
+
# outcome in the tests - if work is happening in a background thread,
|
|
123
|
+
# it's too early to assert on its results.
|
|
124
|
+
def idle?
|
|
125
|
+
# We have a +work_pending?+ method in this class that semantically
|
|
126
|
+
# would be appropriate here instead of calling +buffer.empty?+.
|
|
127
|
+
# Unfortunately IntervalLoop replaces our implementation of
|
|
128
|
+
# +work_pending?+ with one that doesn't make sense at least for the
|
|
129
|
+
# Queue. And we can't change the order of module includes because
|
|
130
|
+
# they all override +perform+ and the correct behavior depends on
|
|
131
|
+
# placing IntervalLoop after Queue.
|
|
132
|
+
#
|
|
133
|
+
# Until this mess is untangled, call +buffer.empty?+ here.
|
|
134
|
+
buffer.empty? && !in_iteration?
|
|
135
|
+
end
|
|
41
136
|
end
|
|
42
137
|
end
|
|
43
138
|
end
|
|
@@ -21,7 +21,15 @@ module Datadog
|
|
|
21
21
|
:metrics
|
|
22
22
|
|
|
23
23
|
def initialize(telemetry:, **options)
|
|
24
|
-
@metrics = options.fetch(:metrics)
|
|
24
|
+
@metrics = options.fetch(:metrics) do
|
|
25
|
+
Core::Runtime::Metrics.new(
|
|
26
|
+
logger: options[:logger],
|
|
27
|
+
telemetry: telemetry,
|
|
28
|
+
experimental_propagate_process_tags_enabled: options.fetch(:propagate_process_tags_enabled) do
|
|
29
|
+
options.fetch(:experimental_propagate_process_tags_enabled)
|
|
30
|
+
end
|
|
31
|
+
)
|
|
32
|
+
end
|
|
25
33
|
|
|
26
34
|
# Workers::Async::Thread settings
|
|
27
35
|
self.fork_policy = options.fetch(:fork_policy, Workers::Async::Thread::FORK_POLICY_STOP)
|
data/lib/datadog/core.rb
CHANGED
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
+
# Keep this at the top, this is needed at require-time by some files
|
|
4
|
+
require_relative 'ruby_version'
|
|
5
|
+
|
|
3
6
|
require_relative 'core/deprecations'
|
|
4
7
|
require_relative 'core/configuration/config_helper'
|
|
5
8
|
require_relative 'core/extensions'
|
|
@@ -18,20 +21,24 @@ module Datadog
|
|
|
18
21
|
require "libdatadog_api.#{RUBY_VERSION[/\d+.\d+/]}_#{RUBY_PLATFORM}"
|
|
19
22
|
nil
|
|
20
23
|
rescue LoadError => e
|
|
21
|
-
e.message
|
|
24
|
+
"#{e.class}: #{e.message}"
|
|
22
25
|
end
|
|
23
26
|
end
|
|
24
27
|
|
|
25
|
-
DATADOG_ENV = Core::Configuration::ConfigHelper.new
|
|
26
28
|
extend Core::Extensions
|
|
27
29
|
|
|
28
30
|
# Add shutdown hook:
|
|
29
31
|
# Ensures the Datadog components have a chance to gracefully
|
|
30
32
|
# shut down and cleanup before terminating the process.
|
|
31
33
|
at_exit do
|
|
32
|
-
|
|
34
|
+
exception = $! # rubocop:disable Style/SpecialGlobalVars
|
|
35
|
+
|
|
36
|
+
if Interrupt === exception # is process terminating due to a ctrl+c or similar?
|
|
33
37
|
Datadog.send(:handle_interrupt_shutdown!)
|
|
34
38
|
else
|
|
39
|
+
# Report unhandled exception to crash tracker before shutdown
|
|
40
|
+
Datadog::Core::Crashtracking::Component.report_unhandled_exception(exception)
|
|
41
|
+
|
|
35
42
|
Datadog.shutdown!
|
|
36
43
|
end
|
|
37
44
|
end
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative '../core/environment/variable_helpers'
|
|
4
|
+
require_relative 'ext'
|
|
5
|
+
|
|
6
|
+
module Datadog
|
|
7
|
+
module DataStreams
|
|
8
|
+
# Configuration for Data Streams Monitoring
|
|
9
|
+
module Configuration
|
|
10
|
+
# Configuration settings for Data Streams Monitoring.
|
|
11
|
+
module Settings
|
|
12
|
+
def self.extended(base)
|
|
13
|
+
base = base.singleton_class unless base.is_a?(Class)
|
|
14
|
+
add_settings!(base)
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def self.add_settings!(base)
|
|
18
|
+
base.class_eval do
|
|
19
|
+
# Data Streams Monitoring configuration
|
|
20
|
+
# @public_api
|
|
21
|
+
settings :data_streams do
|
|
22
|
+
# Whether Data Streams Monitoring is enabled. When enabled, the library will
|
|
23
|
+
# collect and report data lineage information for messaging systems.
|
|
24
|
+
#
|
|
25
|
+
# @default `DD_DATA_STREAMS_ENABLED` environment variable, otherwise `false`.
|
|
26
|
+
# @return [Boolean]
|
|
27
|
+
option :enabled do |o|
|
|
28
|
+
o.type :bool
|
|
29
|
+
o.env Ext::ENV_ENABLED
|
|
30
|
+
o.default false
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
# The interval (in seconds) at which Data Streams Monitoring stats are flushed.
|
|
34
|
+
#
|
|
35
|
+
# @default 10.0
|
|
36
|
+
# @env '_DD_TRACE_STATS_WRITER_INTERVAL'
|
|
37
|
+
# @return [Float]
|
|
38
|
+
# @!visibility private
|
|
39
|
+
option :interval do |o|
|
|
40
|
+
o.type :float
|
|
41
|
+
o.env '_DD_TRACE_STATS_WRITER_INTERVAL'
|
|
42
|
+
o.default 10.0
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
end
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative 'configuration'
|
|
4
|
+
require_relative '../core/configuration'
|
|
5
|
+
|
|
6
|
+
module Datadog
|
|
7
|
+
module DataStreams
|
|
8
|
+
# Extends Datadog with Data Streams Monitoring features
|
|
9
|
+
module Extensions
|
|
10
|
+
# Inject Data Streams settings into global configuration.
|
|
11
|
+
def self.activate!
|
|
12
|
+
Core::Configuration::Settings.extend(Configuration::Settings)
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'stringio'
|
|
4
|
+
require_relative '../core/utils/base64_codec'
|
|
5
|
+
|
|
6
|
+
module Datadog
|
|
7
|
+
module DataStreams
|
|
8
|
+
# Represents a pathway context for data streams monitoring
|
|
9
|
+
class PathwayContext
|
|
10
|
+
# The current pathway hash value (result of FNV-1a hash function)
|
|
11
|
+
attr_accessor :hash
|
|
12
|
+
# When the pathway started
|
|
13
|
+
attr_accessor :pathway_start
|
|
14
|
+
# When the current edge started
|
|
15
|
+
attr_accessor :current_edge_start
|
|
16
|
+
# The hash value of the parent checkpoint
|
|
17
|
+
attr_accessor :parent_hash
|
|
18
|
+
# The direction tag of the previous checkpoint (e.g., 'direction:in', 'direction:out'), or nil if none
|
|
19
|
+
attr_accessor :previous_direction
|
|
20
|
+
# Hash value of the closest checkpoint in opposite direction (used for loop detection)
|
|
21
|
+
attr_accessor :closest_opposite_direction_hash
|
|
22
|
+
# Edge start time of the closest opposite direction checkpoint
|
|
23
|
+
attr_accessor :closest_opposite_direction_edge_start
|
|
24
|
+
|
|
25
|
+
def initialize(hash_value:, pathway_start:, current_edge_start:)
|
|
26
|
+
@hash = hash_value
|
|
27
|
+
@pathway_start = pathway_start
|
|
28
|
+
@current_edge_start = current_edge_start
|
|
29
|
+
@parent_hash = nil
|
|
30
|
+
|
|
31
|
+
@previous_direction = nil
|
|
32
|
+
@closest_opposite_direction_hash = 0
|
|
33
|
+
@closest_opposite_direction_edge_start = current_edge_start
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def encode_b64
|
|
37
|
+
Core::Utils::Base64Codec.strict_encode64(encode)
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
# Decode pathway context from base64 encoded string
|
|
41
|
+
def self.decode_b64(encoded_ctx)
|
|
42
|
+
return nil unless encoded_ctx && !encoded_ctx.empty?
|
|
43
|
+
|
|
44
|
+
begin
|
|
45
|
+
binary_data = Core::Utils::Base64Codec.strict_decode64(encoded_ctx)
|
|
46
|
+
decode(binary_data)
|
|
47
|
+
rescue ArgumentError => e
|
|
48
|
+
# Invalid base64 encoding - may indicate version mismatch or corruption
|
|
49
|
+
Datadog.logger.debug { "Failed to decode DSM pathway context: #{e.class}: #{e.message}" }
|
|
50
|
+
nil
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
private
|
|
55
|
+
|
|
56
|
+
def encode
|
|
57
|
+
# Format:
|
|
58
|
+
# - 8 bytes: hash value (little-endian)
|
|
59
|
+
# - VarInt: pathway start time (milliseconds)
|
|
60
|
+
# - VarInt: current edge start time (milliseconds)
|
|
61
|
+
[@hash].pack('Q') <<
|
|
62
|
+
encode_var_int_64(time_to_ms(@pathway_start)) <<
|
|
63
|
+
encode_var_int_64(time_to_ms(@current_edge_start))
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
# Decode pathway context from binary data
|
|
67
|
+
def self.decode(binary_data)
|
|
68
|
+
return nil unless binary_data && binary_data.bytesize >= 8
|
|
69
|
+
|
|
70
|
+
reader = StringIO.new(binary_data)
|
|
71
|
+
|
|
72
|
+
# Extract 8-byte hash (little-endian)
|
|
73
|
+
hash_bytes = reader.read(8)
|
|
74
|
+
return nil unless hash_bytes
|
|
75
|
+
|
|
76
|
+
hash_value = hash_bytes.unpack1('Q') # : Integer
|
|
77
|
+
|
|
78
|
+
# Extract pathway start time (VarInt milliseconds)
|
|
79
|
+
pathway_start_ms = decode_varint(reader)
|
|
80
|
+
return nil unless pathway_start_ms
|
|
81
|
+
|
|
82
|
+
# Extract current edge start time (VarInt milliseconds)
|
|
83
|
+
current_edge_start_ms = decode_varint(reader)
|
|
84
|
+
return nil unless current_edge_start_ms
|
|
85
|
+
|
|
86
|
+
# Convert milliseconds to Time objects
|
|
87
|
+
pathway_start = ms_to_time(pathway_start_ms)
|
|
88
|
+
current_edge_start = ms_to_time(current_edge_start_ms)
|
|
89
|
+
|
|
90
|
+
new(
|
|
91
|
+
hash_value: hash_value,
|
|
92
|
+
pathway_start: pathway_start,
|
|
93
|
+
current_edge_start: current_edge_start
|
|
94
|
+
)
|
|
95
|
+
rescue EOFError
|
|
96
|
+
# Not enough data in binary stream
|
|
97
|
+
nil
|
|
98
|
+
end
|
|
99
|
+
private_class_method :decode
|
|
100
|
+
|
|
101
|
+
# Encode an unsigned 64-bit integer using LEB128 variable-length encoding.
|
|
102
|
+
#
|
|
103
|
+
# This implements unsigned LEB128 (Little Endian Base 128) encoding as specified
|
|
104
|
+
# in DWARF5 standard section 7.6:
|
|
105
|
+
# https://dwarfstd.org/doc/DWARF5.pdf#page=301
|
|
106
|
+
#
|
|
107
|
+
# Each byte uses 7 bits for data and 1 bit to indicate continuation.
|
|
108
|
+
# The high bit is set if more bytes follow, clear for the final byte.
|
|
109
|
+
#
|
|
110
|
+
# @param value [Integer] Unsigned integer value to encode
|
|
111
|
+
# @return [String] Binary string of encoded bytes
|
|
112
|
+
def encode_var_int_64(value)
|
|
113
|
+
bytes = []
|
|
114
|
+
while value >= 0x80
|
|
115
|
+
bytes << ((value & 0x7F) | 0x80)
|
|
116
|
+
value >>= 7
|
|
117
|
+
end
|
|
118
|
+
bytes << value
|
|
119
|
+
bytes.pack('C*')
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
# Decode an unsigned LEB128 variable-length integer from IO stream.
|
|
123
|
+
#
|
|
124
|
+
# This implements unsigned LEB128 (Little Endian Base 128) decoding as specified
|
|
125
|
+
# in DWARF5 standard section 7.6:
|
|
126
|
+
# https://dwarfstd.org/doc/DWARF5.pdf#page=301
|
|
127
|
+
#
|
|
128
|
+
# VarInt format: Each byte uses 7 bits for data, 1 bit for continuation
|
|
129
|
+
# - High bit set = more bytes follow
|
|
130
|
+
# - High bit clear = final byte
|
|
131
|
+
# - Data bits accumulated in little-endian order
|
|
132
|
+
#
|
|
133
|
+
# @param io [StringIO] IO stream to read from
|
|
134
|
+
# @return [Integer, nil] Decoded unsigned integer, or nil if malformed
|
|
135
|
+
def self.decode_varint(io)
|
|
136
|
+
value = 0
|
|
137
|
+
shift = 0
|
|
138
|
+
|
|
139
|
+
loop do
|
|
140
|
+
byte = io.readbyte
|
|
141
|
+
|
|
142
|
+
# Add this byte's 7 data bits to our value
|
|
143
|
+
value |= (byte & 0x7F) << shift
|
|
144
|
+
|
|
145
|
+
# If high bit is clear, we're done
|
|
146
|
+
return value unless (byte & 0x80).nonzero?
|
|
147
|
+
|
|
148
|
+
shift += 7
|
|
149
|
+
|
|
150
|
+
# Safety: prevent infinite decoding
|
|
151
|
+
return nil if shift >= 64
|
|
152
|
+
end
|
|
153
|
+
rescue EOFError
|
|
154
|
+
# Stream ended unexpectedly - malformed data
|
|
155
|
+
nil
|
|
156
|
+
end
|
|
157
|
+
private_class_method :decode_varint
|
|
158
|
+
|
|
159
|
+
def self.ms_to_time(milliseconds)
|
|
160
|
+
::Time.at(milliseconds / 1000.0)
|
|
161
|
+
end
|
|
162
|
+
private_class_method :ms_to_time
|
|
163
|
+
|
|
164
|
+
def time_to_ms(time)
|
|
165
|
+
(time.to_f * 1000).to_i
|
|
166
|
+
end
|
|
167
|
+
end
|
|
168
|
+
end
|
|
169
|
+
end
|