datadog 2.12.1 → 2.19.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 +243 -2
- data/ext/datadog_profiling_native_extension/collectors_cpu_and_wall_time_worker.c +63 -56
- data/ext/datadog_profiling_native_extension/collectors_stack.c +263 -76
- data/ext/datadog_profiling_native_extension/collectors_stack.h +20 -3
- data/ext/datadog_profiling_native_extension/collectors_thread_context.c +78 -26
- 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 +10 -0
- data/ext/datadog_profiling_native_extension/heap_recorder.c +247 -364
- data/ext/datadog_profiling_native_extension/heap_recorder.h +4 -6
- data/ext/datadog_profiling_native_extension/http_transport.c +60 -94
- 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 +41 -21
- data/ext/datadog_profiling_native_extension/private_vm_api_access.h +6 -4
- data/ext/datadog_profiling_native_extension/profiling.c +2 -0
- data/ext/datadog_profiling_native_extension/ruby_helpers.c +1 -13
- data/ext/datadog_profiling_native_extension/ruby_helpers.h +3 -11
- data/ext/datadog_profiling_native_extension/stack_recorder.c +173 -76
- data/ext/libdatadog_api/crashtracker.c +11 -12
- 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 +24 -2
- 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 +71 -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 +257 -85
- data/lib/datadog/appsec/assets/waf_rules/strict.json +10 -78
- data/lib/datadog/appsec/autoload.rb +1 -1
- data/lib/datadog/appsec/component.rb +46 -61
- data/lib/datadog/appsec/compressed_json.rb +40 -0
- data/lib/datadog/appsec/configuration/settings.rb +153 -30
- data/lib/datadog/appsec/context.rb +7 -7
- data/lib/datadog/appsec/contrib/active_record/instrumentation.rb +10 -12
- data/lib/datadog/appsec/contrib/active_record/integration.rb +2 -2
- data/lib/datadog/appsec/contrib/active_record/patcher.rb +22 -22
- data/lib/datadog/appsec/contrib/auto_instrument.rb +1 -1
- data/lib/datadog/appsec/contrib/devise/configuration.rb +7 -31
- 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 +34 -23
- 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} +2 -2
- data/lib/datadog/appsec/contrib/devise/tracking_middleware.rb +106 -0
- data/lib/datadog/appsec/contrib/excon/integration.rb +1 -1
- data/lib/datadog/appsec/contrib/excon/ssrf_detection_middleware.rb +9 -10
- data/lib/datadog/appsec/contrib/faraday/integration.rb +1 -1
- data/lib/datadog/appsec/contrib/faraday/ssrf_detection_middleware.rb +8 -9
- data/lib/datadog/appsec/contrib/graphql/gateway/watcher.rb +8 -9
- data/lib/datadog/appsec/contrib/graphql/integration.rb +1 -1
- data/lib/datadog/appsec/contrib/rack/ext.rb +34 -0
- data/lib/datadog/appsec/contrib/rack/gateway/watcher.rb +49 -32
- data/lib/datadog/appsec/contrib/rack/integration.rb +1 -1
- data/lib/datadog/appsec/contrib/rack/request_middleware.rb +42 -30
- data/lib/datadog/appsec/contrib/rails/gateway/watcher.rb +11 -13
- data/lib/datadog/appsec/contrib/rails/integration.rb +1 -1
- data/lib/datadog/appsec/contrib/rails/patcher.rb +21 -21
- data/lib/datadog/appsec/contrib/rest_client/integration.rb +1 -1
- data/lib/datadog/appsec/contrib/rest_client/request_ssrf_detection_patch.rb +10 -11
- data/lib/datadog/appsec/contrib/sinatra/gateway/watcher.rb +17 -23
- data/lib/datadog/appsec/contrib/sinatra/integration.rb +1 -1
- data/lib/datadog/appsec/event.rb +96 -135
- data/lib/datadog/appsec/ext.rb +4 -2
- 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/telemetry.rb +1 -1
- data/lib/datadog/appsec/monitor/gateway/watcher.rb +49 -14
- data/lib/datadog/appsec/processor/rule_loader.rb +30 -33
- data/lib/datadog/appsec/remote.rb +31 -59
- data/lib/datadog/appsec/response.rb +6 -6
- data/lib/datadog/appsec/security_engine/engine.rb +194 -0
- data/lib/datadog/appsec/security_engine/runner.rb +13 -14
- data/lib/datadog/appsec/security_event.rb +39 -0
- data/lib/datadog/appsec/utils.rb +0 -2
- data/lib/datadog/appsec.rb +5 -8
- 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 -46
- data/lib/datadog/core/configuration/agentless_settings_resolver.rb +176 -0
- data/lib/datadog/core/configuration/components.rb +48 -31
- data/lib/datadog/core/configuration/components_state.rb +23 -0
- data/lib/datadog/core/configuration/ext.rb +4 -0
- data/lib/datadog/core/configuration/option.rb +81 -45
- data/lib/datadog/core/configuration/option_definition.rb +4 -4
- data/lib/datadog/core/configuration/options.rb +3 -3
- data/lib/datadog/core/configuration/settings.rb +109 -44
- data/lib/datadog/core/configuration/stable_config.rb +22 -0
- data/lib/datadog/core/configuration.rb +40 -16
- data/lib/datadog/core/crashtracking/component.rb +3 -10
- 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 +1 -1
- data/lib/datadog/core/environment/agent_info.rb +4 -3
- 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 +20 -21
- 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.rb +40 -32
- data/lib/datadog/core/remote/component.rb +6 -9
- 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/client.rb +5 -4
- data/lib/datadog/core/remote/transport/http/config.rb +27 -37
- data/lib/datadog/core/remote/transport/http/negotiation.rb +7 -33
- data/lib/datadog/core/remote/transport/http.rb +22 -57
- data/lib/datadog/core/remote/transport/negotiation.rb +4 -3
- 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 +81 -52
- 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 +287 -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 -472
- 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 +11 -5
- data/lib/datadog/core/telemetry/metric.rb +8 -8
- 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 +90 -24
- 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/api/instance.rb +17 -0
- data/lib/datadog/core/transport/http/api/spec.rb +17 -0
- data/lib/datadog/core/transport/http/builder.rb +19 -17
- data/lib/datadog/core/transport/http/env.rb +8 -0
- data/lib/datadog/core/transport/http.rb +39 -2
- 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/boot.rb +34 -0
- data/lib/datadog/di/component.rb +0 -2
- data/lib/datadog/di/instrumenter.rb +48 -5
- data/lib/datadog/di/probe_notification_builder.rb +38 -43
- data/lib/datadog/di/probe_notifier_worker.rb +25 -17
- data/lib/datadog/di/remote.rb +2 -0
- data/lib/datadog/di/serializer.rb +10 -2
- data/lib/datadog/di/transport/diagnostics.rb +4 -3
- data/lib/datadog/di/transport/http/api.rb +2 -12
- data/lib/datadog/di/transport/http/client.rb +4 -3
- data/lib/datadog/di/transport/http/diagnostics.rb +7 -34
- data/lib/datadog/di/transport/http/input.rb +18 -35
- data/lib/datadog/di/transport/http.rb +14 -62
- data/lib/datadog/di/transport/input.rb +14 -5
- data/lib/datadog/di/utils.rb +5 -0
- data/lib/datadog/di.rb +0 -33
- 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/v2.rb +195 -0
- data/lib/datadog/kit/appsec/events.rb +12 -0
- data/lib/datadog/kit/identity.rb +5 -1
- 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 +6 -0
- data/lib/datadog/profiling/collectors/idle_sampling_helper.rb +1 -0
- data/lib/datadog/profiling/collectors/info.rb +44 -0
- data/lib/datadog/profiling/collectors/thread_context.rb +17 -2
- data/lib/datadog/profiling/component.rb +8 -9
- data/lib/datadog/profiling/encoded_profile.rb +11 -0
- data/lib/datadog/profiling/exporter.rb +12 -7
- data/lib/datadog/profiling/ext.rb +0 -14
- data/lib/datadog/profiling/flush.rb +5 -8
- data/lib/datadog/profiling/http_transport.rb +7 -61
- data/lib/datadog/profiling/profiler.rb +2 -0
- data/lib/datadog/profiling/scheduler.rb +10 -2
- data/lib/datadog/profiling/sequence_tracker.rb +44 -0
- data/lib/datadog/profiling/stack_recorder.rb +9 -9
- data/lib/datadog/profiling/tag_builder.rb +7 -41
- data/lib/datadog/profiling/tasks/setup.rb +2 -0
- data/lib/datadog/profiling.rb +7 -2
- data/lib/datadog/single_step_instrument.rb +9 -0
- data/lib/datadog/tracing/analytics.rb +1 -1
- data/lib/datadog/tracing/component.rb +15 -12
- data/lib/datadog/tracing/configuration/ext.rb +7 -1
- data/lib/datadog/tracing/configuration/settings.rb +18 -2
- data/lib/datadog/tracing/context_provider.rb +1 -1
- 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/active_record/integration.rb +1 -1
- data/lib/datadog/tracing/contrib/active_support/cache/events/cache.rb +11 -2
- data/lib/datadog/tracing/contrib/active_support/cache/instrumentation.rb +33 -0
- data/lib/datadog/tracing/contrib/active_support/cache/patcher.rb +4 -0
- data/lib/datadog/tracing/contrib/active_support/cache/redis.rb +2 -4
- data/lib/datadog/tracing/contrib/active_support/configuration/settings.rb +13 -0
- data/lib/datadog/tracing/contrib/aws/instrumentation.rb +10 -0
- data/lib/datadog/tracing/contrib/aws/parsed_context.rb +5 -1
- data/lib/datadog/tracing/contrib/configuration/settings.rb +1 -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/faraday/middleware.rb +5 -3
- 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/httpclient/instrumentation.rb +6 -16
- data/lib/datadog/tracing/contrib/httprb/instrumentation.rb +7 -15
- 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/subscribers.rb +18 -1
- data/lib/datadog/tracing/contrib/mysql2/instrumentation.rb +16 -6
- 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/patcher.rb +5 -1
- data/lib/datadog/tracing/contrib/patcher.rb +5 -2
- data/lib/datadog/tracing/contrib/rack/request_queue.rb +1 -1
- data/lib/datadog/tracing/contrib/rails/patcher.rb +4 -1
- data/lib/datadog/tracing/contrib/rails/runner.rb +61 -40
- 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/support.rb +28 -0
- data/lib/datadog/tracing/contrib.rb +1 -0
- data/lib/datadog/tracing/correlation.rb +9 -2
- data/lib/datadog/tracing/diagnostics/environment_logger.rb +3 -1
- 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 +10 -1
- data/lib/datadog/tracing/span_event.rb +2 -2
- data/lib/datadog/tracing/span_operation.rb +68 -16
- data/lib/datadog/tracing/sync_writer.rb +2 -3
- 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 +51 -7
- data/lib/datadog/tracing/transport/http/api.rb +2 -10
- data/lib/datadog/tracing/transport/http/client.rb +5 -4
- data/lib/datadog/tracing/transport/http/traces.rb +13 -41
- data/lib/datadog/tracing/transport/http.rb +11 -44
- data/lib/datadog/tracing/transport/serializable_trace.rb +3 -1
- data/lib/datadog/tracing/transport/trace_formatter.rb +7 -0
- data/lib/datadog/tracing/transport/traces.rb +26 -9
- data/lib/datadog/tracing/utils.rb +1 -1
- data/lib/datadog/tracing/workers/trace_writer.rb +2 -6
- data/lib/datadog/tracing/writer.rb +2 -6
- data/lib/datadog/tracing.rb +16 -3
- data/lib/datadog/version.rb +2 -2
- data/lib/datadog.rb +8 -2
- metadata +88 -23
- 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 -54
- data/lib/datadog/appsec/contrib/devise/patcher/authenticatable_patch.rb +0 -72
- data/lib/datadog/appsec/contrib/devise/patcher/registration_controller_patch.rb +0 -47
- data/lib/datadog/appsec/contrib/devise/resource.rb +0 -35
- data/lib/datadog/appsec/contrib/devise/tracking.rb +0 -57
- data/lib/datadog/appsec/processor/rule_merger.rb +0 -170
- data/lib/datadog/appsec/processor.rb +0 -107
- data/lib/datadog/appsec/utils/trace_operation.rb +0 -15
- 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
@@ -11,6 +11,7 @@
|
|
11
11
|
#include "stack_recorder.h"
|
12
12
|
#include "time_helpers.h"
|
13
13
|
#include "unsafe_api_calls_check.h"
|
14
|
+
#include "extconf.h"
|
14
15
|
|
15
16
|
// Used to trigger sampling of threads, based on external "events", such as:
|
16
17
|
// * periodic timer for cpu-time and wall-time
|
@@ -124,6 +125,7 @@ typedef struct {
|
|
124
125
|
ddog_prof_Location *locations;
|
125
126
|
uint16_t max_frames;
|
126
127
|
// Hashmap <Thread Object, per_thread_context>
|
128
|
+
// Note: Be very careful when mutating this map, as it gets read e.g. in the middle of GC and signal handlers.
|
127
129
|
st_table *hash_map_per_thread_context;
|
128
130
|
// Datadog::Profiling::StackRecorder instance
|
129
131
|
VALUE recorder_instance;
|
@@ -153,6 +155,10 @@ typedef struct {
|
|
153
155
|
// Qtrue serves as a marker we've not yet extracted it; when we try to extract it, we set it to an object if
|
154
156
|
// successful and Qnil if not.
|
155
157
|
VALUE otel_current_span_key;
|
158
|
+
// Used to enable native filenames in stack traces
|
159
|
+
bool native_filenames_enabled;
|
160
|
+
// Used to cache native filename lookup results (Map[void *function_pointer, char *filename])
|
161
|
+
st_table *native_filenames_cache;
|
156
162
|
|
157
163
|
struct stats {
|
158
164
|
// Track how many garbage collection samples we've taken.
|
@@ -172,7 +178,7 @@ typedef struct {
|
|
172
178
|
|
173
179
|
// Tracks per-thread state
|
174
180
|
typedef struct {
|
175
|
-
sampling_buffer
|
181
|
+
sampling_buffer sampling_buffer;
|
176
182
|
char thread_id[THREAD_ID_LIMIT_CHARS];
|
177
183
|
ddog_CharSlice thread_id_char_slice;
|
178
184
|
char thread_invoke_location[THREAD_INVOKE_LOCATION_LIMIT_CHARS];
|
@@ -205,14 +211,14 @@ typedef struct {
|
|
205
211
|
|
206
212
|
static void thread_context_collector_typed_data_mark(void *state_ptr);
|
207
213
|
static void thread_context_collector_typed_data_free(void *state_ptr);
|
208
|
-
static int hash_map_per_thread_context_mark(st_data_t key_thread, st_data_t
|
214
|
+
static int hash_map_per_thread_context_mark(st_data_t key_thread, st_data_t value_thread_context, DDTRACE_UNUSED st_data_t _argument);
|
209
215
|
static int hash_map_per_thread_context_free_values(st_data_t _thread, st_data_t value_per_thread_context, st_data_t _argument);
|
210
216
|
static VALUE _native_new(VALUE klass);
|
211
217
|
static VALUE _native_initialize(int argc, VALUE *argv, DDTRACE_UNUSED VALUE _self);
|
212
218
|
static VALUE _native_sample(VALUE self, VALUE collector_instance, VALUE profiler_overhead_stack_thread, VALUE allow_exception);
|
213
219
|
static VALUE _native_on_gc_start(VALUE self, VALUE collector_instance);
|
214
220
|
static VALUE _native_on_gc_finish(VALUE self, VALUE collector_instance);
|
215
|
-
static VALUE _native_sample_after_gc(DDTRACE_UNUSED VALUE self, VALUE collector_instance, VALUE
|
221
|
+
static VALUE _native_sample_after_gc(DDTRACE_UNUSED VALUE self, VALUE collector_instance, VALUE allow_exception);
|
216
222
|
static void update_metrics_and_sample(
|
217
223
|
thread_context_collector_state *state,
|
218
224
|
VALUE thread_being_sampled,
|
@@ -297,6 +303,8 @@ static void otel_without_ddtrace_trace_identifiers_for(
|
|
297
303
|
static otel_span otel_span_from(VALUE otel_context, VALUE otel_current_span_key);
|
298
304
|
static uint64_t otel_span_id_to_uint(VALUE otel_span_id);
|
299
305
|
static VALUE safely_lookup_hash_without_going_into_ruby_code(VALUE hash, VALUE key);
|
306
|
+
static VALUE _native_system_epoch_time_now_ns(DDTRACE_UNUSED VALUE self, VALUE collector_instance);
|
307
|
+
static VALUE _native_prepare_sample_inside_signal_handler(DDTRACE_UNUSED VALUE self, VALUE collector_instance);
|
300
308
|
|
301
309
|
void collectors_thread_context_init(VALUE profiling_module) {
|
302
310
|
VALUE collectors_module = rb_define_module_under(profiling_module, "Collectors");
|
@@ -321,13 +329,15 @@ void collectors_thread_context_init(VALUE profiling_module) {
|
|
321
329
|
rb_define_singleton_method(testing_module, "_native_sample_allocation", _native_sample_allocation, 3);
|
322
330
|
rb_define_singleton_method(testing_module, "_native_on_gc_start", _native_on_gc_start, 1);
|
323
331
|
rb_define_singleton_method(testing_module, "_native_on_gc_finish", _native_on_gc_finish, 1);
|
324
|
-
rb_define_singleton_method(testing_module, "_native_sample_after_gc", _native_sample_after_gc,
|
332
|
+
rb_define_singleton_method(testing_module, "_native_sample_after_gc", _native_sample_after_gc, 2);
|
325
333
|
rb_define_singleton_method(testing_module, "_native_thread_list", _native_thread_list, 0);
|
326
334
|
rb_define_singleton_method(testing_module, "_native_per_thread_context", _native_per_thread_context, 1);
|
327
335
|
rb_define_singleton_method(testing_module, "_native_stats", _native_stats, 1);
|
328
336
|
rb_define_singleton_method(testing_module, "_native_gc_tracking", _native_gc_tracking, 1);
|
329
337
|
rb_define_singleton_method(testing_module, "_native_new_empty_thread", _native_new_empty_thread, 0);
|
330
338
|
rb_define_singleton_method(testing_module, "_native_sample_skipped_allocation_samples", _native_sample_skipped_allocation_samples, 2);
|
339
|
+
rb_define_singleton_method(testing_module, "_native_system_epoch_time_now_ns", _native_system_epoch_time_now_ns, 1);
|
340
|
+
rb_define_singleton_method(testing_module, "_native_prepare_sample_inside_signal_handler", _native_prepare_sample_inside_signal_handler, 1);
|
331
341
|
#ifndef NO_GVL_INSTRUMENTATION
|
332
342
|
rb_define_singleton_method(testing_module, "_native_on_gvl_waiting", _native_on_gvl_waiting, 1);
|
333
343
|
rb_define_singleton_method(testing_module, "_native_gvl_waiting_at_for", _native_gvl_waiting_at_for, 1);
|
@@ -403,13 +413,21 @@ static void thread_context_collector_typed_data_free(void *state_ptr) {
|
|
403
413
|
// ...and then the map
|
404
414
|
st_free_table(state->hash_map_per_thread_context);
|
405
415
|
|
416
|
+
st_free_table(state->native_filenames_cache);
|
417
|
+
|
406
418
|
ruby_xfree(state);
|
407
419
|
}
|
408
420
|
|
409
421
|
// Mark Ruby thread references we keep as keys in hash_map_per_thread_context
|
410
|
-
static int hash_map_per_thread_context_mark(st_data_t key_thread,
|
422
|
+
static int hash_map_per_thread_context_mark(st_data_t key_thread, st_data_t value_thread_context, DDTRACE_UNUSED st_data_t _argument) {
|
411
423
|
VALUE thread = (VALUE) key_thread;
|
424
|
+
per_thread_context *thread_context = (per_thread_context *) value_thread_context;
|
425
|
+
|
412
426
|
rb_gc_mark(thread);
|
427
|
+
if (sampling_buffer_needs_marking(&thread_context->sampling_buffer)) {
|
428
|
+
sampling_buffer_mark(&thread_context->sampling_buffer);
|
429
|
+
}
|
430
|
+
|
413
431
|
return ST_CONTINUE;
|
414
432
|
}
|
415
433
|
|
@@ -438,6 +456,8 @@ static VALUE _native_new(VALUE klass) {
|
|
438
456
|
state->thread_list_buffer = thread_list_buffer;
|
439
457
|
state->endpoint_collection_enabled = true;
|
440
458
|
state->timeline_enabled = true;
|
459
|
+
state->native_filenames_enabled = false;
|
460
|
+
state->native_filenames_cache = st_init_numtable();
|
441
461
|
state->otel_context_enabled = OTEL_CONTEXT_ENABLED_FALSE;
|
442
462
|
state->otel_context_source = OTEL_CONTEXT_SOURCE_UNKNOWN;
|
443
463
|
state->time_converter_state = (monotonic_to_system_epoch_state) MONOTONIC_TO_SYSTEM_EPOCH_INITIALIZER;
|
@@ -472,11 +492,13 @@ static VALUE _native_initialize(int argc, VALUE *argv, DDTRACE_UNUSED VALUE _sel
|
|
472
492
|
VALUE timeline_enabled = rb_hash_fetch(options, ID2SYM(rb_intern("timeline_enabled")));
|
473
493
|
VALUE waiting_for_gvl_threshold_ns = rb_hash_fetch(options, ID2SYM(rb_intern("waiting_for_gvl_threshold_ns")));
|
474
494
|
VALUE otel_context_enabled = rb_hash_fetch(options, ID2SYM(rb_intern("otel_context_enabled")));
|
495
|
+
VALUE native_filenames_enabled = rb_hash_fetch(options, ID2SYM(rb_intern("native_filenames_enabled")));
|
475
496
|
|
476
497
|
ENFORCE_TYPE(max_frames, T_FIXNUM);
|
477
498
|
ENFORCE_BOOLEAN(endpoint_collection_enabled);
|
478
499
|
ENFORCE_BOOLEAN(timeline_enabled);
|
479
500
|
ENFORCE_TYPE(waiting_for_gvl_threshold_ns, T_FIXNUM);
|
501
|
+
ENFORCE_BOOLEAN(native_filenames_enabled);
|
480
502
|
|
481
503
|
thread_context_collector_state *state;
|
482
504
|
TypedData_Get_Struct(self_instance, thread_context_collector_state, &thread_context_collector_typed_data, state);
|
@@ -488,6 +510,7 @@ static VALUE _native_initialize(int argc, VALUE *argv, DDTRACE_UNUSED VALUE _sel
|
|
488
510
|
state->recorder_instance = enforce_recorder_instance(recorder_instance);
|
489
511
|
state->endpoint_collection_enabled = (endpoint_collection_enabled == Qtrue);
|
490
512
|
state->timeline_enabled = (timeline_enabled == Qtrue);
|
513
|
+
state->native_filenames_enabled = (native_filenames_enabled == Qtrue);
|
491
514
|
if (otel_context_enabled == Qfalse || otel_context_enabled == Qnil) {
|
492
515
|
state->otel_context_enabled = OTEL_CONTEXT_ENABLED_FALSE;
|
493
516
|
} else if (otel_context_enabled == ID2SYM(rb_intern("only"))) {
|
@@ -551,19 +574,9 @@ static VALUE _native_on_gc_finish(DDTRACE_UNUSED VALUE self, VALUE collector_ins
|
|
551
574
|
return Qtrue;
|
552
575
|
}
|
553
576
|
|
554
|
-
|
555
|
-
// It SHOULD NOT be used for other purposes.
|
556
|
-
static VALUE _native_sample_after_gc(DDTRACE_UNUSED VALUE self, VALUE collector_instance, VALUE reset_monotonic_to_system_state, VALUE allow_exception) {
|
557
|
-
ENFORCE_BOOLEAN(reset_monotonic_to_system_state);
|
577
|
+
static VALUE _native_sample_after_gc(DDTRACE_UNUSED VALUE self, VALUE collector_instance, VALUE allow_exception) {
|
558
578
|
ENFORCE_BOOLEAN(allow_exception);
|
559
579
|
|
560
|
-
thread_context_collector_state *state;
|
561
|
-
TypedData_Get_Struct(collector_instance, thread_context_collector_state, &thread_context_collector_typed_data, state);
|
562
|
-
|
563
|
-
if (reset_monotonic_to_system_state == Qtrue) {
|
564
|
-
state->time_converter_state = (monotonic_to_system_epoch_state) MONOTONIC_TO_SYSTEM_EPOCH_INITIALIZER;
|
565
|
-
}
|
566
|
-
|
567
580
|
if (allow_exception == Qfalse) debug_enter_unsafe_context();
|
568
581
|
|
569
582
|
thread_context_collector_sample_after_gc(collector_instance);
|
@@ -607,7 +620,7 @@ void thread_context_collector_sample(VALUE self_instance, long current_monotonic
|
|
607
620
|
/* thread_being_sampled: */ thread,
|
608
621
|
/* stack_from_thread: */ thread,
|
609
622
|
thread_context,
|
610
|
-
thread_context->sampling_buffer,
|
623
|
+
&thread_context->sampling_buffer,
|
611
624
|
current_cpu_time_ns,
|
612
625
|
current_monotonic_wall_time_ns
|
613
626
|
);
|
@@ -625,7 +638,7 @@ void thread_context_collector_sample(VALUE self_instance, long current_monotonic
|
|
625
638
|
/* stack_from_thread: */ profiler_overhead_stack_thread,
|
626
639
|
current_thread_context,
|
627
640
|
// Here we use the overhead thread's sampling buffer so as to not invalidate the cache in the buffer of the thread being sampled
|
628
|
-
get_or_create_context_for(profiler_overhead_stack_thread, state)->sampling_buffer,
|
641
|
+
&get_or_create_context_for(profiler_overhead_stack_thread, state)->sampling_buffer,
|
629
642
|
cpu_time_now_ns(current_thread_context),
|
630
643
|
monotonic_wall_time_now_ns(RAISE_ON_FAILURE)
|
631
644
|
);
|
@@ -1006,7 +1019,9 @@ static void trigger_sample_for_thread(
|
|
1006
1019
|
.state_label = state_label,
|
1007
1020
|
.end_timestamp_ns = end_timestamp_ns,
|
1008
1021
|
.is_gvl_waiting_state = is_gvl_waiting_state,
|
1009
|
-
}
|
1022
|
+
},
|
1023
|
+
state->native_filenames_enabled,
|
1024
|
+
state->native_filenames_cache
|
1010
1025
|
);
|
1011
1026
|
}
|
1012
1027
|
|
@@ -1031,7 +1046,7 @@ static per_thread_context *get_or_create_context_for(VALUE thread, thread_contex
|
|
1031
1046
|
if (st_lookup(state->hash_map_per_thread_context, (st_data_t) thread, &value_context)) {
|
1032
1047
|
thread_context = (per_thread_context*) value_context;
|
1033
1048
|
} else {
|
1034
|
-
thread_context =
|
1049
|
+
thread_context = calloc(1, sizeof(per_thread_context)); // See "note on calloc vs ruby_xcalloc use" in heap_recorder.c
|
1035
1050
|
initialize_context(thread, thread_context, state);
|
1036
1051
|
st_insert(state->hash_map_per_thread_context, (st_data_t) thread, (st_data_t) thread_context);
|
1037
1052
|
}
|
@@ -1072,7 +1087,7 @@ static bool is_logging_gem_monkey_patch(VALUE invoke_file_location) {
|
|
1072
1087
|
}
|
1073
1088
|
|
1074
1089
|
static void initialize_context(VALUE thread, per_thread_context *thread_context, thread_context_collector_state *state) {
|
1075
|
-
thread_context->sampling_buffer
|
1090
|
+
sampling_buffer_initialize(&thread_context->sampling_buffer, state->max_frames, state->locations);
|
1076
1091
|
|
1077
1092
|
snprintf(thread_context->thread_id, THREAD_ID_LIMIT_CHARS, "%"PRIu64" (%lu)", native_thread_id_for(thread), (unsigned long) thread_id_for(thread));
|
1078
1093
|
thread_context->thread_id_char_slice = (ddog_CharSlice) {.ptr = thread_context->thread_id, .len = strlen(thread_context->thread_id)};
|
@@ -1129,8 +1144,8 @@ static void initialize_context(VALUE thread, per_thread_context *thread_context,
|
|
1129
1144
|
}
|
1130
1145
|
|
1131
1146
|
static void free_context(per_thread_context* thread_context) {
|
1132
|
-
sampling_buffer_free(thread_context->sampling_buffer);
|
1133
|
-
|
1147
|
+
sampling_buffer_free(&thread_context->sampling_buffer);
|
1148
|
+
free(thread_context); // See "note on calloc vs ruby_xcalloc use" in heap_recorder.c
|
1134
1149
|
}
|
1135
1150
|
|
1136
1151
|
static VALUE _native_inspect(DDTRACE_UNUSED VALUE _self, VALUE collector_instance) {
|
@@ -1149,6 +1164,9 @@ static VALUE _native_inspect(DDTRACE_UNUSED VALUE _self, VALUE collector_instanc
|
|
1149
1164
|
rb_str_concat(result, rb_sprintf(" stats=%"PRIsVALUE, stats_as_ruby_hash(state)));
|
1150
1165
|
rb_str_concat(result, rb_sprintf(" endpoint_collection_enabled=%"PRIsVALUE, state->endpoint_collection_enabled ? Qtrue : Qfalse));
|
1151
1166
|
rb_str_concat(result, rb_sprintf(" timeline_enabled=%"PRIsVALUE, state->timeline_enabled ? Qtrue : Qfalse));
|
1167
|
+
rb_str_concat(result, rb_sprintf(" native_filenames_enabled=%"PRIsVALUE, state->native_filenames_enabled ? Qtrue : Qfalse));
|
1168
|
+
// Note: `st_table_size()` is available from Ruby 3.2+ but not before
|
1169
|
+
rb_str_concat(result, rb_sprintf(" native_filenames_cache_size=%zu", state->native_filenames_cache->num_entries));
|
1152
1170
|
rb_str_concat(result, rb_sprintf(" otel_context_enabled=%d", state->otel_context_enabled));
|
1153
1171
|
rb_str_concat(result, rb_sprintf(
|
1154
1172
|
" time_converter_state={.system_epoch_ns_reference=%ld, .delta_to_epoch_ns=%ld}",
|
@@ -1316,7 +1334,7 @@ static long thread_id_for(VALUE thread) {
|
|
1316
1334
|
}
|
1317
1335
|
|
1318
1336
|
VALUE enforce_thread_context_collector_instance(VALUE object) {
|
1319
|
-
|
1337
|
+
ENFORCE_TYPED_DATA(object, &thread_context_collector_typed_data);
|
1320
1338
|
return object;
|
1321
1339
|
}
|
1322
1340
|
|
@@ -1444,6 +1462,26 @@ static VALUE thread_list(thread_context_collector_state *state) {
|
|
1444
1462
|
return result;
|
1445
1463
|
}
|
1446
1464
|
|
1465
|
+
// Inside a signal handler, we don't want to do the whole work of recording a sample, but we only record the stack of
|
1466
|
+
// the current thread.
|
1467
|
+
//
|
1468
|
+
// Assumptions for this function are same as for `thread_context_collector_sample` except that this function is
|
1469
|
+
// expected to be called from a signal handler and to be async-signal-safe.
|
1470
|
+
//
|
1471
|
+
// Also, no allocation (Ruby or malloc) can happen.
|
1472
|
+
bool thread_context_collector_prepare_sample_inside_signal_handler(VALUE self_instance) {
|
1473
|
+
thread_context_collector_state *state;
|
1474
|
+
if (!rb_typeddata_is_kind_of(self_instance, &thread_context_collector_typed_data)) return false;
|
1475
|
+
// This should never fail if the above check passes
|
1476
|
+
TypedData_Get_Struct(self_instance, thread_context_collector_state, &thread_context_collector_typed_data, state);
|
1477
|
+
|
1478
|
+
VALUE current_thread = rb_thread_current();
|
1479
|
+
per_thread_context *thread_context = get_context_for(current_thread, state);
|
1480
|
+
if (thread_context == NULL) return false;
|
1481
|
+
|
1482
|
+
return prepare_sample_thread(current_thread, &thread_context->sampling_buffer);
|
1483
|
+
}
|
1484
|
+
|
1447
1485
|
void thread_context_collector_sample_allocation(VALUE self_instance, unsigned int sample_weight, VALUE new_object) {
|
1448
1486
|
thread_context_collector_state *state;
|
1449
1487
|
TypedData_Get_Struct(self_instance, thread_context_collector_state, &thread_context_collector_typed_data, state);
|
@@ -1523,7 +1561,7 @@ void thread_context_collector_sample_allocation(VALUE self_instance, unsigned in
|
|
1523
1561
|
/* thread: */ current_thread,
|
1524
1562
|
/* stack_from_thread: */ current_thread,
|
1525
1563
|
thread_context,
|
1526
|
-
thread_context->sampling_buffer,
|
1564
|
+
&thread_context->sampling_buffer,
|
1527
1565
|
(sample_values) {.alloc_samples = sample_weight, .alloc_samples_unscaled = 1, .heap_sample = true},
|
1528
1566
|
INVALID_TIME, // For now we're not collecting timestamps for allocation events, as per profiling team internal discussions
|
1529
1567
|
&ruby_vm_type,
|
@@ -1949,7 +1987,7 @@ static uint64_t otel_span_id_to_uint(VALUE otel_span_id) {
|
|
1949
1987
|
/* thread_being_sampled: */ current_thread,
|
1950
1988
|
/* stack_from_thread: */ current_thread,
|
1951
1989
|
thread_context,
|
1952
|
-
thread_context->sampling_buffer,
|
1990
|
+
&thread_context->sampling_buffer,
|
1953
1991
|
cpu_time_for_thread,
|
1954
1992
|
current_monotonic_wall_time_ns
|
1955
1993
|
);
|
@@ -2167,3 +2205,17 @@ static VALUE safely_lookup_hash_without_going_into_ruby_code(VALUE hash, VALUE k
|
|
2167
2205
|
|
2168
2206
|
return state.result;
|
2169
2207
|
}
|
2208
|
+
|
2209
|
+
static VALUE _native_system_epoch_time_now_ns(DDTRACE_UNUSED VALUE self, VALUE collector_instance) {
|
2210
|
+
thread_context_collector_state *state;
|
2211
|
+
TypedData_Get_Struct(collector_instance, thread_context_collector_state, &thread_context_collector_typed_data, state);
|
2212
|
+
|
2213
|
+
long current_monotonic_wall_time_ns = monotonic_wall_time_now_ns(RAISE_ON_FAILURE);
|
2214
|
+
long system_epoch_time_ns = monotonic_to_system_epoch_ns(&state->time_converter_state, current_monotonic_wall_time_ns);
|
2215
|
+
|
2216
|
+
return LONG2NUM(system_epoch_time_ns);
|
2217
|
+
}
|
2218
|
+
|
2219
|
+
static VALUE _native_prepare_sample_inside_signal_handler(DDTRACE_UNUSED VALUE self, VALUE collector_instance) {
|
2220
|
+
return thread_context_collector_prepare_sample_inside_signal_handler(collector_instance) ? Qtrue : Qfalse;
|
2221
|
+
}
|
@@ -10,6 +10,7 @@ void thread_context_collector_sample(
|
|
10
10
|
long current_monotonic_wall_time_ns,
|
11
11
|
VALUE profiler_overhead_stack_thread
|
12
12
|
);
|
13
|
+
__attribute__((warn_unused_result)) bool thread_context_collector_prepare_sample_inside_signal_handler(VALUE self_instance);
|
13
14
|
void thread_context_collector_sample_allocation(VALUE self_instance, unsigned int sample_weight, VALUE new_object);
|
14
15
|
void thread_context_collector_sample_skipped_allocation_samples(VALUE self_instance, unsigned int skipped_samples);
|
15
16
|
VALUE thread_context_collector_sample_after_gc(VALUE self_instance);
|
@@ -29,10 +29,7 @@ VALUE datadog_gem_version(void) {
|
|
29
29
|
}
|
30
30
|
|
31
31
|
static VALUE log_failure_to_process_tag(VALUE err_details) {
|
32
|
-
|
33
|
-
VALUE logger = rb_funcall(datadog_module, rb_intern("logger"), 0);
|
34
|
-
|
35
|
-
return rb_funcall(logger, rb_intern("warn"), 1, rb_sprintf("Failed to convert tag: %"PRIsVALUE, err_details));
|
32
|
+
return log_warning(rb_sprintf("Failed to convert tag: %"PRIsVALUE, err_details));
|
36
33
|
}
|
37
34
|
|
38
35
|
__attribute__((warn_unused_result))
|
@@ -27,6 +27,9 @@
|
|
27
27
|
#define ENFORCE_BOOLEAN(value) \
|
28
28
|
{ if (RB_UNLIKELY(value != Qtrue && value != Qfalse)) raise_unexpected_type(value, ADD_QUOTES(value), "true or false", __FILE__, __LINE__, __func__); }
|
29
29
|
|
30
|
+
#define ENFORCE_TYPED_DATA(value, type) \
|
31
|
+
{ if (RB_UNLIKELY(!rb_typeddata_is_kind_of(value, type))) raise_unexpected_type(value, ADD_QUOTES(value), "TypedData of type " ADD_QUOTES(type), __FILE__, __LINE__, __func__); }
|
32
|
+
|
30
33
|
NORETURN(void raise_unexpected_type(VALUE value, const char *value_name, const char *type_name, const char *file, int line, const char* function_name));
|
31
34
|
|
32
35
|
// Helper to retrieve Datadog::VERSION::STRING
|
@@ -38,6 +41,13 @@ static inline ddog_CharSlice char_slice_from_ruby_string(VALUE string) {
|
|
38
41
|
return char_slice;
|
39
42
|
}
|
40
43
|
|
44
|
+
static inline VALUE log_warning(VALUE warning) {
|
45
|
+
VALUE datadog_module = rb_const_get(rb_cObject, rb_intern("Datadog"));
|
46
|
+
VALUE logger = rb_funcall(datadog_module, rb_intern("logger"), 0);
|
47
|
+
|
48
|
+
return rb_funcall(logger, rb_intern("warn"), 1, warning);
|
49
|
+
}
|
50
|
+
|
41
51
|
__attribute__((warn_unused_result))
|
42
52
|
ddog_Vec_Tag convert_tags(VALUE tags_as_array);
|
43
53
|
|
@@ -0,0 +1,79 @@
|
|
1
|
+
#include "encoded_profile.h"
|
2
|
+
#include "datadog_ruby_common.h"
|
3
|
+
#include "libdatadog_helpers.h"
|
4
|
+
|
5
|
+
// This class exists to wrap a ddog_prof_EncodedProfile into a Ruby object
|
6
|
+
// This file implements the native bits of the Datadog::Profiling::EncodedProfile class
|
7
|
+
|
8
|
+
static void encoded_profile_typed_data_free(void *state_ptr);
|
9
|
+
static VALUE _native_bytes(VALUE self);
|
10
|
+
|
11
|
+
static VALUE encoded_profile_class = Qnil;
|
12
|
+
|
13
|
+
void encoded_profile_init(VALUE profiling_module) {
|
14
|
+
encoded_profile_class = rb_define_class_under(profiling_module, "EncodedProfile", rb_cObject);
|
15
|
+
|
16
|
+
rb_undef_alloc_func(encoded_profile_class); // Class cannot be created from Ruby code
|
17
|
+
rb_global_variable(&encoded_profile_class);
|
18
|
+
|
19
|
+
rb_define_method(encoded_profile_class, "_native_bytes", _native_bytes, 0);
|
20
|
+
}
|
21
|
+
|
22
|
+
// This structure is used to define a Ruby object that stores a `ddog_prof_EncodedProfile`
|
23
|
+
// See also https://github.com/ruby/ruby/blob/master/doc/extension.rdoc for how this works
|
24
|
+
static const rb_data_type_t encoded_profile_typed_data = {
|
25
|
+
.wrap_struct_name = "Datadog::Profiling::EncodedProfile",
|
26
|
+
.function = {
|
27
|
+
.dmark = NULL, // We don't store references to Ruby objects so we don't need to mark any of them
|
28
|
+
.dfree = encoded_profile_typed_data_free,
|
29
|
+
.dsize = NULL, // We don't track memory usage (although it'd be cool if we did!)
|
30
|
+
//.dcompact = NULL, // Not needed -- we don't store references to Ruby objects
|
31
|
+
},
|
32
|
+
.flags = RUBY_TYPED_FREE_IMMEDIATELY
|
33
|
+
};
|
34
|
+
|
35
|
+
VALUE from_ddog_prof_EncodedProfile(ddog_prof_EncodedProfile profile) {
|
36
|
+
ddog_prof_EncodedProfile *state = ruby_xcalloc(1, sizeof(ddog_prof_EncodedProfile));
|
37
|
+
*state = profile;
|
38
|
+
return TypedData_Wrap_Struct(encoded_profile_class, &encoded_profile_typed_data, state);
|
39
|
+
}
|
40
|
+
|
41
|
+
static ddog_ByteSlice get_bytes(ddog_prof_EncodedProfile *state) {
|
42
|
+
ddog_prof_Result_ByteSlice raw_bytes = ddog_prof_EncodedProfile_bytes(state);
|
43
|
+
if (raw_bytes.tag == DDOG_PROF_RESULT_BYTE_SLICE_ERR_BYTE_SLICE) {
|
44
|
+
rb_raise(rb_eRuntimeError, "Failed to get bytes from profile: %"PRIsVALUE, get_error_details_and_drop(&raw_bytes.err));
|
45
|
+
}
|
46
|
+
return raw_bytes.ok;
|
47
|
+
}
|
48
|
+
|
49
|
+
static ddog_prof_EncodedProfile *internal_to_ddog_prof_EncodedProfile(VALUE object) {
|
50
|
+
ddog_prof_EncodedProfile *state;
|
51
|
+
TypedData_Get_Struct(object, ddog_prof_EncodedProfile, &encoded_profile_typed_data, state);
|
52
|
+
return state;
|
53
|
+
}
|
54
|
+
|
55
|
+
ddog_prof_EncodedProfile *to_ddog_prof_EncodedProfile(VALUE object) {
|
56
|
+
ddog_prof_EncodedProfile *state = internal_to_ddog_prof_EncodedProfile(object);
|
57
|
+
get_bytes(state); // Validate profile is still usable -- if it's not, this will raise an exception
|
58
|
+
return state;
|
59
|
+
}
|
60
|
+
|
61
|
+
static void encoded_profile_typed_data_free(void *state_ptr) {
|
62
|
+
ddog_prof_EncodedProfile *state = (ddog_prof_EncodedProfile *) state_ptr;
|
63
|
+
|
64
|
+
// This drops the profile itself
|
65
|
+
ddog_prof_EncodedProfile_drop(state);
|
66
|
+
|
67
|
+
// This drops the tiny bit of memory we allocated to contain the ` ddog_prof_EncodedProfile` struct
|
68
|
+
ruby_xfree(state);
|
69
|
+
}
|
70
|
+
|
71
|
+
static VALUE _native_bytes(VALUE self) {
|
72
|
+
ddog_ByteSlice bytes = get_bytes(internal_to_ddog_prof_EncodedProfile(self));
|
73
|
+
return rb_str_new((const char *) bytes.ptr, bytes.len);
|
74
|
+
}
|
75
|
+
|
76
|
+
VALUE enforce_encoded_profile_instance(VALUE object) {
|
77
|
+
ENFORCE_TYPED_DATA(object, &encoded_profile_typed_data);
|
78
|
+
return object;
|
79
|
+
}
|
@@ -0,0 +1,8 @@
|
|
1
|
+
#pragma once
|
2
|
+
|
3
|
+
#include <ruby.h>
|
4
|
+
#include <datadog/profiling.h>
|
5
|
+
|
6
|
+
VALUE from_ddog_prof_EncodedProfile(ddog_prof_EncodedProfile profile);
|
7
|
+
VALUE enforce_encoded_profile_instance(VALUE object);
|
8
|
+
ddog_prof_EncodedProfile *to_ddog_prof_EncodedProfile(VALUE object);
|
@@ -131,6 +131,16 @@ end
|
|
131
131
|
|
132
132
|
have_func "malloc_stats"
|
133
133
|
|
134
|
+
# Used to get native filenames (dladdr1 is preferred, so we only check for the other if not available)
|
135
|
+
# Note it's possible none are available
|
136
|
+
if have_header("dlfcn.h")
|
137
|
+
(have_struct_member("struct link_map", "l_name", "link.h") && have_func("dladdr1")) ||
|
138
|
+
have_func("dladdr")
|
139
|
+
end
|
140
|
+
|
141
|
+
# On Ruby 3.5, we can't ask the object_id from IMEMOs (https://github.com/ruby/ruby/pull/13347)
|
142
|
+
$defs << "-DNO_IMEMO_OBJECT_ID" unless RUBY_VERSION < "3.5"
|
143
|
+
|
134
144
|
# On Ruby 2.5 and 3.3, this symbol was not visible. It is on 2.6 to 3.2, as well as 3.4+
|
135
145
|
$defs << "-DNO_RB_OBJ_INFO" if RUBY_VERSION.start_with?("2.5", "3.3")
|
136
146
|
|