ddtrace 0.40.0 → 0.54.1
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/.editorconfig +22 -0
- data/.gitignore +7 -1
- data/CHANGELOG.md +1667 -350
- data/CONTRIBUTING.md +3 -7
- data/LICENSE-3rdparty.csv +2 -0
- data/README.md +1 -0
- data/bin/ddtracerb +15 -0
- data/ddtrace.gemspec +21 -37
- data/docs/DevelopmentGuide.md +56 -8
- data/docs/GettingStarted.md +438 -92
- data/docs/ProfilingDevelopment.md +107 -0
- data/ext/ddtrace_profiling_native_extension/NativeExtensionDesign.md +86 -0
- data/ext/ddtrace_profiling_native_extension/clock_id.h +4 -0
- data/ext/ddtrace_profiling_native_extension/clock_id_from_pthread.c +52 -0
- data/ext/ddtrace_profiling_native_extension/clock_id_noop.c +14 -0
- data/ext/ddtrace_profiling_native_extension/extconf.rb +166 -0
- data/ext/ddtrace_profiling_native_extension/private_vm_api_access.c +35 -0
- data/ext/ddtrace_profiling_native_extension/private_vm_api_access.h +3 -0
- data/ext/ddtrace_profiling_native_extension/profiling.c +22 -0
- data/lib/datadog/ci/configuration/components.rb +31 -0
- data/lib/datadog/ci/configuration/settings.rb +37 -0
- data/lib/datadog/ci/context_flush.rb +29 -0
- data/lib/datadog/ci/contrib/cucumber/configuration/settings.rb +31 -0
- data/lib/datadog/ci/contrib/cucumber/ext.rb +20 -0
- data/lib/datadog/ci/contrib/cucumber/formatter.rb +99 -0
- data/lib/datadog/ci/contrib/cucumber/instrumentation.rb +27 -0
- data/lib/datadog/ci/contrib/cucumber/integration.rb +48 -0
- data/lib/datadog/ci/contrib/cucumber/patcher.rb +26 -0
- data/lib/datadog/ci/contrib/rspec/configuration/settings.rb +31 -0
- data/lib/datadog/ci/contrib/rspec/example.rb +75 -0
- data/lib/datadog/ci/contrib/rspec/ext.rb +19 -0
- data/lib/datadog/ci/contrib/rspec/integration.rb +49 -0
- data/lib/datadog/ci/contrib/rspec/patcher.rb +26 -0
- data/lib/datadog/ci/ext/app_types.rb +10 -0
- data/lib/datadog/ci/ext/environment.rb +485 -0
- data/lib/datadog/ci/ext/settings.rb +11 -0
- data/lib/datadog/ci/ext/test.rb +36 -0
- data/lib/datadog/ci/extensions.rb +18 -0
- data/lib/datadog/ci/test.rb +81 -0
- data/lib/datadog/ci.rb +17 -0
- data/lib/datadog/contrib.rb +71 -0
- data/lib/datadog/core/environment/cgroup.rb +52 -0
- data/lib/datadog/core/environment/class_count.rb +20 -0
- data/lib/datadog/core/environment/container.rb +91 -0
- data/lib/datadog/core/environment/ext.rb +27 -0
- data/lib/datadog/core/environment/gc.rb +19 -0
- data/lib/datadog/core/environment/identity.rb +51 -0
- data/lib/datadog/core/environment/socket.rb +17 -0
- data/lib/datadog/core/environment/thread_count.rb +19 -0
- data/lib/datadog/core/environment/variable_helpers.rb +42 -0
- data/lib/datadog/core/environment/vm_cache.rb +46 -0
- data/lib/ddtrace/analytics.rb +3 -0
- data/lib/ddtrace/auto_instrument.rb +5 -0
- data/lib/ddtrace/auto_instrument_base.rb +7 -0
- data/lib/ddtrace/buffer.rb +278 -57
- data/lib/ddtrace/chunker.rb +1 -0
- data/lib/ddtrace/configuration/agent_settings_resolver.rb +309 -0
- data/lib/ddtrace/configuration/base.rb +9 -11
- data/lib/ddtrace/configuration/components.rb +167 -26
- data/lib/ddtrace/configuration/dependency_resolver.rb +1 -0
- data/lib/ddtrace/configuration/option.rb +1 -0
- data/lib/ddtrace/configuration/option_definition.rb +2 -3
- data/lib/ddtrace/configuration/option_definition_set.rb +1 -0
- data/lib/ddtrace/configuration/option_set.rb +1 -0
- data/lib/ddtrace/configuration/options.rb +10 -10
- data/lib/ddtrace/configuration/pin_setup.rb +1 -0
- data/lib/ddtrace/configuration/settings.rb +147 -13
- data/lib/ddtrace/configuration.rb +133 -22
- data/lib/ddtrace/context.rb +51 -22
- data/lib/ddtrace/context_flush.rb +15 -2
- data/lib/ddtrace/context_provider.rb +17 -5
- data/lib/ddtrace/contrib/action_cable/configuration/settings.rb +1 -0
- data/lib/ddtrace/contrib/action_cable/event.rb +6 -4
- data/lib/ddtrace/contrib/action_cable/events/broadcast.rb +1 -0
- data/lib/ddtrace/contrib/action_cable/events/perform_action.rb +1 -0
- data/lib/ddtrace/contrib/action_cable/events/transmit.rb +1 -0
- data/lib/ddtrace/contrib/action_cable/events.rb +1 -0
- data/lib/ddtrace/contrib/action_cable/ext.rb +1 -0
- data/lib/ddtrace/contrib/action_cable/instrumentation.rb +47 -0
- data/lib/ddtrace/contrib/action_cable/integration.rb +8 -0
- data/lib/ddtrace/contrib/action_cable/patcher.rb +2 -0
- data/lib/ddtrace/contrib/action_mailer/configuration/settings.rb +32 -0
- data/lib/ddtrace/contrib/action_mailer/event.rb +50 -0
- data/lib/ddtrace/contrib/action_mailer/events/deliver.rb +54 -0
- data/lib/ddtrace/contrib/action_mailer/events/process.rb +41 -0
- data/lib/ddtrace/contrib/action_mailer/events.rb +31 -0
- data/lib/ddtrace/contrib/action_mailer/ext.rb +32 -0
- data/lib/ddtrace/contrib/action_mailer/integration.rb +45 -0
- data/lib/ddtrace/contrib/action_mailer/patcher.rb +27 -0
- data/lib/ddtrace/contrib/action_pack/action_controller/instrumentation.rb +22 -13
- data/lib/ddtrace/contrib/action_pack/action_controller/patcher.rb +2 -1
- data/lib/ddtrace/contrib/action_pack/configuration/settings.rb +1 -0
- data/lib/ddtrace/contrib/action_pack/ext.rb +1 -0
- data/lib/ddtrace/contrib/action_pack/integration.rb +8 -0
- data/lib/ddtrace/contrib/action_pack/patcher.rb +1 -0
- data/lib/ddtrace/contrib/action_pack/utils.rb +2 -1
- data/lib/ddtrace/contrib/action_view/configuration/settings.rb +1 -0
- data/lib/ddtrace/contrib/action_view/event.rb +4 -7
- data/lib/ddtrace/contrib/action_view/events/render_partial.rb +2 -0
- data/lib/ddtrace/contrib/action_view/events/render_template.rb +2 -0
- data/lib/ddtrace/contrib/action_view/events.rb +1 -0
- data/lib/ddtrace/contrib/action_view/ext.rb +1 -0
- data/lib/ddtrace/contrib/action_view/instrumentation/partial_renderer.rb +1 -0
- data/lib/ddtrace/contrib/action_view/instrumentation/template_renderer.rb +1 -0
- data/lib/ddtrace/contrib/action_view/integration.rb +8 -0
- data/lib/ddtrace/contrib/action_view/patcher.rb +5 -4
- data/lib/ddtrace/contrib/action_view/utils.rb +2 -1
- data/lib/ddtrace/contrib/active_job/configuration/settings.rb +33 -0
- data/lib/ddtrace/contrib/active_job/event.rb +54 -0
- data/lib/ddtrace/contrib/active_job/events/discard.rb +46 -0
- data/lib/ddtrace/contrib/active_job/events/enqueue.rb +45 -0
- data/lib/ddtrace/contrib/active_job/events/enqueue_at.rb +45 -0
- data/lib/ddtrace/contrib/active_job/events/enqueue_retry.rb +47 -0
- data/lib/ddtrace/contrib/active_job/events/perform.rb +45 -0
- data/lib/ddtrace/contrib/active_job/events/retry_stopped.rb +46 -0
- data/lib/ddtrace/contrib/active_job/events.rb +39 -0
- data/lib/ddtrace/contrib/active_job/ext.rb +32 -0
- data/lib/ddtrace/contrib/active_job/integration.rb +46 -0
- data/lib/ddtrace/contrib/active_job/log_injection.rb +21 -0
- data/lib/ddtrace/contrib/active_job/patcher.rb +33 -0
- data/lib/ddtrace/contrib/active_model_serializers/configuration/settings.rb +1 -0
- data/lib/ddtrace/contrib/active_model_serializers/event.rb +3 -2
- data/lib/ddtrace/contrib/active_model_serializers/events/render.rb +1 -0
- data/lib/ddtrace/contrib/active_model_serializers/events/serialize.rb +1 -0
- data/lib/ddtrace/contrib/active_model_serializers/events.rb +1 -0
- data/lib/ddtrace/contrib/active_model_serializers/ext.rb +1 -0
- data/lib/ddtrace/contrib/active_model_serializers/integration.rb +1 -0
- data/lib/ddtrace/contrib/active_model_serializers/patcher.rb +1 -0
- data/lib/ddtrace/contrib/active_record/configuration/makara_resolver.rb +31 -0
- data/lib/ddtrace/contrib/active_record/configuration/resolver.rb +108 -18
- data/lib/ddtrace/contrib/active_record/configuration/settings.rb +1 -0
- data/lib/ddtrace/contrib/active_record/event.rb +3 -2
- data/lib/ddtrace/contrib/active_record/events/instantiation.rb +1 -0
- data/lib/ddtrace/contrib/active_record/events/sql.rb +5 -0
- data/lib/ddtrace/contrib/active_record/events.rb +1 -0
- data/lib/ddtrace/contrib/active_record/ext.rb +1 -0
- data/lib/ddtrace/contrib/active_record/integration.rb +8 -0
- data/lib/ddtrace/contrib/active_record/patcher.rb +1 -0
- data/lib/ddtrace/contrib/active_record/utils.rb +69 -21
- data/lib/ddtrace/contrib/active_support/cache/instrumentation.rb +105 -3
- data/lib/ddtrace/contrib/active_support/cache/patcher.rb +26 -4
- data/lib/ddtrace/contrib/active_support/cache/redis.rb +2 -5
- data/lib/ddtrace/contrib/active_support/configuration/settings.rb +1 -0
- data/lib/ddtrace/contrib/active_support/ext.rb +4 -0
- data/lib/ddtrace/contrib/active_support/integration.rb +8 -1
- data/lib/ddtrace/contrib/active_support/notifications/event.rb +15 -3
- data/lib/ddtrace/contrib/active_support/notifications/subscriber.rb +3 -1
- data/lib/ddtrace/contrib/active_support/notifications/subscription.rb +12 -7
- data/lib/ddtrace/contrib/active_support/patcher.rb +1 -0
- data/lib/ddtrace/contrib/analytics.rb +1 -0
- data/lib/ddtrace/contrib/auto_instrument.rb +48 -0
- data/lib/ddtrace/contrib/aws/configuration/settings.rb +1 -0
- data/lib/ddtrace/contrib/aws/ext.rb +1 -0
- data/lib/ddtrace/contrib/aws/instrumentation.rb +36 -1
- data/lib/ddtrace/contrib/aws/integration.rb +1 -0
- data/lib/ddtrace/contrib/aws/parsed_context.rb +1 -0
- data/lib/ddtrace/contrib/aws/patcher.rb +6 -1
- data/lib/ddtrace/contrib/aws/services.rb +4 -0
- data/lib/ddtrace/contrib/concurrent_ruby/configuration/settings.rb +1 -0
- data/lib/ddtrace/contrib/concurrent_ruby/context_composite_executor_service.rb +1 -0
- data/lib/ddtrace/contrib/concurrent_ruby/ext.rb +1 -0
- data/lib/ddtrace/contrib/concurrent_ruby/future_patch.rb +1 -0
- data/lib/ddtrace/contrib/concurrent_ruby/integration.rb +1 -0
- data/lib/ddtrace/contrib/concurrent_ruby/patcher.rb +3 -1
- data/lib/ddtrace/contrib/configurable.rb +65 -38
- data/lib/ddtrace/contrib/configuration/resolver.rb +71 -5
- data/lib/ddtrace/contrib/configuration/resolvers/pattern_resolver.rb +21 -20
- data/lib/ddtrace/contrib/configuration/settings.rb +8 -6
- data/lib/ddtrace/contrib/dalli/configuration/settings.rb +1 -0
- data/lib/ddtrace/contrib/dalli/ext.rb +1 -0
- data/lib/ddtrace/contrib/dalli/instrumentation.rb +6 -1
- data/lib/ddtrace/contrib/dalli/integration.rb +1 -0
- data/lib/ddtrace/contrib/dalli/patcher.rb +2 -39
- data/lib/ddtrace/contrib/dalli/quantize.rb +1 -0
- data/lib/ddtrace/contrib/delayed_job/configuration/settings.rb +3 -0
- data/lib/ddtrace/contrib/delayed_job/ext.rb +3 -0
- data/lib/ddtrace/contrib/delayed_job/integration.rb +1 -0
- data/lib/ddtrace/contrib/delayed_job/patcher.rb +1 -0
- data/lib/ddtrace/contrib/delayed_job/plugin.rb +40 -16
- data/lib/ddtrace/contrib/elasticsearch/configuration/settings.rb +1 -0
- data/lib/ddtrace/contrib/elasticsearch/ext.rb +1 -0
- data/lib/ddtrace/contrib/elasticsearch/integration.rb +1 -0
- data/lib/ddtrace/contrib/elasticsearch/patcher.rb +6 -0
- data/lib/ddtrace/contrib/elasticsearch/quantize.rb +6 -2
- data/lib/ddtrace/contrib/ethon/configuration/settings.rb +1 -0
- data/lib/ddtrace/contrib/ethon/easy_patch.rb +15 -11
- data/lib/ddtrace/contrib/ethon/ext.rb +2 -0
- data/lib/ddtrace/contrib/ethon/integration.rb +1 -0
- data/lib/ddtrace/contrib/ethon/multi_patch.rb +6 -1
- data/lib/ddtrace/contrib/ethon/patcher.rb +4 -2
- data/lib/ddtrace/contrib/excon/configuration/settings.rb +1 -0
- data/lib/ddtrace/contrib/excon/ext.rb +1 -0
- data/lib/ddtrace/contrib/excon/integration.rb +1 -0
- data/lib/ddtrace/contrib/excon/middleware.rb +14 -7
- data/lib/ddtrace/contrib/excon/patcher.rb +1 -0
- data/lib/ddtrace/contrib/extensions.rb +90 -14
- data/lib/ddtrace/contrib/faraday/configuration/settings.rb +1 -0
- data/lib/ddtrace/contrib/faraday/connection.rb +1 -0
- data/lib/ddtrace/contrib/faraday/ext.rb +1 -0
- data/lib/ddtrace/contrib/faraday/integration.rb +1 -0
- data/lib/ddtrace/contrib/faraday/middleware.rb +6 -3
- data/lib/ddtrace/contrib/faraday/patcher.rb +3 -38
- data/lib/ddtrace/contrib/faraday/rack_builder.rb +1 -0
- data/lib/ddtrace/contrib/grape/configuration/settings.rb +8 -0
- data/lib/ddtrace/contrib/grape/endpoint.rb +73 -35
- data/lib/ddtrace/contrib/grape/ext.rb +2 -0
- data/lib/ddtrace/contrib/grape/instrumentation.rb +4 -3
- data/lib/ddtrace/contrib/grape/integration.rb +1 -0
- data/lib/ddtrace/contrib/grape/patcher.rb +2 -43
- data/lib/ddtrace/contrib/graphql/configuration/settings.rb +1 -0
- data/lib/ddtrace/contrib/graphql/ext.rb +1 -0
- data/lib/ddtrace/contrib/graphql/integration.rb +1 -0
- data/lib/ddtrace/contrib/graphql/patcher.rb +1 -0
- data/lib/ddtrace/contrib/grpc/configuration/settings.rb +2 -0
- data/lib/ddtrace/contrib/grpc/datadog_interceptor/client.rb +6 -1
- data/lib/ddtrace/contrib/grpc/datadog_interceptor/server.rb +5 -1
- data/lib/ddtrace/contrib/grpc/datadog_interceptor.rb +13 -8
- data/lib/ddtrace/contrib/grpc/ext.rb +1 -0
- data/lib/ddtrace/contrib/grpc/integration.rb +1 -0
- data/lib/ddtrace/contrib/grpc/intercept_with_datadog.rb +1 -0
- data/lib/ddtrace/contrib/grpc/patcher.rb +3 -37
- data/lib/ddtrace/contrib/http/circuit_breaker.rb +2 -3
- data/lib/ddtrace/contrib/http/configuration/settings.rb +1 -0
- data/lib/ddtrace/contrib/http/ext.rb +1 -0
- data/lib/ddtrace/contrib/http/instrumentation.rb +13 -8
- data/lib/ddtrace/contrib/http/integration.rb +1 -0
- data/lib/ddtrace/contrib/http/patcher.rb +2 -1
- data/lib/ddtrace/contrib/http_annotation_helper.rb +1 -0
- data/lib/ddtrace/contrib/httpclient/configuration/settings.rb +33 -0
- data/lib/ddtrace/contrib/httpclient/ext.rb +18 -0
- data/lib/ddtrace/contrib/httpclient/instrumentation.rb +148 -0
- data/lib/ddtrace/contrib/httpclient/integration.rb +44 -0
- data/lib/ddtrace/contrib/httpclient/patcher.rb +39 -0
- data/lib/ddtrace/contrib/httprb/configuration/settings.rb +1 -0
- data/lib/ddtrace/contrib/httprb/ext.rb +1 -0
- data/lib/ddtrace/contrib/httprb/instrumentation.rb +20 -22
- data/lib/ddtrace/contrib/httprb/integration.rb +1 -0
- data/lib/ddtrace/contrib/httprb/patcher.rb +8 -4
- data/lib/ddtrace/contrib/integration.rb +4 -3
- data/lib/ddtrace/contrib/kafka/configuration/settings.rb +1 -0
- data/lib/ddtrace/contrib/kafka/consumer_event.rb +1 -0
- data/lib/ddtrace/contrib/kafka/consumer_group_event.rb +1 -0
- data/lib/ddtrace/contrib/kafka/event.rb +4 -3
- data/lib/ddtrace/contrib/kafka/events/connection/request.rb +1 -0
- data/lib/ddtrace/contrib/kafka/events/consumer/process_batch.rb +1 -0
- data/lib/ddtrace/contrib/kafka/events/consumer/process_message.rb +1 -0
- data/lib/ddtrace/contrib/kafka/events/consumer_group/heartbeat.rb +1 -0
- data/lib/ddtrace/contrib/kafka/events/consumer_group/join_group.rb +1 -0
- data/lib/ddtrace/contrib/kafka/events/consumer_group/leave_group.rb +1 -0
- data/lib/ddtrace/contrib/kafka/events/consumer_group/sync_group.rb +1 -0
- data/lib/ddtrace/contrib/kafka/events/produce_operation/send_messages.rb +1 -0
- data/lib/ddtrace/contrib/kafka/events/producer/deliver_messages.rb +1 -0
- data/lib/ddtrace/contrib/kafka/events.rb +1 -0
- data/lib/ddtrace/contrib/kafka/ext.rb +1 -0
- data/lib/ddtrace/contrib/kafka/integration.rb +1 -0
- data/lib/ddtrace/contrib/kafka/patcher.rb +1 -0
- data/lib/ddtrace/contrib/lograge/configuration/settings.rb +19 -0
- data/lib/ddtrace/contrib/lograge/ext.rb +11 -0
- data/lib/ddtrace/contrib/lograge/instrumentation.rb +39 -0
- data/lib/ddtrace/contrib/lograge/integration.rb +46 -0
- data/lib/ddtrace/contrib/lograge/patcher.rb +26 -0
- data/lib/ddtrace/contrib/mongodb/configuration/settings.rb +1 -0
- data/lib/ddtrace/contrib/mongodb/ext.rb +1 -0
- data/lib/ddtrace/contrib/mongodb/instrumentation.rb +6 -3
- data/lib/ddtrace/contrib/mongodb/integration.rb +6 -0
- data/lib/ddtrace/contrib/mongodb/parsers.rb +1 -0
- data/lib/ddtrace/contrib/mongodb/patcher.rb +3 -2
- data/lib/ddtrace/contrib/mongodb/subscribers.rb +7 -3
- data/lib/ddtrace/contrib/mysql2/configuration/settings.rb +1 -0
- data/lib/ddtrace/contrib/mysql2/ext.rb +1 -0
- data/lib/ddtrace/contrib/mysql2/instrumentation.rb +6 -1
- data/lib/ddtrace/contrib/mysql2/integration.rb +1 -0
- data/lib/ddtrace/contrib/mysql2/patcher.rb +2 -1
- data/lib/ddtrace/contrib/patchable.rb +21 -9
- data/lib/ddtrace/contrib/patcher.rb +12 -8
- data/lib/ddtrace/contrib/presto/configuration/settings.rb +1 -0
- data/lib/ddtrace/contrib/presto/ext.rb +1 -0
- data/lib/ddtrace/contrib/presto/instrumentation.rb +5 -1
- data/lib/ddtrace/contrib/presto/integration.rb +1 -0
- data/lib/ddtrace/contrib/presto/patcher.rb +7 -3
- data/lib/ddtrace/contrib/qless/configuration/settings.rb +36 -0
- data/lib/ddtrace/contrib/qless/ext.rb +21 -0
- data/lib/ddtrace/contrib/qless/integration.rb +39 -0
- data/lib/ddtrace/contrib/qless/patcher.rb +35 -0
- data/lib/ddtrace/contrib/qless/qless_job.rb +74 -0
- data/lib/ddtrace/contrib/qless/tracer_cleaner.rb +34 -0
- data/lib/ddtrace/contrib/que/configuration/settings.rb +2 -0
- data/lib/ddtrace/contrib/que/ext.rb +20 -19
- data/lib/ddtrace/contrib/que/integration.rb +1 -0
- data/lib/ddtrace/contrib/que/patcher.rb +1 -0
- data/lib/ddtrace/contrib/que/tracer.rb +4 -2
- data/lib/ddtrace/contrib/racecar/configuration/settings.rb +1 -0
- data/lib/ddtrace/contrib/racecar/event.rb +8 -2
- data/lib/ddtrace/contrib/racecar/events/batch.rb +1 -0
- data/lib/ddtrace/contrib/racecar/events/consume.rb +1 -0
- data/lib/ddtrace/contrib/racecar/events/message.rb +1 -0
- data/lib/ddtrace/contrib/racecar/events.rb +1 -0
- data/lib/ddtrace/contrib/racecar/ext.rb +1 -0
- data/lib/ddtrace/contrib/racecar/integration.rb +1 -0
- data/lib/ddtrace/contrib/racecar/patcher.rb +1 -0
- data/lib/ddtrace/contrib/rack/configuration/settings.rb +4 -3
- data/lib/ddtrace/contrib/rack/ext.rb +1 -0
- data/lib/ddtrace/contrib/rack/integration.rb +8 -0
- data/lib/ddtrace/contrib/rack/middlewares.rb +8 -12
- data/lib/ddtrace/contrib/rack/patcher.rb +2 -3
- data/lib/ddtrace/contrib/rack/request_queue.rb +7 -1
- data/lib/ddtrace/contrib/rails/auto_instrument_railtie.rb +10 -0
- data/lib/ddtrace/contrib/rails/configuration/settings.rb +8 -0
- data/lib/ddtrace/contrib/rails/ext.rb +1 -0
- data/lib/ddtrace/contrib/rails/framework.rb +50 -2
- data/lib/ddtrace/contrib/rails/integration.rb +1 -0
- data/lib/ddtrace/contrib/rails/log_injection.rb +1 -40
- data/lib/ddtrace/contrib/rails/middlewares.rb +1 -0
- data/lib/ddtrace/contrib/rails/patcher.rb +47 -17
- data/lib/ddtrace/contrib/rails/railtie.rb +1 -0
- data/lib/ddtrace/contrib/rails/utils.rb +5 -0
- data/lib/ddtrace/contrib/rake/configuration/settings.rb +1 -0
- data/lib/ddtrace/contrib/rake/ext.rb +1 -0
- data/lib/ddtrace/contrib/rake/instrumentation.rb +6 -3
- data/lib/ddtrace/contrib/rake/integration.rb +2 -1
- data/lib/ddtrace/contrib/rake/patcher.rb +2 -1
- data/lib/ddtrace/contrib/redis/configuration/resolver.rb +15 -5
- data/lib/ddtrace/contrib/redis/configuration/settings.rb +6 -0
- data/lib/ddtrace/contrib/redis/ext.rb +2 -0
- data/lib/ddtrace/contrib/redis/instrumentation.rb +90 -0
- data/lib/ddtrace/contrib/redis/integration.rb +1 -0
- data/lib/ddtrace/contrib/redis/patcher.rb +3 -67
- data/lib/ddtrace/contrib/redis/quantize.rb +29 -0
- data/lib/ddtrace/contrib/redis/tags.rb +10 -1
- data/lib/ddtrace/contrib/redis/vendor/LICENSE +20 -0
- data/lib/ddtrace/contrib/redis/vendor/resolver.rb +7 -7
- data/lib/ddtrace/contrib/registerable.rb +4 -4
- data/lib/ddtrace/contrib/registry.rb +3 -2
- data/lib/ddtrace/contrib/resque/configuration/settings.rb +19 -1
- data/lib/ddtrace/contrib/resque/ext.rb +1 -0
- data/lib/ddtrace/contrib/resque/integration.rb +2 -5
- data/lib/ddtrace/contrib/resque/patcher.rb +5 -4
- data/lib/ddtrace/contrib/resque/resque_job.rb +26 -2
- data/lib/ddtrace/contrib/rest_client/configuration/settings.rb +1 -0
- data/lib/ddtrace/contrib/rest_client/ext.rb +1 -0
- data/lib/ddtrace/contrib/rest_client/integration.rb +1 -0
- data/lib/ddtrace/contrib/rest_client/patcher.rb +3 -1
- data/lib/ddtrace/contrib/rest_client/request_patch.rb +7 -4
- data/lib/ddtrace/contrib/semantic_logger/configuration/settings.rb +19 -0
- data/lib/ddtrace/contrib/semantic_logger/ext.rb +11 -0
- data/lib/ddtrace/contrib/semantic_logger/instrumentation.rb +43 -0
- data/lib/ddtrace/contrib/semantic_logger/integration.rb +48 -0
- data/lib/ddtrace/contrib/semantic_logger/patcher.rb +26 -0
- data/lib/ddtrace/contrib/sequel/configuration/settings.rb +1 -0
- data/lib/ddtrace/contrib/sequel/database.rb +5 -2
- data/lib/ddtrace/contrib/sequel/dataset.rb +5 -3
- data/lib/ddtrace/contrib/sequel/ext.rb +2 -0
- data/lib/ddtrace/contrib/sequel/integration.rb +1 -0
- data/lib/ddtrace/contrib/sequel/patcher.rb +3 -2
- data/lib/ddtrace/contrib/sequel/utils.rb +16 -5
- data/lib/ddtrace/contrib/shoryuken/configuration/settings.rb +3 -0
- data/lib/ddtrace/contrib/shoryuken/ext.rb +1 -0
- data/lib/ddtrace/contrib/shoryuken/integration.rb +1 -0
- data/lib/ddtrace/contrib/shoryuken/patcher.rb +1 -0
- data/lib/ddtrace/contrib/shoryuken/tracer.rb +9 -2
- data/lib/ddtrace/contrib/sidekiq/client_tracer.rb +1 -0
- data/lib/ddtrace/contrib/sidekiq/configuration/settings.rb +2 -0
- data/lib/ddtrace/contrib/sidekiq/ext.rb +4 -0
- data/lib/ddtrace/contrib/sidekiq/integration.rb +11 -0
- data/lib/ddtrace/contrib/sidekiq/patcher.rb +27 -0
- data/lib/ddtrace/contrib/sidekiq/server_internal_tracer/heartbeat.rb +30 -0
- data/lib/ddtrace/contrib/sidekiq/server_internal_tracer/job_fetch.rb +30 -0
- data/lib/ddtrace/contrib/sidekiq/server_internal_tracer/scheduled_push.rb +29 -0
- data/lib/ddtrace/contrib/sidekiq/server_tracer.rb +6 -7
- data/lib/ddtrace/contrib/sidekiq/tracing.rb +1 -1
- data/lib/ddtrace/contrib/sinatra/configuration/settings.rb +1 -0
- data/lib/ddtrace/contrib/sinatra/env.rb +4 -4
- data/lib/ddtrace/contrib/sinatra/ext.rb +1 -0
- data/lib/ddtrace/contrib/sinatra/headers.rb +2 -3
- data/lib/ddtrace/contrib/sinatra/integration.rb +1 -0
- data/lib/ddtrace/contrib/sinatra/patcher.rb +3 -1
- data/lib/ddtrace/contrib/sinatra/tracer.rb +28 -7
- data/lib/ddtrace/contrib/sinatra/tracer_middleware.rb +13 -6
- data/lib/ddtrace/contrib/sneakers/configuration/settings.rb +2 -0
- data/lib/ddtrace/contrib/sneakers/ext.rb +12 -11
- data/lib/ddtrace/contrib/sneakers/integration.rb +1 -0
- data/lib/ddtrace/contrib/sneakers/patcher.rb +1 -0
- data/lib/ddtrace/contrib/sneakers/tracer.rb +17 -21
- data/lib/ddtrace/contrib/status_code_matcher.rb +70 -0
- data/lib/ddtrace/contrib/sucker_punch/configuration/settings.rb +1 -0
- data/lib/ddtrace/contrib/sucker_punch/exception_handler.rb +5 -6
- data/lib/ddtrace/contrib/sucker_punch/ext.rb +1 -0
- data/lib/ddtrace/contrib/sucker_punch/instrumentation.rb +5 -0
- data/lib/ddtrace/contrib/sucker_punch/integration.rb +1 -0
- data/lib/ddtrace/contrib/sucker_punch/patcher.rb +2 -0
- data/lib/ddtrace/correlation.rb +3 -1
- data/lib/ddtrace/diagnostics/environment_logger.rb +9 -7
- data/lib/ddtrace/diagnostics/health.rb +1 -0
- data/lib/ddtrace/distributed_tracing/headers/b3.rb +1 -0
- data/lib/ddtrace/distributed_tracing/headers/b3_single.rb +1 -0
- data/lib/ddtrace/distributed_tracing/headers/datadog.rb +1 -0
- data/lib/ddtrace/distributed_tracing/headers/headers.rb +2 -0
- data/lib/ddtrace/distributed_tracing/headers/helpers.rb +2 -3
- data/lib/ddtrace/encoding.rb +3 -0
- data/lib/ddtrace/error.rb +78 -8
- data/lib/ddtrace/event.rb +1 -0
- data/lib/ddtrace/ext/analytics.rb +1 -0
- data/lib/ddtrace/ext/app_types.rb +1 -0
- data/lib/ddtrace/ext/correlation.rb +1 -0
- data/lib/ddtrace/ext/diagnostics.rb +1 -0
- data/lib/ddtrace/ext/distributed.rb +9 -2
- data/lib/ddtrace/ext/environment.rb +8 -0
- data/lib/ddtrace/ext/errors.rb +1 -0
- data/lib/ddtrace/ext/forced_tracing.rb +1 -0
- data/lib/ddtrace/ext/git.rb +32 -0
- data/lib/ddtrace/ext/http.rb +2 -1
- data/lib/ddtrace/ext/integration.rb +9 -0
- data/lib/ddtrace/ext/manual_tracing.rb +1 -0
- data/lib/ddtrace/ext/metrics.rb +1 -0
- data/lib/ddtrace/ext/net.rb +1 -0
- data/lib/ddtrace/ext/priority.rb +7 -4
- data/lib/ddtrace/ext/profiling.rb +57 -0
- data/lib/ddtrace/ext/runtime.rb +5 -6
- data/lib/ddtrace/ext/sampling.rb +1 -0
- data/lib/ddtrace/ext/sql.rb +1 -0
- data/lib/ddtrace/ext/test.rb +9 -0
- data/lib/ddtrace/ext/transport.rb +14 -0
- data/lib/ddtrace/forced_tracing.rb +3 -0
- data/lib/ddtrace/logger.rb +2 -1
- data/lib/ddtrace/metrics.rb +84 -24
- data/lib/ddtrace/opentelemetry/extensions.rb +2 -1
- data/lib/ddtrace/opentelemetry/span.rb +1 -0
- data/lib/ddtrace/opentracer/binary_propagator.rb +1 -0
- data/lib/ddtrace/opentracer/carrier.rb +1 -0
- data/lib/ddtrace/opentracer/distributed_headers.rb +5 -1
- data/lib/ddtrace/opentracer/global_tracer.rb +1 -0
- data/lib/ddtrace/opentracer/propagator.rb +1 -0
- data/lib/ddtrace/opentracer/rack_propagator.rb +1 -0
- data/lib/ddtrace/opentracer/scope.rb +1 -0
- data/lib/ddtrace/opentracer/scope_manager.rb +1 -0
- data/lib/ddtrace/opentracer/span.rb +3 -6
- data/lib/ddtrace/opentracer/span_context.rb +1 -0
- data/lib/ddtrace/opentracer/span_context_factory.rb +1 -0
- data/lib/ddtrace/opentracer/text_map_propagator.rb +1 -0
- data/lib/ddtrace/opentracer/thread_local_scope.rb +2 -0
- data/lib/ddtrace/opentracer/thread_local_scope_manager.rb +1 -0
- data/lib/ddtrace/opentracer/tracer.rb +1 -0
- data/lib/ddtrace/opentracer.rb +21 -39
- data/lib/ddtrace/patcher.rb +28 -6
- data/lib/ddtrace/pin.rb +9 -61
- data/lib/ddtrace/pipeline/span_filter.rb +2 -1
- data/lib/ddtrace/pipeline/span_processor.rb +1 -0
- data/lib/ddtrace/pipeline.rb +1 -0
- data/lib/ddtrace/profiling/backtrace_location.rb +33 -0
- data/lib/ddtrace/profiling/buffer.rb +42 -0
- data/lib/ddtrace/profiling/collectors/stack.rb +301 -0
- data/lib/ddtrace/profiling/encoding/profile.rb +46 -0
- data/lib/ddtrace/profiling/event.rb +14 -0
- data/lib/ddtrace/profiling/events/stack.rb +81 -0
- data/lib/ddtrace/profiling/exporter.rb +24 -0
- data/lib/ddtrace/profiling/ext/forking.rb +98 -0
- data/lib/ddtrace/profiling/flush.rb +44 -0
- data/lib/ddtrace/profiling/native_extension.rb +40 -0
- data/lib/ddtrace/profiling/pprof/builder.rb +126 -0
- data/lib/ddtrace/profiling/pprof/converter.rb +103 -0
- data/lib/ddtrace/profiling/pprof/message_set.rb +15 -0
- data/lib/ddtrace/profiling/pprof/payload.rb +19 -0
- data/lib/ddtrace/profiling/pprof/pprof.proto +212 -0
- data/lib/ddtrace/profiling/pprof/pprof_pb.rb +82 -0
- data/lib/ddtrace/profiling/pprof/stack_sample.rb +140 -0
- data/lib/ddtrace/profiling/pprof/string_table.rb +11 -0
- data/lib/ddtrace/profiling/pprof/template.rb +119 -0
- data/lib/ddtrace/profiling/preload.rb +4 -0
- data/lib/ddtrace/profiling/profiler.rb +31 -0
- data/lib/ddtrace/profiling/recorder.rb +96 -0
- data/lib/ddtrace/profiling/scheduler.rb +134 -0
- data/lib/ddtrace/profiling/tasks/setup.rb +90 -0
- data/lib/ddtrace/profiling/trace_identifiers/ddtrace.rb +42 -0
- data/lib/ddtrace/profiling/trace_identifiers/helper.rb +46 -0
- data/lib/ddtrace/profiling/transport/client.rb +15 -0
- data/lib/ddtrace/profiling/transport/http/api/endpoint.rb +101 -0
- data/lib/ddtrace/profiling/transport/http/api/instance.rb +37 -0
- data/lib/ddtrace/profiling/transport/http/api/spec.rb +41 -0
- data/lib/ddtrace/profiling/transport/http/api.rb +44 -0
- data/lib/ddtrace/profiling/transport/http/builder.rb +29 -0
- data/lib/ddtrace/profiling/transport/http/client.rb +34 -0
- data/lib/ddtrace/profiling/transport/http/response.rb +22 -0
- data/lib/ddtrace/profiling/transport/http.rb +111 -0
- data/lib/ddtrace/profiling/transport/io/client.rb +28 -0
- data/lib/ddtrace/profiling/transport/io/response.rb +17 -0
- data/lib/ddtrace/profiling/transport/io.rb +31 -0
- data/lib/ddtrace/profiling/transport/parcel.rb +18 -0
- data/lib/ddtrace/profiling/transport/request.rb +16 -0
- data/lib/ddtrace/profiling/transport/response.rb +9 -0
- data/lib/ddtrace/profiling.rb +149 -0
- data/lib/ddtrace/propagation/grpc_propagator.rb +20 -6
- data/lib/ddtrace/propagation/http_propagator.rb +18 -2
- data/lib/ddtrace/quantization/hash.rb +1 -0
- data/lib/ddtrace/quantization/http.rb +4 -0
- data/lib/ddtrace/runtime/metrics.rb +40 -15
- data/lib/ddtrace/sampler.rb +22 -11
- data/lib/ddtrace/sampling/matcher.rb +1 -0
- data/lib/ddtrace/sampling/rate_limiter.rb +66 -16
- data/lib/ddtrace/sampling/rule.rb +2 -1
- data/lib/ddtrace/sampling/rule_sampler.rb +19 -11
- data/lib/ddtrace/sampling.rb +1 -0
- data/lib/ddtrace/span.rb +174 -36
- data/lib/ddtrace/sync_writer.rb +17 -15
- data/lib/ddtrace/tasks/exec.rb +47 -0
- data/lib/ddtrace/tasks/help.rb +15 -0
- data/lib/ddtrace/tracer.rb +72 -62
- data/lib/ddtrace/transport/http/adapters/net.rb +48 -12
- data/lib/ddtrace/transport/http/adapters/registry.rb +2 -0
- data/lib/ddtrace/transport/http/adapters/test.rb +5 -2
- data/lib/ddtrace/transport/http/adapters/unix_socket.rb +26 -16
- data/lib/ddtrace/transport/http/api/endpoint.rb +1 -0
- data/lib/ddtrace/transport/http/api/fallbacks.rb +1 -0
- data/lib/ddtrace/transport/http/api/instance.rb +1 -0
- data/lib/ddtrace/transport/http/api/map.rb +1 -0
- data/lib/ddtrace/transport/http/api/spec.rb +1 -0
- data/lib/ddtrace/transport/http/api.rb +1 -0
- data/lib/ddtrace/transport/http/builder.rb +21 -7
- data/lib/ddtrace/transport/http/client.rb +3 -1
- data/lib/ddtrace/transport/http/env.rb +9 -0
- data/lib/ddtrace/transport/http/response.rb +1 -0
- data/lib/ddtrace/transport/http/statistics.rb +17 -3
- data/lib/ddtrace/transport/http/traces.rb +6 -6
- data/lib/ddtrace/transport/http.rb +48 -41
- data/lib/ddtrace/transport/io/client.rb +17 -9
- data/lib/ddtrace/transport/io/response.rb +2 -3
- data/lib/ddtrace/transport/io/traces.rb +10 -1
- data/lib/ddtrace/transport/io.rb +2 -1
- data/lib/ddtrace/transport/parcel.rb +7 -0
- data/lib/ddtrace/transport/request.rb +1 -0
- data/lib/ddtrace/transport/response.rb +1 -0
- data/lib/ddtrace/transport/statistics.rb +1 -0
- data/lib/ddtrace/transport/traces.rb +28 -5
- data/lib/ddtrace/utils/compression.rb +28 -0
- data/lib/ddtrace/utils/database.rb +1 -0
- data/lib/ddtrace/utils/forking.rb +53 -0
- data/lib/ddtrace/utils/object_set.rb +40 -0
- data/lib/ddtrace/utils/only_once.rb +41 -0
- data/lib/ddtrace/utils/sequence.rb +18 -0
- data/lib/ddtrace/utils/string_table.rb +46 -0
- data/lib/ddtrace/utils/time.rb +40 -3
- data/lib/ddtrace/utils.rb +29 -14
- data/lib/ddtrace/vendor/active_record/MIT-LICENSE +20 -0
- data/lib/ddtrace/vendor/active_record/connection_specification.rb +1 -0
- data/lib/ddtrace/vendor/multipart-post/LICENSE +11 -0
- data/lib/ddtrace/vendor/multipart-post/multipart/post/composite_read_io.rb +117 -0
- data/lib/ddtrace/vendor/multipart-post/multipart/post/multipartable.rb +58 -0
- data/lib/ddtrace/vendor/multipart-post/multipart/post/parts.rb +136 -0
- data/lib/ddtrace/vendor/multipart-post/multipart/post/version.rb +10 -0
- data/lib/ddtrace/vendor/multipart-post/multipart/post.rb +9 -0
- data/lib/ddtrace/vendor/multipart-post/multipart.rb +13 -0
- data/lib/ddtrace/vendor/multipart-post/net/http/post/multipart.rb +33 -0
- data/lib/ddtrace/version.rb +16 -3
- data/lib/ddtrace/worker.rb +1 -0
- data/lib/ddtrace/workers/async.rb +15 -5
- data/lib/ddtrace/workers/loop.rb +32 -5
- data/lib/ddtrace/workers/polling.rb +13 -5
- data/lib/ddtrace/workers/queue.rb +3 -1
- data/lib/ddtrace/workers/runtime_metrics.rb +22 -4
- data/lib/ddtrace/workers/trace_writer.rb +14 -16
- data/lib/ddtrace/workers.rb +8 -2
- data/lib/ddtrace/writer.rb +33 -8
- data/lib/ddtrace.rb +22 -48
- metadata +180 -374
- data/.circleci/config.yml +0 -548
- data/.circleci/images/primary/Dockerfile-2.0.0 +0 -73
- data/.circleci/images/primary/Dockerfile-2.1.10 +0 -73
- data/.circleci/images/primary/Dockerfile-2.2.10 +0 -73
- data/.circleci/images/primary/Dockerfile-2.3.8 +0 -75
- data/.circleci/images/primary/Dockerfile-2.4.6 +0 -73
- data/.circleci/images/primary/Dockerfile-2.5.6 +0 -73
- data/.circleci/images/primary/Dockerfile-2.6.4 +0 -73
- data/.circleci/images/primary/Dockerfile-2.7.0 +0 -73
- data/.circleci/images/primary/Dockerfile-jruby-9.2 +0 -77
- data/.dockerignore +0 -1
- data/.env +0 -26
- data/.github/CODEOWNERS +0 -1
- data/.gitlab-ci.yml +0 -27
- data/.rspec +0 -1
- data/.rubocop.yml +0 -85
- data/.simplecov +0 -38
- data/Appraisals +0 -1071
- data/Gemfile +0 -7
- data/Rakefile +0 -791
- data/benchmarks/postgres_database.yml +0 -9
- data/benchmarks/sidekiq_test.rb +0 -154
- data/docker-compose.yml +0 -370
- data/lib/ddtrace/augmentation/method_wrapper.rb +0 -20
- data/lib/ddtrace/augmentation/method_wrapping.rb +0 -38
- data/lib/ddtrace/augmentation/shim.rb +0 -102
- data/lib/ddtrace/augmentation.rb +0 -13
- data/lib/ddtrace/environment.rb +0 -41
- data/lib/ddtrace/monkey.rb +0 -58
- data/lib/ddtrace/runtime/cgroup.rb +0 -44
- data/lib/ddtrace/runtime/class_count.rb +0 -17
- data/lib/ddtrace/runtime/container.rb +0 -73
- data/lib/ddtrace/runtime/gc.rb +0 -16
- data/lib/ddtrace/runtime/identity.rb +0 -41
- data/lib/ddtrace/runtime/object_space.rb +0 -19
- data/lib/ddtrace/runtime/socket.rb +0 -14
- data/lib/ddtrace/runtime/thread_count.rb +0 -16
- data/tasks/release_gem.rake +0 -28
|
@@ -0,0 +1,301 @@
|
|
|
1
|
+
# typed: true
|
|
2
|
+
|
|
3
|
+
require 'ddtrace/profiling/native_extension'
|
|
4
|
+
require 'ddtrace/profiling/backtrace_location'
|
|
5
|
+
require 'ddtrace/profiling/events/stack'
|
|
6
|
+
require 'ddtrace/utils/only_once'
|
|
7
|
+
require 'ddtrace/utils/time'
|
|
8
|
+
require 'ddtrace/worker'
|
|
9
|
+
require 'ddtrace/workers/polling'
|
|
10
|
+
|
|
11
|
+
module Datadog
|
|
12
|
+
module Profiling
|
|
13
|
+
module Collectors
|
|
14
|
+
# Collects stack trace samples from Ruby threads for both CPU-time (if available) and wall-clock.
|
|
15
|
+
# Runs on its own background thread.
|
|
16
|
+
#
|
|
17
|
+
class Stack < Worker # rubocop:disable Metrics/ClassLength
|
|
18
|
+
include Workers::Polling
|
|
19
|
+
|
|
20
|
+
DEFAULT_MAX_TIME_USAGE_PCT = 2.0
|
|
21
|
+
MIN_INTERVAL = 0.01
|
|
22
|
+
THREAD_LAST_CPU_TIME_KEY = :datadog_profiler_last_cpu_time
|
|
23
|
+
THREAD_LAST_WALL_CLOCK_KEY = :datadog_profiler_last_wall_clock
|
|
24
|
+
SYNTHETIC_STACK_IN_NATIVE_CODE = [BacktraceLocation.new('', 0, 'In native code').freeze].freeze
|
|
25
|
+
|
|
26
|
+
# This default was picked based on the current sampling performance and on expected concurrency on an average
|
|
27
|
+
# Ruby MRI application. Lowering this optimizes for latency (less impact each time we sample), and raising
|
|
28
|
+
# optimizes for coverage (less chance to miss what a given thread is doing).
|
|
29
|
+
DEFAULT_MAX_THREADS_SAMPLED = 16
|
|
30
|
+
|
|
31
|
+
attr_reader \
|
|
32
|
+
:recorder,
|
|
33
|
+
:max_frames,
|
|
34
|
+
:trace_identifiers_helper,
|
|
35
|
+
:ignore_thread,
|
|
36
|
+
:max_time_usage_pct,
|
|
37
|
+
:thread_api,
|
|
38
|
+
:cpu_time_provider
|
|
39
|
+
|
|
40
|
+
def initialize(
|
|
41
|
+
recorder,
|
|
42
|
+
max_frames:,
|
|
43
|
+
trace_identifiers_helper:, # Usually an instance of Datadog::Profiling::TraceIdentifiers::Helper
|
|
44
|
+
ignore_thread: nil,
|
|
45
|
+
max_time_usage_pct: DEFAULT_MAX_TIME_USAGE_PCT,
|
|
46
|
+
max_threads_sampled: DEFAULT_MAX_THREADS_SAMPLED,
|
|
47
|
+
thread_api: Thread,
|
|
48
|
+
cpu_time_provider: Datadog::Profiling::NativeExtension,
|
|
49
|
+
fork_policy: Workers::Async::Thread::FORK_POLICY_RESTART, # Restart in forks by default
|
|
50
|
+
interval: MIN_INTERVAL,
|
|
51
|
+
enabled: true
|
|
52
|
+
)
|
|
53
|
+
@recorder = recorder
|
|
54
|
+
@max_frames = max_frames
|
|
55
|
+
@trace_identifiers_helper = trace_identifiers_helper
|
|
56
|
+
@ignore_thread = ignore_thread
|
|
57
|
+
@max_time_usage_pct = max_time_usage_pct
|
|
58
|
+
@max_threads_sampled = max_threads_sampled
|
|
59
|
+
@thread_api = thread_api
|
|
60
|
+
# Only set the provider if it's able to work in the current Ruby/OS combo
|
|
61
|
+
@cpu_time_provider = cpu_time_provider unless cpu_time_provider.cpu_time_ns_for(thread_api.current).nil?
|
|
62
|
+
|
|
63
|
+
# Workers::Async::Thread settings
|
|
64
|
+
self.fork_policy = fork_policy
|
|
65
|
+
|
|
66
|
+
# Workers::IntervalLoop settings
|
|
67
|
+
self.loop_base_interval = interval
|
|
68
|
+
|
|
69
|
+
# Workers::Polling settings
|
|
70
|
+
self.enabled = enabled
|
|
71
|
+
|
|
72
|
+
# Cache this proc, since it's pretty expensive to keep recreating it
|
|
73
|
+
@build_backtrace_location = method(:build_backtrace_location).to_proc
|
|
74
|
+
# Cache this buffer, since it's pretty expensive to keep accessing it
|
|
75
|
+
@stack_sample_event_recorder = recorder[Events::StackSample]
|
|
76
|
+
# See below for details on why this is needed
|
|
77
|
+
@needs_process_waiter_workaround =
|
|
78
|
+
Gem::Version.new(RUBY_VERSION) >= Gem::Version.new('2.3') &&
|
|
79
|
+
Gem::Version.new(RUBY_VERSION) < Gem::Version.new('2.7')
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
def start
|
|
83
|
+
reset_cpu_time_tracking
|
|
84
|
+
perform
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
def perform
|
|
88
|
+
collect_and_wait
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
def loop_back_off?
|
|
92
|
+
false
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
def collect_and_wait
|
|
96
|
+
run_time = Datadog::Utils::Time.measure do
|
|
97
|
+
collect_events
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
# Update wait time to throttle profiling
|
|
101
|
+
self.loop_wait_time = compute_wait_time(run_time)
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
def collect_events
|
|
105
|
+
events = []
|
|
106
|
+
current_wall_time_ns = get_current_wall_time_timestamp_ns
|
|
107
|
+
|
|
108
|
+
# Collect backtraces from each thread
|
|
109
|
+
threads_to_sample.each do |thread|
|
|
110
|
+
next unless thread.alive?
|
|
111
|
+
next if ignore_thread.is_a?(Proc) && ignore_thread.call(thread)
|
|
112
|
+
|
|
113
|
+
event = collect_thread_event(thread, current_wall_time_ns)
|
|
114
|
+
events << event unless event.nil?
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
# Send events to recorder
|
|
118
|
+
recorder.push(events) unless events.empty?
|
|
119
|
+
|
|
120
|
+
events
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
def collect_thread_event(thread, current_wall_time_ns)
|
|
124
|
+
locations = thread.backtrace_locations
|
|
125
|
+
return if locations.nil?
|
|
126
|
+
|
|
127
|
+
# Having empty locations means that the thread is alive, but we don't know what it's doing:
|
|
128
|
+
#
|
|
129
|
+
# 1. It can be starting up
|
|
130
|
+
# ```
|
|
131
|
+
# > Thread.new { sleep }.backtrace
|
|
132
|
+
# => [] # <-- note the thread hasn't actually started running sleep yet, we got there first
|
|
133
|
+
# ```
|
|
134
|
+
# 2. It can be running native code
|
|
135
|
+
# ```
|
|
136
|
+
# > t = Process.detach(fork { sleep })
|
|
137
|
+
# => #<Process::Waiter:0x00007ffe7285f7a0 run>
|
|
138
|
+
# > t.backtrace
|
|
139
|
+
# => [] # <-- this can happen even minutes later, e.g. it's not a race as in 1.
|
|
140
|
+
# ```
|
|
141
|
+
# This effect has been observed in threads created by the Iodine web server and the ffi gem
|
|
142
|
+
#
|
|
143
|
+
# To give customers visibility into these threads, we replace the empty stack with one containing a
|
|
144
|
+
# synthetic placeholder frame, so that these threads are properly represented in the UX.
|
|
145
|
+
locations = SYNTHETIC_STACK_IN_NATIVE_CODE if locations.empty?
|
|
146
|
+
|
|
147
|
+
# Get actual stack size then trim the stack
|
|
148
|
+
stack_size = locations.length
|
|
149
|
+
locations = locations[0..(max_frames - 1)]
|
|
150
|
+
|
|
151
|
+
# Convert backtrace locations into structs
|
|
152
|
+
locations = convert_backtrace_locations(locations)
|
|
153
|
+
|
|
154
|
+
thread_id = thread.object_id
|
|
155
|
+
root_span_id, span_id, trace_resource = trace_identifiers_helper.trace_identifiers_for(thread)
|
|
156
|
+
cpu_time = get_cpu_time_interval!(thread)
|
|
157
|
+
wall_time_interval_ns =
|
|
158
|
+
get_elapsed_since_last_sample_and_set_value(thread, THREAD_LAST_WALL_CLOCK_KEY, current_wall_time_ns)
|
|
159
|
+
|
|
160
|
+
Events::StackSample.new(
|
|
161
|
+
nil,
|
|
162
|
+
locations,
|
|
163
|
+
stack_size,
|
|
164
|
+
thread_id,
|
|
165
|
+
root_span_id,
|
|
166
|
+
span_id,
|
|
167
|
+
trace_resource,
|
|
168
|
+
cpu_time,
|
|
169
|
+
wall_time_interval_ns
|
|
170
|
+
)
|
|
171
|
+
end
|
|
172
|
+
|
|
173
|
+
def get_cpu_time_interval!(thread)
|
|
174
|
+
return unless cpu_time_provider
|
|
175
|
+
|
|
176
|
+
current_cpu_time_ns = cpu_time_provider.cpu_time_ns_for(thread)
|
|
177
|
+
|
|
178
|
+
return unless current_cpu_time_ns
|
|
179
|
+
|
|
180
|
+
get_elapsed_since_last_sample_and_set_value(thread, THREAD_LAST_CPU_TIME_KEY, current_cpu_time_ns)
|
|
181
|
+
end
|
|
182
|
+
|
|
183
|
+
def compute_wait_time(used_time)
|
|
184
|
+
# We took used_time to get the last sample.
|
|
185
|
+
#
|
|
186
|
+
# What we're computing here is -- if used_time corresponds to max_time_usage_pct of the time we should
|
|
187
|
+
# spend working, how much is (100% - max_time_usage_pct) of the time?
|
|
188
|
+
#
|
|
189
|
+
# For instance, if we took 10ms to sample, and max_time_usage_pct is 1%, then the other 99% is 990ms, which
|
|
190
|
+
# means we need to sleep for 990ms to guarantee that we don't spend more than 1% of the time working.
|
|
191
|
+
used_time_ns = used_time * 1e9
|
|
192
|
+
interval = (used_time_ns / (max_time_usage_pct / 100.0)) - used_time_ns
|
|
193
|
+
[interval / 1e9, MIN_INTERVAL].max
|
|
194
|
+
end
|
|
195
|
+
|
|
196
|
+
# Convert backtrace locations into structs
|
|
197
|
+
# Re-use old backtrace location objects if they already exist in the buffer
|
|
198
|
+
def convert_backtrace_locations(locations)
|
|
199
|
+
locations.collect do |location|
|
|
200
|
+
# Re-use existing BacktraceLocation if identical copy, otherwise build a new one.
|
|
201
|
+
@stack_sample_event_recorder.cache(:backtrace_locations).fetch(
|
|
202
|
+
# Function name
|
|
203
|
+
location.base_label,
|
|
204
|
+
# Line number
|
|
205
|
+
location.lineno,
|
|
206
|
+
# Filename
|
|
207
|
+
location.path,
|
|
208
|
+
# Build function
|
|
209
|
+
&@build_backtrace_location
|
|
210
|
+
)
|
|
211
|
+
end
|
|
212
|
+
end
|
|
213
|
+
|
|
214
|
+
def build_backtrace_location(_id, base_label, lineno, path)
|
|
215
|
+
string_table = @stack_sample_event_recorder.string_table
|
|
216
|
+
|
|
217
|
+
Profiling::BacktraceLocation.new(
|
|
218
|
+
string_table.fetch_string(base_label),
|
|
219
|
+
lineno,
|
|
220
|
+
string_table.fetch_string(path)
|
|
221
|
+
)
|
|
222
|
+
end
|
|
223
|
+
|
|
224
|
+
private
|
|
225
|
+
|
|
226
|
+
# If the profiler is started for a while, stopped and then restarted OR whenever the process forks, we need to
|
|
227
|
+
# clean up any leftover per-thread counters, so that the first sample after starting doesn't end up with:
|
|
228
|
+
#
|
|
229
|
+
# a) negative time: At least on my test docker container, and on the reliability environment, after the process
|
|
230
|
+
# forks, the cpu time reference changes and (old cpu time - new cpu time) can be < 0
|
|
231
|
+
#
|
|
232
|
+
# b) large amount of time: if the profiler was started, then stopped for some amount of time, and then
|
|
233
|
+
# restarted, we don't want the first sample to be "blamed" for multiple minutes of CPU time
|
|
234
|
+
#
|
|
235
|
+
# By resetting the last cpu time seen, we start with a clean slate every time we start the stack collector.
|
|
236
|
+
def reset_cpu_time_tracking
|
|
237
|
+
thread_api.list.each do |thread|
|
|
238
|
+
# See below for details on why this is needed
|
|
239
|
+
next if @needs_process_waiter_workaround && thread.is_a?(::Process::Waiter)
|
|
240
|
+
|
|
241
|
+
thread.thread_variable_set(THREAD_LAST_CPU_TIME_KEY, nil)
|
|
242
|
+
thread.thread_variable_set(THREAD_LAST_WALL_CLOCK_KEY, nil)
|
|
243
|
+
end
|
|
244
|
+
end
|
|
245
|
+
|
|
246
|
+
def get_elapsed_since_last_sample_and_set_value(thread, key, current_value)
|
|
247
|
+
# Process::Waiter crash workaround:
|
|
248
|
+
#
|
|
249
|
+
# This is a workaround for a Ruby VM segfault (usually something like
|
|
250
|
+
# "[BUG] Segmentation fault at 0x0000000000000008") in the affected Ruby versions.
|
|
251
|
+
# See https://bugs.ruby-lang.org/issues/17807 for details.
|
|
252
|
+
#
|
|
253
|
+
# In those Ruby versions, there's a very special subclass of `Thread` called `Process::Waiter` that causes VM
|
|
254
|
+
# crashes whenever something tries to read its instance or thread variables. This subclass of thread only
|
|
255
|
+
# shows up when the `Process.detach` API gets used.
|
|
256
|
+
# In the specs you'll find crash regression tests that include a way of reproducing it.
|
|
257
|
+
#
|
|
258
|
+
# As workaround for now we just skip it for the affected Rubies
|
|
259
|
+
return 0 if @needs_process_waiter_workaround && thread.is_a?(::Process::Waiter)
|
|
260
|
+
|
|
261
|
+
last_value = thread.thread_variable_get(key) || current_value
|
|
262
|
+
thread.thread_variable_set(key, current_value)
|
|
263
|
+
|
|
264
|
+
current_value - last_value
|
|
265
|
+
end
|
|
266
|
+
|
|
267
|
+
# Whenever there are more than max_threads_sampled active, we only sample a subset of them.
|
|
268
|
+
# We do this to avoid impacting the latency of the service being profiled. We want to avoid doing
|
|
269
|
+
# a big burst of work all at once (sample everything), and instead do a little work each time
|
|
270
|
+
# (sample a bit by bit).
|
|
271
|
+
#
|
|
272
|
+
# Because we pick the threads to sample randomly, we'll eventually sample all threads -- just not at once.
|
|
273
|
+
# Notice also that this will interact with our dynamic sampling mechanism -- if samples are faster, we take
|
|
274
|
+
# them more often, if they are slower, we take them less often -- which again means that over a longer period
|
|
275
|
+
# we should take sample roughly the same samples.
|
|
276
|
+
#
|
|
277
|
+
# One downside of this approach is that if there really are many threads, the resulting wall clock times
|
|
278
|
+
# in a one minute profile may "drift" around the 60 second mark, e.g. maybe we only sampled a thread once per
|
|
279
|
+
# second and only 59 times, so we'll report 59s, but on the next report we'll include the missing one, so
|
|
280
|
+
# then the result will be 61s. I've observed 60 +- 1.68 secs for an app with ~65 threads, given the
|
|
281
|
+
# default maximum of 16 threads. This seems a reasonable enough margin of error given the improvement to
|
|
282
|
+
# latency (especially on such a large application! -> even bigger latency impact if we tried to sample all
|
|
283
|
+
# threads).
|
|
284
|
+
#
|
|
285
|
+
def threads_to_sample
|
|
286
|
+
all_threads = thread_api.list
|
|
287
|
+
|
|
288
|
+
if all_threads.size > @max_threads_sampled
|
|
289
|
+
all_threads.sample(@max_threads_sampled)
|
|
290
|
+
else
|
|
291
|
+
all_threads
|
|
292
|
+
end
|
|
293
|
+
end
|
|
294
|
+
|
|
295
|
+
def get_current_wall_time_timestamp_ns
|
|
296
|
+
Datadog::Utils::Time.get_time(:nanosecond)
|
|
297
|
+
end
|
|
298
|
+
end
|
|
299
|
+
end
|
|
300
|
+
end
|
|
301
|
+
end
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
# typed: true
|
|
2
|
+
require 'set'
|
|
3
|
+
require 'time'
|
|
4
|
+
|
|
5
|
+
require 'ddtrace/profiling/flush'
|
|
6
|
+
require 'ddtrace/profiling/pprof/template'
|
|
7
|
+
|
|
8
|
+
module Datadog
|
|
9
|
+
module Profiling
|
|
10
|
+
module Encoding
|
|
11
|
+
module Profile
|
|
12
|
+
# Encodes gathered data into the pprof format
|
|
13
|
+
module Protobuf
|
|
14
|
+
module_function
|
|
15
|
+
|
|
16
|
+
def encode(flush)
|
|
17
|
+
return unless flush
|
|
18
|
+
|
|
19
|
+
# Create a pprof template from the list of event types
|
|
20
|
+
event_classes = flush.event_groups.collect(&:event_class).uniq
|
|
21
|
+
template = Pprof::Template.for_event_classes(event_classes)
|
|
22
|
+
|
|
23
|
+
# Add all events to the pprof
|
|
24
|
+
flush.event_groups.each { |event_group| template.add_events!(event_group.event_class, event_group.events) }
|
|
25
|
+
|
|
26
|
+
Datadog.logger.debug do
|
|
27
|
+
max_events = Datadog.configuration.profiling.advanced.max_events
|
|
28
|
+
events_sampled =
|
|
29
|
+
if flush.event_count == max_events
|
|
30
|
+
'max events limit hit, events were sampled [profile will be biased], '
|
|
31
|
+
else
|
|
32
|
+
''
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
"Encoding profile covering #{flush.start.iso8601} to #{flush.finish.iso8601}, " \
|
|
36
|
+
"events: #{flush.event_count} (#{events_sampled}#{template.debug_statistics})"
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
# Build the profile and encode it
|
|
40
|
+
template.to_pprof(start: flush.start, finish: flush.finish)
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
end
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
# typed: true
|
|
2
|
+
module Datadog
|
|
3
|
+
module Profiling
|
|
4
|
+
# Describes a sample of some data obtained from the runtime.
|
|
5
|
+
class Event
|
|
6
|
+
attr_reader \
|
|
7
|
+
:timestamp
|
|
8
|
+
|
|
9
|
+
def initialize(timestamp = nil)
|
|
10
|
+
@timestamp = timestamp || Time.now.utc.to_f
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
end
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
# typed: true
|
|
2
|
+
require 'ddtrace/profiling/event'
|
|
3
|
+
|
|
4
|
+
module Datadog
|
|
5
|
+
module Profiling
|
|
6
|
+
module Events
|
|
7
|
+
# Describes a stack profiling event
|
|
8
|
+
class Stack < Event
|
|
9
|
+
attr_reader \
|
|
10
|
+
:hash,
|
|
11
|
+
:frames,
|
|
12
|
+
:total_frame_count,
|
|
13
|
+
:thread_id,
|
|
14
|
+
:root_span_id,
|
|
15
|
+
:span_id,
|
|
16
|
+
:trace_resource
|
|
17
|
+
|
|
18
|
+
def initialize(
|
|
19
|
+
timestamp,
|
|
20
|
+
frames,
|
|
21
|
+
total_frame_count,
|
|
22
|
+
thread_id,
|
|
23
|
+
root_span_id,
|
|
24
|
+
span_id,
|
|
25
|
+
trace_resource
|
|
26
|
+
)
|
|
27
|
+
super(timestamp)
|
|
28
|
+
|
|
29
|
+
@frames = frames
|
|
30
|
+
@total_frame_count = total_frame_count
|
|
31
|
+
@thread_id = thread_id
|
|
32
|
+
@root_span_id = root_span_id
|
|
33
|
+
@span_id = span_id
|
|
34
|
+
@trace_resource = trace_resource
|
|
35
|
+
|
|
36
|
+
@hash = [
|
|
37
|
+
thread_id,
|
|
38
|
+
root_span_id,
|
|
39
|
+
span_id,
|
|
40
|
+
# trace_resource is deliberately not included -- events that share the same (root_span_id, span_id) refer
|
|
41
|
+
# to the same trace
|
|
42
|
+
frames.collect(&:hash),
|
|
43
|
+
total_frame_count
|
|
44
|
+
].hash
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
# Describes a stack sample
|
|
49
|
+
class StackSample < Stack
|
|
50
|
+
attr_reader \
|
|
51
|
+
:cpu_time_interval_ns,
|
|
52
|
+
:wall_time_interval_ns
|
|
53
|
+
|
|
54
|
+
def initialize(
|
|
55
|
+
timestamp,
|
|
56
|
+
frames,
|
|
57
|
+
total_frame_count,
|
|
58
|
+
thread_id,
|
|
59
|
+
root_span_id,
|
|
60
|
+
span_id,
|
|
61
|
+
trace_resource,
|
|
62
|
+
cpu_time_interval_ns,
|
|
63
|
+
wall_time_interval_ns
|
|
64
|
+
)
|
|
65
|
+
super(
|
|
66
|
+
timestamp,
|
|
67
|
+
frames,
|
|
68
|
+
total_frame_count,
|
|
69
|
+
thread_id,
|
|
70
|
+
root_span_id,
|
|
71
|
+
span_id,
|
|
72
|
+
trace_resource
|
|
73
|
+
)
|
|
74
|
+
|
|
75
|
+
@cpu_time_interval_ns = cpu_time_interval_ns
|
|
76
|
+
@wall_time_interval_ns = wall_time_interval_ns
|
|
77
|
+
end
|
|
78
|
+
end
|
|
79
|
+
end
|
|
80
|
+
end
|
|
81
|
+
end
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
# typed: true
|
|
2
|
+
require 'ddtrace/profiling/transport/io/client'
|
|
3
|
+
|
|
4
|
+
module Datadog
|
|
5
|
+
module Profiling
|
|
6
|
+
# Writes profiling data to a given transport
|
|
7
|
+
class Exporter
|
|
8
|
+
attr_reader \
|
|
9
|
+
:transport
|
|
10
|
+
|
|
11
|
+
def initialize(transport)
|
|
12
|
+
unless transport.is_a?(Profiling::Transport::Client)
|
|
13
|
+
raise ArgumentError, 'Unsupported transport for profiling exporter.'
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
@transport = transport
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def export(flush)
|
|
20
|
+
transport.send_profiling_flush(flush)
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
# typed: false
|
|
2
|
+
module Datadog
|
|
3
|
+
module Profiling
|
|
4
|
+
module Ext
|
|
5
|
+
# Monkey patches `Kernel#fork`, adding a `Kernel#at_fork` callback mechanism which is used to restore
|
|
6
|
+
# profiling abilities after the VM forks.
|
|
7
|
+
module Forking
|
|
8
|
+
def self.supported?
|
|
9
|
+
Process.respond_to?(:fork)
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def self.apply!
|
|
13
|
+
return false unless supported?
|
|
14
|
+
|
|
15
|
+
modules = [::Process, ::Kernel]
|
|
16
|
+
# TODO: Ruby < 2.3 doesn't support Binding#receiver.
|
|
17
|
+
# Remove "else #eval" clause when Ruby < 2.3 support is dropped.
|
|
18
|
+
# NOTE: Modifying the "main" object as we do here is (as far as I know) irreversible. During tests, this change
|
|
19
|
+
# will stick around even if we otherwise stub `Process` and `Kernel`.
|
|
20
|
+
modules << (TOPLEVEL_BINDING.respond_to?(:receiver) ? TOPLEVEL_BINDING.receiver : TOPLEVEL_BINDING.eval('self'))
|
|
21
|
+
|
|
22
|
+
# Patch top-level binding, Kernel, Process.
|
|
23
|
+
# NOTE: We could instead do Kernel.module_eval { def fork; ... end }
|
|
24
|
+
# however, this method rewrite is more invasive and irreversible.
|
|
25
|
+
# It could also have collisions with other libraries that patch.
|
|
26
|
+
# Opt to modify the inheritance of each relevant target instead.
|
|
27
|
+
modules.each do |mod|
|
|
28
|
+
clazz = if mod.class <= Module
|
|
29
|
+
mod.singleton_class
|
|
30
|
+
else
|
|
31
|
+
mod.class
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
clazz.prepend(Kernel)
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
# Extensions for kernel
|
|
39
|
+
module Kernel
|
|
40
|
+
FORK_STAGES = [:prepare, :parent, :child].freeze
|
|
41
|
+
|
|
42
|
+
def fork
|
|
43
|
+
# If a block is provided, it must be wrapped to trigger callbacks.
|
|
44
|
+
child_block = if block_given?
|
|
45
|
+
proc do
|
|
46
|
+
# Trigger :child callback
|
|
47
|
+
at_fork_blocks[:child].each(&:call) if at_fork_blocks.key?(:child)
|
|
48
|
+
|
|
49
|
+
# Invoke original block
|
|
50
|
+
yield
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
# Trigger :prepare callback
|
|
55
|
+
at_fork_blocks[:prepare].each(&:call) if at_fork_blocks.key?(:prepare)
|
|
56
|
+
|
|
57
|
+
# Start fork
|
|
58
|
+
# If a block is provided, use the wrapped version.
|
|
59
|
+
result = child_block.nil? ? super : super(&child_block)
|
|
60
|
+
|
|
61
|
+
# Trigger correct callbacks depending on whether we're in the parent or child.
|
|
62
|
+
# If we're in the fork, result = nil: trigger child callbacks.
|
|
63
|
+
# If we're in the parent, result = fork PID: trigger parent callbacks.
|
|
64
|
+
# rubocop:disable Style/IfInsideElse
|
|
65
|
+
if result.nil?
|
|
66
|
+
# Trigger :child callback
|
|
67
|
+
at_fork_blocks[:child].each(&:call) if at_fork_blocks.key?(:child)
|
|
68
|
+
else
|
|
69
|
+
# Trigger :parent callback
|
|
70
|
+
at_fork_blocks[:parent].each(&:call) if at_fork_blocks.key?(:parent)
|
|
71
|
+
end
|
|
72
|
+
# rubocop:enable Style/IfInsideElse
|
|
73
|
+
|
|
74
|
+
# Return PID from #fork
|
|
75
|
+
result
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
def at_fork(stage = :prepare, &block)
|
|
79
|
+
raise ArgumentError, 'Bad \'stage\' for ::at_fork' unless FORK_STAGES.include?(stage)
|
|
80
|
+
|
|
81
|
+
at_fork_blocks[stage] = [] unless at_fork_blocks.key?(stage)
|
|
82
|
+
at_fork_blocks[stage] << block
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
module_function
|
|
86
|
+
|
|
87
|
+
def at_fork_blocks
|
|
88
|
+
# Blocks should be shared across all users of this module,
|
|
89
|
+
# e.g. Process#fork, Kernel#fork, etc. should all invoke the same callbacks.
|
|
90
|
+
# rubocop:disable Style/ClassVars
|
|
91
|
+
@@at_fork_blocks ||= {}
|
|
92
|
+
# rubocop:enable Style/ClassVars
|
|
93
|
+
end
|
|
94
|
+
end
|
|
95
|
+
end
|
|
96
|
+
end
|
|
97
|
+
end
|
|
98
|
+
end
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
# typed: false
|
|
2
|
+
require 'datadog/core/environment/identity'
|
|
3
|
+
require 'datadog/core/environment/socket'
|
|
4
|
+
|
|
5
|
+
module Datadog
|
|
6
|
+
module Profiling
|
|
7
|
+
# Entity class used to represent metadata for a given profile
|
|
8
|
+
Flush = Struct.new(
|
|
9
|
+
:start,
|
|
10
|
+
:finish,
|
|
11
|
+
:event_groups,
|
|
12
|
+
:event_count,
|
|
13
|
+
:runtime_id,
|
|
14
|
+
:service,
|
|
15
|
+
:env,
|
|
16
|
+
:version,
|
|
17
|
+
:host,
|
|
18
|
+
:language,
|
|
19
|
+
:runtime_engine,
|
|
20
|
+
:runtime_platform,
|
|
21
|
+
:runtime_version,
|
|
22
|
+
:profiler_version,
|
|
23
|
+
:tags
|
|
24
|
+
) do
|
|
25
|
+
def initialize(*args)
|
|
26
|
+
super
|
|
27
|
+
self.runtime_id = runtime_id || Datadog::Core::Environment::Identity.id
|
|
28
|
+
self.service = service || Datadog.configuration.service
|
|
29
|
+
self.env = env || Datadog.configuration.env
|
|
30
|
+
self.version = version || Datadog.configuration.version
|
|
31
|
+
self.host = host || Datadog::Core::Environment::Socket.hostname
|
|
32
|
+
self.language = language || Datadog::Core::Environment::Identity.lang
|
|
33
|
+
self.runtime_engine = runtime_engine || Datadog::Core::Environment::Identity.lang_engine
|
|
34
|
+
self.runtime_platform = runtime_platform || Datadog::Core::Environment::Identity.lang_platform
|
|
35
|
+
self.runtime_version = runtime_version || Datadog::Core::Environment::Identity.lang_version
|
|
36
|
+
self.profiler_version = profiler_version || Datadog::Core::Environment::Identity.tracer_version
|
|
37
|
+
self.tags = tags || Datadog.configuration.tags
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
# Represents a collection of events of a specific type being flushed.
|
|
42
|
+
EventGroup = Struct.new(:event_class, :events).freeze
|
|
43
|
+
end
|
|
44
|
+
end
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
# typed: true
|
|
2
|
+
module Datadog
|
|
3
|
+
module Profiling
|
|
4
|
+
# This module contains classes and methods which are implemented using native code in the
|
|
5
|
+
# ext/ddtrace_profiling_native_extension folder, as well as some Ruby-level utilities that don't make sense to
|
|
6
|
+
# write using C
|
|
7
|
+
module NativeExtension
|
|
8
|
+
private_class_method def self.working?
|
|
9
|
+
native_working?
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
unless singleton_class.private_method_defined?(:native_working?)
|
|
13
|
+
private_class_method def self.native_working?
|
|
14
|
+
false
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
unless singleton_class.method_defined?(:clock_id_for)
|
|
19
|
+
def self.clock_id_for(_)
|
|
20
|
+
nil
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def self.cpu_time_ns_for(thread)
|
|
25
|
+
clock_id =
|
|
26
|
+
begin
|
|
27
|
+
clock_id_for(thread)
|
|
28
|
+
rescue Errno::ESRCH
|
|
29
|
+
nil
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
begin
|
|
33
|
+
::Process.clock_gettime(clock_id, :nanosecond) if clock_id
|
|
34
|
+
rescue Errno::EINVAL
|
|
35
|
+
nil
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
end
|