datadog 2.7.1 → 2.17.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 +310 -1
- data/ext/datadog_profiling_native_extension/clock_id.h +2 -2
- data/ext/datadog_profiling_native_extension/collectors_cpu_and_wall_time_worker.c +66 -56
- data/ext/datadog_profiling_native_extension/collectors_discrete_dynamic_sampler.c +1 -1
- data/ext/datadog_profiling_native_extension/collectors_discrete_dynamic_sampler.h +1 -1
- data/ext/datadog_profiling_native_extension/collectors_idle_sampling_helper.c +16 -16
- data/ext/datadog_profiling_native_extension/collectors_stack.c +10 -10
- data/ext/datadog_profiling_native_extension/collectors_stack.h +2 -2
- data/ext/datadog_profiling_native_extension/collectors_thread_context.c +314 -145
- data/ext/datadog_profiling_native_extension/datadog_ruby_common.c +1 -4
- data/ext/datadog_profiling_native_extension/datadog_ruby_common.h +10 -0
- data/ext/datadog_profiling_native_extension/encoded_profile.c +79 -0
- data/ext/datadog_profiling_native_extension/encoded_profile.h +8 -0
- data/ext/datadog_profiling_native_extension/extconf.rb +7 -8
- data/ext/datadog_profiling_native_extension/gvl_profiling_helper.c +2 -0
- data/ext/datadog_profiling_native_extension/gvl_profiling_helper.h +0 -8
- data/ext/datadog_profiling_native_extension/heap_recorder.c +61 -174
- data/ext/datadog_profiling_native_extension/heap_recorder.h +2 -2
- data/ext/datadog_profiling_native_extension/http_transport.c +64 -98
- data/ext/datadog_profiling_native_extension/private_vm_api_access.c +68 -1
- data/ext/datadog_profiling_native_extension/private_vm_api_access.h +10 -1
- data/ext/datadog_profiling_native_extension/profiling.c +19 -8
- data/ext/datadog_profiling_native_extension/ruby_helpers.c +8 -8
- data/ext/datadog_profiling_native_extension/stack_recorder.c +84 -131
- data/ext/datadog_profiling_native_extension/stack_recorder.h +2 -2
- data/ext/datadog_profiling_native_extension/time_helpers.h +1 -1
- data/ext/datadog_profiling_native_extension/unsafe_api_calls_check.c +47 -0
- data/ext/datadog_profiling_native_extension/unsafe_api_calls_check.h +31 -0
- data/ext/libdatadog_api/crashtracker.c +17 -15
- data/ext/libdatadog_api/crashtracker.h +5 -0
- data/ext/libdatadog_api/datadog_ruby_common.c +1 -4
- data/ext/libdatadog_api/datadog_ruby_common.h +10 -0
- data/ext/libdatadog_api/init.c +15 -0
- data/ext/libdatadog_api/library_config.c +122 -0
- data/ext/libdatadog_api/library_config.h +19 -0
- data/ext/libdatadog_api/macos_development.md +3 -3
- data/ext/libdatadog_api/process_discovery.c +117 -0
- data/ext/libdatadog_api/process_discovery.h +5 -0
- data/ext/libdatadog_extconf_helpers.rb +1 -1
- data/lib/datadog/appsec/actions_handler/serializable_backtrace.rb +89 -0
- data/lib/datadog/appsec/actions_handler.rb +49 -0
- data/lib/datadog/appsec/anonymizer.rb +16 -0
- data/lib/datadog/appsec/api_security/lru_cache.rb +49 -0
- data/lib/datadog/appsec/api_security.rb +9 -0
- data/lib/datadog/appsec/assets/waf_rules/README.md +50 -5
- data/lib/datadog/appsec/assets/waf_rules/processors.json +239 -10
- data/lib/datadog/appsec/assets/waf_rules/recommended.json +355 -157
- data/lib/datadog/appsec/assets/waf_rules/scanners.json +926 -17
- data/lib/datadog/appsec/assets/waf_rules/strict.json +62 -32
- data/lib/datadog/appsec/autoload.rb +1 -1
- data/lib/datadog/appsec/component.rb +41 -33
- data/lib/datadog/appsec/compressed_json.rb +40 -0
- data/lib/datadog/appsec/configuration/settings.rb +152 -25
- data/lib/datadog/appsec/context.rb +74 -0
- data/lib/datadog/appsec/contrib/active_record/instrumentation.rb +92 -0
- data/lib/datadog/appsec/contrib/active_record/integration.rb +41 -0
- data/lib/datadog/appsec/contrib/active_record/patcher.rb +101 -0
- data/lib/datadog/appsec/contrib/auto_instrument.rb +1 -1
- data/lib/datadog/appsec/contrib/devise/configuration.rb +52 -0
- data/lib/datadog/appsec/contrib/devise/data_extractor.rb +78 -0
- data/lib/datadog/appsec/contrib/devise/ext.rb +22 -0
- data/lib/datadog/appsec/contrib/devise/integration.rb +1 -2
- data/lib/datadog/appsec/contrib/devise/patcher.rb +33 -25
- data/lib/datadog/appsec/contrib/devise/patches/signin_tracking_patch.rb +102 -0
- data/lib/datadog/appsec/contrib/devise/patches/signup_tracking_patch.rb +69 -0
- data/lib/datadog/appsec/contrib/devise/{patcher/rememberable_patch.rb → patches/skip_signin_tracking_patch.rb} +3 -3
- data/lib/datadog/appsec/contrib/devise/tracking_middleware.rb +106 -0
- data/lib/datadog/appsec/contrib/excon/integration.rb +41 -0
- data/lib/datadog/appsec/contrib/excon/patcher.rb +28 -0
- data/lib/datadog/appsec/contrib/excon/ssrf_detection_middleware.rb +42 -0
- data/lib/datadog/appsec/contrib/faraday/connection_patch.rb +22 -0
- data/lib/datadog/appsec/contrib/faraday/integration.rb +42 -0
- data/lib/datadog/appsec/contrib/faraday/patcher.rb +53 -0
- data/lib/datadog/appsec/contrib/faraday/rack_builder_patch.rb +22 -0
- data/lib/datadog/appsec/contrib/faraday/ssrf_detection_middleware.rb +41 -0
- data/lib/datadog/appsec/contrib/graphql/appsec_trace.rb +1 -7
- data/lib/datadog/appsec/contrib/graphql/gateway/watcher.rb +17 -30
- data/lib/datadog/appsec/contrib/graphql/integration.rb +1 -1
- data/lib/datadog/appsec/contrib/graphql/patcher.rb +0 -3
- data/lib/datadog/appsec/contrib/rack/ext.rb +34 -0
- data/lib/datadog/appsec/contrib/rack/gateway/response.rb +3 -3
- data/lib/datadog/appsec/contrib/rack/gateway/watcher.rb +78 -98
- data/lib/datadog/appsec/contrib/rack/integration.rb +1 -1
- data/lib/datadog/appsec/contrib/rack/patcher.rb +0 -3
- data/lib/datadog/appsec/contrib/rack/request_body_middleware.rb +10 -11
- data/lib/datadog/appsec/contrib/rack/request_middleware.rb +52 -68
- data/lib/datadog/appsec/contrib/rails/gateway/watcher.rb +16 -33
- data/lib/datadog/appsec/contrib/rails/integration.rb +1 -1
- data/lib/datadog/appsec/contrib/rails/patcher.rb +25 -38
- data/lib/datadog/appsec/contrib/rest_client/integration.rb +45 -0
- data/lib/datadog/appsec/contrib/rest_client/patcher.rb +28 -0
- data/lib/datadog/appsec/contrib/rest_client/request_ssrf_detection_patch.rb +38 -0
- data/lib/datadog/appsec/contrib/sinatra/gateway/watcher.rb +31 -68
- data/lib/datadog/appsec/contrib/sinatra/integration.rb +1 -1
- data/lib/datadog/appsec/contrib/sinatra/patcher.rb +5 -31
- data/lib/datadog/appsec/event.rb +96 -135
- data/lib/datadog/appsec/ext.rb +12 -3
- data/lib/datadog/appsec/instrumentation/gateway/argument.rb +7 -2
- data/lib/datadog/appsec/instrumentation/gateway/middleware.rb +24 -0
- data/lib/datadog/appsec/instrumentation/gateway.rb +17 -22
- data/lib/datadog/appsec/metrics/collector.rb +38 -0
- data/lib/datadog/appsec/metrics/exporter.rb +35 -0
- data/lib/datadog/appsec/metrics/telemetry.rb +23 -0
- data/lib/datadog/appsec/metrics.rb +13 -0
- data/lib/datadog/appsec/monitor/gateway/watcher.rb +52 -32
- data/lib/datadog/appsec/processor/rule_loader.rb +26 -31
- data/lib/datadog/appsec/processor/rule_merger.rb +7 -6
- data/lib/datadog/appsec/processor.rb +5 -4
- data/lib/datadog/appsec/remote.rb +26 -12
- data/lib/datadog/appsec/response.rb +19 -85
- data/lib/datadog/appsec/security_engine/result.rb +67 -0
- data/lib/datadog/appsec/security_engine/runner.rb +88 -0
- data/lib/datadog/appsec/security_engine.rb +9 -0
- data/lib/datadog/appsec/security_event.rb +39 -0
- data/lib/datadog/appsec/utils.rb +0 -2
- data/lib/datadog/appsec.rb +23 -10
- data/lib/datadog/auto_instrument.rb +3 -0
- data/lib/datadog/core/buffer/random.rb +18 -2
- data/lib/datadog/core/configuration/agent_settings_resolver.rb +42 -14
- data/lib/datadog/core/configuration/agentless_settings_resolver.rb +176 -0
- data/lib/datadog/core/configuration/components.rb +76 -32
- data/lib/datadog/core/configuration/components_state.rb +23 -0
- data/lib/datadog/core/configuration/ext.rb +5 -1
- data/lib/datadog/core/configuration/option.rb +79 -43
- data/lib/datadog/core/configuration/option_definition.rb +6 -4
- data/lib/datadog/core/configuration/options.rb +3 -3
- data/lib/datadog/core/configuration/settings.rb +100 -41
- data/lib/datadog/core/configuration/stable_config.rb +23 -0
- data/lib/datadog/core/configuration.rb +43 -11
- data/lib/datadog/{tracing → core}/contrib/rails/utils.rb +1 -3
- data/lib/datadog/core/crashtracking/component.rb +4 -13
- data/lib/datadog/core/diagnostics/environment_logger.rb +1 -1
- data/lib/datadog/core/encoding.rb +17 -1
- data/lib/datadog/core/environment/agent_info.rb +78 -0
- data/lib/datadog/core/environment/cgroup.rb +10 -12
- data/lib/datadog/core/environment/container.rb +38 -40
- data/lib/datadog/core/environment/ext.rb +6 -6
- data/lib/datadog/core/environment/git.rb +1 -0
- data/lib/datadog/core/environment/identity.rb +3 -3
- data/lib/datadog/core/environment/platform.rb +3 -3
- data/lib/datadog/core/environment/variable_helpers.rb +1 -1
- data/lib/datadog/core/error.rb +11 -9
- data/lib/datadog/core/logger.rb +2 -2
- data/lib/datadog/core/metrics/client.rb +27 -27
- data/lib/datadog/core/metrics/logging.rb +5 -5
- data/lib/datadog/core/process_discovery.rb +32 -0
- data/lib/datadog/core/rate_limiter.rb +4 -2
- data/lib/datadog/core/remote/client/capabilities.rb +6 -0
- data/lib/datadog/core/remote/client.rb +107 -92
- data/lib/datadog/core/remote/component.rb +18 -19
- data/lib/datadog/core/remote/configuration/digest.rb +7 -7
- data/lib/datadog/core/remote/configuration/path.rb +1 -1
- data/lib/datadog/core/remote/configuration/repository.rb +2 -1
- data/lib/datadog/core/remote/negotiation.rb +9 -9
- data/lib/datadog/core/remote/transport/config.rb +4 -3
- data/lib/datadog/core/remote/transport/http/api.rb +13 -18
- data/lib/datadog/core/remote/transport/http/client.rb +5 -4
- data/lib/datadog/core/remote/transport/http/config.rb +27 -55
- data/lib/datadog/core/remote/transport/http/negotiation.rb +8 -51
- data/lib/datadog/core/remote/transport/http.rb +25 -94
- data/lib/datadog/core/remote/transport/negotiation.rb +17 -4
- data/lib/datadog/core/remote/worker.rb +10 -7
- data/lib/datadog/core/runtime/metrics.rb +12 -5
- data/lib/datadog/core/telemetry/component.rb +84 -49
- data/lib/datadog/core/telemetry/emitter.rb +23 -11
- data/lib/datadog/core/telemetry/event/app_client_configuration_change.rb +65 -0
- data/lib/datadog/core/telemetry/event/app_closing.rb +18 -0
- data/lib/datadog/core/telemetry/event/app_dependencies_loaded.rb +33 -0
- data/lib/datadog/core/telemetry/event/app_heartbeat.rb +18 -0
- data/lib/datadog/core/telemetry/event/app_integrations_change.rb +58 -0
- data/lib/datadog/core/telemetry/event/app_started.rb +179 -0
- data/lib/datadog/core/telemetry/event/base.rb +40 -0
- data/lib/datadog/core/telemetry/event/distributions.rb +18 -0
- data/lib/datadog/core/telemetry/event/generate_metrics.rb +43 -0
- data/lib/datadog/core/telemetry/event/log.rb +76 -0
- data/lib/datadog/core/telemetry/event/message_batch.rb +42 -0
- data/lib/datadog/core/telemetry/event/synth_app_client_configuration_change.rb +43 -0
- data/lib/datadog/core/telemetry/event.rb +17 -383
- data/lib/datadog/core/telemetry/ext.rb +1 -0
- data/lib/datadog/core/telemetry/http/adapters/net.rb +12 -97
- data/lib/datadog/core/telemetry/logger.rb +1 -1
- data/lib/datadog/core/telemetry/logging.rb +2 -2
- data/lib/datadog/core/telemetry/metric.rb +28 -6
- data/lib/datadog/core/telemetry/request.rb +4 -4
- data/lib/datadog/core/telemetry/transport/http/api.rb +43 -0
- data/lib/datadog/core/telemetry/transport/http/client.rb +49 -0
- data/lib/datadog/core/telemetry/transport/http/telemetry.rb +92 -0
- data/lib/datadog/core/telemetry/transport/http.rb +63 -0
- data/lib/datadog/core/telemetry/transport/telemetry.rb +51 -0
- data/lib/datadog/core/telemetry/worker.rb +128 -25
- data/lib/datadog/core/transport/http/adapters/test.rb +2 -1
- data/lib/datadog/core/transport/http/adapters/unix_socket.rb +1 -1
- data/lib/datadog/{tracing → core}/transport/http/api/instance.rb +18 -1
- data/lib/datadog/core/transport/http/api/spec.rb +36 -0
- data/lib/datadog/{tracing → core}/transport/http/builder.rb +53 -31
- data/lib/datadog/core/transport/http.rb +75 -0
- data/lib/datadog/core/transport/response.rb +4 -0
- data/lib/datadog/core/utils/at_fork_monkey_patch.rb +6 -6
- data/lib/datadog/core/utils/duration.rb +32 -32
- data/lib/datadog/core/utils/forking.rb +2 -2
- data/lib/datadog/core/utils/network.rb +6 -6
- data/lib/datadog/core/utils/only_once_successful.rb +16 -5
- data/lib/datadog/core/utils/time.rb +20 -0
- data/lib/datadog/core/utils/truncation.rb +21 -0
- data/lib/datadog/core/vendor/multipart-post/multipart/post/composite_read_io.rb +1 -1
- data/lib/datadog/core/vendor/multipart-post/multipart/post/multipartable.rb +8 -8
- data/lib/datadog/core/vendor/multipart-post/multipart/post/parts.rb +7 -7
- data/lib/datadog/core/worker.rb +1 -1
- data/lib/datadog/core/workers/async.rb +29 -12
- data/lib/datadog/core/workers/interval_loop.rb +12 -1
- data/lib/datadog/core/workers/runtime_metrics.rb +2 -2
- data/lib/datadog/core.rb +8 -0
- data/lib/datadog/di/base.rb +115 -0
- data/lib/datadog/di/boot.rb +34 -0
- data/lib/datadog/di/code_tracker.rb +26 -15
- data/lib/datadog/di/component.rb +23 -14
- data/lib/datadog/di/configuration/settings.rb +25 -1
- data/lib/datadog/di/contrib/active_record.rb +1 -0
- data/lib/datadog/di/contrib/railtie.rb +15 -0
- data/lib/datadog/di/contrib.rb +28 -0
- data/lib/datadog/di/error.rb +5 -0
- data/lib/datadog/di/instrumenter.rb +111 -20
- data/lib/datadog/di/logger.rb +30 -0
- data/lib/datadog/di/preload.rb +18 -0
- data/lib/datadog/di/probe.rb +14 -7
- data/lib/datadog/di/probe_builder.rb +1 -0
- data/lib/datadog/di/probe_manager.rb +11 -5
- data/lib/datadog/di/probe_notification_builder.rb +34 -8
- data/lib/datadog/di/probe_notifier_worker.rb +52 -26
- data/lib/datadog/di/redactor.rb +0 -1
- data/lib/datadog/di/remote.rb +147 -0
- data/lib/datadog/di/serializer.rb +14 -7
- data/lib/datadog/di/transport/diagnostics.rb +62 -0
- data/lib/datadog/di/transport/http/api.rb +42 -0
- data/lib/datadog/di/transport/http/client.rb +47 -0
- data/lib/datadog/di/transport/http/diagnostics.rb +65 -0
- data/lib/datadog/di/transport/http/input.rb +67 -0
- data/lib/datadog/di/transport/http.rb +57 -0
- data/lib/datadog/di/transport/input.rb +62 -0
- data/lib/datadog/di/utils.rb +103 -0
- data/lib/datadog/di.rb +14 -76
- data/lib/datadog/error_tracking/collector.rb +87 -0
- data/lib/datadog/error_tracking/component.rb +167 -0
- data/lib/datadog/error_tracking/configuration/settings.rb +63 -0
- data/lib/datadog/error_tracking/configuration.rb +11 -0
- data/lib/datadog/error_tracking/ext.rb +18 -0
- data/lib/datadog/error_tracking/extensions.rb +16 -0
- data/lib/datadog/error_tracking/filters.rb +77 -0
- data/lib/datadog/error_tracking.rb +18 -0
- data/lib/datadog/kit/appsec/events.rb +15 -3
- data/lib/datadog/kit/identity.rb +9 -5
- data/lib/datadog/opentelemetry/api/baggage.rb +90 -0
- data/lib/datadog/opentelemetry/api/baggage.rbs +26 -0
- data/lib/datadog/opentelemetry/api/context.rb +16 -2
- data/lib/datadog/opentelemetry/sdk/trace/span.rb +1 -1
- data/lib/datadog/opentelemetry.rb +2 -1
- data/lib/datadog/profiling/collectors/code_provenance.rb +1 -1
- data/lib/datadog/profiling/collectors/info.rb +3 -0
- data/lib/datadog/profiling/collectors/thread_context.rb +1 -1
- data/lib/datadog/profiling/component.rb +60 -76
- data/lib/datadog/profiling/encoded_profile.rb +11 -0
- data/lib/datadog/profiling/exporter.rb +3 -4
- data/lib/datadog/profiling/ext.rb +0 -2
- data/lib/datadog/profiling/flush.rb +5 -8
- data/lib/datadog/profiling/http_transport.rb +6 -85
- data/lib/datadog/profiling/load_native_extension.rb +1 -33
- data/lib/datadog/profiling/scheduler.rb +8 -1
- data/lib/datadog/profiling/stack_recorder.rb +4 -4
- data/lib/datadog/profiling/tag_builder.rb +1 -5
- data/lib/datadog/profiling.rb +6 -2
- data/lib/datadog/tracing/analytics.rb +1 -1
- data/lib/datadog/tracing/component.rb +16 -12
- data/lib/datadog/tracing/configuration/ext.rb +8 -1
- data/lib/datadog/tracing/configuration/settings.rb +22 -10
- data/lib/datadog/tracing/context_provider.rb +1 -1
- data/lib/datadog/tracing/contrib/action_cable/integration.rb +5 -2
- data/lib/datadog/tracing/contrib/action_mailer/integration.rb +6 -2
- data/lib/datadog/tracing/contrib/action_pack/integration.rb +5 -2
- data/lib/datadog/tracing/contrib/action_view/integration.rb +5 -2
- data/lib/datadog/tracing/contrib/active_job/integration.rb +5 -2
- data/lib/datadog/tracing/contrib/active_record/integration.rb +7 -3
- data/lib/datadog/tracing/contrib/active_support/cache/events/cache.rb +7 -2
- data/lib/datadog/tracing/contrib/active_support/cache/instrumentation.rb +36 -1
- data/lib/datadog/tracing/contrib/active_support/cache/patcher.rb +4 -0
- data/lib/datadog/tracing/contrib/active_support/cache/redis.rb +14 -4
- data/lib/datadog/tracing/contrib/active_support/configuration/settings.rb +10 -0
- data/lib/datadog/tracing/contrib/active_support/integration.rb +5 -2
- data/lib/datadog/tracing/contrib/auto_instrument.rb +2 -2
- data/lib/datadog/tracing/contrib/aws/instrumentation.rb +10 -0
- data/lib/datadog/tracing/contrib/aws/integration.rb +3 -0
- data/lib/datadog/tracing/contrib/aws/parsed_context.rb +5 -1
- data/lib/datadog/tracing/contrib/concurrent_ruby/integration.rb +3 -0
- data/lib/datadog/tracing/contrib/configuration/settings.rb +1 -1
- data/lib/datadog/tracing/contrib/elasticsearch/configuration/settings.rb +4 -0
- data/lib/datadog/tracing/contrib/elasticsearch/patcher.rb +6 -1
- data/lib/datadog/tracing/contrib/ethon/easy_patch.rb +4 -5
- data/lib/datadog/tracing/contrib/excon/middleware.rb +5 -3
- data/lib/datadog/tracing/contrib/ext.rb +1 -0
- data/lib/datadog/tracing/contrib/extensions.rb +29 -3
- data/lib/datadog/tracing/contrib/faraday/middleware.rb +5 -3
- data/lib/datadog/tracing/contrib/graphql/configuration/error_extension_env_parser.rb +21 -0
- data/lib/datadog/tracing/contrib/graphql/configuration/settings.rb +11 -0
- data/lib/datadog/tracing/contrib/graphql/ext.rb +5 -0
- data/lib/datadog/tracing/contrib/graphql/unified_trace.rb +102 -11
- data/lib/datadog/tracing/contrib/grpc/datadog_interceptor/client.rb +7 -1
- data/lib/datadog/tracing/contrib/grpc/distributed/propagation.rb +3 -0
- data/lib/datadog/tracing/contrib/http/circuit_breaker.rb +0 -15
- data/lib/datadog/tracing/contrib/http/distributed/propagation.rb +4 -1
- data/lib/datadog/tracing/contrib/http/instrumentation.rb +6 -10
- data/lib/datadog/tracing/contrib/http/integration.rb +3 -0
- data/lib/datadog/tracing/contrib/httpclient/instrumentation.rb +6 -16
- data/lib/datadog/tracing/contrib/httprb/instrumentation.rb +7 -15
- data/lib/datadog/tracing/contrib/httprb/integration.rb +3 -0
- data/lib/datadog/tracing/contrib/kafka/integration.rb +3 -0
- data/lib/datadog/tracing/contrib/karafka/configuration/settings.rb +27 -0
- data/lib/datadog/tracing/contrib/karafka/distributed/propagation.rb +48 -0
- data/lib/datadog/tracing/contrib/karafka/ext.rb +27 -0
- data/lib/datadog/tracing/contrib/karafka/integration.rb +45 -0
- data/lib/datadog/tracing/contrib/karafka/monitor.rb +66 -0
- data/lib/datadog/tracing/contrib/karafka/patcher.rb +71 -0
- data/lib/datadog/tracing/contrib/karafka.rb +37 -0
- data/lib/datadog/tracing/contrib/mongodb/configuration/settings.rb +8 -0
- data/lib/datadog/tracing/contrib/mongodb/ext.rb +1 -0
- data/lib/datadog/tracing/contrib/mongodb/integration.rb +3 -0
- data/lib/datadog/tracing/contrib/mongodb/subscribers.rb +18 -1
- data/lib/datadog/tracing/contrib/opensearch/configuration/settings.rb +17 -0
- data/lib/datadog/tracing/contrib/opensearch/ext.rb +9 -0
- data/lib/datadog/tracing/contrib/opensearch/integration.rb +3 -0
- data/lib/datadog/tracing/contrib/opensearch/patcher.rb +5 -1
- data/lib/datadog/tracing/contrib/patcher.rb +5 -2
- data/lib/datadog/tracing/contrib/presto/integration.rb +3 -0
- data/lib/datadog/tracing/contrib/rack/header_collection.rb +11 -1
- data/lib/datadog/tracing/contrib/rack/integration.rb +2 -2
- data/lib/datadog/tracing/contrib/rack/middlewares.rb +1 -1
- data/lib/datadog/tracing/contrib/rack/request_queue.rb +1 -1
- data/lib/datadog/tracing/contrib/rails/framework.rb +2 -2
- data/lib/datadog/tracing/contrib/rails/patcher.rb +1 -1
- data/lib/datadog/tracing/contrib/rest_client/integration.rb +3 -0
- data/lib/datadog/tracing/contrib/rest_client/request_patch.rb +5 -3
- data/lib/datadog/tracing/contrib/sidekiq/client_tracer.rb +6 -1
- data/lib/datadog/tracing/contrib/sidekiq/distributed/propagation.rb +3 -0
- data/lib/datadog/tracing/contrib/sidekiq/server_tracer.rb +1 -1
- data/lib/datadog/tracing/contrib/span_attribute_schema.rb +6 -1
- data/lib/datadog/tracing/contrib/support.rb +28 -0
- data/lib/datadog/tracing/contrib.rb +1 -0
- data/lib/datadog/tracing/correlation.rb +9 -2
- data/lib/datadog/tracing/distributed/b3_multi.rb +1 -1
- data/lib/datadog/tracing/distributed/b3_single.rb +1 -1
- data/lib/datadog/tracing/distributed/baggage.rb +131 -0
- data/lib/datadog/tracing/distributed/datadog.rb +4 -2
- data/lib/datadog/tracing/distributed/propagation.rb +25 -4
- data/lib/datadog/tracing/distributed/propagation_policy.rb +42 -0
- data/lib/datadog/tracing/metadata/errors.rb +4 -4
- data/lib/datadog/tracing/metadata/ext.rb +5 -0
- data/lib/datadog/tracing/metadata/metastruct.rb +36 -0
- data/lib/datadog/tracing/metadata/metastruct_tagging.rb +42 -0
- data/lib/datadog/tracing/metadata.rb +2 -0
- data/lib/datadog/tracing/sampling/rate_sampler.rb +2 -1
- data/lib/datadog/tracing/sampling/span/rule.rb +0 -1
- data/lib/datadog/tracing/span.rb +22 -5
- data/lib/datadog/tracing/span_event.rb +124 -4
- data/lib/datadog/tracing/span_operation.rb +52 -16
- data/lib/datadog/tracing/sync_writer.rb +9 -5
- data/lib/datadog/tracing/trace_digest.rb +9 -2
- data/lib/datadog/tracing/trace_operation.rb +44 -24
- data/lib/datadog/tracing/trace_segment.rb +6 -4
- data/lib/datadog/tracing/tracer.rb +60 -12
- data/lib/datadog/tracing/transport/http/api.rb +5 -4
- data/lib/datadog/tracing/transport/http/client.rb +5 -4
- data/lib/datadog/tracing/transport/http/traces.rb +13 -44
- data/lib/datadog/tracing/transport/http.rb +13 -70
- data/lib/datadog/tracing/transport/serializable_trace.rb +31 -7
- data/lib/datadog/tracing/transport/trace_formatter.rb +7 -0
- data/lib/datadog/tracing/transport/traces.rb +47 -13
- data/lib/datadog/tracing/utils.rb +1 -1
- data/lib/datadog/tracing/workers/trace_writer.rb +8 -5
- data/lib/datadog/tracing/workers.rb +5 -4
- data/lib/datadog/tracing/writer.rb +10 -6
- data/lib/datadog/tracing.rb +16 -3
- data/lib/datadog/version.rb +2 -2
- data/lib/datadog.rb +2 -0
- metadata +143 -50
- data/ext/datadog_profiling_loader/datadog_profiling_loader.c +0 -142
- data/ext/datadog_profiling_loader/extconf.rb +0 -60
- data/lib/datadog/appsec/contrib/devise/event.rb +0 -57
- data/lib/datadog/appsec/contrib/devise/patcher/authenticatable_patch.rb +0 -77
- data/lib/datadog/appsec/contrib/devise/patcher/registration_controller_patch.rb +0 -54
- data/lib/datadog/appsec/contrib/devise/resource.rb +0 -35
- data/lib/datadog/appsec/contrib/devise/tracking.rb +0 -57
- data/lib/datadog/appsec/contrib/graphql/reactive/multiplex.rb +0 -46
- data/lib/datadog/appsec/contrib/patcher.rb +0 -12
- data/lib/datadog/appsec/contrib/rack/reactive/request.rb +0 -69
- data/lib/datadog/appsec/contrib/rack/reactive/request_body.rb +0 -47
- data/lib/datadog/appsec/contrib/rack/reactive/response.rb +0 -53
- data/lib/datadog/appsec/contrib/rails/reactive/action.rb +0 -53
- data/lib/datadog/appsec/contrib/sinatra/ext.rb +0 -14
- data/lib/datadog/appsec/contrib/sinatra/reactive/routed.rb +0 -48
- data/lib/datadog/appsec/monitor/reactive/set_user.rb +0 -45
- data/lib/datadog/appsec/processor/actions.rb +0 -49
- data/lib/datadog/appsec/processor/context.rb +0 -107
- data/lib/datadog/appsec/reactive/address_hash.rb +0 -22
- data/lib/datadog/appsec/reactive/engine.rb +0 -47
- data/lib/datadog/appsec/reactive/operation.rb +0 -68
- data/lib/datadog/appsec/reactive/subscriber.rb +0 -19
- data/lib/datadog/appsec/scope.rb +0 -58
- data/lib/datadog/appsec/utils/trace_operation.rb +0 -15
- data/lib/datadog/core/crashtracking/agent_base_url.rb +0 -21
- data/lib/datadog/core/remote/transport/http/api/instance.rb +0 -39
- data/lib/datadog/core/remote/transport/http/api/spec.rb +0 -21
- data/lib/datadog/core/remote/transport/http/builder.rb +0 -219
- data/lib/datadog/core/telemetry/http/env.rb +0 -20
- data/lib/datadog/core/telemetry/http/ext.rb +0 -28
- data/lib/datadog/core/telemetry/http/response.rb +0 -70
- data/lib/datadog/core/telemetry/http/transport.rb +0 -90
- data/lib/datadog/di/transport.rb +0 -81
- data/lib/datadog/tracing/transport/http/api/spec.rb +0 -19
@@ -4,6 +4,7 @@
|
|
4
4
|
#include "helpers.h"
|
5
5
|
#include "libdatadog_helpers.h"
|
6
6
|
#include "ruby_helpers.h"
|
7
|
+
#include "encoded_profile.h"
|
7
8
|
|
8
9
|
// Used to report profiling data to Datadog.
|
9
10
|
// This file implements the native bits of the Datadog::Profiling::HttpTransport class
|
@@ -13,33 +14,23 @@ static VALUE error_symbol = Qnil; // :error in Ruby
|
|
13
14
|
|
14
15
|
static VALUE library_version_string = Qnil;
|
15
16
|
|
16
|
-
struct
|
17
|
-
|
18
|
-
|
17
|
+
typedef struct {
|
18
|
+
ddog_prof_ProfileExporter *exporter;
|
19
|
+
ddog_prof_Request_Result *build_result;
|
19
20
|
ddog_CancellationToken *cancel_token;
|
20
|
-
|
21
|
+
ddog_prof_Result_HttpStatus result;
|
21
22
|
bool send_ran;
|
22
|
-
};
|
23
|
+
} call_exporter_without_gvl_arguments;
|
23
24
|
|
24
25
|
static inline ddog_ByteSlice byte_slice_from_ruby_string(VALUE string);
|
25
26
|
static VALUE _native_validate_exporter(VALUE self, VALUE exporter_configuration);
|
26
|
-
static
|
27
|
-
static VALUE handle_exporter_failure(
|
27
|
+
static ddog_prof_ProfileExporter_Result create_exporter(VALUE exporter_configuration, VALUE tags_as_array);
|
28
|
+
static VALUE handle_exporter_failure(ddog_prof_ProfileExporter_Result exporter_result);
|
28
29
|
static VALUE _native_do_export(
|
29
30
|
VALUE self,
|
30
31
|
VALUE exporter_configuration,
|
31
32
|
VALUE upload_timeout_milliseconds,
|
32
|
-
VALUE
|
33
|
-
VALUE start_timespec_nanoseconds,
|
34
|
-
VALUE finish_timespec_seconds,
|
35
|
-
VALUE finish_timespec_nanoseconds,
|
36
|
-
VALUE pprof_file_name,
|
37
|
-
VALUE pprof_data,
|
38
|
-
VALUE code_provenance_file_name,
|
39
|
-
VALUE code_provenance_data,
|
40
|
-
VALUE tags_as_array,
|
41
|
-
VALUE internal_metadata_json,
|
42
|
-
VALUE info_json
|
33
|
+
VALUE flush
|
43
34
|
);
|
44
35
|
static void *call_exporter_without_gvl(void *call_args);
|
45
36
|
static void interrupt_exporter_call(void *cancel_token);
|
@@ -48,7 +39,7 @@ void http_transport_init(VALUE profiling_module) {
|
|
48
39
|
VALUE http_transport_class = rb_define_class_under(profiling_module, "HttpTransport", rb_cObject);
|
49
40
|
|
50
41
|
rb_define_singleton_method(http_transport_class, "_native_validate_exporter", _native_validate_exporter, 1);
|
51
|
-
rb_define_singleton_method(http_transport_class, "_native_do_export", _native_do_export,
|
42
|
+
rb_define_singleton_method(http_transport_class, "_native_do_export", _native_do_export, 3);
|
52
43
|
|
53
44
|
ok_symbol = ID2SYM(rb_intern_const("ok"));
|
54
45
|
error_symbol = ID2SYM(rb_intern_const("error"));
|
@@ -65,14 +56,14 @@ static inline ddog_ByteSlice byte_slice_from_ruby_string(VALUE string) {
|
|
65
56
|
|
66
57
|
static VALUE _native_validate_exporter(DDTRACE_UNUSED VALUE _self, VALUE exporter_configuration) {
|
67
58
|
ENFORCE_TYPE(exporter_configuration, T_ARRAY);
|
68
|
-
|
59
|
+
ddog_prof_ProfileExporter_Result exporter_result = create_exporter(exporter_configuration, rb_ary_new());
|
69
60
|
|
70
61
|
VALUE failure_tuple = handle_exporter_failure(exporter_result);
|
71
62
|
if (!NIL_P(failure_tuple)) return failure_tuple;
|
72
63
|
|
73
64
|
// We don't actually need the exporter for now -- we just wanted to validate that we could create it with the
|
74
65
|
// settings we were given
|
75
|
-
ddog_prof_Exporter_drop(exporter_result.ok);
|
66
|
+
ddog_prof_Exporter_drop(&exporter_result.ok);
|
76
67
|
|
77
68
|
return rb_ary_new_from_args(2, ok_symbol, Qnil);
|
78
69
|
}
|
@@ -84,26 +75,21 @@ static ddog_prof_Endpoint endpoint_from(VALUE exporter_configuration) {
|
|
84
75
|
ENFORCE_TYPE(exporter_working_mode, T_SYMBOL);
|
85
76
|
ID working_mode = SYM2ID(exporter_working_mode);
|
86
77
|
|
87
|
-
|
88
|
-
ID agent_id = rb_intern("agent");
|
89
|
-
|
90
|
-
if (working_mode != agentless_id && working_mode != agent_id) {
|
91
|
-
rb_raise(rb_eArgError, "Failed to initialize transport: Unexpected working mode, expected :agentless or :agent");
|
92
|
-
}
|
93
|
-
|
94
|
-
if (working_mode == agentless_id) {
|
78
|
+
if (working_mode == rb_intern("agentless")) {
|
95
79
|
VALUE site = rb_ary_entry(exporter_configuration, 1);
|
96
80
|
VALUE api_key = rb_ary_entry(exporter_configuration, 2);
|
97
81
|
|
98
82
|
return ddog_prof_Endpoint_agentless(char_slice_from_ruby_string(site), char_slice_from_ruby_string(api_key));
|
99
|
-
} else
|
83
|
+
} else if (working_mode == rb_intern("agent")) {
|
100
84
|
VALUE base_url = rb_ary_entry(exporter_configuration, 1);
|
101
85
|
|
102
86
|
return ddog_prof_Endpoint_agent(char_slice_from_ruby_string(base_url));
|
87
|
+
} else {
|
88
|
+
rb_raise(rb_eArgError, "Failed to initialize transport: Unexpected working mode, expected :agentless or :agent");
|
103
89
|
}
|
104
90
|
}
|
105
91
|
|
106
|
-
static
|
92
|
+
static ddog_prof_ProfileExporter_Result create_exporter(VALUE exporter_configuration, VALUE tags_as_array) {
|
107
93
|
ENFORCE_TYPE(exporter_configuration, T_ARRAY);
|
108
94
|
ENFORCE_TYPE(tags_as_array, T_ARRAY);
|
109
95
|
|
@@ -117,7 +103,7 @@ static ddog_prof_Exporter_NewResult create_exporter(VALUE exporter_configuration
|
|
117
103
|
ddog_CharSlice library_version = char_slice_from_ruby_string(library_version_string);
|
118
104
|
ddog_CharSlice profiling_family = DDOG_CHARSLICE_C("ruby");
|
119
105
|
|
120
|
-
|
106
|
+
ddog_prof_ProfileExporter_Result exporter_result =
|
121
107
|
ddog_prof_Exporter_new(library_name, library_version, profiling_family, &tags, endpoint);
|
122
108
|
|
123
109
|
ddog_Vec_Tag_drop(tags);
|
@@ -125,8 +111,12 @@ static ddog_prof_Exporter_NewResult create_exporter(VALUE exporter_configuration
|
|
125
111
|
return exporter_result;
|
126
112
|
}
|
127
113
|
|
128
|
-
static
|
129
|
-
|
114
|
+
static void validate_token(ddog_CancellationToken token, const char *file, int line) {
|
115
|
+
if (token.inner == NULL) rb_raise(rb_eRuntimeError, "Unexpected: Validation token was empty at %s:%d", file, line);
|
116
|
+
}
|
117
|
+
|
118
|
+
static VALUE handle_exporter_failure(ddog_prof_ProfileExporter_Result exporter_result) {
|
119
|
+
return exporter_result.tag == DDOG_PROF_PROFILE_EXPORTER_RESULT_OK_HANDLE_PROFILE_EXPORTER ?
|
130
120
|
Qnil :
|
131
121
|
rb_ary_new_from_args(2, error_symbol, get_error_details_and_drop(&exporter_result.err));
|
132
122
|
}
|
@@ -134,39 +124,37 @@ static VALUE handle_exporter_failure(ddog_prof_Exporter_NewResult exporter_resul
|
|
134
124
|
// Note: This function handles a bunch of libdatadog dynamically-allocated objects, so it MUST not use any Ruby APIs
|
135
125
|
// which can raise exceptions, otherwise the objects will be leaked.
|
136
126
|
static VALUE perform_export(
|
137
|
-
|
138
|
-
|
139
|
-
ddog_Timespec finish,
|
127
|
+
ddog_prof_ProfileExporter *exporter,
|
128
|
+
ddog_prof_EncodedProfile *profile,
|
140
129
|
ddog_prof_Exporter_Slice_File files_to_compress_and_export,
|
141
|
-
ddog_prof_Exporter_Slice_File files_to_export_unmodified,
|
142
|
-
ddog_Vec_Tag *additional_tags,
|
143
130
|
ddog_CharSlice internal_metadata,
|
144
131
|
ddog_CharSlice info
|
145
132
|
) {
|
146
|
-
|
147
|
-
ddog_prof_Exporter_Request_BuildResult build_result = ddog_prof_Exporter_Request_build(
|
133
|
+
ddog_prof_Request_Result build_result = ddog_prof_Exporter_Request_build(
|
148
134
|
exporter,
|
149
|
-
|
150
|
-
finish,
|
135
|
+
profile,
|
151
136
|
files_to_compress_and_export,
|
152
|
-
files_to_export_unmodified,
|
153
|
-
|
154
|
-
endpoints_stats,
|
137
|
+
/* files_to_export_unmodified: */ ddog_prof_Exporter_Slice_File_empty(),
|
138
|
+
/* optional_additional_tags: */ NULL,
|
155
139
|
&internal_metadata,
|
156
140
|
&info
|
157
141
|
);
|
158
142
|
|
159
|
-
if (build_result.tag ==
|
143
|
+
if (build_result.tag == DDOG_PROF_REQUEST_RESULT_ERR_HANDLE_REQUEST) {
|
160
144
|
ddog_prof_Exporter_drop(exporter);
|
161
145
|
return rb_ary_new_from_args(2, error_symbol, get_error_details_and_drop(&build_result.err));
|
162
146
|
}
|
163
147
|
|
164
|
-
ddog_CancellationToken
|
148
|
+
ddog_CancellationToken cancel_token_request = ddog_CancellationToken_new();
|
149
|
+
ddog_CancellationToken cancel_token_interrupt = ddog_CancellationToken_clone(&cancel_token_request);
|
150
|
+
|
151
|
+
validate_token(cancel_token_request, __FILE__, __LINE__);
|
152
|
+
validate_token(cancel_token_interrupt, __FILE__, __LINE__);
|
165
153
|
|
166
154
|
// We'll release the Global VM Lock while we're calling send, so that the Ruby VM can continue to work while this
|
167
155
|
// is pending
|
168
|
-
|
169
|
-
{.exporter = exporter, .build_result = &build_result, .cancel_token =
|
156
|
+
call_exporter_without_gvl_arguments args =
|
157
|
+
{.exporter = exporter, .build_result = &build_result, .cancel_token = &cancel_token_request, .send_ran = false};
|
170
158
|
|
171
159
|
// We use rb_thread_call_without_gvl2 instead of rb_thread_call_without_gvl as the gvl2 variant never raises any
|
172
160
|
// exceptions.
|
@@ -183,14 +171,15 @@ static VALUE perform_export(
|
|
183
171
|
int pending_exception = 0;
|
184
172
|
|
185
173
|
while (!args.send_ran && !pending_exception) {
|
186
|
-
rb_thread_call_without_gvl2(call_exporter_without_gvl, &args, interrupt_exporter_call,
|
174
|
+
rb_thread_call_without_gvl2(call_exporter_without_gvl, &args, interrupt_exporter_call, &cancel_token_interrupt);
|
187
175
|
|
188
176
|
// To make sure we don't leak memory, we never check for pending exceptions if send ran
|
189
177
|
if (!args.send_ran) pending_exception = check_if_pending_exception();
|
190
178
|
}
|
191
179
|
|
192
180
|
// Cleanup exporter and token, no longer needed
|
193
|
-
ddog_CancellationToken_drop(
|
181
|
+
ddog_CancellationToken_drop(&cancel_token_request);
|
182
|
+
ddog_CancellationToken_drop(&cancel_token_interrupt);
|
194
183
|
ddog_prof_Exporter_drop(exporter);
|
195
184
|
|
196
185
|
if (pending_exception) {
|
@@ -203,10 +192,10 @@ static VALUE perform_export(
|
|
203
192
|
|
204
193
|
// The request itself does not need to be freed as libdatadog takes ownership of it as part of sending.
|
205
194
|
|
206
|
-
|
195
|
+
ddog_prof_Result_HttpStatus result = args.result;
|
207
196
|
|
208
|
-
return result.tag ==
|
209
|
-
rb_ary_new_from_args(2, ok_symbol, UINT2NUM(result.
|
197
|
+
return result.tag == DDOG_PROF_RESULT_HTTP_STATUS_OK_HTTP_STATUS ?
|
198
|
+
rb_ary_new_from_args(2, ok_symbol, UINT2NUM(result.ok.code)) :
|
210
199
|
rb_ary_new_from_args(2, error_symbol, get_error_details_and_drop(&result.err));
|
211
200
|
}
|
212
201
|
|
@@ -214,26 +203,19 @@ static VALUE _native_do_export(
|
|
214
203
|
DDTRACE_UNUSED VALUE _self,
|
215
204
|
VALUE exporter_configuration,
|
216
205
|
VALUE upload_timeout_milliseconds,
|
217
|
-
VALUE
|
218
|
-
VALUE start_timespec_nanoseconds,
|
219
|
-
VALUE finish_timespec_seconds,
|
220
|
-
VALUE finish_timespec_nanoseconds,
|
221
|
-
VALUE pprof_file_name,
|
222
|
-
VALUE pprof_data,
|
223
|
-
VALUE code_provenance_file_name,
|
224
|
-
VALUE code_provenance_data,
|
225
|
-
VALUE tags_as_array,
|
226
|
-
VALUE internal_metadata_json,
|
227
|
-
VALUE info_json
|
206
|
+
VALUE flush
|
228
207
|
) {
|
208
|
+
VALUE encoded_profile = rb_funcall(flush, rb_intern("encoded_profile"), 0);
|
209
|
+
VALUE code_provenance_file_name = rb_funcall(flush, rb_intern("code_provenance_file_name"), 0);
|
210
|
+
VALUE code_provenance_data = rb_funcall(flush, rb_intern("code_provenance_data"), 0);
|
211
|
+
VALUE tags_as_array = rb_funcall(flush, rb_intern("tags_as_array"), 0);
|
212
|
+
VALUE internal_metadata_json = rb_funcall(flush, rb_intern("internal_metadata_json"), 0);
|
213
|
+
VALUE info_json = rb_funcall(flush, rb_intern("info_json"), 0);
|
214
|
+
|
229
215
|
ENFORCE_TYPE(upload_timeout_milliseconds, T_FIXNUM);
|
230
|
-
|
231
|
-
ENFORCE_TYPE(start_timespec_nanoseconds, T_FIXNUM);
|
232
|
-
ENFORCE_TYPE(finish_timespec_seconds, T_FIXNUM);
|
233
|
-
ENFORCE_TYPE(finish_timespec_nanoseconds, T_FIXNUM);
|
234
|
-
ENFORCE_TYPE(pprof_file_name, T_STRING);
|
235
|
-
ENFORCE_TYPE(pprof_data, T_STRING);
|
216
|
+
enforce_encoded_profile_instance(encoded_profile);
|
236
217
|
ENFORCE_TYPE(code_provenance_file_name, T_STRING);
|
218
|
+
ENFORCE_TYPE(tags_as_array, T_ARRAY);
|
237
219
|
ENFORCE_TYPE(internal_metadata_json, T_STRING);
|
238
220
|
ENFORCE_TYPE(info_json, T_STRING);
|
239
221
|
|
@@ -243,23 +225,9 @@ static VALUE _native_do_export(
|
|
243
225
|
|
244
226
|
uint64_t timeout_milliseconds = NUM2ULONG(upload_timeout_milliseconds);
|
245
227
|
|
246
|
-
ddog_Timespec start =
|
247
|
-
{.seconds = NUM2LONG(start_timespec_seconds), .nanoseconds = NUM2UINT(start_timespec_nanoseconds)};
|
248
|
-
ddog_Timespec finish =
|
249
|
-
{.seconds = NUM2LONG(finish_timespec_seconds), .nanoseconds = NUM2UINT(finish_timespec_nanoseconds)};
|
250
|
-
|
251
228
|
int to_compress_length = have_code_provenance ? 1 : 0;
|
252
229
|
ddog_prof_Exporter_File to_compress[to_compress_length];
|
253
|
-
int already_compressed_length = 1; // pprof
|
254
|
-
ddog_prof_Exporter_File already_compressed[already_compressed_length];
|
255
|
-
|
256
230
|
ddog_prof_Exporter_Slice_File files_to_compress_and_export = {.ptr = to_compress, .len = to_compress_length};
|
257
|
-
ddog_prof_Exporter_Slice_File files_to_export_unmodified = {.ptr = already_compressed, .len = already_compressed_length};
|
258
|
-
|
259
|
-
already_compressed[0] = (ddog_prof_Exporter_File) {
|
260
|
-
.name = char_slice_from_ruby_string(pprof_file_name),
|
261
|
-
.file = byte_slice_from_ruby_string(pprof_data),
|
262
|
-
};
|
263
231
|
|
264
232
|
if (have_code_provenance) {
|
265
233
|
to_compress[0] = (ddog_prof_Exporter_File) {
|
@@ -268,39 +236,35 @@ static VALUE _native_do_export(
|
|
268
236
|
};
|
269
237
|
}
|
270
238
|
|
271
|
-
ddog_Vec_Tag *null_additional_tags = NULL;
|
272
239
|
ddog_CharSlice internal_metadata = char_slice_from_ruby_string(internal_metadata_json);
|
273
240
|
ddog_CharSlice info = char_slice_from_ruby_string(info_json);
|
274
241
|
|
275
|
-
|
242
|
+
ddog_prof_ProfileExporter_Result exporter_result = create_exporter(exporter_configuration, tags_as_array);
|
276
243
|
// Note: Do not add anything that can raise exceptions after this line, as otherwise the exporter memory will leak
|
277
244
|
|
278
245
|
VALUE failure_tuple = handle_exporter_failure(exporter_result);
|
279
246
|
if (!NIL_P(failure_tuple)) return failure_tuple;
|
280
247
|
|
281
|
-
|
282
|
-
if (timeout_result.tag ==
|
248
|
+
ddog_VoidResult timeout_result = ddog_prof_Exporter_set_timeout(&exporter_result.ok, timeout_milliseconds);
|
249
|
+
if (timeout_result.tag == DDOG_VOID_RESULT_ERR) {
|
283
250
|
// NOTE: Seems a bit harsh to fail the upload if we can't set a timeout. OTOH, this is only expected to fail
|
284
251
|
// if the exporter is not well built. Because such a situation should already be caught above I think it's
|
285
252
|
// preferable to leave this here as a virtually unreachable exception rather than ignoring it.
|
286
|
-
ddog_prof_Exporter_drop(exporter_result.ok);
|
287
|
-
return rb_ary_new_from_args(2, error_symbol, get_error_details_and_drop(&timeout_result.
|
253
|
+
ddog_prof_Exporter_drop(&exporter_result.ok);
|
254
|
+
return rb_ary_new_from_args(2, error_symbol, get_error_details_and_drop(&timeout_result.err));
|
288
255
|
}
|
289
256
|
|
290
257
|
return perform_export(
|
291
|
-
exporter_result.ok,
|
292
|
-
|
293
|
-
finish,
|
258
|
+
&exporter_result.ok,
|
259
|
+
to_ddog_prof_EncodedProfile(encoded_profile),
|
294
260
|
files_to_compress_and_export,
|
295
|
-
files_to_export_unmodified,
|
296
|
-
null_additional_tags,
|
297
261
|
internal_metadata,
|
298
262
|
info
|
299
263
|
);
|
300
264
|
}
|
301
265
|
|
302
266
|
static void *call_exporter_without_gvl(void *call_args) {
|
303
|
-
|
267
|
+
call_exporter_without_gvl_arguments *args = (call_exporter_without_gvl_arguments*) call_args;
|
304
268
|
|
305
269
|
args->result = ddog_prof_Exporter_send(args->exporter, &args->build_result->ok, args->cancel_token);
|
306
270
|
args->send_ran = true;
|
@@ -310,5 +274,7 @@ static void *call_exporter_without_gvl(void *call_args) {
|
|
310
274
|
|
311
275
|
// Called by Ruby when it wants to interrupt call_exporter_without_gvl above, e.g. when the app wants to exit cleanly
|
312
276
|
static void interrupt_exporter_call(void *cancel_token) {
|
277
|
+
// TODO: False here can mean two things: it was already cancelled OR it failed to cancel.
|
278
|
+
// Would be nice to change libdatadog to be able to distinguish between them...
|
313
279
|
ddog_CancellationToken_cancel((ddog_CancellationToken *) cancel_token);
|
314
280
|
}
|
@@ -40,6 +40,13 @@
|
|
40
40
|
#endif
|
41
41
|
#endif
|
42
42
|
|
43
|
+
// This file can't include datadog_ruby_common.h so we replicate this here
|
44
|
+
#ifdef __GNUC__
|
45
|
+
#define DDTRACE_UNUSED __attribute__((unused))
|
46
|
+
#else
|
47
|
+
#define DDTRACE_UNUSED
|
48
|
+
#endif
|
49
|
+
|
43
50
|
#define PRIVATE_VM_API_ACCESS_SKIP_RUBY_INCLUDES
|
44
51
|
#include "private_vm_api_access.h"
|
45
52
|
|
@@ -158,7 +165,7 @@ bool is_current_thread_holding_the_gvl(void) {
|
|
158
165
|
//
|
159
166
|
// Thus an incorrect `is_current_thread_holding_the_gvl` result may lead to issues inside `rb_postponed_job_register_one`.
|
160
167
|
//
|
161
|
-
// For this reason we
|
168
|
+
// For this reason we default to use the "no signals workaround" on Ruby 2.5 by default, and we print a
|
162
169
|
// warning when customers force-enable it.
|
163
170
|
bool gvl_acquired = vm->gvl.acquired != 0;
|
164
171
|
rb_thread_t *current_owner = vm->running_thread;
|
@@ -305,6 +312,7 @@ VALUE thread_name_for(VALUE thread) {
|
|
305
312
|
// to support our custom rb_profile_frames (see below)
|
306
313
|
// Modifications:
|
307
314
|
// * Support int first_lineno for Ruby 3.2.0+ (https://github.com/ruby/ruby/pull/6430)
|
315
|
+
// * Validate iseq and pos before calling `rb_iseq_line_no` as a safety measure (see comment below for details)
|
308
316
|
//
|
309
317
|
// `node_id` gets used depending on Ruby VM compilation settings (USE_ISEQ_NODE_ID being defined).
|
310
318
|
// To avoid getting false "unused argument" warnings in setups where it's not used, we need to do this weird dance
|
@@ -351,6 +359,13 @@ calc_pos(const rb_iseq_t *iseq, const VALUE *pc, int *lineno, int *node_id)
|
|
351
359
|
__builtin_trap();
|
352
360
|
}
|
353
361
|
#endif
|
362
|
+
|
363
|
+
// In PROF-11475 we spotted a crash when calling `rb_iseq_line_no` from this method. We couldn't reproduce or
|
364
|
+
// figure out the root cause, but "just in case", we're validating that the iseq looks valid and that the
|
365
|
+
// `n` used for the position is also sane, and if they don't look good, we don't calculate the line, rather
|
366
|
+
// than potentially trigger any issues.
|
367
|
+
if (RB_UNLIKELY(!RB_TYPE_P((VALUE) iseq, T_IMEMO) || n < 0 || n > ISEQ_BODY(iseq)->iseq_size)) return 0;
|
368
|
+
|
354
369
|
if (lineno) *lineno = rb_iseq_line_no(iseq, pos);
|
355
370
|
#ifdef USE_ISEQ_NODE_ID
|
356
371
|
if (node_id) *node_id = rb_iseq_node_id(iseq, pos);
|
@@ -800,3 +815,55 @@ static inline int ddtrace_imemo_type(VALUE imemo) {
|
|
800
815
|
return current_thread;
|
801
816
|
}
|
802
817
|
#endif
|
818
|
+
|
819
|
+
// Is the VM smack in the middle of raising an exception?
|
820
|
+
bool is_raised_flag_set(VALUE thread) { return thread_struct_from_object(thread)->ec->raised_flag > 0; }
|
821
|
+
|
822
|
+
#ifndef NO_CURRENT_FIBER_FOR
|
823
|
+
// The following three declarations are all
|
824
|
+
// taken from upstream cont.c at commit d97884a58be32e829fd03a80cd521f4733d65c79 (February 2025, master branch)
|
825
|
+
// (See the Ruby project copyright and license above)
|
826
|
+
// to enable building `current_fiber_for`.
|
827
|
+
//
|
828
|
+
// We needed to copy them because they aren't otherwise exposed in any VM APIs or headers.
|
829
|
+
// @ivoanjo: I manually checked the Ruby 3.1, 3.2, 3.3 and 3.4 branches + master, and the parts we care about in these
|
830
|
+
// structures have not changed in many years (in fact, last change I spotted was for 2.7).
|
831
|
+
enum context_type {
|
832
|
+
CONTINUATION_CONTEXT = 0,
|
833
|
+
FIBER_CONTEXT = 1
|
834
|
+
};
|
835
|
+
|
836
|
+
typedef struct rb_context_struct { // This declaration is incomplete -- only contains up to `self` which is the part we care about
|
837
|
+
enum context_type type;
|
838
|
+
int argc;
|
839
|
+
int kw_splat;
|
840
|
+
VALUE self;
|
841
|
+
} rb_context_t;
|
842
|
+
|
843
|
+
struct rb_fiber_struct { // This declaration is incomplete -- only contains the first entry which is the part we care about
|
844
|
+
rb_context_t cont;
|
845
|
+
};
|
846
|
+
|
847
|
+
VALUE current_fiber_for(VALUE thread) {
|
848
|
+
VALUE self = thread_struct_from_object(thread)->ec->fiber_ptr->cont.self;
|
849
|
+
return self == 0 ? Qnil : self;
|
850
|
+
}
|
851
|
+
|
852
|
+
void self_test_current_fiber_for(void) {
|
853
|
+
VALUE expected_current_fiber = current_fiber_for(rb_thread_current());
|
854
|
+
VALUE actual_current_fiber = rb_fiber_current();
|
855
|
+
|
856
|
+
if (expected_current_fiber == Qnil) {
|
857
|
+
// On purpose above we tried reading before calling `rb_fiber_current()` so the fiber may have not existed yet.
|
858
|
+
// But now it should be there.
|
859
|
+
expected_current_fiber = current_fiber_for(rb_thread_current());
|
860
|
+
}
|
861
|
+
|
862
|
+
if (expected_current_fiber != actual_current_fiber) rb_raise(rb_eRuntimeError, "current_fiber_for() self-test failed");
|
863
|
+
}
|
864
|
+
#else
|
865
|
+
NORETURN(VALUE current_fiber_for(DDTRACE_UNUSED VALUE thread));
|
866
|
+
|
867
|
+
VALUE current_fiber_for(DDTRACE_UNUSED VALUE thread) { rb_raise(rb_eRuntimeError, "Not implemented for Ruby < 3.1"); }
|
868
|
+
void self_test_current_fiber_for(void) { } // Nothing to do
|
869
|
+
#endif
|
@@ -18,7 +18,7 @@ typedef struct {
|
|
18
18
|
rb_nativethread_id_t owner;
|
19
19
|
} current_gvl_owner;
|
20
20
|
|
21
|
-
typedef struct
|
21
|
+
typedef struct {
|
22
22
|
union {
|
23
23
|
struct {
|
24
24
|
VALUE iseq;
|
@@ -44,6 +44,7 @@ bool is_thread_alive(VALUE thread);
|
|
44
44
|
VALUE thread_name_for(VALUE thread);
|
45
45
|
|
46
46
|
int ddtrace_rb_profile_frames(VALUE thread, int start, int limit, frame_info *stack_buffer);
|
47
|
+
|
47
48
|
// Returns true if the current thread belongs to the main Ractor or if Ruby has no Ractor support
|
48
49
|
bool ddtrace_rb_ractor_main_p(void);
|
49
50
|
|
@@ -68,3 +69,11 @@ const char *imemo_kind(VALUE imemo);
|
|
68
69
|
|
69
70
|
#define ENFORCE_THREAD(value) \
|
70
71
|
{ if (RB_UNLIKELY(!rb_typeddata_is_kind_of(value, RTYPEDDATA_TYPE(rb_thread_current())))) raise_unexpected_type(value, ADD_QUOTES(value), "Thread", __FILE__, __LINE__, __func__); }
|
72
|
+
|
73
|
+
bool is_raised_flag_set(VALUE thread);
|
74
|
+
|
75
|
+
// Can be nil if `rb_fiber_current()` or similar has not been called (gets allocated lazily)
|
76
|
+
// Only implemented for Ruby 3.1+
|
77
|
+
VALUE current_fiber_for(VALUE thread);
|
78
|
+
|
79
|
+
void self_test_current_fiber_for(void);
|
@@ -11,6 +11,7 @@
|
|
11
11
|
#include "ruby_helpers.h"
|
12
12
|
#include "setup_signal_handler.h"
|
13
13
|
#include "time_helpers.h"
|
14
|
+
#include "unsafe_api_calls_check.h"
|
14
15
|
|
15
16
|
// Each class/module here is implemented in their separate file
|
16
17
|
void collectors_cpu_and_wall_time_worker_init(VALUE profiling_module);
|
@@ -19,6 +20,7 @@ void collectors_dynamic_sampling_rate_init(VALUE profiling_module);
|
|
19
20
|
void collectors_idle_sampling_helper_init(VALUE profiling_module);
|
20
21
|
void collectors_stack_init(VALUE profiling_module);
|
21
22
|
void collectors_thread_context_init(VALUE profiling_module);
|
23
|
+
void encoded_profile_init(VALUE profiling_module);
|
22
24
|
void http_transport_init(VALUE profiling_module);
|
23
25
|
void stack_recorder_init(VALUE profiling_module);
|
24
26
|
|
@@ -40,6 +42,12 @@ static VALUE _native_malloc_stats(DDTRACE_UNUSED VALUE _self);
|
|
40
42
|
static VALUE _native_safe_object_info(DDTRACE_UNUSED VALUE _self, VALUE obj);
|
41
43
|
|
42
44
|
void DDTRACE_EXPORT Init_datadog_profiling_native_extension(void) {
|
45
|
+
// The profiler still has a lot of limitations around being used in Ractors BUT for now we're choosing to take care of those
|
46
|
+
// on our side, rather than asking Ruby to block calling our APIs from Ractors.
|
47
|
+
#ifdef HAVE_RB_EXT_RACTOR_SAFE
|
48
|
+
rb_ext_ractor_safe(true);
|
49
|
+
#endif
|
50
|
+
|
43
51
|
VALUE datadog_module = rb_define_module("Datadog");
|
44
52
|
VALUE profiling_module = rb_define_module_under(datadog_module, "Profiling");
|
45
53
|
VALUE native_extension_module = rb_define_module_under(profiling_module, "NativeExtension");
|
@@ -54,8 +62,10 @@ void DDTRACE_EXPORT Init_datadog_profiling_native_extension(void) {
|
|
54
62
|
collectors_idle_sampling_helper_init(profiling_module);
|
55
63
|
collectors_stack_init(profiling_module);
|
56
64
|
collectors_thread_context_init(profiling_module);
|
65
|
+
encoded_profile_init(profiling_module);
|
57
66
|
http_transport_init(profiling_module);
|
58
67
|
stack_recorder_init(profiling_module);
|
68
|
+
unsafe_api_calls_check_init();
|
59
69
|
|
60
70
|
// Hosts methods used for testing the native code using RSpec
|
61
71
|
VALUE testing_module = rb_define_module_under(native_extension_module, "Testing");
|
@@ -78,21 +88,22 @@ void DDTRACE_EXPORT Init_datadog_profiling_native_extension(void) {
|
|
78
88
|
|
79
89
|
static VALUE native_working_p(DDTRACE_UNUSED VALUE _self) {
|
80
90
|
self_test_clock_id();
|
91
|
+
self_test_current_fiber_for();
|
81
92
|
self_test_mn_enabled();
|
82
93
|
|
83
94
|
return Qtrue;
|
84
95
|
}
|
85
96
|
|
86
|
-
struct
|
97
|
+
typedef struct {
|
87
98
|
VALUE exception_class;
|
88
99
|
char *test_message;
|
89
100
|
int test_message_arg;
|
90
|
-
};
|
101
|
+
} trigger_grab_gvl_and_raise_arguments;
|
91
102
|
|
92
103
|
static VALUE _native_grab_gvl_and_raise(DDTRACE_UNUSED VALUE _self, VALUE exception_class, VALUE test_message, VALUE test_message_arg, VALUE release_gvl) {
|
93
104
|
ENFORCE_TYPE(test_message, T_STRING);
|
94
105
|
|
95
|
-
|
106
|
+
trigger_grab_gvl_and_raise_arguments args;
|
96
107
|
|
97
108
|
args.exception_class = exception_class;
|
98
109
|
args.test_message = StringValueCStr(test_message);
|
@@ -108,7 +119,7 @@ static VALUE _native_grab_gvl_and_raise(DDTRACE_UNUSED VALUE _self, VALUE except
|
|
108
119
|
}
|
109
120
|
|
110
121
|
static void *trigger_grab_gvl_and_raise(void *trigger_args) {
|
111
|
-
|
122
|
+
trigger_grab_gvl_and_raise_arguments *args = (trigger_grab_gvl_and_raise_arguments *) trigger_args;
|
112
123
|
|
113
124
|
if (args->test_message_arg >= 0) {
|
114
125
|
grab_gvl_and_raise(args->exception_class, "%s%d", args->test_message, args->test_message_arg);
|
@@ -119,16 +130,16 @@ static void *trigger_grab_gvl_and_raise(void *trigger_args) {
|
|
119
130
|
return NULL;
|
120
131
|
}
|
121
132
|
|
122
|
-
struct
|
133
|
+
typedef struct {
|
123
134
|
int syserr_errno;
|
124
135
|
char *test_message;
|
125
136
|
int test_message_arg;
|
126
|
-
};
|
137
|
+
} trigger_grab_gvl_and_raise_syserr_arguments;
|
127
138
|
|
128
139
|
static VALUE _native_grab_gvl_and_raise_syserr(DDTRACE_UNUSED VALUE _self, VALUE syserr_errno, VALUE test_message, VALUE test_message_arg, VALUE release_gvl) {
|
129
140
|
ENFORCE_TYPE(test_message, T_STRING);
|
130
141
|
|
131
|
-
|
142
|
+
trigger_grab_gvl_and_raise_syserr_arguments args;
|
132
143
|
|
133
144
|
args.syserr_errno = NUM2INT(syserr_errno);
|
134
145
|
args.test_message = StringValueCStr(test_message);
|
@@ -144,7 +155,7 @@ static VALUE _native_grab_gvl_and_raise_syserr(DDTRACE_UNUSED VALUE _self, VALUE
|
|
144
155
|
}
|
145
156
|
|
146
157
|
static void *trigger_grab_gvl_and_raise_syserr(void *trigger_args) {
|
147
|
-
|
158
|
+
trigger_grab_gvl_and_raise_syserr_arguments *args = (trigger_grab_gvl_and_raise_syserr_arguments *) trigger_args;
|
148
159
|
|
149
160
|
if (args->test_message_arg >= 0) {
|
150
161
|
grab_gvl_and_raise_syserr(args->syserr_errno, "%s%d", args->test_message, args->test_message_arg);
|
@@ -23,18 +23,18 @@ void ruby_helpers_init(void) {
|
|
23
23
|
|
24
24
|
#define MAX_RAISE_MESSAGE_SIZE 256
|
25
25
|
|
26
|
-
struct
|
26
|
+
typedef struct {
|
27
27
|
VALUE exception_class;
|
28
28
|
char exception_message[MAX_RAISE_MESSAGE_SIZE];
|
29
|
-
};
|
29
|
+
} raise_args;
|
30
30
|
|
31
31
|
static void *trigger_raise(void *raise_arguments) {
|
32
|
-
|
32
|
+
raise_args *args = (raise_args *) raise_arguments;
|
33
33
|
rb_raise(args->exception_class, "%s", args->exception_message);
|
34
34
|
}
|
35
35
|
|
36
36
|
void grab_gvl_and_raise(VALUE exception_class, const char *format_string, ...) {
|
37
|
-
|
37
|
+
raise_args args;
|
38
38
|
|
39
39
|
args.exception_class = exception_class;
|
40
40
|
|
@@ -55,18 +55,18 @@ void grab_gvl_and_raise(VALUE exception_class, const char *format_string, ...) {
|
|
55
55
|
rb_bug("[ddtrace] Unexpected: Reached the end of grab_gvl_and_raise while raising '%s'\n", args.exception_message);
|
56
56
|
}
|
57
57
|
|
58
|
-
struct
|
58
|
+
typedef struct {
|
59
59
|
int syserr_errno;
|
60
60
|
char exception_message[MAX_RAISE_MESSAGE_SIZE];
|
61
|
-
};
|
61
|
+
} syserr_raise_args;
|
62
62
|
|
63
63
|
static void *trigger_syserr_raise(void *syserr_raise_arguments) {
|
64
|
-
|
64
|
+
syserr_raise_args *args = (syserr_raise_args *) syserr_raise_arguments;
|
65
65
|
rb_syserr_fail(args->syserr_errno, args->exception_message);
|
66
66
|
}
|
67
67
|
|
68
68
|
void grab_gvl_and_raise_syserr(int syserr_errno, const char *format_string, ...) {
|
69
|
-
|
69
|
+
syserr_raise_args args;
|
70
70
|
|
71
71
|
args.syserr_errno = syserr_errno;
|
72
72
|
|