datadog 2.7.1 → 2.18.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 +353 -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 +78 -102
- 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 +235 -57
- data/ext/datadog_profiling_native_extension/collectors_stack.h +21 -5
- data/ext/datadog_profiling_native_extension/collectors_thread_context.c +376 -156
- data/ext/datadog_profiling_native_extension/collectors_thread_context.h +1 -0
- 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 +14 -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 +295 -532
- data/ext/datadog_profiling_native_extension/heap_recorder.h +6 -8
- data/ext/datadog_profiling_native_extension/http_transport.c +64 -98
- data/ext/datadog_profiling_native_extension/libdatadog_helpers.c +22 -0
- data/ext/datadog_profiling_native_extension/libdatadog_helpers.h +8 -5
- data/ext/datadog_profiling_native_extension/private_vm_api_access.c +69 -1
- data/ext/datadog_profiling_native_extension/private_vm_api_access.h +16 -4
- data/ext/datadog_profiling_native_extension/profiling.c +19 -8
- data/ext/datadog_profiling_native_extension/ruby_helpers.c +9 -21
- data/ext/datadog_profiling_native_extension/ruby_helpers.h +2 -10
- data/ext/datadog_profiling_native_extension/stack_recorder.c +231 -181
- 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/extconf.rb +2 -2
- data/ext/libdatadog_api/init.c +15 -0
- data/ext/libdatadog_api/library_config.c +164 -0
- data/ext/libdatadog_api/library_config.h +25 -0
- data/ext/libdatadog_api/macos_development.md +3 -3
- data/ext/libdatadog_api/process_discovery.c +112 -0
- data/ext/libdatadog_api/process_discovery.h +5 -0
- data/ext/libdatadog_extconf_helpers.rb +2 -2
- 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 +56 -0
- data/lib/datadog/appsec/api_security/route_extractor.rb +65 -0
- data/lib/datadog/appsec/api_security/sampler.rb +59 -0
- data/lib/datadog/appsec/api_security.rb +23 -0
- data/lib/datadog/appsec/assets/waf_rules/README.md +50 -5
- data/lib/datadog/appsec/assets/waf_rules/recommended.json +623 -253
- data/lib/datadog/appsec/assets/waf_rules/strict.json +69 -107
- data/lib/datadog/appsec/autoload.rb +1 -1
- data/lib/datadog/appsec/component.rb +49 -65
- data/lib/datadog/appsec/compressed_json.rb +40 -0
- data/lib/datadog/appsec/configuration/settings.rb +212 -27
- 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 +73 -78
- 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 +30 -36
- data/lib/datadog/appsec/remote.rb +31 -57
- data/lib/datadog/appsec/response.rb +19 -85
- data/lib/datadog/appsec/security_engine/engine.rb +194 -0
- data/lib/datadog/appsec/security_engine/result.rb +67 -0
- data/lib/datadog/appsec/security_engine/runner.rb +87 -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 +22 -12
- data/lib/datadog/auto_instrument.rb +3 -0
- data/lib/datadog/core/buffer/random.rb +18 -2
- data/lib/datadog/core/configuration/agent_settings.rb +52 -0
- data/lib/datadog/core/configuration/agent_settings_resolver.rb +4 -18
- data/lib/datadog/core/configuration/agentless_settings_resolver.rb +176 -0
- data/lib/datadog/core/configuration/components.rb +74 -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 +81 -45
- 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 +121 -50
- data/lib/datadog/core/configuration/stable_config.rb +22 -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/crashtracking/tag_builder.rb +4 -22
- 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/tracer_memfd.rb +15 -0
- data/lib/datadog/core/process_discovery.rb +36 -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 +14 -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/tag_builder.rb +56 -0
- 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 +66 -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 +269 -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 +5 -4
- data/lib/datadog/core/telemetry/logging.rb +12 -6
- 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/net.rb +17 -2
- 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/env.rb +8 -0
- 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/utils.rb +7 -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 +162 -21
- 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 +54 -38
- data/lib/datadog/di/probe_notifier_worker.rb +60 -26
- data/lib/datadog/di/redactor.rb +0 -1
- data/lib/datadog/di/remote.rb +147 -0
- data/lib/datadog/di/serializer.rb +19 -8
- 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 +77 -0
- data/lib/datadog/di/transport/http.rb +57 -0
- data/lib/datadog/di/transport/input.rb +70 -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 +18 -9
- data/lib/datadog/profiling/collectors/cpu_and_wall_time_worker.rb +4 -0
- data/lib/datadog/profiling/collectors/idle_sampling_helper.rb +1 -0
- data/lib/datadog/profiling/collectors/info.rb +3 -0
- data/lib/datadog/profiling/collectors/thread_context.rb +17 -2
- data/lib/datadog/profiling/component.rb +64 -82
- data/lib/datadog/profiling/encoded_profile.rb +11 -0
- data/lib/datadog/profiling/exporter.rb +3 -4
- data/lib/datadog/profiling/ext.rb +0 -14
- data/lib/datadog/profiling/flush.rb +5 -8
- data/lib/datadog/profiling/http_transport.rb +8 -87
- data/lib/datadog/profiling/load_native_extension.rb +1 -33
- data/lib/datadog/profiling/profiler.rb +2 -0
- data/lib/datadog/profiling/scheduler.rb +10 -2
- data/lib/datadog/profiling/stack_recorder.rb +9 -9
- data/lib/datadog/profiling/tag_builder.rb +5 -41
- data/lib/datadog/profiling/tasks/setup.rb +2 -0
- 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/action_controller/instrumentation.rb +15 -0
- data/lib/datadog/tracing/contrib/action_pack/action_dispatch/instrumentation.rb +19 -12
- data/lib/datadog/tracing/contrib/action_pack/ext.rb +2 -0
- 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/lograge/patcher.rb +4 -2
- 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/ext.rb +1 -0
- data/lib/datadog/tracing/contrib/sidekiq/server_tracer.rb +5 -2
- 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 +10 -6
- data/lib/datadog/tracing/trace_digest.rb +9 -2
- data/lib/datadog/tracing/trace_operation.rb +55 -27
- data/lib/datadog/tracing/trace_segment.rb +6 -4
- data/lib/datadog/tracing/tracer.rb +66 -14
- 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 +149 -54
- data/ext/datadog_profiling_loader/datadog_profiling_loader.c +0 -142
- data/ext/datadog_profiling_loader/extconf.rb +0 -60
- data/lib/datadog/appsec/assets/waf_rules/processors.json +0 -92
- data/lib/datadog/appsec/assets/waf_rules/scanners.json +0 -114
- 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/processor/rule_merger.rb +0 -170
- data/lib/datadog/appsec/processor.rb +0 -106
- 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
@@ -8,6 +8,7 @@
|
|
8
8
|
#include "ruby_helpers.h"
|
9
9
|
#include "time_helpers.h"
|
10
10
|
#include "heap_recorder.h"
|
11
|
+
#include "encoded_profile.h"
|
11
12
|
|
12
13
|
// Used to wrap a ddog_prof_Profile in a Ruby object and expose Ruby-level serialization APIs
|
13
14
|
// This file implements the native bits of the Datadog::Profiling::StackRecorder class
|
@@ -173,18 +174,19 @@ static const uint8_t all_value_types_positions[] =
|
|
173
174
|
|
174
175
|
// Struct for storing stats related to a profile in a particular slot.
|
175
176
|
// These stats will share the same lifetime as the data in that profile slot.
|
176
|
-
typedef struct
|
177
|
+
typedef struct {
|
177
178
|
// How many individual samples were recorded into this slot (un-weighted)
|
178
179
|
uint64_t recorded_samples;
|
179
180
|
} stats_slot;
|
180
181
|
|
181
|
-
typedef struct
|
182
|
+
typedef struct {
|
182
183
|
ddog_prof_Profile profile;
|
183
184
|
stats_slot stats;
|
185
|
+
ddog_Timespec start_timestamp;
|
184
186
|
} profile_slot;
|
185
187
|
|
186
188
|
// Contains native state for each instance
|
187
|
-
struct
|
189
|
+
typedef struct {
|
188
190
|
// Heap recorder instance
|
189
191
|
heap_recorder *heap_recorder;
|
190
192
|
bool heap_clean_after_gc_enabled;
|
@@ -194,6 +196,10 @@ struct stack_recorder_state {
|
|
194
196
|
pthread_mutex_t mutex_slot_two;
|
195
197
|
profile_slot profile_slot_two;
|
196
198
|
|
199
|
+
ddog_prof_ManagedStringStorage string_storage;
|
200
|
+
ddog_prof_ManagedStringId label_key_allocation_class;
|
201
|
+
ddog_prof_ManagedStringId label_key_gc_gen_age;
|
202
|
+
|
197
203
|
short active_slot; // MUST NEVER BE ACCESSED FROM record_sample; this is NOT for the sampler thread to use.
|
198
204
|
|
199
205
|
uint8_t position_for[ALL_VALUE_TYPES_COUNT];
|
@@ -210,17 +216,17 @@ struct stack_recorder_state {
|
|
210
216
|
long serialization_time_ns_max;
|
211
217
|
uint64_t serialization_time_ns_total;
|
212
218
|
} stats_lifetime;
|
213
|
-
};
|
219
|
+
} stack_recorder_state;
|
214
220
|
|
215
221
|
// Used to group mutex and the corresponding profile slot for easy unlocking after work is done.
|
216
|
-
typedef struct
|
222
|
+
typedef struct {
|
217
223
|
pthread_mutex_t *mutex;
|
218
224
|
profile_slot *data;
|
219
225
|
} locked_profile_slot;
|
220
226
|
|
221
|
-
struct
|
227
|
+
typedef struct {
|
222
228
|
// Set by caller
|
223
|
-
|
229
|
+
stack_recorder_state *state;
|
224
230
|
ddog_Timespec finish_timestamp;
|
225
231
|
|
226
232
|
// Set by callee
|
@@ -228,43 +234,43 @@ struct call_serialize_without_gvl_arguments {
|
|
228
234
|
ddog_prof_Profile_SerializeResult result;
|
229
235
|
long heap_profile_build_time_ns;
|
230
236
|
long serialize_no_gvl_time_ns;
|
237
|
+
ddog_prof_MaybeError advance_gen_result;
|
231
238
|
|
232
239
|
// Set by both
|
233
240
|
bool serialize_ran;
|
234
|
-
};
|
241
|
+
} call_serialize_without_gvl_arguments;
|
235
242
|
|
236
243
|
static VALUE _native_new(VALUE klass);
|
237
|
-
static void initialize_slot_concurrency_control(
|
238
|
-
static void initialize_profiles(
|
244
|
+
static void initialize_slot_concurrency_control(stack_recorder_state *state);
|
245
|
+
static void initialize_profiles(stack_recorder_state *state, ddog_prof_Slice_ValueType sample_types);
|
239
246
|
static void stack_recorder_typed_data_free(void *data);
|
240
247
|
static VALUE _native_initialize(int argc, VALUE *argv, DDTRACE_UNUSED VALUE _self);
|
241
248
|
static VALUE _native_serialize(VALUE self, VALUE recorder_instance);
|
242
249
|
static VALUE ruby_time_from(ddog_Timespec ddprof_time);
|
243
250
|
static void *call_serialize_without_gvl(void *call_args);
|
244
|
-
static locked_profile_slot sampler_lock_active_profile(
|
251
|
+
static locked_profile_slot sampler_lock_active_profile(stack_recorder_state *state);
|
245
252
|
static void sampler_unlock_active_profile(locked_profile_slot active_slot);
|
246
|
-
static profile_slot* serializer_flip_active_and_inactive_slots(
|
253
|
+
static profile_slot* serializer_flip_active_and_inactive_slots(stack_recorder_state *state);
|
247
254
|
static VALUE _native_active_slot(DDTRACE_UNUSED VALUE _self, VALUE recorder_instance);
|
248
255
|
static VALUE _native_is_slot_one_mutex_locked(DDTRACE_UNUSED VALUE _self, VALUE recorder_instance);
|
249
256
|
static VALUE _native_is_slot_two_mutex_locked(DDTRACE_UNUSED VALUE _self, VALUE recorder_instance);
|
250
257
|
static VALUE test_slot_mutex_state(VALUE recorder_instance, int slot);
|
251
258
|
static ddog_Timespec system_epoch_now_timespec(void);
|
252
259
|
static VALUE _native_reset_after_fork(DDTRACE_UNUSED VALUE self, VALUE recorder_instance);
|
253
|
-
static void serializer_set_start_timestamp_for_next_profile(
|
260
|
+
static void serializer_set_start_timestamp_for_next_profile(stack_recorder_state *state, ddog_Timespec start_time);
|
254
261
|
static VALUE _native_record_endpoint(DDTRACE_UNUSED VALUE _self, VALUE recorder_instance, VALUE local_root_span_id, VALUE endpoint);
|
255
|
-
static void reset_profile_slot(profile_slot *slot, ddog_Timespec
|
262
|
+
static void reset_profile_slot(profile_slot *slot, ddog_Timespec start_timestamp);
|
256
263
|
static VALUE _native_track_object(DDTRACE_UNUSED VALUE _self, VALUE recorder_instance, VALUE new_obj, VALUE weight, VALUE alloc_class);
|
257
|
-
static VALUE _native_check_heap_hashes(DDTRACE_UNUSED VALUE _self, VALUE locations);
|
258
264
|
static VALUE _native_start_fake_slow_heap_serialization(DDTRACE_UNUSED VALUE _self, VALUE recorder_instance);
|
259
265
|
static VALUE _native_end_fake_slow_heap_serialization(DDTRACE_UNUSED VALUE _self, VALUE recorder_instance);
|
260
266
|
static VALUE _native_debug_heap_recorder(DDTRACE_UNUSED VALUE _self, VALUE recorder_instance);
|
261
|
-
static VALUE _native_gc_force_recycle(DDTRACE_UNUSED VALUE _self, VALUE obj);
|
262
|
-
static VALUE _native_has_seen_id_flag(DDTRACE_UNUSED VALUE _self, VALUE obj);
|
263
267
|
static VALUE _native_stats(DDTRACE_UNUSED VALUE self, VALUE instance);
|
264
268
|
static VALUE build_profile_stats(profile_slot *slot, long serialization_time_ns, long heap_iteration_prep_time_ns, long heap_profile_build_time_ns);
|
265
269
|
static VALUE _native_is_object_recorded(DDTRACE_UNUSED VALUE _self, VALUE recorder_instance, VALUE object_id);
|
266
270
|
static VALUE _native_heap_recorder_reset_last_update(DDTRACE_UNUSED VALUE _self, VALUE recorder_instance);
|
267
271
|
static VALUE _native_recorder_after_gc_step(DDTRACE_UNUSED VALUE _self, VALUE recorder_instance);
|
272
|
+
static VALUE _native_benchmark_intern(DDTRACE_UNUSED VALUE _self, VALUE recorder_instance, VALUE string, VALUE times, VALUE use_all);
|
273
|
+
static VALUE _native_test_managed_string_storage_produces_valid_profiles(DDTRACE_UNUSED VALUE _self);
|
268
274
|
|
269
275
|
void stack_recorder_init(VALUE profiling_module) {
|
270
276
|
VALUE stack_recorder_class = rb_define_class_under(profiling_module, "StackRecorder", rb_cObject);
|
@@ -290,20 +296,17 @@ void stack_recorder_init(VALUE profiling_module) {
|
|
290
296
|
rb_define_singleton_method(testing_module, "_native_slot_two_mutex_locked?", _native_is_slot_two_mutex_locked, 1);
|
291
297
|
rb_define_singleton_method(testing_module, "_native_record_endpoint", _native_record_endpoint, 3);
|
292
298
|
rb_define_singleton_method(testing_module, "_native_track_object", _native_track_object, 4);
|
293
|
-
rb_define_singleton_method(testing_module, "_native_check_heap_hashes", _native_check_heap_hashes, 1);
|
294
299
|
rb_define_singleton_method(testing_module, "_native_start_fake_slow_heap_serialization",
|
295
300
|
_native_start_fake_slow_heap_serialization, 1);
|
296
301
|
rb_define_singleton_method(testing_module, "_native_end_fake_slow_heap_serialization",
|
297
302
|
_native_end_fake_slow_heap_serialization, 1);
|
298
303
|
rb_define_singleton_method(testing_module, "_native_debug_heap_recorder",
|
299
304
|
_native_debug_heap_recorder, 1);
|
300
|
-
rb_define_singleton_method(testing_module, "_native_gc_force_recycle",
|
301
|
-
_native_gc_force_recycle, 1);
|
302
|
-
rb_define_singleton_method(testing_module, "_native_has_seen_id_flag",
|
303
|
-
_native_has_seen_id_flag, 1);
|
304
305
|
rb_define_singleton_method(testing_module, "_native_is_object_recorded?", _native_is_object_recorded, 2);
|
305
306
|
rb_define_singleton_method(testing_module, "_native_heap_recorder_reset_last_update", _native_heap_recorder_reset_last_update, 1);
|
306
307
|
rb_define_singleton_method(testing_module, "_native_recorder_after_gc_step", _native_recorder_after_gc_step, 1);
|
308
|
+
rb_define_singleton_method(testing_module, "_native_benchmark_intern", _native_benchmark_intern, 4);
|
309
|
+
rb_define_singleton_method(testing_module, "_native_test_managed_string_storage_produces_valid_profiles", _native_test_managed_string_storage_produces_valid_profiles, 0);
|
307
310
|
|
308
311
|
ok_symbol = ID2SYM(rb_intern_const("ok"));
|
309
312
|
error_symbol = ID2SYM(rb_intern_const("error"));
|
@@ -322,7 +325,7 @@ static const rb_data_type_t stack_recorder_typed_data = {
|
|
322
325
|
};
|
323
326
|
|
324
327
|
static VALUE _native_new(VALUE klass) {
|
325
|
-
|
328
|
+
stack_recorder_state *state = ruby_xcalloc(1, sizeof(stack_recorder_state));
|
326
329
|
|
327
330
|
// Note: Any exceptions raised from this note until the TypedData_Wrap_Struct call will lead to the state memory
|
328
331
|
// being leaked.
|
@@ -338,29 +341,32 @@ static VALUE _native_new(VALUE klass) {
|
|
338
341
|
.serialization_time_ns_min = INT64_MAX,
|
339
342
|
};
|
340
343
|
|
341
|
-
// Note: At this point, slot_one_profile
|
344
|
+
// Note: At this point, slot_one_profile/slot_two_profile/string_storage contain null pointers. Libdatadog validates pointers
|
342
345
|
// before using them so it's ok for us to go ahead and create the StackRecorder object.
|
343
346
|
|
344
|
-
// Note: As of this writing, no new Ruby objects get created and stored in the state. If that ever changes, remember
|
345
|
-
// to keep them on the stack and mark them with RB_GC_GUARD -- otherwise it's possible for a GC to run and
|
346
|
-
// since the instance representing the state does not yet exist, such objects will not get marked.
|
347
|
-
|
348
347
|
VALUE stack_recorder = TypedData_Wrap_Struct(klass, &stack_recorder_typed_data, state);
|
349
348
|
|
350
|
-
|
351
|
-
|
352
|
-
|
353
|
-
|
354
|
-
|
349
|
+
ddog_prof_ManagedStringStorageNewResult string_storage = ddog_prof_ManagedStringStorage_new();
|
350
|
+
|
351
|
+
if (string_storage.tag == DDOG_PROF_MANAGED_STRING_STORAGE_NEW_RESULT_ERR) {
|
352
|
+
rb_raise(rb_eRuntimeError, "Failed to initialize string storage: %"PRIsVALUE, get_error_details_and_drop(&string_storage.err));
|
353
|
+
}
|
355
354
|
|
356
|
-
|
355
|
+
state->string_storage = string_storage.ok;
|
356
|
+
state->label_key_allocation_class = intern_or_raise(state->string_storage, DDOG_CHARSLICE_C("allocation class"));
|
357
|
+
state->label_key_gc_gen_age = intern_or_raise(state->string_storage, DDOG_CHARSLICE_C("gc gen age"));
|
357
358
|
|
358
359
|
initialize_profiles(state, sample_types);
|
359
360
|
|
361
|
+
// NOTE: We initialize this because we want a new recorder to be operational even before #initialize runs and our
|
362
|
+
// default is everything enabled. However, if during recording initialization it turns out we don't want
|
363
|
+
// heap samples, we will free and reset heap_recorder back to NULL.
|
364
|
+
state->heap_recorder = heap_recorder_new(state->string_storage);
|
365
|
+
|
360
366
|
return stack_recorder;
|
361
367
|
}
|
362
368
|
|
363
|
-
static void initialize_slot_concurrency_control(
|
369
|
+
static void initialize_slot_concurrency_control(stack_recorder_state *state) {
|
364
370
|
state->mutex_slot_one = (pthread_mutex_t) PTHREAD_MUTEX_INITIALIZER;
|
365
371
|
state->mutex_slot_two = (pthread_mutex_t) PTHREAD_MUTEX_INITIALIZER;
|
366
372
|
|
@@ -370,34 +376,31 @@ static void initialize_slot_concurrency_control(struct stack_recorder_state *sta
|
|
370
376
|
state->active_slot = 1;
|
371
377
|
}
|
372
378
|
|
373
|
-
static void initialize_profiles(
|
379
|
+
static void initialize_profiles(stack_recorder_state *state, ddog_prof_Slice_ValueType sample_types) {
|
380
|
+
ddog_Timespec start_timestamp = system_epoch_now_timespec();
|
381
|
+
|
374
382
|
ddog_prof_Profile_NewResult slot_one_profile_result =
|
375
|
-
|
383
|
+
ddog_prof_Profile_with_string_storage(sample_types, NULL /* period is optional */, state->string_storage);
|
376
384
|
|
377
385
|
if (slot_one_profile_result.tag == DDOG_PROF_PROFILE_NEW_RESULT_ERR) {
|
378
386
|
rb_raise(rb_eRuntimeError, "Failed to initialize slot one profile: %"PRIsVALUE, get_error_details_and_drop(&slot_one_profile_result.err));
|
379
387
|
}
|
380
388
|
|
389
|
+
state->profile_slot_one = (profile_slot) { .profile = slot_one_profile_result.ok, .start_timestamp = start_timestamp };
|
390
|
+
|
381
391
|
ddog_prof_Profile_NewResult slot_two_profile_result =
|
382
|
-
|
392
|
+
ddog_prof_Profile_with_string_storage(sample_types, NULL /* period is optional */, state->string_storage);
|
383
393
|
|
384
394
|
if (slot_two_profile_result.tag == DDOG_PROF_PROFILE_NEW_RESULT_ERR) {
|
385
|
-
//
|
386
|
-
ddog_prof_Profile_drop(&slot_one_profile_result.ok);
|
387
|
-
// And now we can raise...
|
395
|
+
// Note: No need to take any special care of slot one, it'll get cleaned up by stack_recorder_typed_data_free
|
388
396
|
rb_raise(rb_eRuntimeError, "Failed to initialize slot two profile: %"PRIsVALUE, get_error_details_and_drop(&slot_two_profile_result.err));
|
389
397
|
}
|
390
398
|
|
391
|
-
state->
|
392
|
-
.profile = slot_one_profile_result.ok,
|
393
|
-
};
|
394
|
-
state->profile_slot_two = (profile_slot) {
|
395
|
-
.profile = slot_two_profile_result.ok,
|
396
|
-
};
|
399
|
+
state->profile_slot_two = (profile_slot) { .profile = slot_two_profile_result.ok, .start_timestamp = start_timestamp };
|
397
400
|
}
|
398
401
|
|
399
402
|
static void stack_recorder_typed_data_free(void *state_ptr) {
|
400
|
-
|
403
|
+
stack_recorder_state *state = (stack_recorder_state *) state_ptr;
|
401
404
|
|
402
405
|
pthread_mutex_destroy(&state->mutex_slot_one);
|
403
406
|
ddog_prof_Profile_drop(&state->profile_slot_one.profile);
|
@@ -407,6 +410,8 @@ static void stack_recorder_typed_data_free(void *state_ptr) {
|
|
407
410
|
|
408
411
|
heap_recorder_free(state->heap_recorder);
|
409
412
|
|
413
|
+
ddog_prof_ManagedStringStorage_drop(state->string_storage);
|
414
|
+
|
410
415
|
ruby_xfree(state);
|
411
416
|
}
|
412
417
|
|
@@ -432,8 +437,8 @@ static VALUE _native_initialize(int argc, VALUE *argv, DDTRACE_UNUSED VALUE _sel
|
|
432
437
|
ENFORCE_BOOLEAN(timeline_enabled);
|
433
438
|
ENFORCE_BOOLEAN(heap_clean_after_gc_enabled);
|
434
439
|
|
435
|
-
|
436
|
-
TypedData_Get_Struct(recorder_instance,
|
440
|
+
stack_recorder_state *state;
|
441
|
+
TypedData_Get_Struct(recorder_instance, stack_recorder_state, &stack_recorder_typed_data, state);
|
437
442
|
|
438
443
|
state->heap_clean_after_gc_enabled = (heap_clean_after_gc_enabled == Qtrue);
|
439
444
|
|
@@ -523,8 +528,8 @@ static VALUE _native_initialize(int argc, VALUE *argv, DDTRACE_UNUSED VALUE _sel
|
|
523
528
|
}
|
524
529
|
|
525
530
|
static VALUE _native_serialize(DDTRACE_UNUSED VALUE _self, VALUE recorder_instance) {
|
526
|
-
|
527
|
-
TypedData_Get_Struct(recorder_instance,
|
531
|
+
stack_recorder_state *state;
|
532
|
+
TypedData_Get_Struct(recorder_instance, stack_recorder_state, &stack_recorder_typed_data, state);
|
528
533
|
|
529
534
|
ddog_Timespec finish_timestamp = system_epoch_now_timespec();
|
530
535
|
// Need to do this while still holding on to the Global VM Lock; see comments on method for why
|
@@ -533,15 +538,17 @@ static VALUE _native_serialize(DDTRACE_UNUSED VALUE _self, VALUE recorder_instan
|
|
533
538
|
long heap_iteration_prep_start_time_ns = monotonic_wall_time_now_ns(DO_NOT_RAISE_ON_FAILURE);
|
534
539
|
// Prepare the iteration on heap recorder we'll be doing outside the GVL. The preparation needs to
|
535
540
|
// happen while holding on to the GVL.
|
541
|
+
// NOTE: While rare, it's possible for the GVL to be released inside this function (see comments on `heap_recorder_update`)
|
542
|
+
// and thus don't assume this is an "atomic" step -- other threads may get some running time in the meanwhile.
|
536
543
|
heap_recorder_prepare_iteration(state->heap_recorder);
|
537
544
|
long heap_iteration_prep_time_ns = monotonic_wall_time_now_ns(DO_NOT_RAISE_ON_FAILURE) - heap_iteration_prep_start_time_ns;
|
538
545
|
|
539
546
|
// We'll release the Global VM Lock while we're calling serialize, so that the Ruby VM can continue to work while this
|
540
547
|
// is pending
|
541
|
-
|
548
|
+
call_serialize_without_gvl_arguments args = {
|
542
549
|
.state = state,
|
543
550
|
.finish_timestamp = finish_timestamp,
|
544
|
-
.serialize_ran = false
|
551
|
+
.serialize_ran = false,
|
545
552
|
};
|
546
553
|
|
547
554
|
while (!args.serialize_ran) {
|
@@ -565,13 +572,9 @@ static VALUE _native_serialize(DDTRACE_UNUSED VALUE _self, VALUE recorder_instan
|
|
565
572
|
// really cover the full serialization process but it gives a more useful number since it bypasses
|
566
573
|
// the noise of acquiring GVLs and dealing with interruptions which is highly specific to runtime
|
567
574
|
// conditions and over which we really have no control about.
|
568
|
-
|
569
|
-
|
570
|
-
|
571
|
-
state->stats_lifetime.serialization_time_ns_max = long_max_of(state->stats_lifetime.serialization_time_ns_max, serialization_time_ns);
|
572
|
-
state->stats_lifetime.serialization_time_ns_min = long_min_of(state->stats_lifetime.serialization_time_ns_min, serialization_time_ns);
|
573
|
-
state->stats_lifetime.serialization_time_ns_total += serialization_time_ns;
|
574
|
-
}
|
575
|
+
state->stats_lifetime.serialization_time_ns_max = long_max_of(state->stats_lifetime.serialization_time_ns_max, args.serialize_no_gvl_time_ns);
|
576
|
+
state->stats_lifetime.serialization_time_ns_min = long_min_of(state->stats_lifetime.serialization_time_ns_min, args.serialize_no_gvl_time_ns);
|
577
|
+
state->stats_lifetime.serialization_time_ns_total += args.serialize_no_gvl_time_ns;
|
575
578
|
|
576
579
|
ddog_prof_Profile_SerializeResult serialized_profile = args.result;
|
577
580
|
|
@@ -580,20 +583,22 @@ static VALUE _native_serialize(DDTRACE_UNUSED VALUE _self, VALUE recorder_instan
|
|
580
583
|
return rb_ary_new_from_args(2, error_symbol, get_error_details_and_drop(&serialized_profile.err));
|
581
584
|
}
|
582
585
|
|
586
|
+
// Note: If we got here, the profile serialized correctly.
|
587
|
+
// Once we wrap this into a Ruby object, our `EncodedProfile` class will automatically manage memory for it and we
|
588
|
+
// can raise exceptions without worrying about leaking the profile.
|
583
589
|
state->stats_lifetime.serialization_successes++;
|
590
|
+
VALUE encoded_profile = from_ddog_prof_EncodedProfile(serialized_profile.ok);
|
584
591
|
|
585
|
-
|
586
|
-
|
587
|
-
|
588
|
-
|
589
|
-
|
590
|
-
ddog_prof_EncodedProfile_drop(&serialized_profile.ok);
|
592
|
+
ddog_prof_MaybeError result = args.advance_gen_result;
|
593
|
+
if (result.tag == DDOG_PROF_OPTION_ERROR_SOME_ERROR) {
|
594
|
+
rb_raise(rb_eRuntimeError, "Failed to advance string storage gen: %"PRIsVALUE, get_error_details_and_drop(&result.some));
|
595
|
+
}
|
591
596
|
|
592
|
-
VALUE start = ruby_time_from(
|
593
|
-
VALUE finish = ruby_time_from(
|
594
|
-
VALUE profile_stats = build_profile_stats(args.slot,
|
597
|
+
VALUE start = ruby_time_from(args.slot->start_timestamp);
|
598
|
+
VALUE finish = ruby_time_from(finish_timestamp);
|
599
|
+
VALUE profile_stats = build_profile_stats(args.slot, args.serialize_no_gvl_time_ns, heap_iteration_prep_time_ns, args.heap_profile_build_time_ns);
|
595
600
|
|
596
|
-
return rb_ary_new_from_args(2, ok_symbol, rb_ary_new_from_args(4, start, finish,
|
601
|
+
return rb_ary_new_from_args(2, ok_symbol, rb_ary_new_from_args(4, start, finish, encoded_profile, profile_stats));
|
597
602
|
}
|
598
603
|
|
599
604
|
static VALUE ruby_time_from(ddog_Timespec ddprof_time) {
|
@@ -603,8 +608,8 @@ static VALUE ruby_time_from(ddog_Timespec ddprof_time) {
|
|
603
608
|
}
|
604
609
|
|
605
610
|
void record_sample(VALUE recorder_instance, ddog_prof_Slice_Location locations, sample_values values, sample_labels labels) {
|
606
|
-
|
607
|
-
TypedData_Get_Struct(recorder_instance,
|
611
|
+
stack_recorder_state *state;
|
612
|
+
TypedData_Get_Struct(recorder_instance, stack_recorder_state, &stack_recorder_typed_data, state);
|
608
613
|
|
609
614
|
locked_profile_slot active_slot = sampler_lock_active_profile(state);
|
610
615
|
|
@@ -657,9 +662,9 @@ void record_sample(VALUE recorder_instance, ddog_prof_Slice_Location locations,
|
|
657
662
|
}
|
658
663
|
}
|
659
664
|
|
660
|
-
void track_object(VALUE recorder_instance, VALUE new_object, unsigned int sample_weight, ddog_CharSlice
|
661
|
-
|
662
|
-
TypedData_Get_Struct(recorder_instance,
|
665
|
+
void track_object(VALUE recorder_instance, VALUE new_object, unsigned int sample_weight, ddog_CharSlice alloc_class) {
|
666
|
+
stack_recorder_state *state;
|
667
|
+
TypedData_Get_Struct(recorder_instance, stack_recorder_state, &stack_recorder_typed_data, state);
|
663
668
|
// FIXME: Heap sampling currently has to be done in 2 parts because the construction of locations is happening
|
664
669
|
// very late in the allocation-sampling path (which is shared with the cpu sampling path). This can
|
665
670
|
// be fixed with some refactoring but for now this leads to a less impactful change.
|
@@ -667,8 +672,8 @@ void track_object(VALUE recorder_instance, VALUE new_object, unsigned int sample
|
|
667
672
|
}
|
668
673
|
|
669
674
|
void record_endpoint(VALUE recorder_instance, uint64_t local_root_span_id, ddog_CharSlice endpoint) {
|
670
|
-
|
671
|
-
TypedData_Get_Struct(recorder_instance,
|
675
|
+
stack_recorder_state *state;
|
676
|
+
TypedData_Get_Struct(recorder_instance, stack_recorder_state, &stack_recorder_typed_data, state);
|
672
677
|
|
673
678
|
locked_profile_slot active_slot = sampler_lock_active_profile(state);
|
674
679
|
|
@@ -682,8 +687,8 @@ void record_endpoint(VALUE recorder_instance, uint64_t local_root_span_id, ddog_
|
|
682
687
|
}
|
683
688
|
|
684
689
|
void recorder_after_gc_step(VALUE recorder_instance) {
|
685
|
-
|
686
|
-
TypedData_Get_Struct(recorder_instance,
|
690
|
+
stack_recorder_state *state;
|
691
|
+
TypedData_Get_Struct(recorder_instance, stack_recorder_state, &stack_recorder_typed_data, state);
|
687
692
|
|
688
693
|
if (state->heap_clean_after_gc_enabled) heap_recorder_update_young_objects(state->heap_recorder);
|
689
694
|
}
|
@@ -693,7 +698,7 @@ void recorder_after_gc_step(VALUE recorder_instance) {
|
|
693
698
|
// Heap recorder iteration context allows us access to stack recorder state and profile being serialized
|
694
699
|
// during iteration of heap recorder live objects.
|
695
700
|
typedef struct heap_recorder_iteration_context {
|
696
|
-
|
701
|
+
stack_recorder_state *state;
|
697
702
|
profile_slot *slot;
|
698
703
|
|
699
704
|
bool error;
|
@@ -714,18 +719,15 @@ static bool add_heap_sample_to_active_profile_without_gvl(heap_recorder_iteratio
|
|
714
719
|
ddog_prof_Label labels[2];
|
715
720
|
size_t label_offset = 0;
|
716
721
|
|
717
|
-
if (object_data->class
|
722
|
+
if (object_data->class.value > 0) {
|
718
723
|
labels[label_offset++] = (ddog_prof_Label) {
|
719
|
-
.
|
720
|
-
.
|
721
|
-
.ptr = object_data->class,
|
722
|
-
.len = strlen(object_data->class),
|
723
|
-
},
|
724
|
+
.key_id = context->state->label_key_allocation_class,
|
725
|
+
.str_id = object_data->class,
|
724
726
|
.num = 0, // This shouldn't be needed but the tracer-2.7 docker image ships a buggy gcc that complains about this
|
725
727
|
};
|
726
728
|
}
|
727
729
|
labels[label_offset++] = (ddog_prof_Label) {
|
728
|
-
.
|
730
|
+
.key_id = context->state->label_key_gc_gen_age,
|
729
731
|
.num = object_data->gen_age,
|
730
732
|
};
|
731
733
|
|
@@ -755,7 +757,7 @@ static bool add_heap_sample_to_active_profile_without_gvl(heap_recorder_iteratio
|
|
755
757
|
return true;
|
756
758
|
}
|
757
759
|
|
758
|
-
static void build_heap_profile_without_gvl(
|
760
|
+
static void build_heap_profile_without_gvl(stack_recorder_state *state, profile_slot *slot) {
|
759
761
|
heap_recorder_iteration_context iteration_context = {
|
760
762
|
.state = state,
|
761
763
|
.slot = slot,
|
@@ -776,12 +778,11 @@ static void build_heap_profile_without_gvl(struct stack_recorder_state *state, p
|
|
776
778
|
}
|
777
779
|
|
778
780
|
static void *call_serialize_without_gvl(void *call_args) {
|
779
|
-
|
781
|
+
call_serialize_without_gvl_arguments *args = (call_serialize_without_gvl_arguments *) call_args;
|
780
782
|
|
781
783
|
long serialize_no_gvl_start_time_ns = monotonic_wall_time_now_ns(DO_NOT_RAISE_ON_FAILURE);
|
782
784
|
|
783
785
|
profile_slot *slot_now_inactive = serializer_flip_active_and_inactive_slots(args->state);
|
784
|
-
|
785
786
|
args->slot = slot_now_inactive;
|
786
787
|
|
787
788
|
// Now that we have the inactive profile with all but heap samples, lets fill it with heap data
|
@@ -790,19 +791,20 @@ static void *call_serialize_without_gvl(void *call_args) {
|
|
790
791
|
args->heap_profile_build_time_ns = monotonic_wall_time_now_ns(DO_NOT_RAISE_ON_FAILURE) - serialize_no_gvl_start_time_ns;
|
791
792
|
|
792
793
|
// Note: The profile gets reset by the serialize call
|
793
|
-
args->result = ddog_prof_Profile_serialize(&args->slot->profile, &args->
|
794
|
+
args->result = ddog_prof_Profile_serialize(&args->slot->profile, &args->slot->start_timestamp, &args->finish_timestamp);
|
795
|
+
args->advance_gen_result = ddog_prof_ManagedStringStorage_advance_gen(args->state->string_storage);
|
794
796
|
args->serialize_ran = true;
|
795
|
-
args->serialize_no_gvl_time_ns = monotonic_wall_time_now_ns(DO_NOT_RAISE_ON_FAILURE) - serialize_no_gvl_start_time_ns;
|
797
|
+
args->serialize_no_gvl_time_ns = long_max_of(0, monotonic_wall_time_now_ns(DO_NOT_RAISE_ON_FAILURE) - serialize_no_gvl_start_time_ns);
|
796
798
|
|
797
799
|
return NULL; // Unused
|
798
800
|
}
|
799
801
|
|
800
802
|
VALUE enforce_recorder_instance(VALUE object) {
|
801
|
-
|
803
|
+
ENFORCE_TYPED_DATA(object, &stack_recorder_typed_data);
|
802
804
|
return object;
|
803
805
|
}
|
804
806
|
|
805
|
-
static locked_profile_slot sampler_lock_active_profile(
|
807
|
+
static locked_profile_slot sampler_lock_active_profile(stack_recorder_state *state) {
|
806
808
|
int error;
|
807
809
|
|
808
810
|
for (int attempts = 0; attempts < 2; attempts++) {
|
@@ -829,7 +831,7 @@ static void sampler_unlock_active_profile(locked_profile_slot active_slot) {
|
|
829
831
|
ENFORCE_SUCCESS_GVL(pthread_mutex_unlock(active_slot.mutex));
|
830
832
|
}
|
831
833
|
|
832
|
-
static profile_slot* serializer_flip_active_and_inactive_slots(
|
834
|
+
static profile_slot* serializer_flip_active_and_inactive_slots(stack_recorder_state *state) {
|
833
835
|
int previously_active_slot = state->active_slot;
|
834
836
|
|
835
837
|
if (previously_active_slot != 1 && previously_active_slot != 2) {
|
@@ -855,8 +857,8 @@ static profile_slot* serializer_flip_active_and_inactive_slots(struct stack_reco
|
|
855
857
|
// This method exists only to enable testing Datadog::Profiling::StackRecorder behavior using RSpec.
|
856
858
|
// It SHOULD NOT be used for other purposes.
|
857
859
|
static VALUE _native_active_slot(DDTRACE_UNUSED VALUE _self, VALUE recorder_instance) {
|
858
|
-
|
859
|
-
TypedData_Get_Struct(recorder_instance,
|
860
|
+
stack_recorder_state *state;
|
861
|
+
TypedData_Get_Struct(recorder_instance, stack_recorder_state, &stack_recorder_typed_data, state);
|
860
862
|
|
861
863
|
return INT2NUM(state->active_slot);
|
862
864
|
}
|
@@ -870,8 +872,8 @@ static VALUE _native_is_slot_one_mutex_locked(DDTRACE_UNUSED VALUE _self, VALUE
|
|
870
872
|
static VALUE _native_is_slot_two_mutex_locked(DDTRACE_UNUSED VALUE _self, VALUE recorder_instance) { return test_slot_mutex_state(recorder_instance, 2); }
|
871
873
|
|
872
874
|
static VALUE test_slot_mutex_state(VALUE recorder_instance, int slot) {
|
873
|
-
|
874
|
-
TypedData_Get_Struct(recorder_instance,
|
875
|
+
stack_recorder_state *state;
|
876
|
+
TypedData_Get_Struct(recorder_instance, stack_recorder_state, &stack_recorder_typed_data, state);
|
875
877
|
|
876
878
|
pthread_mutex_t *slot_mutex = (slot == 1) ? &state->mutex_slot_one : &state->mutex_slot_two;
|
877
879
|
|
@@ -901,15 +903,15 @@ static ddog_Timespec system_epoch_now_timespec(void) {
|
|
901
903
|
// Assumption: This method gets called BEFORE restarting profiling -- e.g. there are no components attempting to
|
902
904
|
// trigger samples at the same time.
|
903
905
|
static VALUE _native_reset_after_fork(DDTRACE_UNUSED VALUE self, VALUE recorder_instance) {
|
904
|
-
|
905
|
-
TypedData_Get_Struct(recorder_instance,
|
906
|
+
stack_recorder_state *state;
|
907
|
+
TypedData_Get_Struct(recorder_instance, stack_recorder_state, &stack_recorder_typed_data, state);
|
906
908
|
|
907
909
|
// In case the fork happened halfway through `serializer_flip_active_and_inactive_slots` execution and the
|
908
910
|
// resulting state is inconsistent, we make sure to reset it back to the initial state.
|
909
911
|
initialize_slot_concurrency_control(state);
|
910
|
-
|
911
|
-
reset_profile_slot(&state->profile_slot_one,
|
912
|
-
reset_profile_slot(&state->profile_slot_two,
|
912
|
+
ddog_Timespec start_timestamp = system_epoch_now_timespec();
|
913
|
+
reset_profile_slot(&state->profile_slot_one, start_timestamp);
|
914
|
+
reset_profile_slot(&state->profile_slot_two, start_timestamp);
|
913
915
|
|
914
916
|
heap_recorder_after_fork(state->heap_recorder);
|
915
917
|
|
@@ -918,10 +920,10 @@ static VALUE _native_reset_after_fork(DDTRACE_UNUSED VALUE self, VALUE recorder_
|
|
918
920
|
|
919
921
|
// Assumption 1: This method is called with the GVL being held, because `ddog_prof_Profile_reset` mutates the profile and must
|
920
922
|
// not be interrupted part-way through by a VM fork.
|
921
|
-
static void serializer_set_start_timestamp_for_next_profile(
|
923
|
+
static void serializer_set_start_timestamp_for_next_profile(stack_recorder_state *state, ddog_Timespec start_time) {
|
922
924
|
// Before making this profile active, we reset it so that it uses the correct start_time for its start
|
923
925
|
profile_slot *next_profile_slot = (state->active_slot == 1) ? &state->profile_slot_two : &state->profile_slot_one;
|
924
|
-
reset_profile_slot(next_profile_slot,
|
926
|
+
reset_profile_slot(next_profile_slot, start_time);
|
925
927
|
}
|
926
928
|
|
927
929
|
static VALUE _native_record_endpoint(DDTRACE_UNUSED VALUE _self, VALUE recorder_instance, VALUE local_root_span_id, VALUE endpoint) {
|
@@ -932,54 +934,24 @@ static VALUE _native_record_endpoint(DDTRACE_UNUSED VALUE _self, VALUE recorder_
|
|
932
934
|
|
933
935
|
static VALUE _native_track_object(DDTRACE_UNUSED VALUE _self, VALUE recorder_instance, VALUE new_obj, VALUE weight, VALUE alloc_class) {
|
934
936
|
ENFORCE_TYPE(weight, T_FIXNUM);
|
935
|
-
|
936
|
-
track_object(recorder_instance, new_obj, NUM2UINT(weight), &alloc_class_slice);
|
937
|
+
track_object(recorder_instance, new_obj, NUM2UINT(weight), char_slice_from_ruby_string(alloc_class));
|
937
938
|
return Qtrue;
|
938
939
|
}
|
939
940
|
|
940
|
-
static
|
941
|
-
|
942
|
-
size_t locations_len = rb_array_len(locations);
|
943
|
-
ddog_prof_Location locations_arr[locations_len];
|
944
|
-
for (size_t i = 0; i < locations_len; i++) {
|
945
|
-
VALUE location = rb_ary_entry(locations, i);
|
946
|
-
ENFORCE_TYPE(location, T_ARRAY);
|
947
|
-
VALUE name = rb_ary_entry(location, 0);
|
948
|
-
VALUE filename = rb_ary_entry(location, 1);
|
949
|
-
VALUE line = rb_ary_entry(location, 2);
|
950
|
-
ENFORCE_TYPE(name, T_STRING);
|
951
|
-
ENFORCE_TYPE(filename, T_STRING);
|
952
|
-
ENFORCE_TYPE(line, T_FIXNUM);
|
953
|
-
locations_arr[i] = (ddog_prof_Location) {
|
954
|
-
.line = line,
|
955
|
-
.function = (ddog_prof_Function) {
|
956
|
-
.name = char_slice_from_ruby_string(name),
|
957
|
-
.filename = char_slice_from_ruby_string(filename),
|
958
|
-
}
|
959
|
-
};
|
960
|
-
}
|
961
|
-
ddog_prof_Slice_Location ddog_locations = {
|
962
|
-
.len = locations_len,
|
963
|
-
.ptr = locations_arr,
|
964
|
-
};
|
965
|
-
heap_recorder_testonly_assert_hash_matches(ddog_locations);
|
966
|
-
|
967
|
-
return Qnil;
|
968
|
-
}
|
969
|
-
|
970
|
-
static void reset_profile_slot(profile_slot *slot, ddog_Timespec *start_time /* Can be null */) {
|
971
|
-
ddog_prof_Profile_Result reset_result = ddog_prof_Profile_reset(&slot->profile, start_time);
|
941
|
+
static void reset_profile_slot(profile_slot *slot, ddog_Timespec start_timestamp) {
|
942
|
+
ddog_prof_Profile_Result reset_result = ddog_prof_Profile_reset(&slot->profile);
|
972
943
|
if (reset_result.tag == DDOG_PROF_PROFILE_RESULT_ERR) {
|
973
944
|
rb_raise(rb_eRuntimeError, "Failed to reset profile: %"PRIsVALUE, get_error_details_and_drop(&reset_result.err));
|
974
945
|
}
|
946
|
+
slot->start_timestamp = start_timestamp;
|
975
947
|
slot->stats = (stats_slot) {};
|
976
948
|
}
|
977
949
|
|
978
950
|
// This method exists only to enable testing Datadog::Profiling::StackRecorder behavior using RSpec.
|
979
951
|
// It SHOULD NOT be used for other purposes.
|
980
952
|
static VALUE _native_start_fake_slow_heap_serialization(DDTRACE_UNUSED VALUE _self, VALUE recorder_instance) {
|
981
|
-
|
982
|
-
TypedData_Get_Struct(recorder_instance,
|
953
|
+
stack_recorder_state *state;
|
954
|
+
TypedData_Get_Struct(recorder_instance, stack_recorder_state, &stack_recorder_typed_data, state);
|
983
955
|
|
984
956
|
heap_recorder_prepare_iteration(state->heap_recorder);
|
985
957
|
|
@@ -989,8 +961,8 @@ static VALUE _native_start_fake_slow_heap_serialization(DDTRACE_UNUSED VALUE _se
|
|
989
961
|
// This method exists only to enable testing Datadog::Profiling::StackRecorder behavior using RSpec.
|
990
962
|
// It SHOULD NOT be used for other purposes.
|
991
963
|
static VALUE _native_end_fake_slow_heap_serialization(DDTRACE_UNUSED VALUE _self, VALUE recorder_instance) {
|
992
|
-
|
993
|
-
TypedData_Get_Struct(recorder_instance,
|
964
|
+
stack_recorder_state *state;
|
965
|
+
TypedData_Get_Struct(recorder_instance, stack_recorder_state, &stack_recorder_typed_data, state);
|
994
966
|
|
995
967
|
heap_recorder_finish_iteration(state->heap_recorder);
|
996
968
|
|
@@ -1000,43 +972,15 @@ static VALUE _native_end_fake_slow_heap_serialization(DDTRACE_UNUSED VALUE _self
|
|
1000
972
|
// This method exists only to enable testing Datadog::Profiling::StackRecorder behavior using RSpec.
|
1001
973
|
// It SHOULD NOT be used for other purposes.
|
1002
974
|
static VALUE _native_debug_heap_recorder(DDTRACE_UNUSED VALUE _self, VALUE recorder_instance) {
|
1003
|
-
|
1004
|
-
TypedData_Get_Struct(recorder_instance,
|
975
|
+
stack_recorder_state *state;
|
976
|
+
TypedData_Get_Struct(recorder_instance, stack_recorder_state, &stack_recorder_typed_data, state);
|
1005
977
|
|
1006
978
|
return heap_recorder_testonly_debug(state->heap_recorder);
|
1007
979
|
}
|
1008
980
|
|
1009
|
-
#pragma GCC diagnostic push
|
1010
|
-
// rb_gc_force_recycle was deprecated in latest versions of Ruby and is a noop.
|
1011
|
-
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
|
1012
|
-
#pragma GCC diagnostic ignored "-Wunused-parameter"
|
1013
|
-
// This method exists only to enable testing Datadog::Profiling::StackRecorder behavior using RSpec.
|
1014
|
-
// It SHOULD NOT be used for other purposes.
|
1015
|
-
static VALUE _native_gc_force_recycle(DDTRACE_UNUSED VALUE _self, VALUE obj) {
|
1016
|
-
#ifdef HAVE_WORKING_RB_GC_FORCE_RECYCLE
|
1017
|
-
rb_gc_force_recycle(obj);
|
1018
|
-
#endif
|
1019
|
-
return Qnil;
|
1020
|
-
}
|
1021
|
-
#pragma GCC diagnostic pop
|
1022
|
-
|
1023
|
-
// This method exists only to enable testing Datadog::Profiling::StackRecorder behavior using RSpec.
|
1024
|
-
// It SHOULD NOT be used for other purposes.
|
1025
|
-
static VALUE _native_has_seen_id_flag(DDTRACE_UNUSED VALUE _self, VALUE obj) {
|
1026
|
-
#ifndef NO_SEEN_OBJ_ID_FLAG
|
1027
|
-
if (RB_FL_TEST(obj, RUBY_FL_SEEN_OBJ_ID)) {
|
1028
|
-
return Qtrue;
|
1029
|
-
} else {
|
1030
|
-
return Qfalse;
|
1031
|
-
}
|
1032
|
-
#else
|
1033
|
-
return Qfalse;
|
1034
|
-
#endif
|
1035
|
-
}
|
1036
|
-
|
1037
981
|
static VALUE _native_stats(DDTRACE_UNUSED VALUE self, VALUE recorder_instance) {
|
1038
|
-
|
1039
|
-
TypedData_Get_Struct(recorder_instance,
|
982
|
+
stack_recorder_state *state;
|
983
|
+
TypedData_Get_Struct(recorder_instance, stack_recorder_state, &stack_recorder_typed_data, state);
|
1040
984
|
|
1041
985
|
uint64_t total_serializations = state->stats_lifetime.serialization_successes + state->stats_lifetime.serialization_failures;
|
1042
986
|
|
@@ -1074,15 +1018,15 @@ static VALUE build_profile_stats(profile_slot *slot, long serialization_time_ns,
|
|
1074
1018
|
static VALUE _native_is_object_recorded(DDTRACE_UNUSED VALUE _self, VALUE recorder_instance, VALUE obj_id) {
|
1075
1019
|
ENFORCE_TYPE(obj_id, T_FIXNUM);
|
1076
1020
|
|
1077
|
-
|
1078
|
-
TypedData_Get_Struct(recorder_instance,
|
1021
|
+
stack_recorder_state *state;
|
1022
|
+
TypedData_Get_Struct(recorder_instance, stack_recorder_state, &stack_recorder_typed_data, state);
|
1079
1023
|
|
1080
1024
|
return heap_recorder_testonly_is_object_recorded(state->heap_recorder, obj_id);
|
1081
1025
|
}
|
1082
1026
|
|
1083
1027
|
static VALUE _native_heap_recorder_reset_last_update(DDTRACE_UNUSED VALUE _self, VALUE recorder_instance) {
|
1084
|
-
|
1085
|
-
TypedData_Get_Struct(recorder_instance,
|
1028
|
+
stack_recorder_state *state;
|
1029
|
+
TypedData_Get_Struct(recorder_instance, stack_recorder_state, &stack_recorder_typed_data, state);
|
1086
1030
|
|
1087
1031
|
heap_recorder_testonly_reset_last_update(state->heap_recorder);
|
1088
1032
|
|
@@ -1093,3 +1037,109 @@ static VALUE _native_recorder_after_gc_step(DDTRACE_UNUSED VALUE _self, VALUE re
|
|
1093
1037
|
recorder_after_gc_step(recorder_instance);
|
1094
1038
|
return Qtrue;
|
1095
1039
|
}
|
1040
|
+
|
1041
|
+
static VALUE _native_benchmark_intern(DDTRACE_UNUSED VALUE _self, VALUE recorder_instance, VALUE string, VALUE times, VALUE use_all) {
|
1042
|
+
ENFORCE_TYPE(string, T_STRING);
|
1043
|
+
ENFORCE_TYPE(times, T_FIXNUM);
|
1044
|
+
ENFORCE_BOOLEAN(use_all);
|
1045
|
+
|
1046
|
+
stack_recorder_state *state;
|
1047
|
+
TypedData_Get_Struct(recorder_instance, stack_recorder_state, &stack_recorder_typed_data, state);
|
1048
|
+
|
1049
|
+
heap_recorder_testonly_benchmark_intern(state->heap_recorder, char_slice_from_ruby_string(string), FIX2INT(times), use_all == Qtrue);
|
1050
|
+
|
1051
|
+
return Qtrue;
|
1052
|
+
}
|
1053
|
+
|
1054
|
+
// See comments in rspec test for details on what we're testing here.
|
1055
|
+
static VALUE _native_test_managed_string_storage_produces_valid_profiles(DDTRACE_UNUSED VALUE _self) {
|
1056
|
+
ddog_prof_ManagedStringStorageNewResult string_storage = ddog_prof_ManagedStringStorage_new();
|
1057
|
+
|
1058
|
+
if (string_storage.tag == DDOG_PROF_MANAGED_STRING_STORAGE_NEW_RESULT_ERR) {
|
1059
|
+
rb_raise(rb_eRuntimeError, "Failed to initialize string storage: %"PRIsVALUE, get_error_details_and_drop(&string_storage.err));
|
1060
|
+
}
|
1061
|
+
|
1062
|
+
ddog_prof_Slice_ValueType sample_types = {.ptr = all_value_types, .len = ALL_VALUE_TYPES_COUNT};
|
1063
|
+
ddog_prof_Profile_NewResult profile = ddog_prof_Profile_with_string_storage(sample_types, NULL, string_storage.ok);
|
1064
|
+
|
1065
|
+
if (profile.tag == DDOG_PROF_PROFILE_NEW_RESULT_ERR) {
|
1066
|
+
rb_raise(rb_eRuntimeError, "Failed to initialize profile: %"PRIsVALUE, get_error_details_and_drop(&profile.err));
|
1067
|
+
}
|
1068
|
+
|
1069
|
+
ddog_prof_ManagedStringId hello = intern_or_raise(string_storage.ok, DDOG_CHARSLICE_C("hello"));
|
1070
|
+
ddog_prof_ManagedStringId world = intern_or_raise(string_storage.ok, DDOG_CHARSLICE_C("world"));
|
1071
|
+
ddog_prof_ManagedStringId key = intern_or_raise(string_storage.ok, DDOG_CHARSLICE_C("key"));
|
1072
|
+
|
1073
|
+
int64_t metric_values[] = {1, 2, 3, 4, 5, 6, 7, 8};
|
1074
|
+
ddog_prof_Label labels[] = {{.key_id = key, .str_id = key}};
|
1075
|
+
|
1076
|
+
ddog_prof_Location locations[] = {
|
1077
|
+
(ddog_prof_Location) {
|
1078
|
+
.mapping = {.filename = DDOG_CHARSLICE_C(""), .build_id = DDOG_CHARSLICE_C(""), .build_id_id = {}},
|
1079
|
+
.function = {
|
1080
|
+
.name = DDOG_CHARSLICE_C(""),
|
1081
|
+
.name_id = hello,
|
1082
|
+
.filename = DDOG_CHARSLICE_C(""),
|
1083
|
+
.filename_id = world,
|
1084
|
+
},
|
1085
|
+
.line = 1,
|
1086
|
+
}
|
1087
|
+
};
|
1088
|
+
|
1089
|
+
ddog_prof_Profile_Result result = ddog_prof_Profile_add(
|
1090
|
+
&profile.ok,
|
1091
|
+
(ddog_prof_Sample) {
|
1092
|
+
.locations = (ddog_prof_Slice_Location) { .ptr = locations, .len = 1},
|
1093
|
+
.values = (ddog_Slice_I64) {.ptr = metric_values, .len = 8},
|
1094
|
+
.labels = (ddog_prof_Slice_Label) { .ptr = labels, .len = 1 }
|
1095
|
+
},
|
1096
|
+
0
|
1097
|
+
);
|
1098
|
+
|
1099
|
+
if (result.tag == DDOG_PROF_PROFILE_RESULT_ERR) {
|
1100
|
+
rb_raise(rb_eArgError, "Failed to record sample: %"PRIsVALUE, get_error_details_and_drop(&result.err));
|
1101
|
+
}
|
1102
|
+
|
1103
|
+
ddog_Timespec finish_timestamp = system_epoch_now_timespec();
|
1104
|
+
ddog_Timespec start_timestamp = {.seconds = finish_timestamp.seconds - 60};
|
1105
|
+
ddog_prof_Profile_SerializeResult serialize_result = ddog_prof_Profile_serialize(&profile.ok, &start_timestamp, &finish_timestamp);
|
1106
|
+
|
1107
|
+
if (serialize_result.tag == DDOG_PROF_PROFILE_SERIALIZE_RESULT_ERR) {
|
1108
|
+
rb_raise(rb_eRuntimeError, "Failed to serialize: %"PRIsVALUE, get_error_details_and_drop(&serialize_result.err));
|
1109
|
+
}
|
1110
|
+
|
1111
|
+
ddog_prof_MaybeError advance_gen_result = ddog_prof_ManagedStringStorage_advance_gen(string_storage.ok);
|
1112
|
+
|
1113
|
+
if (advance_gen_result.tag == DDOG_PROF_OPTION_ERROR_SOME_ERROR) {
|
1114
|
+
rb_raise(rb_eRuntimeError, "Failed to advance string storage gen: %"PRIsVALUE, get_error_details_and_drop(&advance_gen_result.some));
|
1115
|
+
}
|
1116
|
+
|
1117
|
+
VALUE encoded_pprof_1 = from_ddog_prof_EncodedProfile(serialize_result.ok);
|
1118
|
+
|
1119
|
+
result = ddog_prof_Profile_add(
|
1120
|
+
&profile.ok,
|
1121
|
+
(ddog_prof_Sample) {
|
1122
|
+
.locations = (ddog_prof_Slice_Location) { .ptr = locations, .len = 1},
|
1123
|
+
.values = (ddog_Slice_I64) {.ptr = metric_values, .len = 8},
|
1124
|
+
.labels = (ddog_prof_Slice_Label) { .ptr = labels, .len = 1 }
|
1125
|
+
},
|
1126
|
+
0
|
1127
|
+
);
|
1128
|
+
|
1129
|
+
if (result.tag == DDOG_PROF_PROFILE_RESULT_ERR) {
|
1130
|
+
rb_raise(rb_eArgError, "Failed to record sample: %"PRIsVALUE, get_error_details_and_drop(&result.err));
|
1131
|
+
}
|
1132
|
+
|
1133
|
+
serialize_result = ddog_prof_Profile_serialize(&profile.ok, &start_timestamp, &finish_timestamp);
|
1134
|
+
|
1135
|
+
if (serialize_result.tag == DDOG_PROF_PROFILE_SERIALIZE_RESULT_ERR) {
|
1136
|
+
rb_raise(rb_eArgError, "Failed to serialize: %"PRIsVALUE, get_error_details_and_drop(&serialize_result.err));
|
1137
|
+
}
|
1138
|
+
|
1139
|
+
VALUE encoded_pprof_2 = from_ddog_prof_EncodedProfile(serialize_result.ok);
|
1140
|
+
|
1141
|
+
ddog_prof_Profile_drop(&profile.ok);
|
1142
|
+
ddog_prof_ManagedStringStorage_drop(string_storage.ok);
|
1143
|
+
|
1144
|
+
return rb_ary_new_from_args(2, encoded_pprof_1, encoded_pprof_2);
|
1145
|
+
}
|