datadog 2.7.1 → 2.18.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +353 -1
- data/ext/datadog_profiling_native_extension/clock_id.h +2 -2
- data/ext/datadog_profiling_native_extension/collectors_cpu_and_wall_time_worker.c +78 -102
- data/ext/datadog_profiling_native_extension/collectors_discrete_dynamic_sampler.c +1 -1
- data/ext/datadog_profiling_native_extension/collectors_discrete_dynamic_sampler.h +1 -1
- data/ext/datadog_profiling_native_extension/collectors_idle_sampling_helper.c +16 -16
- data/ext/datadog_profiling_native_extension/collectors_stack.c +235 -57
- data/ext/datadog_profiling_native_extension/collectors_stack.h +21 -5
- data/ext/datadog_profiling_native_extension/collectors_thread_context.c +376 -156
- data/ext/datadog_profiling_native_extension/collectors_thread_context.h +1 -0
- data/ext/datadog_profiling_native_extension/datadog_ruby_common.c +1 -4
- data/ext/datadog_profiling_native_extension/datadog_ruby_common.h +10 -0
- data/ext/datadog_profiling_native_extension/encoded_profile.c +79 -0
- data/ext/datadog_profiling_native_extension/encoded_profile.h +8 -0
- data/ext/datadog_profiling_native_extension/extconf.rb +14 -8
- data/ext/datadog_profiling_native_extension/gvl_profiling_helper.c +2 -0
- data/ext/datadog_profiling_native_extension/gvl_profiling_helper.h +0 -8
- data/ext/datadog_profiling_native_extension/heap_recorder.c +295 -532
- data/ext/datadog_profiling_native_extension/heap_recorder.h +6 -8
- data/ext/datadog_profiling_native_extension/http_transport.c +64 -98
- data/ext/datadog_profiling_native_extension/libdatadog_helpers.c +22 -0
- data/ext/datadog_profiling_native_extension/libdatadog_helpers.h +8 -5
- data/ext/datadog_profiling_native_extension/private_vm_api_access.c +69 -1
- data/ext/datadog_profiling_native_extension/private_vm_api_access.h +16 -4
- data/ext/datadog_profiling_native_extension/profiling.c +19 -8
- data/ext/datadog_profiling_native_extension/ruby_helpers.c +9 -21
- data/ext/datadog_profiling_native_extension/ruby_helpers.h +2 -10
- data/ext/datadog_profiling_native_extension/stack_recorder.c +231 -181
- data/ext/datadog_profiling_native_extension/stack_recorder.h +2 -2
- data/ext/datadog_profiling_native_extension/time_helpers.h +1 -1
- data/ext/datadog_profiling_native_extension/unsafe_api_calls_check.c +47 -0
- data/ext/datadog_profiling_native_extension/unsafe_api_calls_check.h +31 -0
- data/ext/libdatadog_api/crashtracker.c +17 -15
- data/ext/libdatadog_api/crashtracker.h +5 -0
- data/ext/libdatadog_api/datadog_ruby_common.c +1 -4
- data/ext/libdatadog_api/datadog_ruby_common.h +10 -0
- data/ext/libdatadog_api/extconf.rb +2 -2
- data/ext/libdatadog_api/init.c +15 -0
- data/ext/libdatadog_api/library_config.c +164 -0
- data/ext/libdatadog_api/library_config.h +25 -0
- data/ext/libdatadog_api/macos_development.md +3 -3
- data/ext/libdatadog_api/process_discovery.c +112 -0
- data/ext/libdatadog_api/process_discovery.h +5 -0
- data/ext/libdatadog_extconf_helpers.rb +2 -2
- data/lib/datadog/appsec/actions_handler/serializable_backtrace.rb +89 -0
- data/lib/datadog/appsec/actions_handler.rb +49 -0
- data/lib/datadog/appsec/anonymizer.rb +16 -0
- data/lib/datadog/appsec/api_security/lru_cache.rb +56 -0
- data/lib/datadog/appsec/api_security/route_extractor.rb +65 -0
- data/lib/datadog/appsec/api_security/sampler.rb +59 -0
- data/lib/datadog/appsec/api_security.rb +23 -0
- data/lib/datadog/appsec/assets/waf_rules/README.md +50 -5
- data/lib/datadog/appsec/assets/waf_rules/recommended.json +623 -253
- data/lib/datadog/appsec/assets/waf_rules/strict.json +69 -107
- data/lib/datadog/appsec/autoload.rb +1 -1
- data/lib/datadog/appsec/component.rb +49 -65
- data/lib/datadog/appsec/compressed_json.rb +40 -0
- data/lib/datadog/appsec/configuration/settings.rb +212 -27
- data/lib/datadog/appsec/context.rb +74 -0
- data/lib/datadog/appsec/contrib/active_record/instrumentation.rb +92 -0
- data/lib/datadog/appsec/contrib/active_record/integration.rb +41 -0
- data/lib/datadog/appsec/contrib/active_record/patcher.rb +101 -0
- data/lib/datadog/appsec/contrib/auto_instrument.rb +1 -1
- data/lib/datadog/appsec/contrib/devise/configuration.rb +52 -0
- data/lib/datadog/appsec/contrib/devise/data_extractor.rb +78 -0
- data/lib/datadog/appsec/contrib/devise/ext.rb +22 -0
- data/lib/datadog/appsec/contrib/devise/integration.rb +1 -2
- data/lib/datadog/appsec/contrib/devise/patcher.rb +33 -25
- data/lib/datadog/appsec/contrib/devise/patches/signin_tracking_patch.rb +102 -0
- data/lib/datadog/appsec/contrib/devise/patches/signup_tracking_patch.rb +69 -0
- data/lib/datadog/appsec/contrib/devise/{patcher/rememberable_patch.rb → patches/skip_signin_tracking_patch.rb} +3 -3
- data/lib/datadog/appsec/contrib/devise/tracking_middleware.rb +106 -0
- data/lib/datadog/appsec/contrib/excon/integration.rb +41 -0
- data/lib/datadog/appsec/contrib/excon/patcher.rb +28 -0
- data/lib/datadog/appsec/contrib/excon/ssrf_detection_middleware.rb +42 -0
- data/lib/datadog/appsec/contrib/faraday/connection_patch.rb +22 -0
- data/lib/datadog/appsec/contrib/faraday/integration.rb +42 -0
- data/lib/datadog/appsec/contrib/faraday/patcher.rb +53 -0
- data/lib/datadog/appsec/contrib/faraday/rack_builder_patch.rb +22 -0
- data/lib/datadog/appsec/contrib/faraday/ssrf_detection_middleware.rb +41 -0
- data/lib/datadog/appsec/contrib/graphql/appsec_trace.rb +1 -7
- data/lib/datadog/appsec/contrib/graphql/gateway/watcher.rb +17 -30
- data/lib/datadog/appsec/contrib/graphql/integration.rb +1 -1
- data/lib/datadog/appsec/contrib/graphql/patcher.rb +0 -3
- data/lib/datadog/appsec/contrib/rack/ext.rb +34 -0
- data/lib/datadog/appsec/contrib/rack/gateway/response.rb +3 -3
- data/lib/datadog/appsec/contrib/rack/gateway/watcher.rb +78 -98
- data/lib/datadog/appsec/contrib/rack/integration.rb +1 -1
- data/lib/datadog/appsec/contrib/rack/patcher.rb +0 -3
- data/lib/datadog/appsec/contrib/rack/request_body_middleware.rb +10 -11
- data/lib/datadog/appsec/contrib/rack/request_middleware.rb +73 -78
- data/lib/datadog/appsec/contrib/rails/gateway/watcher.rb +16 -33
- data/lib/datadog/appsec/contrib/rails/integration.rb +1 -1
- data/lib/datadog/appsec/contrib/rails/patcher.rb +25 -38
- data/lib/datadog/appsec/contrib/rest_client/integration.rb +45 -0
- data/lib/datadog/appsec/contrib/rest_client/patcher.rb +28 -0
- data/lib/datadog/appsec/contrib/rest_client/request_ssrf_detection_patch.rb +38 -0
- data/lib/datadog/appsec/contrib/sinatra/gateway/watcher.rb +31 -68
- data/lib/datadog/appsec/contrib/sinatra/integration.rb +1 -1
- data/lib/datadog/appsec/contrib/sinatra/patcher.rb +5 -31
- data/lib/datadog/appsec/event.rb +96 -135
- data/lib/datadog/appsec/ext.rb +12 -3
- data/lib/datadog/appsec/instrumentation/gateway/argument.rb +7 -2
- data/lib/datadog/appsec/instrumentation/gateway/middleware.rb +24 -0
- data/lib/datadog/appsec/instrumentation/gateway.rb +17 -22
- data/lib/datadog/appsec/metrics/collector.rb +38 -0
- data/lib/datadog/appsec/metrics/exporter.rb +35 -0
- data/lib/datadog/appsec/metrics/telemetry.rb +23 -0
- data/lib/datadog/appsec/metrics.rb +13 -0
- data/lib/datadog/appsec/monitor/gateway/watcher.rb +52 -32
- data/lib/datadog/appsec/processor/rule_loader.rb +30 -36
- data/lib/datadog/appsec/remote.rb +31 -57
- data/lib/datadog/appsec/response.rb +19 -85
- data/lib/datadog/appsec/security_engine/engine.rb +194 -0
- data/lib/datadog/appsec/security_engine/result.rb +67 -0
- data/lib/datadog/appsec/security_engine/runner.rb +87 -0
- data/lib/datadog/appsec/security_engine.rb +9 -0
- data/lib/datadog/appsec/security_event.rb +39 -0
- data/lib/datadog/appsec/utils.rb +0 -2
- data/lib/datadog/appsec.rb +22 -12
- data/lib/datadog/auto_instrument.rb +3 -0
- data/lib/datadog/core/buffer/random.rb +18 -2
- data/lib/datadog/core/configuration/agent_settings.rb +52 -0
- data/lib/datadog/core/configuration/agent_settings_resolver.rb +4 -18
- data/lib/datadog/core/configuration/agentless_settings_resolver.rb +176 -0
- data/lib/datadog/core/configuration/components.rb +74 -32
- data/lib/datadog/core/configuration/components_state.rb +23 -0
- data/lib/datadog/core/configuration/ext.rb +5 -1
- data/lib/datadog/core/configuration/option.rb +81 -45
- data/lib/datadog/core/configuration/option_definition.rb +6 -4
- data/lib/datadog/core/configuration/options.rb +3 -3
- data/lib/datadog/core/configuration/settings.rb +121 -50
- data/lib/datadog/core/configuration/stable_config.rb +22 -0
- data/lib/datadog/core/configuration.rb +43 -11
- data/lib/datadog/{tracing → core}/contrib/rails/utils.rb +1 -3
- data/lib/datadog/core/crashtracking/component.rb +4 -13
- data/lib/datadog/core/crashtracking/tag_builder.rb +4 -22
- data/lib/datadog/core/diagnostics/environment_logger.rb +1 -1
- data/lib/datadog/core/encoding.rb +17 -1
- data/lib/datadog/core/environment/agent_info.rb +78 -0
- data/lib/datadog/core/environment/cgroup.rb +10 -12
- data/lib/datadog/core/environment/container.rb +38 -40
- data/lib/datadog/core/environment/ext.rb +6 -6
- data/lib/datadog/core/environment/git.rb +1 -0
- data/lib/datadog/core/environment/identity.rb +3 -3
- data/lib/datadog/core/environment/platform.rb +3 -3
- data/lib/datadog/core/environment/variable_helpers.rb +1 -1
- data/lib/datadog/core/error.rb +11 -9
- data/lib/datadog/core/logger.rb +2 -2
- data/lib/datadog/core/metrics/client.rb +27 -27
- data/lib/datadog/core/metrics/logging.rb +5 -5
- data/lib/datadog/core/process_discovery/tracer_memfd.rb +15 -0
- data/lib/datadog/core/process_discovery.rb +36 -0
- data/lib/datadog/core/rate_limiter.rb +4 -2
- data/lib/datadog/core/remote/client/capabilities.rb +6 -0
- data/lib/datadog/core/remote/client.rb +107 -92
- data/lib/datadog/core/remote/component.rb +18 -19
- data/lib/datadog/core/remote/configuration/digest.rb +7 -7
- data/lib/datadog/core/remote/configuration/path.rb +1 -1
- data/lib/datadog/core/remote/configuration/repository.rb +14 -1
- data/lib/datadog/core/remote/negotiation.rb +9 -9
- data/lib/datadog/core/remote/transport/config.rb +4 -3
- data/lib/datadog/core/remote/transport/http/api.rb +13 -18
- data/lib/datadog/core/remote/transport/http/client.rb +5 -4
- data/lib/datadog/core/remote/transport/http/config.rb +27 -55
- data/lib/datadog/core/remote/transport/http/negotiation.rb +8 -51
- data/lib/datadog/core/remote/transport/http.rb +25 -94
- data/lib/datadog/core/remote/transport/negotiation.rb +17 -4
- data/lib/datadog/core/remote/worker.rb +10 -7
- data/lib/datadog/core/runtime/metrics.rb +12 -5
- data/lib/datadog/core/tag_builder.rb +56 -0
- data/lib/datadog/core/telemetry/component.rb +84 -49
- data/lib/datadog/core/telemetry/emitter.rb +23 -11
- data/lib/datadog/core/telemetry/event/app_client_configuration_change.rb +66 -0
- data/lib/datadog/core/telemetry/event/app_closing.rb +18 -0
- data/lib/datadog/core/telemetry/event/app_dependencies_loaded.rb +33 -0
- data/lib/datadog/core/telemetry/event/app_heartbeat.rb +18 -0
- data/lib/datadog/core/telemetry/event/app_integrations_change.rb +58 -0
- data/lib/datadog/core/telemetry/event/app_started.rb +269 -0
- data/lib/datadog/core/telemetry/event/base.rb +40 -0
- data/lib/datadog/core/telemetry/event/distributions.rb +18 -0
- data/lib/datadog/core/telemetry/event/generate_metrics.rb +43 -0
- data/lib/datadog/core/telemetry/event/log.rb +76 -0
- data/lib/datadog/core/telemetry/event/message_batch.rb +42 -0
- data/lib/datadog/core/telemetry/event/synth_app_client_configuration_change.rb +43 -0
- data/lib/datadog/core/telemetry/event.rb +17 -383
- data/lib/datadog/core/telemetry/ext.rb +1 -0
- data/lib/datadog/core/telemetry/http/adapters/net.rb +12 -97
- data/lib/datadog/core/telemetry/logger.rb +5 -4
- data/lib/datadog/core/telemetry/logging.rb +12 -6
- data/lib/datadog/core/telemetry/metric.rb +28 -6
- data/lib/datadog/core/telemetry/request.rb +4 -4
- data/lib/datadog/core/telemetry/transport/http/api.rb +43 -0
- data/lib/datadog/core/telemetry/transport/http/client.rb +49 -0
- data/lib/datadog/core/telemetry/transport/http/telemetry.rb +92 -0
- data/lib/datadog/core/telemetry/transport/http.rb +63 -0
- data/lib/datadog/core/telemetry/transport/telemetry.rb +51 -0
- data/lib/datadog/core/telemetry/worker.rb +128 -25
- data/lib/datadog/core/transport/http/adapters/net.rb +17 -2
- data/lib/datadog/core/transport/http/adapters/test.rb +2 -1
- data/lib/datadog/core/transport/http/adapters/unix_socket.rb +1 -1
- data/lib/datadog/{tracing → core}/transport/http/api/instance.rb +18 -1
- data/lib/datadog/core/transport/http/api/spec.rb +36 -0
- data/lib/datadog/{tracing → core}/transport/http/builder.rb +53 -31
- data/lib/datadog/core/transport/http/env.rb +8 -0
- data/lib/datadog/core/transport/http.rb +75 -0
- data/lib/datadog/core/transport/response.rb +4 -0
- data/lib/datadog/core/utils/at_fork_monkey_patch.rb +6 -6
- data/lib/datadog/core/utils/duration.rb +32 -32
- data/lib/datadog/core/utils/forking.rb +2 -2
- data/lib/datadog/core/utils/network.rb +6 -6
- data/lib/datadog/core/utils/only_once_successful.rb +16 -5
- data/lib/datadog/core/utils/time.rb +20 -0
- data/lib/datadog/core/utils/truncation.rb +21 -0
- data/lib/datadog/core/utils.rb +7 -0
- data/lib/datadog/core/vendor/multipart-post/multipart/post/composite_read_io.rb +1 -1
- data/lib/datadog/core/vendor/multipart-post/multipart/post/multipartable.rb +8 -8
- data/lib/datadog/core/vendor/multipart-post/multipart/post/parts.rb +7 -7
- data/lib/datadog/core/worker.rb +1 -1
- data/lib/datadog/core/workers/async.rb +29 -12
- data/lib/datadog/core/workers/interval_loop.rb +12 -1
- data/lib/datadog/core/workers/runtime_metrics.rb +2 -2
- data/lib/datadog/core.rb +8 -0
- data/lib/datadog/di/base.rb +115 -0
- data/lib/datadog/di/boot.rb +34 -0
- data/lib/datadog/di/code_tracker.rb +26 -15
- data/lib/datadog/di/component.rb +23 -14
- data/lib/datadog/di/configuration/settings.rb +25 -1
- data/lib/datadog/di/contrib/active_record.rb +1 -0
- data/lib/datadog/di/contrib/railtie.rb +15 -0
- data/lib/datadog/di/contrib.rb +28 -0
- data/lib/datadog/di/error.rb +5 -0
- data/lib/datadog/di/instrumenter.rb +162 -21
- data/lib/datadog/di/logger.rb +30 -0
- data/lib/datadog/di/preload.rb +18 -0
- data/lib/datadog/di/probe.rb +14 -7
- data/lib/datadog/di/probe_builder.rb +1 -0
- data/lib/datadog/di/probe_manager.rb +11 -5
- data/lib/datadog/di/probe_notification_builder.rb +54 -38
- data/lib/datadog/di/probe_notifier_worker.rb +60 -26
- data/lib/datadog/di/redactor.rb +0 -1
- data/lib/datadog/di/remote.rb +147 -0
- data/lib/datadog/di/serializer.rb +19 -8
- data/lib/datadog/di/transport/diagnostics.rb +62 -0
- data/lib/datadog/di/transport/http/api.rb +42 -0
- data/lib/datadog/di/transport/http/client.rb +47 -0
- data/lib/datadog/di/transport/http/diagnostics.rb +65 -0
- data/lib/datadog/di/transport/http/input.rb +77 -0
- data/lib/datadog/di/transport/http.rb +57 -0
- data/lib/datadog/di/transport/input.rb +70 -0
- data/lib/datadog/di/utils.rb +103 -0
- data/lib/datadog/di.rb +14 -76
- data/lib/datadog/error_tracking/collector.rb +87 -0
- data/lib/datadog/error_tracking/component.rb +167 -0
- data/lib/datadog/error_tracking/configuration/settings.rb +63 -0
- data/lib/datadog/error_tracking/configuration.rb +11 -0
- data/lib/datadog/error_tracking/ext.rb +18 -0
- data/lib/datadog/error_tracking/extensions.rb +16 -0
- data/lib/datadog/error_tracking/filters.rb +77 -0
- data/lib/datadog/error_tracking.rb +18 -0
- data/lib/datadog/kit/appsec/events.rb +15 -3
- data/lib/datadog/kit/identity.rb +9 -5
- data/lib/datadog/opentelemetry/api/baggage.rb +90 -0
- data/lib/datadog/opentelemetry/api/baggage.rbs +26 -0
- data/lib/datadog/opentelemetry/api/context.rb +16 -2
- data/lib/datadog/opentelemetry/sdk/trace/span.rb +1 -1
- data/lib/datadog/opentelemetry.rb +2 -1
- data/lib/datadog/profiling/collectors/code_provenance.rb +18 -9
- data/lib/datadog/profiling/collectors/cpu_and_wall_time_worker.rb +4 -0
- data/lib/datadog/profiling/collectors/idle_sampling_helper.rb +1 -0
- data/lib/datadog/profiling/collectors/info.rb +3 -0
- data/lib/datadog/profiling/collectors/thread_context.rb +17 -2
- data/lib/datadog/profiling/component.rb +64 -82
- data/lib/datadog/profiling/encoded_profile.rb +11 -0
- data/lib/datadog/profiling/exporter.rb +3 -4
- data/lib/datadog/profiling/ext.rb +0 -14
- data/lib/datadog/profiling/flush.rb +5 -8
- data/lib/datadog/profiling/http_transport.rb +8 -87
- data/lib/datadog/profiling/load_native_extension.rb +1 -33
- data/lib/datadog/profiling/profiler.rb +2 -0
- data/lib/datadog/profiling/scheduler.rb +10 -2
- data/lib/datadog/profiling/stack_recorder.rb +9 -9
- data/lib/datadog/profiling/tag_builder.rb +5 -41
- data/lib/datadog/profiling/tasks/setup.rb +2 -0
- data/lib/datadog/profiling.rb +6 -2
- data/lib/datadog/tracing/analytics.rb +1 -1
- data/lib/datadog/tracing/component.rb +16 -12
- data/lib/datadog/tracing/configuration/ext.rb +8 -1
- data/lib/datadog/tracing/configuration/settings.rb +22 -10
- data/lib/datadog/tracing/context_provider.rb +1 -1
- data/lib/datadog/tracing/contrib/action_cable/integration.rb +5 -2
- data/lib/datadog/tracing/contrib/action_mailer/integration.rb +6 -2
- data/lib/datadog/tracing/contrib/action_pack/action_controller/instrumentation.rb +15 -0
- data/lib/datadog/tracing/contrib/action_pack/action_dispatch/instrumentation.rb +19 -12
- data/lib/datadog/tracing/contrib/action_pack/ext.rb +2 -0
- data/lib/datadog/tracing/contrib/action_pack/integration.rb +5 -2
- data/lib/datadog/tracing/contrib/action_view/integration.rb +5 -2
- data/lib/datadog/tracing/contrib/active_job/integration.rb +5 -2
- data/lib/datadog/tracing/contrib/active_record/integration.rb +7 -3
- data/lib/datadog/tracing/contrib/active_support/cache/events/cache.rb +7 -2
- data/lib/datadog/tracing/contrib/active_support/cache/instrumentation.rb +36 -1
- data/lib/datadog/tracing/contrib/active_support/cache/patcher.rb +4 -0
- data/lib/datadog/tracing/contrib/active_support/cache/redis.rb +14 -4
- data/lib/datadog/tracing/contrib/active_support/configuration/settings.rb +10 -0
- data/lib/datadog/tracing/contrib/active_support/integration.rb +5 -2
- data/lib/datadog/tracing/contrib/auto_instrument.rb +2 -2
- data/lib/datadog/tracing/contrib/aws/instrumentation.rb +10 -0
- data/lib/datadog/tracing/contrib/aws/integration.rb +3 -0
- data/lib/datadog/tracing/contrib/aws/parsed_context.rb +5 -1
- data/lib/datadog/tracing/contrib/concurrent_ruby/integration.rb +3 -0
- data/lib/datadog/tracing/contrib/configuration/settings.rb +1 -1
- data/lib/datadog/tracing/contrib/elasticsearch/configuration/settings.rb +4 -0
- data/lib/datadog/tracing/contrib/elasticsearch/patcher.rb +6 -1
- data/lib/datadog/tracing/contrib/ethon/easy_patch.rb +4 -5
- data/lib/datadog/tracing/contrib/excon/middleware.rb +5 -3
- data/lib/datadog/tracing/contrib/ext.rb +1 -0
- data/lib/datadog/tracing/contrib/extensions.rb +29 -3
- data/lib/datadog/tracing/contrib/faraday/middleware.rb +5 -3
- data/lib/datadog/tracing/contrib/graphql/configuration/error_extension_env_parser.rb +21 -0
- data/lib/datadog/tracing/contrib/graphql/configuration/settings.rb +11 -0
- data/lib/datadog/tracing/contrib/graphql/ext.rb +5 -0
- data/lib/datadog/tracing/contrib/graphql/unified_trace.rb +102 -11
- data/lib/datadog/tracing/contrib/grpc/datadog_interceptor/client.rb +7 -1
- data/lib/datadog/tracing/contrib/grpc/distributed/propagation.rb +3 -0
- data/lib/datadog/tracing/contrib/http/circuit_breaker.rb +0 -15
- data/lib/datadog/tracing/contrib/http/distributed/propagation.rb +4 -1
- data/lib/datadog/tracing/contrib/http/instrumentation.rb +6 -10
- data/lib/datadog/tracing/contrib/http/integration.rb +3 -0
- data/lib/datadog/tracing/contrib/httpclient/instrumentation.rb +6 -16
- data/lib/datadog/tracing/contrib/httprb/instrumentation.rb +7 -15
- data/lib/datadog/tracing/contrib/httprb/integration.rb +3 -0
- data/lib/datadog/tracing/contrib/kafka/integration.rb +3 -0
- data/lib/datadog/tracing/contrib/karafka/configuration/settings.rb +27 -0
- data/lib/datadog/tracing/contrib/karafka/distributed/propagation.rb +48 -0
- data/lib/datadog/tracing/contrib/karafka/ext.rb +27 -0
- data/lib/datadog/tracing/contrib/karafka/integration.rb +45 -0
- data/lib/datadog/tracing/contrib/karafka/monitor.rb +66 -0
- data/lib/datadog/tracing/contrib/karafka/patcher.rb +71 -0
- data/lib/datadog/tracing/contrib/karafka.rb +37 -0
- data/lib/datadog/tracing/contrib/lograge/patcher.rb +4 -2
- data/lib/datadog/tracing/contrib/mongodb/configuration/settings.rb +8 -0
- data/lib/datadog/tracing/contrib/mongodb/ext.rb +1 -0
- data/lib/datadog/tracing/contrib/mongodb/integration.rb +3 -0
- data/lib/datadog/tracing/contrib/mongodb/subscribers.rb +18 -1
- data/lib/datadog/tracing/contrib/opensearch/configuration/settings.rb +17 -0
- data/lib/datadog/tracing/contrib/opensearch/ext.rb +9 -0
- data/lib/datadog/tracing/contrib/opensearch/integration.rb +3 -0
- data/lib/datadog/tracing/contrib/opensearch/patcher.rb +5 -1
- data/lib/datadog/tracing/contrib/patcher.rb +5 -2
- data/lib/datadog/tracing/contrib/presto/integration.rb +3 -0
- data/lib/datadog/tracing/contrib/rack/header_collection.rb +11 -1
- data/lib/datadog/tracing/contrib/rack/integration.rb +2 -2
- data/lib/datadog/tracing/contrib/rack/middlewares.rb +1 -1
- data/lib/datadog/tracing/contrib/rack/request_queue.rb +1 -1
- data/lib/datadog/tracing/contrib/rails/framework.rb +2 -2
- data/lib/datadog/tracing/contrib/rails/patcher.rb +1 -1
- data/lib/datadog/tracing/contrib/rest_client/integration.rb +3 -0
- data/lib/datadog/tracing/contrib/rest_client/request_patch.rb +5 -3
- data/lib/datadog/tracing/contrib/sidekiq/client_tracer.rb +6 -1
- data/lib/datadog/tracing/contrib/sidekiq/distributed/propagation.rb +3 -0
- data/lib/datadog/tracing/contrib/sidekiq/ext.rb +1 -0
- data/lib/datadog/tracing/contrib/sidekiq/server_tracer.rb +5 -2
- data/lib/datadog/tracing/contrib/span_attribute_schema.rb +6 -1
- data/lib/datadog/tracing/contrib/support.rb +28 -0
- data/lib/datadog/tracing/contrib.rb +1 -0
- data/lib/datadog/tracing/correlation.rb +9 -2
- data/lib/datadog/tracing/distributed/b3_multi.rb +1 -1
- data/lib/datadog/tracing/distributed/b3_single.rb +1 -1
- data/lib/datadog/tracing/distributed/baggage.rb +131 -0
- data/lib/datadog/tracing/distributed/datadog.rb +4 -2
- data/lib/datadog/tracing/distributed/propagation.rb +25 -4
- data/lib/datadog/tracing/distributed/propagation_policy.rb +42 -0
- data/lib/datadog/tracing/metadata/errors.rb +4 -4
- data/lib/datadog/tracing/metadata/ext.rb +5 -0
- data/lib/datadog/tracing/metadata/metastruct.rb +36 -0
- data/lib/datadog/tracing/metadata/metastruct_tagging.rb +42 -0
- data/lib/datadog/tracing/metadata.rb +2 -0
- data/lib/datadog/tracing/sampling/rate_sampler.rb +2 -1
- data/lib/datadog/tracing/sampling/span/rule.rb +0 -1
- data/lib/datadog/tracing/span.rb +22 -5
- data/lib/datadog/tracing/span_event.rb +124 -4
- data/lib/datadog/tracing/span_operation.rb +52 -16
- data/lib/datadog/tracing/sync_writer.rb +10 -6
- data/lib/datadog/tracing/trace_digest.rb +9 -2
- data/lib/datadog/tracing/trace_operation.rb +55 -27
- data/lib/datadog/tracing/trace_segment.rb +6 -4
- data/lib/datadog/tracing/tracer.rb +66 -14
- data/lib/datadog/tracing/transport/http/api.rb +5 -4
- data/lib/datadog/tracing/transport/http/client.rb +5 -4
- data/lib/datadog/tracing/transport/http/traces.rb +13 -44
- data/lib/datadog/tracing/transport/http.rb +13 -70
- data/lib/datadog/tracing/transport/serializable_trace.rb +31 -7
- data/lib/datadog/tracing/transport/trace_formatter.rb +7 -0
- data/lib/datadog/tracing/transport/traces.rb +47 -13
- data/lib/datadog/tracing/utils.rb +1 -1
- data/lib/datadog/tracing/workers/trace_writer.rb +8 -5
- data/lib/datadog/tracing/workers.rb +5 -4
- data/lib/datadog/tracing/writer.rb +10 -6
- data/lib/datadog/tracing.rb +16 -3
- data/lib/datadog/version.rb +2 -2
- data/lib/datadog.rb +2 -0
- metadata +149 -54
- data/ext/datadog_profiling_loader/datadog_profiling_loader.c +0 -142
- data/ext/datadog_profiling_loader/extconf.rb +0 -60
- data/lib/datadog/appsec/assets/waf_rules/processors.json +0 -92
- data/lib/datadog/appsec/assets/waf_rules/scanners.json +0 -114
- data/lib/datadog/appsec/contrib/devise/event.rb +0 -57
- data/lib/datadog/appsec/contrib/devise/patcher/authenticatable_patch.rb +0 -77
- data/lib/datadog/appsec/contrib/devise/patcher/registration_controller_patch.rb +0 -54
- data/lib/datadog/appsec/contrib/devise/resource.rb +0 -35
- data/lib/datadog/appsec/contrib/devise/tracking.rb +0 -57
- data/lib/datadog/appsec/contrib/graphql/reactive/multiplex.rb +0 -46
- data/lib/datadog/appsec/contrib/patcher.rb +0 -12
- data/lib/datadog/appsec/contrib/rack/reactive/request.rb +0 -69
- data/lib/datadog/appsec/contrib/rack/reactive/request_body.rb +0 -47
- data/lib/datadog/appsec/contrib/rack/reactive/response.rb +0 -53
- data/lib/datadog/appsec/contrib/rails/reactive/action.rb +0 -53
- data/lib/datadog/appsec/contrib/sinatra/ext.rb +0 -14
- data/lib/datadog/appsec/contrib/sinatra/reactive/routed.rb +0 -48
- data/lib/datadog/appsec/monitor/reactive/set_user.rb +0 -45
- data/lib/datadog/appsec/processor/actions.rb +0 -49
- data/lib/datadog/appsec/processor/context.rb +0 -107
- data/lib/datadog/appsec/processor/rule_merger.rb +0 -170
- data/lib/datadog/appsec/processor.rb +0 -106
- data/lib/datadog/appsec/reactive/address_hash.rb +0 -22
- data/lib/datadog/appsec/reactive/engine.rb +0 -47
- data/lib/datadog/appsec/reactive/operation.rb +0 -68
- data/lib/datadog/appsec/reactive/subscriber.rb +0 -19
- data/lib/datadog/appsec/scope.rb +0 -58
- data/lib/datadog/appsec/utils/trace_operation.rb +0 -15
- data/lib/datadog/core/crashtracking/agent_base_url.rb +0 -21
- data/lib/datadog/core/remote/transport/http/api/instance.rb +0 -39
- data/lib/datadog/core/remote/transport/http/api/spec.rb +0 -21
- data/lib/datadog/core/remote/transport/http/builder.rb +0 -219
- data/lib/datadog/core/telemetry/http/env.rb +0 -20
- data/lib/datadog/core/telemetry/http/ext.rb +0 -28
- data/lib/datadog/core/telemetry/http/response.rb +0 -70
- data/lib/datadog/core/telemetry/http/transport.rb +0 -90
- data/lib/datadog/di/transport.rb +0 -81
- data/lib/datadog/tracing/transport/http/api/spec.rb +0 -19
@@ -1,8 +1,8 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
|
3
|
+
require_relative '../core/utils/time'
|
4
4
|
|
5
|
-
|
5
|
+
# rubocop:disable Lint/AssignmentInCondition
|
6
6
|
|
7
7
|
module Datadog
|
8
8
|
module DI
|
@@ -52,6 +52,17 @@ module Datadog
|
|
52
52
|
# (however, Probe instances can be replaced by OpenStruct instances
|
53
53
|
# providing the same interface with not much effort).
|
54
54
|
#
|
55
|
+
# Instrumenter (this class) is responsible for building snapshots.
|
56
|
+
# This is because to capture values on method entry, those values need to
|
57
|
+
# be duplicated or serialized into immutable values to prevent their
|
58
|
+
# modification by the instrumented method. Therefore this class must
|
59
|
+
# do at least some serialization/snapshot building and to keep the code
|
60
|
+
# well-encapsulated, all serialization/snapshot building should thus be
|
61
|
+
# initiated from this class rather than downstream code.
|
62
|
+
#
|
63
|
+
# As a consequence of Instrumenter building snapshots, it should not
|
64
|
+
# expose TracePoint objects to any downstream code.
|
65
|
+
#
|
55
66
|
# @api private
|
56
67
|
class Instrumenter
|
57
68
|
def initialize(settings, serializer, logger, code_tracker: nil, telemetry: nil)
|
@@ -92,34 +103,90 @@ module Datadog
|
|
92
103
|
cls = symbolize_class_name(probe.type_name)
|
93
104
|
serializer = self.serializer
|
94
105
|
method_name = probe.method_name
|
95
|
-
|
96
|
-
|
106
|
+
loc = begin
|
107
|
+
cls.instance_method(method_name).source_location
|
108
|
+
rescue NameError
|
109
|
+
# The target method is not defined.
|
110
|
+
# This could be because it will be explicitly defined later
|
111
|
+
# (since classes can be reopened in Ruby)
|
112
|
+
# or the method is virtual (provided by a method_missing handler).
|
113
|
+
# In these cases we do not have a source location for the
|
114
|
+
# target method here.
|
115
|
+
end
|
97
116
|
rate_limiter = probe.rate_limiter
|
117
|
+
settings = self.settings
|
98
118
|
|
99
119
|
mod = Module.new do
|
100
|
-
define_method(method_name) do |*args, **kwargs| # steep:ignore
|
120
|
+
define_method(method_name) do |*args, **kwargs, &target_block| # steep:ignore
|
101
121
|
if rate_limiter.nil? || rate_limiter.allow?
|
102
122
|
# Arguments may be mutated by the method, therefore
|
103
123
|
# they need to be serialized prior to method invocation.
|
104
124
|
entry_args = if probe.capture_snapshot?
|
105
|
-
|
125
|
+
instance_vars = Instrumenter.get_instance_variables(self)
|
126
|
+
serializer.serialize_args(args, kwargs, instance_vars,
|
127
|
+
depth: probe.max_capture_depth || settings.dynamic_instrumentation.max_capture_depth,
|
128
|
+
attribute_count: probe.max_capture_attribute_count || settings.dynamic_instrumentation.max_capture_attribute_count)
|
106
129
|
end
|
107
|
-
|
108
|
-
|
109
|
-
|
130
|
+
start_time = Core::Utils::Time.get_time
|
131
|
+
# Under Ruby 2.6 we cannot just call super(*args, **kwargs)
|
132
|
+
# for methods defined via method_missing.
|
133
|
+
rv = if args.any?
|
134
|
+
if kwargs.any?
|
135
|
+
super(*args, **kwargs, &target_block)
|
136
|
+
else
|
137
|
+
super(*args, &target_block)
|
138
|
+
end
|
139
|
+
elsif kwargs.any?
|
140
|
+
super(**kwargs, &target_block)
|
141
|
+
else
|
142
|
+
super(&target_block)
|
110
143
|
end
|
144
|
+
duration = Core::Utils::Time.get_time - start_time
|
111
145
|
# The method itself is not part of the stack trace because
|
112
146
|
# we are getting the stack trace from outside of the method.
|
113
147
|
# Add the method in manually as the top frame.
|
114
|
-
method_frame =
|
115
|
-
|
148
|
+
method_frame = if loc
|
149
|
+
[Location.new(loc.first, loc.last, method_name)]
|
150
|
+
else
|
151
|
+
# For virtual and lazily-defined methods, we do not have
|
152
|
+
# the original source location here, and they won't be
|
153
|
+
# included in the stack trace currently.
|
154
|
+
# TODO when begin/end trace points are added for local
|
155
|
+
# variable capture in method probes, we should be able
|
156
|
+
# to obtain actual method execution location and use
|
157
|
+
# that location here.
|
158
|
+
[]
|
159
|
+
end
|
160
|
+
caller_locs = method_frame + caller_locations # steep:ignore
|
116
161
|
# TODO capture arguments at exit
|
117
162
|
# & is to stop steep complaints, block is always present here.
|
118
163
|
block&.call(probe: probe, rv: rv, duration: duration, caller_locations: caller_locs,
|
164
|
+
instance_vars: probe.capture_snapshot? ? Instrumenter.get_instance_variables(self) : nil,
|
119
165
|
serialized_entry_args: entry_args)
|
120
166
|
rv
|
121
167
|
else
|
122
|
-
|
168
|
+
# stop standard from trying to mess up my code
|
169
|
+
_ = 42
|
170
|
+
|
171
|
+
# The necessity to invoke super in each of these specific
|
172
|
+
# ways is very difficult to test.
|
173
|
+
# Existing tests, even though I wrote many, still don't
|
174
|
+
# cause a failure if I replace all of the below with a
|
175
|
+
# simple super(*args, **kwargs, &target_block).
|
176
|
+
# But, let's be safe and go through the motions in case
|
177
|
+
# there is actually a legitimate need for the breakdown.
|
178
|
+
# TODO figure out how to test this properly.
|
179
|
+
if args.any?
|
180
|
+
if kwargs.any?
|
181
|
+
super(*args, **kwargs, &target_block)
|
182
|
+
else
|
183
|
+
super(*args, &target_block)
|
184
|
+
end
|
185
|
+
elsif kwargs.any?
|
186
|
+
super(**kwargs, &target_block)
|
187
|
+
else
|
188
|
+
super(&target_block)
|
189
|
+
end
|
123
190
|
end
|
124
191
|
end
|
125
192
|
end
|
@@ -191,11 +258,12 @@ module Datadog
|
|
191
258
|
#
|
192
259
|
# If the requested file is not in code tracker's registry,
|
193
260
|
# or the code tracker does not exist at all,
|
194
|
-
# do not attempt to
|
261
|
+
# do not attempt to instrument now.
|
195
262
|
# The caller should add the line to the list of pending lines
|
196
263
|
# to instrument and install the hook when the file in
|
197
264
|
# question is loaded (and hopefully, by then code tracking
|
198
265
|
# is active, otherwise the line will never be instrumented.)
|
266
|
+
raise_if_probe_in_loaded_features(probe)
|
199
267
|
raise Error::DITargetNotDefined, "File not in code tracker registry: #{probe.file}"
|
200
268
|
end
|
201
269
|
end
|
@@ -203,6 +271,7 @@ module Datadog
|
|
203
271
|
# Same as previous comment, if untargeted trace points are not
|
204
272
|
# explicitly defined, and we do not have code tracking, do not
|
205
273
|
# instrument the method.
|
274
|
+
raise_if_probe_in_loaded_features(probe)
|
206
275
|
raise Error::DITargetNotDefined, "File not in code tracker registry: #{probe.file}"
|
207
276
|
end
|
208
277
|
|
@@ -222,26 +291,51 @@ module Datadog
|
|
222
291
|
# overhead of targeted trace points is minimal, don't worry about
|
223
292
|
# this optimization just yet and create a trace point for each probe.
|
224
293
|
|
225
|
-
|
294
|
+
types = if iseq
|
295
|
+
# When targeting trace points we can target the 'end' line of a method.
|
296
|
+
# However, by adding the :return trace point we lose diagnostics
|
297
|
+
# for lines that contain no executable code (e.g. comments only)
|
298
|
+
# and thus cannot actually be instrumented.
|
299
|
+
[:line, :return, :b_return]
|
300
|
+
else
|
301
|
+
[:line]
|
302
|
+
end
|
303
|
+
tp = TracePoint.new(*types) do |tp|
|
226
304
|
begin
|
227
305
|
# If trace point is not targeted, we must verify that the invocation
|
228
306
|
# is the file & line that we want, because untargeted trace points
|
229
307
|
# are invoked for *each* line of Ruby executed.
|
230
|
-
|
308
|
+
# TODO find out exactly when the path in trace point is relative.
|
309
|
+
# Looks like this is the case when line trace point is not targeted?
|
310
|
+
if iseq || tp.lineno == probe.line_no && (
|
311
|
+
probe.file == tp.path || probe.file_matches?(tp.path)
|
312
|
+
)
|
231
313
|
if rate_limiter.nil? || rate_limiter.allow?
|
314
|
+
locals = if probe.capture_snapshot?
|
315
|
+
serializer.serialize_vars(Instrumenter.get_local_variables(tp),
|
316
|
+
depth: probe.max_capture_depth || settings.dynamic_instrumentation.max_capture_depth,
|
317
|
+
attribute_count: probe.max_capture_attribute_count || settings.dynamic_instrumentation.max_capture_attribute_count,)
|
318
|
+
end
|
319
|
+
instance_vars = if probe.capture_snapshot?
|
320
|
+
serializer.serialize_vars(Instrumenter.get_instance_variables(tp.self),
|
321
|
+
depth: probe.max_capture_depth || settings.dynamic_instrumentation.max_capture_depth,
|
322
|
+
attribute_count: probe.max_capture_attribute_count || settings.dynamic_instrumentation.max_capture_attribute_count,)
|
323
|
+
end
|
232
324
|
# & is to stop steep complaints, block is always present here.
|
233
|
-
block&.call(probe: probe,
|
325
|
+
block&.call(probe: probe,
|
326
|
+
locals: locals, instance_vars: instance_vars,
|
327
|
+
path: tp.path, caller_locations: caller_locations)
|
234
328
|
end
|
235
329
|
end
|
236
330
|
rescue => exc
|
237
331
|
raise if settings.dynamic_instrumentation.internal.propagate_all_exceptions
|
238
|
-
logger.
|
332
|
+
logger.debug { "di: unhandled exception in line trace point: #{exc.class}: #{exc}" }
|
239
333
|
telemetry&.report(exc, description: "Unhandled exception in line trace point")
|
240
334
|
# TODO test this path
|
241
335
|
end
|
242
336
|
rescue => exc
|
243
|
-
raise if settings.dynamic_instrumentation.propagate_all_exceptions
|
244
|
-
logger.
|
337
|
+
raise if settings.dynamic_instrumentation.internal.propagate_all_exceptions
|
338
|
+
logger.debug { "di: unhandled exception in line trace point: #{exc.class}: #{exc}" }
|
245
339
|
telemetry&.report(exc, description: "Unhandled exception in line trace point")
|
246
340
|
# TODO test this path
|
247
341
|
end
|
@@ -266,7 +360,9 @@ module Datadog
|
|
266
360
|
else
|
267
361
|
tp.enable
|
268
362
|
end
|
363
|
+
# TracePoint#enable returns false when it succeeds.
|
269
364
|
end
|
365
|
+
true
|
270
366
|
end
|
271
367
|
|
272
368
|
def unhook_line(probe)
|
@@ -285,7 +381,7 @@ module Datadog
|
|
285
381
|
hook_line(probe, &block)
|
286
382
|
else
|
287
383
|
# TODO add test coverage for this path
|
288
|
-
logger.
|
384
|
+
logger.debug { "di: unknown probe type to hook: #{probe}" }
|
289
385
|
end
|
290
386
|
end
|
291
387
|
|
@@ -296,7 +392,32 @@ module Datadog
|
|
296
392
|
unhook_line(probe)
|
297
393
|
else
|
298
394
|
# TODO add test coverage for this path
|
299
|
-
logger.
|
395
|
+
logger.debug { "di: unknown probe type to unhook: #{probe}" }
|
396
|
+
end
|
397
|
+
end
|
398
|
+
|
399
|
+
class << self
|
400
|
+
def get_instance_variables(object)
|
401
|
+
{}.tap do |hash|
|
402
|
+
object.instance_variables.each do |var|
|
403
|
+
hash[var] = object.instance_variable_get(var)
|
404
|
+
end
|
405
|
+
end
|
406
|
+
end
|
407
|
+
|
408
|
+
def get_local_variables(trace_point)
|
409
|
+
# binding appears to be constructed on access, therefore
|
410
|
+
# 1) we should attempt to cache it and
|
411
|
+
# 2) we should not call +binding+ until we actually need variable values.
|
412
|
+
binding = trace_point.binding
|
413
|
+
|
414
|
+
# steep hack - should never happen
|
415
|
+
return {} unless binding
|
416
|
+
|
417
|
+
binding.local_variables.each_with_object({}) do |name, map|
|
418
|
+
value = binding.local_variable_get(name)
|
419
|
+
map[name] = value
|
420
|
+
end
|
300
421
|
end
|
301
422
|
end
|
302
423
|
|
@@ -304,6 +425,26 @@ module Datadog
|
|
304
425
|
|
305
426
|
attr_reader :lock
|
306
427
|
|
428
|
+
def raise_if_probe_in_loaded_features(probe)
|
429
|
+
return unless probe.file
|
430
|
+
|
431
|
+
# If the probe file is in the list of loaded files
|
432
|
+
# (as per $LOADED_FEATURES, using either exact or suffix match),
|
433
|
+
# raise an error indicating that
|
434
|
+
# code tracker is missing the loaded file because the file
|
435
|
+
# won't be loaded again (DI only works in production environments
|
436
|
+
# that do not normally reload code).
|
437
|
+
if $LOADED_FEATURES.include?(probe.file)
|
438
|
+
raise Error::DITargetNotInRegistry, "File loaded but is not in code tracker registry: #{probe.file}"
|
439
|
+
end
|
440
|
+
# Ths is an expensive check
|
441
|
+
$LOADED_FEATURES.each do |path|
|
442
|
+
if Utils.path_matches_suffix?(path, probe.file)
|
443
|
+
raise Error::DITargetNotInRegistry, "File matching probe path (#{probe.file}) was loaded and is not in code tracker registry: #{path}"
|
444
|
+
end
|
445
|
+
end
|
446
|
+
end
|
447
|
+
|
307
448
|
# TODO test that this resolves qualified names e.g. A::B
|
308
449
|
def symbolize_class_name(cls_name)
|
309
450
|
Object.const_get(cls_name)
|
@@ -0,0 +1,30 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'forwardable'
|
4
|
+
|
5
|
+
module Datadog
|
6
|
+
module DI
|
7
|
+
# Logger facade to add the +trace+ method.
|
8
|
+
#
|
9
|
+
# @api private
|
10
|
+
class Logger
|
11
|
+
extend Forwardable # steep:ignore
|
12
|
+
|
13
|
+
def initialize(settings, target)
|
14
|
+
@settings = settings
|
15
|
+
@target = target
|
16
|
+
end
|
17
|
+
|
18
|
+
attr_reader :settings
|
19
|
+
attr_reader :target
|
20
|
+
|
21
|
+
def_delegators :target, :debug # steep:ignore
|
22
|
+
|
23
|
+
def trace(&block)
|
24
|
+
if settings.dynamic_instrumentation.internal.trace_logging
|
25
|
+
debug(&block)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Require 'datadog/di/preload' early in the application boot process to
|
4
|
+
# enable dynamic instrumentation for third-party libraries used by the
|
5
|
+
# application.
|
6
|
+
|
7
|
+
require_relative 'base'
|
8
|
+
|
9
|
+
# Code tracking is required for line probes to work; see the comments
|
10
|
+
# on the activate_tracking methods in di.rb for further details.
|
11
|
+
#
|
12
|
+
# Unlike di.rb which conditionally activates tracking only if the
|
13
|
+
# DD_DYNAMIC_INSTRUMENTATION_ENABLED environment variable is set, this file
|
14
|
+
# always activates tracking. This is because this file is explicitly loaded
|
15
|
+
# by customer applications for the purpose of enabling code tracking
|
16
|
+
# early in application boot process (i.e., before datadog library itself
|
17
|
+
# is loaded).
|
18
|
+
Datadog::DI.activate_tracking
|
data/lib/datadog/di/probe.rb
CHANGED
@@ -36,7 +36,9 @@ module Datadog
|
|
36
36
|
|
37
37
|
def initialize(id:, type:,
|
38
38
|
file: nil, line_no: nil, type_name: nil, method_name: nil,
|
39
|
-
template: nil, capture_snapshot: false, max_capture_depth: nil,
|
39
|
+
template: nil, capture_snapshot: false, max_capture_depth: nil,
|
40
|
+
max_capture_attribute_count: nil,
|
41
|
+
rate_limit: nil)
|
40
42
|
# Perform some sanity checks here to detect unexpected attribute
|
41
43
|
# combinations, in order to not do them in subsequent code.
|
42
44
|
unless KNOWN_TYPES.include?(type)
|
@@ -64,6 +66,7 @@ module Datadog
|
|
64
66
|
@template = template
|
65
67
|
@capture_snapshot = !!capture_snapshot
|
66
68
|
@max_capture_depth = max_capture_depth
|
69
|
+
@max_capture_attribute_count = max_capture_attribute_count
|
67
70
|
|
68
71
|
# These checks use instance methods that have more complex logic
|
69
72
|
# than checking a single argument value. To avoid duplicating
|
@@ -91,6 +94,10 @@ module Datadog
|
|
91
94
|
# the global default will be used.
|
92
95
|
attr_reader :max_capture_depth
|
93
96
|
|
97
|
+
# Configured maximum capture attribute count. Can be nil in which case
|
98
|
+
# the global default will be used.
|
99
|
+
attr_reader :max_capture_attribute_count
|
100
|
+
|
94
101
|
# Rate limit in effect, in invocations per second. Always present.
|
95
102
|
attr_reader :rate_limit
|
96
103
|
|
@@ -148,16 +155,16 @@ module Datadog
|
|
148
155
|
# Returns whether the provided +path+ matches the user-designated
|
149
156
|
# file (of a line probe).
|
150
157
|
#
|
151
|
-
#
|
152
|
-
#
|
153
|
-
#
|
154
|
-
# If file is not an absolute path, the path matches if the file is its suffix,
|
155
|
-
# at a path component boundary.
|
158
|
+
# Delegates to Utils.path_can_match_spec? which performs fuzzy
|
159
|
+
# matching. See the comments in utils.rb for details.
|
156
160
|
def file_matches?(path)
|
161
|
+
if path.nil?
|
162
|
+
raise ArgumentError, "Cannot match against a nil path"
|
163
|
+
end
|
157
164
|
unless file
|
158
165
|
raise ArgumentError, "Probe does not have a file to match against"
|
159
166
|
end
|
160
|
-
Utils.
|
167
|
+
Utils.path_can_match_spec?(path, file)
|
161
168
|
end
|
162
169
|
|
163
170
|
# Instrumentation module for method probes.
|
@@ -37,6 +37,7 @@ module Datadog
|
|
37
37
|
template: config["template"],
|
38
38
|
capture_snapshot: !!config["captureSnapshot"],
|
39
39
|
max_capture_depth: config["capture"]&.[]("maxReferenceDepth"),
|
40
|
+
max_capture_attribute_count: config["capture"]&.[]("maxFieldCount"),
|
40
41
|
rate_limit: config["sampling"]&.[]("snapshotsPerSecond"),
|
41
42
|
)
|
42
43
|
rescue KeyError => exc
|
@@ -32,7 +32,7 @@ module Datadog
|
|
32
32
|
install_pending_method_probes(tp.self)
|
33
33
|
rescue => exc
|
34
34
|
raise if settings.dynamic_instrumentation.internal.propagate_all_exceptions
|
35
|
-
logger.
|
35
|
+
logger.debug { "di: unhandled exception in definition trace point: #{exc.class}: #{exc}" }
|
36
36
|
telemetry&.report(exc, description: "Unhandled exception in definition trace point")
|
37
37
|
# TODO test this path
|
38
38
|
end
|
@@ -111,16 +111,18 @@ module Datadog
|
|
111
111
|
# Always remove from pending list here because it makes the
|
112
112
|
# API smaller and shouldn't cause any actual problems.
|
113
113
|
@pending_probes.delete(probe.id)
|
114
|
+
logger.trace { "di: installed #{probe.type} probe at #{probe.location} (#{probe.id})" }
|
114
115
|
true
|
115
116
|
rescue Error::DITargetNotDefined
|
116
117
|
@pending_probes[probe.id] = probe
|
118
|
+
logger.trace { "di: could not install #{probe.type} probe at #{probe.location} (#{probe.id}) because its target is not defined, adding it to pending list" }
|
117
119
|
false
|
118
120
|
end
|
119
121
|
rescue => exc
|
120
122
|
# In "propagate all exceptions" mode we will try to instrument again.
|
121
123
|
raise if settings.dynamic_instrumentation.internal.propagate_all_exceptions
|
122
124
|
|
123
|
-
logger.
|
125
|
+
logger.debug { "di: error processing probe configuration: #{exc.class}: #{exc}" }
|
124
126
|
telemetry&.report(exc, description: "Error processing probe configuration")
|
125
127
|
# TODO report probe as failed to agent since we won't attempt to
|
126
128
|
# install it again.
|
@@ -160,8 +162,8 @@ module Datadog
|
|
160
162
|
raise if settings.dynamic_instrumentation.internal.propagate_all_exceptions
|
161
163
|
# Silence all exceptions?
|
162
164
|
# TODO should we propagate here and rescue upstream?
|
163
|
-
logger.
|
164
|
-
telemetry&.report(exc, description: "Error removing probe
|
165
|
+
logger.debug { "di: error removing #{probe.type} probe at #{probe.location} (#{probe.id}): #{exc.class}: #{exc}" }
|
166
|
+
telemetry&.report(exc, description: "Error removing probe")
|
165
167
|
end
|
166
168
|
end
|
167
169
|
end
|
@@ -190,7 +192,7 @@ module Datadog
|
|
190
192
|
rescue => exc
|
191
193
|
raise if settings.dynamic_instrumentation.internal.propagate_all_exceptions
|
192
194
|
|
193
|
-
logger.
|
195
|
+
logger.debug { "di: error installing #{probe.type} probe at #{probe.location} (#{probe.id}) after class is defined: #{exc.class}: #{exc}" }
|
194
196
|
telemetry&.report(exc, description: "Error installing probe after class is defined")
|
195
197
|
end
|
196
198
|
end
|
@@ -206,6 +208,9 @@ module Datadog
|
|
206
208
|
# point, which is invoked for each required or loaded file
|
207
209
|
# (and also for eval'd code, but those invocations are filtered out).
|
208
210
|
def install_pending_line_probes(path)
|
211
|
+
if path.nil?
|
212
|
+
raise ArgumentError, "path must not be nil"
|
213
|
+
end
|
209
214
|
@lock.synchronize do
|
210
215
|
@pending_probes.values.each do |probe|
|
211
216
|
if probe.line?
|
@@ -225,6 +230,7 @@ module Datadog
|
|
225
230
|
# backend (once per the probe's lifetime) and a snapshot corresponding
|
226
231
|
# to the current invocation.
|
227
232
|
def probe_executed_callback(probe:, **opts)
|
233
|
+
logger.trace { "di: executed #{probe.type} probe at #{probe.location} (#{probe.id})" }
|
228
234
|
unless probe.emitting_notified?
|
229
235
|
payload = probe_notification_builder.build_emitting(probe)
|
230
236
|
probe_notifier_worker.add_status(payload)
|
@@ -32,55 +32,72 @@ module Datadog
|
|
32
32
|
status: 'EMITTING',)
|
33
33
|
end
|
34
34
|
|
35
|
+
def build_errored(probe, exc)
|
36
|
+
build_status(probe,
|
37
|
+
message: "Instrumentation for probe #{probe.id} failed: #{exc}",
|
38
|
+
status: 'ERROR',)
|
39
|
+
end
|
40
|
+
|
35
41
|
# Duration is in seconds.
|
42
|
+
# path is the actual path of the instrumented file.
|
36
43
|
def build_executed(probe,
|
37
|
-
|
38
|
-
args: nil, kwargs: nil,
|
39
|
-
|
40
|
-
|
41
|
-
raise "Cannot create snapshot because there is no trace point"
|
42
|
-
end
|
43
|
-
get_local_variables(trace_point)
|
44
|
-
end
|
45
|
-
# TODO check how many stack frames we should be keeping/sending,
|
46
|
-
# this should be all frames for enriched probes and no frames for
|
47
|
-
# non-enriched probes?
|
48
|
-
build_snapshot(probe, rv: rv, snapshot: snapshot,
|
44
|
+
path: nil, rv: nil, duration: nil, caller_locations: nil,
|
45
|
+
locals: nil, args: nil, kwargs: nil, instance_vars: nil,
|
46
|
+
serialized_entry_args: nil)
|
47
|
+
build_snapshot(probe, rv: rv, locals: locals,
|
49
48
|
# Actual path of the instrumented file.
|
50
|
-
path:
|
51
|
-
duration: duration,
|
49
|
+
path: path,
|
50
|
+
duration: duration,
|
51
|
+
# TODO check how many stack frames we should be keeping/sending,
|
52
|
+
# this should be all frames for enriched probes and no frames for
|
53
|
+
# non-enriched probes?
|
54
|
+
caller_locations: caller_locations,
|
55
|
+
args: args, kwargs: kwargs, instance_vars: instance_vars,
|
52
56
|
serialized_entry_args: serialized_entry_args)
|
53
57
|
end
|
54
58
|
|
55
|
-
def build_snapshot(probe, rv: nil,
|
56
|
-
duration: nil, caller_locations: nil,
|
59
|
+
def build_snapshot(probe, rv: nil, locals: nil, path: nil,
|
60
|
+
duration: nil, caller_locations: nil,
|
61
|
+
args: nil, kwargs: nil, instance_vars: nil,
|
57
62
|
serialized_entry_args: nil)
|
58
63
|
# TODO also verify that non-capturing probe does not pass
|
59
64
|
# snapshot or vars/args into this method
|
60
65
|
captures = if probe.capture_snapshot?
|
61
66
|
if probe.method?
|
67
|
+
return_arguments = {
|
68
|
+
"@return": serializer.serialize_value(rv,
|
69
|
+
depth: probe.max_capture_depth || settings.dynamic_instrumentation.max_capture_depth,
|
70
|
+
attribute_count: probe.max_capture_attribute_count || settings.dynamic_instrumentation.max_capture_attribute_count),
|
71
|
+
}
|
72
|
+
if instance_vars
|
73
|
+
return_arguments.update(
|
74
|
+
serializer.serialize_vars(instance_vars,
|
75
|
+
depth: probe.max_capture_depth || settings.dynamic_instrumentation.max_capture_depth,
|
76
|
+
attribute_count: probe.max_capture_attribute_count || settings.dynamic_instrumentation.max_capture_attribute_count,)
|
77
|
+
)
|
78
|
+
end
|
62
79
|
{
|
63
80
|
entry: {
|
64
81
|
# standard:disable all
|
65
82
|
arguments: if serialized_entry_args
|
66
83
|
serialized_entry_args
|
67
84
|
else
|
68
|
-
(args || kwargs) && serializer.serialize_args(args, kwargs
|
85
|
+
(args || kwargs) && serializer.serialize_args(args, kwargs, instance_vars,
|
86
|
+
depth: probe.max_capture_depth || settings.dynamic_instrumentation.max_capture_depth,
|
87
|
+
attribute_count: probe.max_capture_attribute_count || settings.dynamic_instrumentation.max_capture_attribute_count)
|
69
88
|
end,
|
70
89
|
throwable: nil,
|
71
90
|
# standard:enable all
|
72
91
|
},
|
73
92
|
return: {
|
74
|
-
arguments:
|
75
|
-
"@return": serializer.serialize_value(rv),
|
76
|
-
},
|
93
|
+
arguments: return_arguments,
|
77
94
|
throwable: nil,
|
78
95
|
},
|
79
96
|
}
|
80
97
|
elsif probe.line?
|
81
98
|
{
|
82
|
-
lines:
|
83
|
-
probe.line_no => {locals:
|
99
|
+
lines: locals && {
|
100
|
+
probe.line_no => {locals: locals.merge(instance_vars || {})},
|
84
101
|
},
|
85
102
|
}
|
86
103
|
end
|
@@ -121,7 +138,7 @@ module Datadog
|
|
121
138
|
},
|
122
139
|
# In python tracer duration is under debugger.snapshot,
|
123
140
|
# but UI appears to expect it here at top level.
|
124
|
-
duration: duration ? (duration * 10**9).to_i :
|
141
|
+
duration: duration ? (duration * 10**9).to_i : 0,
|
125
142
|
host: nil,
|
126
143
|
logger: {
|
127
144
|
name: probe.file,
|
@@ -135,15 +152,17 @@ module Datadog
|
|
135
152
|
version: 2,
|
136
153
|
},
|
137
154
|
# TODO add tests that the trace/span id is correctly propagated
|
138
|
-
"dd.trace_id":
|
139
|
-
"dd.span_id":
|
155
|
+
"dd.trace_id": active_trace&.id&.to_s,
|
156
|
+
"dd.span_id": active_span&.id&.to_s,
|
140
157
|
ddsource: 'dd_debugger',
|
141
158
|
message: probe.template && evaluate_template(probe.template,
|
142
|
-
duration: duration ? duration * 1000 :
|
159
|
+
duration: duration ? duration * 1000 : 0),
|
143
160
|
timestamp: timestamp,
|
144
161
|
}
|
145
162
|
end
|
146
163
|
|
164
|
+
private
|
165
|
+
|
147
166
|
def build_status(probe, message:, status:)
|
148
167
|
{
|
149
168
|
service: settings.service,
|
@@ -177,21 +196,18 @@ module Datadog
|
|
177
196
|
end
|
178
197
|
|
179
198
|
def timestamp_now
|
180
|
-
(Time.now.to_f * 1000).to_i
|
199
|
+
(Core::Utils::Time.now.to_f * 1000).to_i
|
181
200
|
end
|
182
201
|
|
183
|
-
def
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
# steep hack - should never happen
|
190
|
-
return {} unless binding
|
202
|
+
def active_trace
|
203
|
+
if defined?(Datadog::Tracing)
|
204
|
+
Datadog::Tracing.active_trace
|
205
|
+
end
|
206
|
+
end
|
191
207
|
|
192
|
-
|
193
|
-
|
194
|
-
|
208
|
+
def active_span
|
209
|
+
if defined?(Datadog::Tracing)
|
210
|
+
Datadog::Tracing.active_span
|
195
211
|
end
|
196
212
|
end
|
197
213
|
end
|