datadog 2.20.0 → 2.26.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 +212 -1
- data/README.md +0 -1
- data/ext/LIBDATADOG_DEVELOPMENT.md +3 -0
- data/ext/datadog_profiling_native_extension/collectors_cpu_and_wall_time_worker.c +93 -23
- data/ext/datadog_profiling_native_extension/collectors_discrete_dynamic_sampler.c +1 -1
- data/ext/datadog_profiling_native_extension/collectors_stack.c +21 -5
- data/ext/datadog_profiling_native_extension/crashtracking_runtime_stacks.c +239 -0
- data/ext/datadog_profiling_native_extension/datadog_ruby_common.h +1 -1
- data/ext/datadog_profiling_native_extension/extconf.rb +9 -4
- data/ext/datadog_profiling_native_extension/heap_recorder.c +1 -1
- data/ext/datadog_profiling_native_extension/http_transport.c +1 -0
- data/ext/datadog_profiling_native_extension/private_vm_api_access.c +12 -0
- data/ext/datadog_profiling_native_extension/private_vm_api_access.h +4 -0
- data/ext/datadog_profiling_native_extension/profiling.c +2 -0
- data/ext/libdatadog_api/datadog_ruby_common.h +1 -1
- data/ext/libdatadog_api/ddsketch.c +106 -0
- data/ext/libdatadog_api/feature_flags.c +554 -0
- data/ext/libdatadog_api/feature_flags.h +5 -0
- data/ext/libdatadog_api/init.c +5 -0
- data/ext/libdatadog_api/library_config.c +34 -25
- data/ext/libdatadog_api/process_discovery.c +24 -18
- data/ext/libdatadog_extconf_helpers.rb +1 -1
- data/lib/datadog/ai_guard/api_client.rb +82 -0
- data/lib/datadog/ai_guard/component.rb +42 -0
- data/lib/datadog/ai_guard/configuration/ext.rb +17 -0
- data/lib/datadog/ai_guard/configuration/settings.rb +98 -0
- data/lib/datadog/ai_guard/configuration.rb +11 -0
- data/lib/datadog/ai_guard/evaluation/message.rb +25 -0
- data/lib/datadog/ai_guard/evaluation/no_op_result.rb +34 -0
- data/lib/datadog/ai_guard/evaluation/request.rb +81 -0
- data/lib/datadog/ai_guard/evaluation/result.rb +43 -0
- data/lib/datadog/ai_guard/evaluation/tool_call.rb +18 -0
- data/lib/datadog/ai_guard/evaluation.rb +72 -0
- data/lib/datadog/ai_guard/ext.rb +16 -0
- data/lib/datadog/ai_guard.rb +153 -0
- data/lib/datadog/appsec/api_security/endpoint_collection/grape_route_serializer.rb +26 -0
- data/lib/datadog/appsec/api_security/endpoint_collection/rails_collector.rb +59 -0
- data/lib/datadog/appsec/api_security/endpoint_collection/rails_route_serializer.rb +29 -0
- data/lib/datadog/appsec/api_security/endpoint_collection/sinatra_route_serializer.rb +26 -0
- data/lib/datadog/appsec/api_security/endpoint_collection.rb +10 -0
- data/lib/datadog/appsec/api_security/route_extractor.rb +26 -5
- data/lib/datadog/appsec/api_security/sampler.rb +7 -4
- data/lib/datadog/appsec/assets/blocked.html +8 -0
- data/lib/datadog/appsec/assets/blocked.json +1 -1
- data/lib/datadog/appsec/assets/blocked.text +3 -1
- data/lib/datadog/appsec/assets/waf_rules/README.md +30 -36
- data/lib/datadog/appsec/assets/waf_rules/recommended.json +359 -4
- data/lib/datadog/appsec/assets/waf_rules/strict.json +43 -2
- data/lib/datadog/appsec/assets.rb +1 -1
- data/lib/datadog/appsec/autoload.rb +1 -1
- data/lib/datadog/appsec/compressed_json.rb +1 -1
- data/lib/datadog/appsec/configuration/settings.rb +9 -0
- data/lib/datadog/appsec/context.rb +2 -1
- data/lib/datadog/appsec/contrib/active_record/instrumentation.rb +3 -1
- data/lib/datadog/appsec/contrib/excon/ssrf_detection_middleware.rb +3 -2
- data/lib/datadog/appsec/contrib/faraday/ssrf_detection_middleware.rb +3 -1
- data/lib/datadog/appsec/contrib/graphql/gateway/watcher.rb +3 -1
- data/lib/datadog/appsec/contrib/rack/gateway/watcher.rb +9 -4
- data/lib/datadog/appsec/contrib/rack/request_middleware.rb +5 -1
- data/lib/datadog/appsec/contrib/rails/gateway/watcher.rb +7 -2
- data/lib/datadog/appsec/contrib/rails/patcher.rb +30 -0
- data/lib/datadog/appsec/contrib/rest_client/request_ssrf_detection_patch.rb +3 -1
- data/lib/datadog/appsec/contrib/sinatra/gateway/watcher.rb +10 -4
- data/lib/datadog/appsec/event.rb +12 -14
- data/lib/datadog/appsec/metrics/collector.rb +19 -3
- data/lib/datadog/appsec/metrics/telemetry_exporter.rb +2 -1
- data/lib/datadog/appsec/monitor/gateway/watcher.rb +4 -4
- data/lib/datadog/appsec/remote.rb +34 -25
- data/lib/datadog/appsec/response.rb +18 -4
- data/lib/datadog/appsec/security_engine/engine.rb +3 -3
- data/lib/datadog/appsec/security_engine/result.rb +29 -9
- data/lib/datadog/appsec/security_engine/runner.rb +19 -9
- data/lib/datadog/appsec/security_event.rb +5 -7
- data/lib/datadog/core/configuration/agent_settings_resolver.rb +4 -4
- data/lib/datadog/core/configuration/components.rb +59 -11
- data/lib/datadog/core/configuration/config_helper.rb +100 -0
- data/lib/datadog/core/configuration/deprecations.rb +36 -0
- data/lib/datadog/core/configuration/ext.rb +0 -1
- data/lib/datadog/core/configuration/option.rb +38 -43
- data/lib/datadog/core/configuration/option_definition.rb +4 -11
- data/lib/datadog/core/configuration/options.rb +9 -10
- data/lib/datadog/core/configuration/settings.rb +38 -9
- data/lib/datadog/core/configuration/stable_config.rb +10 -0
- data/lib/datadog/core/configuration/supported_configurations.rb +373 -0
- data/lib/datadog/core/configuration.rb +2 -2
- data/lib/datadog/core/ddsketch.rb +19 -0
- data/lib/datadog/core/deprecations.rb +2 -2
- data/lib/datadog/core/environment/cgroup.rb +52 -25
- data/lib/datadog/core/environment/container.rb +140 -46
- data/lib/datadog/core/environment/ext.rb +7 -2
- data/lib/datadog/core/environment/git.rb +2 -2
- data/lib/datadog/core/environment/process.rb +87 -0
- data/lib/datadog/core/environment/variable_helpers.rb +3 -3
- data/lib/datadog/core/environment/yjit.rb +2 -1
- data/lib/datadog/core/error.rb +6 -6
- data/lib/datadog/core/feature_flags.rb +61 -0
- data/lib/datadog/core/metrics/client.rb +2 -2
- data/lib/datadog/core/pin.rb +8 -8
- data/lib/datadog/core/process_discovery/tracer_memfd.rb +2 -4
- data/lib/datadog/core/process_discovery.rb +48 -23
- data/lib/datadog/core/rate_limiter.rb +9 -1
- data/lib/datadog/core/remote/client/capabilities.rb +7 -0
- data/lib/datadog/core/remote/client.rb +14 -6
- data/lib/datadog/core/remote/component.rb +10 -10
- data/lib/datadog/core/remote/configuration/content.rb +15 -2
- data/lib/datadog/core/remote/configuration/digest.rb +14 -7
- data/lib/datadog/core/remote/configuration/repository.rb +1 -1
- data/lib/datadog/core/remote/configuration/target.rb +13 -6
- data/lib/datadog/core/remote/transport/config.rb +4 -25
- data/lib/datadog/core/remote/transport/http/config.rb +10 -50
- data/lib/datadog/core/remote/transport/http/negotiation.rb +14 -44
- data/lib/datadog/core/remote/transport/http.rb +15 -24
- data/lib/datadog/core/remote/transport/negotiation.rb +8 -33
- data/lib/datadog/core/remote/worker.rb +25 -37
- data/lib/datadog/core/runtime/ext.rb +0 -1
- data/lib/datadog/core/runtime/metrics.rb +11 -1
- data/lib/datadog/core/semaphore.rb +1 -4
- data/lib/datadog/core/tag_builder.rb +0 -4
- data/lib/datadog/core/tag_normalizer.rb +84 -0
- data/lib/datadog/core/telemetry/component.rb +69 -15
- data/lib/datadog/core/telemetry/emitter.rb +6 -6
- data/lib/datadog/core/telemetry/event/app_endpoints_loaded.rb +30 -0
- data/lib/datadog/core/telemetry/event/app_started.rb +89 -51
- data/lib/datadog/core/telemetry/event/synth_app_client_configuration_change.rb +27 -4
- data/lib/datadog/core/telemetry/event.rb +1 -0
- data/lib/datadog/core/telemetry/logger.rb +2 -2
- data/lib/datadog/core/telemetry/logging.rb +2 -8
- data/lib/datadog/core/telemetry/metrics_manager.rb +9 -0
- data/lib/datadog/core/telemetry/request.rb +17 -3
- data/lib/datadog/core/telemetry/transport/http/telemetry.rb +3 -34
- data/lib/datadog/core/telemetry/transport/http.rb +21 -16
- data/lib/datadog/core/telemetry/transport/telemetry.rb +3 -11
- data/lib/datadog/core/telemetry/worker.rb +88 -32
- data/lib/datadog/core/transport/ext.rb +2 -0
- data/lib/datadog/core/transport/http/api/endpoint.rb +9 -4
- data/lib/datadog/core/transport/http/api/instance.rb +4 -21
- data/lib/datadog/core/transport/http/builder.rb +9 -5
- data/lib/datadog/core/transport/http/client.rb +80 -0
- data/lib/datadog/core/transport/http.rb +22 -19
- data/lib/datadog/core/transport/response.rb +15 -1
- data/lib/datadog/core/transport/transport.rb +90 -0
- data/lib/datadog/core/utils/array.rb +29 -0
- data/lib/datadog/{appsec/api_security → core/utils}/lru_cache.rb +10 -21
- data/lib/datadog/core/utils/network.rb +22 -1
- data/lib/datadog/core/utils/only_once_successful.rb +8 -2
- data/lib/datadog/core/utils/safe_dup.rb +2 -2
- data/lib/datadog/core/utils/sequence.rb +2 -0
- data/lib/datadog/core/utils/time.rb +1 -1
- data/lib/datadog/core/utils.rb +2 -0
- data/lib/datadog/core/workers/async.rb +10 -1
- data/lib/datadog/core/workers/interval_loop.rb +44 -3
- data/lib/datadog/core/workers/polling.rb +2 -0
- data/lib/datadog/core/workers/queue.rb +100 -1
- data/lib/datadog/core.rb +2 -0
- data/lib/datadog/data_streams/configuration/settings.rb +49 -0
- data/lib/datadog/data_streams/configuration.rb +11 -0
- data/lib/datadog/data_streams/ext.rb +11 -0
- data/lib/datadog/data_streams/extensions.rb +16 -0
- data/lib/datadog/data_streams/pathway_context.rb +169 -0
- data/lib/datadog/data_streams/processor.rb +509 -0
- data/lib/datadog/data_streams/transport/http/stats.rb +52 -0
- data/lib/datadog/data_streams/transport/http.rb +40 -0
- data/lib/datadog/data_streams/transport/stats.rb +46 -0
- data/lib/datadog/data_streams.rb +100 -0
- data/lib/datadog/di/boot.rb +7 -3
- data/lib/datadog/di/component.rb +14 -16
- data/lib/datadog/di/context.rb +70 -0
- data/lib/datadog/di/contrib/active_record.rb +30 -5
- data/lib/datadog/di/el/compiler.rb +168 -0
- data/lib/datadog/di/el/evaluator.rb +159 -0
- data/lib/datadog/di/el/expression.rb +42 -0
- data/lib/datadog/di/el.rb +5 -0
- data/lib/datadog/di/error.rb +34 -0
- data/lib/datadog/di/instrumenter.rb +189 -55
- data/lib/datadog/di/logger.rb +2 -2
- data/lib/datadog/di/probe.rb +55 -15
- data/lib/datadog/di/probe_builder.rb +41 -2
- data/lib/datadog/di/probe_file_loader/railtie.rb +1 -1
- data/lib/datadog/di/probe_file_loader.rb +1 -1
- data/lib/datadog/di/probe_manager.rb +50 -35
- data/lib/datadog/di/probe_notification_builder.rb +121 -70
- data/lib/datadog/di/probe_notifier_worker.rb +5 -5
- data/lib/datadog/di/proc_responder.rb +32 -0
- data/lib/datadog/di/remote.rb +89 -84
- data/lib/datadog/di/serializer.rb +151 -7
- data/lib/datadog/di/transport/diagnostics.rb +8 -36
- data/lib/datadog/di/transport/http/diagnostics.rb +1 -33
- data/lib/datadog/di/transport/http/input.rb +1 -33
- data/lib/datadog/di/transport/http.rb +32 -17
- data/lib/datadog/di/transport/input.rb +67 -34
- data/lib/datadog/di.rb +61 -5
- data/lib/datadog/error_tracking/filters.rb +2 -2
- data/lib/datadog/kit/appsec/events/v2.rb +2 -3
- data/lib/datadog/open_feature/component.rb +60 -0
- data/lib/datadog/open_feature/configuration.rb +27 -0
- data/lib/datadog/open_feature/evaluation_engine.rb +70 -0
- data/lib/datadog/open_feature/exposures/batch_builder.rb +32 -0
- data/lib/datadog/open_feature/exposures/buffer.rb +43 -0
- data/lib/datadog/open_feature/exposures/deduplicator.rb +30 -0
- data/lib/datadog/open_feature/exposures/event.rb +60 -0
- data/lib/datadog/open_feature/exposures/reporter.rb +40 -0
- data/lib/datadog/open_feature/exposures/worker.rb +116 -0
- data/lib/datadog/open_feature/ext.rb +14 -0
- data/lib/datadog/open_feature/native_evaluator.rb +38 -0
- data/lib/datadog/open_feature/noop_evaluator.rb +26 -0
- data/lib/datadog/open_feature/provider.rb +141 -0
- data/lib/datadog/open_feature/remote.rb +67 -0
- data/lib/datadog/open_feature/resolution_details.rb +35 -0
- data/lib/datadog/open_feature/transport.rb +70 -0
- data/lib/datadog/open_feature.rb +19 -0
- data/lib/datadog/opentelemetry/api/baggage.rb +1 -1
- data/lib/datadog/opentelemetry/configuration/settings.rb +159 -0
- data/lib/datadog/opentelemetry/metrics.rb +117 -0
- data/lib/datadog/opentelemetry/sdk/configurator.rb +26 -2
- data/lib/datadog/opentelemetry/sdk/metrics_exporter.rb +35 -0
- data/lib/datadog/opentelemetry.rb +3 -0
- data/lib/datadog/profiling/collectors/code_provenance.rb +41 -7
- data/lib/datadog/profiling/collectors/cpu_and_wall_time_worker.rb +3 -2
- data/lib/datadog/profiling/collectors/idle_sampling_helper.rb +1 -1
- data/lib/datadog/profiling/collectors/info.rb +6 -5
- data/lib/datadog/profiling/component.rb +12 -11
- data/lib/datadog/profiling/ext/dir_monkey_patches.rb +18 -0
- data/lib/datadog/profiling/ext.rb +2 -1
- data/lib/datadog/profiling/http_transport.rb +5 -2
- data/lib/datadog/profiling/profiler.rb +4 -0
- data/lib/datadog/profiling/tag_builder.rb +36 -3
- data/lib/datadog/profiling/tasks/exec.rb +2 -2
- data/lib/datadog/profiling.rb +1 -2
- data/lib/datadog/single_step_instrument.rb +1 -1
- data/lib/datadog/tracing/component.rb +6 -17
- data/lib/datadog/tracing/configuration/dynamic.rb +2 -2
- data/lib/datadog/tracing/configuration/ext.rb +9 -3
- data/lib/datadog/tracing/configuration/settings.rb +89 -10
- data/lib/datadog/tracing/contrib/action_pack/action_controller/instrumentation.rb +4 -4
- data/lib/datadog/tracing/contrib/action_pack/utils.rb +1 -2
- data/lib/datadog/tracing/contrib/active_job/log_injection.rb +21 -7
- data/lib/datadog/tracing/contrib/active_job/patcher.rb +5 -1
- data/lib/datadog/tracing/contrib/aws/instrumentation.rb +4 -2
- data/lib/datadog/tracing/contrib/component.rb +2 -2
- data/lib/datadog/tracing/contrib/ethon/easy_patch.rb +4 -1
- data/lib/datadog/tracing/contrib/excon/configuration/settings.rb +11 -3
- data/lib/datadog/tracing/contrib/extensions.rb +10 -2
- data/lib/datadog/tracing/contrib/faraday/configuration/settings.rb +11 -7
- data/lib/datadog/tracing/contrib/grape/configuration/settings.rb +7 -3
- data/lib/datadog/tracing/contrib/graphql/configuration/settings.rb +7 -0
- data/lib/datadog/tracing/contrib/graphql/ext.rb +1 -0
- data/lib/datadog/tracing/contrib/graphql/unified_trace.rb +84 -43
- data/lib/datadog/tracing/contrib/http/configuration/settings.rb +11 -3
- data/lib/datadog/tracing/contrib/httpclient/configuration/settings.rb +11 -3
- data/lib/datadog/tracing/contrib/httprb/configuration/settings.rb +11 -3
- data/lib/datadog/tracing/contrib/kafka/instrumentation/consumer.rb +66 -0
- data/lib/datadog/tracing/contrib/kafka/instrumentation/producer.rb +66 -0
- data/lib/datadog/tracing/contrib/kafka/patcher.rb +14 -0
- data/lib/datadog/tracing/contrib/karafka/framework.rb +30 -0
- data/lib/datadog/tracing/contrib/karafka/monitor.rb +11 -0
- data/lib/datadog/tracing/contrib/karafka/patcher.rb +35 -4
- data/lib/datadog/tracing/contrib/rack/middlewares.rb +59 -27
- data/lib/datadog/tracing/contrib/rack/request_queue.rb +1 -0
- data/lib/datadog/tracing/contrib/rack/route_inference.rb +53 -0
- data/lib/datadog/tracing/contrib/rack/trace_proxy_middleware.rb +7 -1
- data/lib/datadog/tracing/contrib/rails/ext.rb +2 -1
- data/lib/datadog/tracing/contrib/rails/integration.rb +1 -1
- data/lib/datadog/tracing/contrib/rails/middlewares.rb +2 -2
- data/lib/datadog/tracing/contrib/rest_client/request_patch.rb +4 -1
- data/lib/datadog/tracing/contrib/roda/instrumentation.rb +3 -1
- data/lib/datadog/tracing/contrib/sinatra/tracer_middleware.rb +3 -1
- data/lib/datadog/tracing/contrib/span_attribute_schema.rb +1 -1
- data/lib/datadog/tracing/contrib/status_range_matcher.rb +9 -1
- data/lib/datadog/tracing/contrib/utils/quantization/hash.rb +3 -1
- data/lib/datadog/tracing/contrib/waterdrop/configuration/settings.rb +27 -0
- data/lib/datadog/tracing/contrib/waterdrop/distributed/propagation.rb +48 -0
- data/lib/datadog/tracing/contrib/waterdrop/ext.rb +17 -0
- data/lib/datadog/tracing/contrib/waterdrop/integration.rb +43 -0
- data/lib/datadog/tracing/contrib/waterdrop/middleware.rb +46 -0
- data/lib/datadog/tracing/contrib/waterdrop/patcher.rb +49 -0
- data/lib/datadog/tracing/contrib/waterdrop/producer.rb +50 -0
- data/lib/datadog/tracing/contrib/waterdrop.rb +41 -0
- data/lib/datadog/tracing/contrib.rb +1 -0
- data/lib/datadog/tracing/diagnostics/environment_logger.rb +1 -1
- data/lib/datadog/tracing/distributed/baggage.rb +3 -2
- data/lib/datadog/tracing/metadata/ext.rb +9 -1
- data/lib/datadog/tracing/remote.rb +1 -9
- data/lib/datadog/tracing/sampling/priority_sampler.rb +3 -1
- data/lib/datadog/tracing/span.rb +1 -1
- data/lib/datadog/tracing/span_event.rb +2 -2
- data/lib/datadog/tracing/span_operation.rb +20 -9
- data/lib/datadog/tracing/trace_operation.rb +44 -6
- data/lib/datadog/tracing/tracer.rb +42 -16
- data/lib/datadog/tracing/transport/http/client.rb +12 -26
- data/lib/datadog/tracing/transport/http/traces.rb +2 -50
- data/lib/datadog/tracing/transport/http.rb +15 -9
- data/lib/datadog/tracing/transport/io/client.rb +1 -1
- data/lib/datadog/tracing/transport/trace_formatter.rb +11 -0
- data/lib/datadog/tracing/transport/traces.rb +9 -71
- data/lib/datadog/tracing/workers/trace_writer.rb +5 -0
- data/lib/datadog/tracing/writer.rb +1 -0
- data/lib/datadog/version.rb +2 -2
- data/lib/datadog.rb +3 -0
- metadata +110 -24
- data/ext/libdatadog_api/macos_development.md +0 -26
- data/lib/datadog/core/remote/transport/http/api.rb +0 -53
- data/lib/datadog/core/remote/transport/http/client.rb +0 -49
- data/lib/datadog/core/telemetry/transport/http/api.rb +0 -43
- data/lib/datadog/core/telemetry/transport/http/client.rb +0 -49
- data/lib/datadog/core/transport/http/api/spec.rb +0 -36
- data/lib/datadog/di/transport/http/api.rb +0 -42
- data/lib/datadog/di/transport/http/client.rb +0 -47
- data/lib/datadog/opentelemetry/api/baggage.rbs +0 -26
- data/lib/datadog/tracing/transport/http/api.rb +0 -44
|
@@ -64,6 +64,9 @@ module Datadog
|
|
|
64
64
|
# a common base class but are all of different classes) or for Mongoid
|
|
65
65
|
# models (that do not have a common base class at all but include a
|
|
66
66
|
# standard Mongoid module).
|
|
67
|
+
#
|
|
68
|
+
# Important: these serializers are NOT used in log messages.
|
|
69
|
+
# They are only used for variables that are captured in the snapshots.
|
|
67
70
|
@@flat_registry = []
|
|
68
71
|
def self.register(condition: nil, &block)
|
|
69
72
|
@@flat_registry << {condition: condition, proc: block}
|
|
@@ -79,6 +82,18 @@ module Datadog
|
|
|
79
82
|
attr_reader :redactor
|
|
80
83
|
attr_reader :telemetry
|
|
81
84
|
|
|
85
|
+
def combine_args(args, kwargs, target_self)
|
|
86
|
+
counter = 0
|
|
87
|
+
combined = args.each_with_object({}) do |value, c|
|
|
88
|
+
counter += 1
|
|
89
|
+
# Conversion to symbol is needed here to put args ahead of
|
|
90
|
+
# kwargs when they are merged below.
|
|
91
|
+
c[:"arg#{counter}"] = value
|
|
92
|
+
end.update(kwargs)
|
|
93
|
+
combined[:self] = target_self
|
|
94
|
+
combined
|
|
95
|
+
end
|
|
96
|
+
|
|
82
97
|
# Serializes positional and keyword arguments to a method,
|
|
83
98
|
# as obtained by a method probe.
|
|
84
99
|
#
|
|
@@ -93,13 +108,7 @@ module Datadog
|
|
|
93
108
|
def serialize_args(args, kwargs, target_self,
|
|
94
109
|
depth: settings.dynamic_instrumentation.max_capture_depth,
|
|
95
110
|
attribute_count: settings.dynamic_instrumentation.max_capture_attribute_count)
|
|
96
|
-
|
|
97
|
-
combined = args.each_with_object({}) do |value, c|
|
|
98
|
-
counter += 1
|
|
99
|
-
# Conversion to symbol is needed here to put args ahead of
|
|
100
|
-
# kwargs when they are merged below.
|
|
101
|
-
c[:"arg#{counter}"] = value
|
|
102
|
-
end.update(kwargs).update(self: target_self)
|
|
111
|
+
combined = combine_args(args, kwargs, target_self)
|
|
103
112
|
serialize_vars(combined, depth: depth, attribute_count: attribute_count)
|
|
104
113
|
end
|
|
105
114
|
|
|
@@ -150,6 +159,8 @@ module Datadog
|
|
|
150
159
|
end
|
|
151
160
|
|
|
152
161
|
serialized = {type: class_name(cls)}
|
|
162
|
+
# https://github.com/soutaro/steep/issues/1860
|
|
163
|
+
# @type var serialized: untyped
|
|
153
164
|
case value
|
|
154
165
|
when NilClass
|
|
155
166
|
serialized.update(isNull: true)
|
|
@@ -261,8 +272,120 @@ module Datadog
|
|
|
261
272
|
end
|
|
262
273
|
end
|
|
263
274
|
|
|
275
|
+
# This method is used for serializing arbitrary values into log messages.
|
|
276
|
+
# Because the output is meant to be human-readable, we cannot use
|
|
277
|
+
# the "normal" serialization format which is meant to be machine-readable.
|
|
278
|
+
# Serialize objects with depth of 1 and include the class name.
|
|
279
|
+
#
|
|
280
|
+
# Note that this method does not (currently) utilize the custom
|
|
281
|
+
# serializers that the "normal" serialization logic uses.
|
|
282
|
+
#
|
|
283
|
+
# This serializer differs from the RFC in two ways:
|
|
284
|
+
# 1. We omit the middle of long strings rather than the end,
|
|
285
|
+
# and also the inner entries in arrays/hashes/objects.
|
|
286
|
+
# 2. We use Ruby-ish syntax for hashes and objects.
|
|
287
|
+
#
|
|
288
|
+
# We also use the Ruby-like syntax for symbols, which don't exist
|
|
289
|
+
# in other languages.
|
|
290
|
+
def serialize_value_for_message(value, depth = 1)
|
|
291
|
+
# This method is more verbose than "normal" Ruby code to avoid
|
|
292
|
+
# array allocations.
|
|
293
|
+
case value
|
|
294
|
+
when NilClass
|
|
295
|
+
'nil'
|
|
296
|
+
when Integer, Float, TrueClass, FalseClass, Time, Date
|
|
297
|
+
value.to_s
|
|
298
|
+
when String
|
|
299
|
+
serialize_string_or_symbol_for_message(value)
|
|
300
|
+
when Symbol
|
|
301
|
+
':' + serialize_string_or_symbol_for_message(value)
|
|
302
|
+
when Array
|
|
303
|
+
return '...' if depth <= 0
|
|
304
|
+
|
|
305
|
+
max = max_capture_collection_size_for_message
|
|
306
|
+
if value.length > max
|
|
307
|
+
value_ = value[0...max - 1] || []
|
|
308
|
+
value_ << '...'
|
|
309
|
+
value_ << value[-1]
|
|
310
|
+
value = value_
|
|
311
|
+
end
|
|
312
|
+
'[' + value.map do |item|
|
|
313
|
+
serialize_value_for_message(item, depth - 1)
|
|
314
|
+
end.join(', ') + ']'
|
|
315
|
+
when Hash
|
|
316
|
+
return '...' if depth <= 0
|
|
317
|
+
|
|
318
|
+
max = max_capture_collection_size_for_message
|
|
319
|
+
keys = value.keys
|
|
320
|
+
truncated = false
|
|
321
|
+
if value.length > max
|
|
322
|
+
keys_ = keys[0...max - 1] || []
|
|
323
|
+
keys_ << keys[-1]
|
|
324
|
+
keys = keys_
|
|
325
|
+
truncated = true
|
|
326
|
+
end
|
|
327
|
+
serialized = keys.map do |key|
|
|
328
|
+
"#{serialize_value_for_message(key, depth - 1)} => #{serialize_value_for_message(value[key], depth - 1)}"
|
|
329
|
+
end
|
|
330
|
+
if truncated
|
|
331
|
+
serialized[serialized.length] = serialized[serialized.length - 1]
|
|
332
|
+
serialized[serialized.length - 2] = '...'
|
|
333
|
+
end
|
|
334
|
+
"{#{serialized.join(", ")}}"
|
|
335
|
+
else
|
|
336
|
+
return '...' if depth <= 0
|
|
337
|
+
|
|
338
|
+
vars = value.instance_variables
|
|
339
|
+
truncated = false
|
|
340
|
+
max = max_capture_attribute_count_for_message
|
|
341
|
+
if vars.length > max
|
|
342
|
+
vars_ = vars[0...max - 1] || []
|
|
343
|
+
vars_ << vars[-1]
|
|
344
|
+
truncated = true
|
|
345
|
+
vars = vars_
|
|
346
|
+
end
|
|
347
|
+
serialized = vars.map do |var|
|
|
348
|
+
# +var+ here is always the instance variable name which is a
|
|
349
|
+
# symbol, we do not need to run it through our serializer.
|
|
350
|
+
"#{var}=#{serialize_value_for_message(value.send(:instance_variable_get, var), depth - 1)}"
|
|
351
|
+
end
|
|
352
|
+
if truncated
|
|
353
|
+
serialized << serialized.last
|
|
354
|
+
serialized[-2] = '...'
|
|
355
|
+
end
|
|
356
|
+
serialized = if serialized.any?
|
|
357
|
+
' ' + serialized.join(' ')
|
|
358
|
+
end
|
|
359
|
+
"#<#{class_name(value.class)}#{serialized}>"
|
|
360
|
+
end
|
|
361
|
+
rescue => exc
|
|
362
|
+
telemetry&.report(exc, description: "Error serializing for message")
|
|
363
|
+
# TODO class_name(foo) can also fail, which we don't handle here.
|
|
364
|
+
# Telemetry reporting could potentially also fail?
|
|
365
|
+
"#<#{class_name(value.class)}: serialization error>"
|
|
366
|
+
end
|
|
367
|
+
|
|
264
368
|
private
|
|
265
369
|
|
|
370
|
+
MAX_MESSAGE_COLLECTION_SIZE = 3
|
|
371
|
+
MAX_MESSAGE_ATTRIBUTE_COUNT = 5
|
|
372
|
+
|
|
373
|
+
def max_capture_collection_size_for_message
|
|
374
|
+
max = settings.dynamic_instrumentation.max_capture_collection_size
|
|
375
|
+
if max > MAX_MESSAGE_COLLECTION_SIZE
|
|
376
|
+
max = MAX_MESSAGE_COLLECTION_SIZE
|
|
377
|
+
end
|
|
378
|
+
max
|
|
379
|
+
end
|
|
380
|
+
|
|
381
|
+
def max_capture_attribute_count_for_message
|
|
382
|
+
max = settings.dynamic_instrumentation.max_capture_attribute_count
|
|
383
|
+
if max > MAX_MESSAGE_ATTRIBUTE_COUNT
|
|
384
|
+
max = MAX_MESSAGE_ATTRIBUTE_COUNT
|
|
385
|
+
end
|
|
386
|
+
max
|
|
387
|
+
end
|
|
388
|
+
|
|
266
389
|
# Returns the name for the specified class object.
|
|
267
390
|
#
|
|
268
391
|
# Ruby can have nameless classes, e.g. Class.new is a class object
|
|
@@ -273,6 +396,27 @@ module Datadog
|
|
|
273
396
|
# and we don't want to invoke user code.
|
|
274
397
|
cls.name || "[Unnamed class]"
|
|
275
398
|
end
|
|
399
|
+
|
|
400
|
+
def serialize_string_or_symbol_for_message(value)
|
|
401
|
+
max = settings.dynamic_instrumentation.max_capture_string_length
|
|
402
|
+
if max > 100
|
|
403
|
+
max = 100
|
|
404
|
+
end
|
|
405
|
+
value = value.to_s
|
|
406
|
+
if (length = value.length) > max
|
|
407
|
+
if max < 5
|
|
408
|
+
value[0...max]
|
|
409
|
+
else
|
|
410
|
+
upper = length - max / 2 + 1
|
|
411
|
+
if max % 2 == 0
|
|
412
|
+
upper += 1
|
|
413
|
+
end
|
|
414
|
+
value[0...max / 2 - 1] + '...' + value[upper...length]
|
|
415
|
+
end
|
|
416
|
+
else
|
|
417
|
+
value
|
|
418
|
+
end
|
|
419
|
+
end
|
|
276
420
|
end
|
|
277
421
|
end
|
|
278
422
|
end
|
|
@@ -1,7 +1,11 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
+
require 'json'
|
|
4
|
+
|
|
3
5
|
require_relative '../../core/transport/parcel'
|
|
4
|
-
require_relative '
|
|
6
|
+
require_relative '../../core/transport/request'
|
|
7
|
+
require_relative '../../core/transport/transport'
|
|
8
|
+
require_relative 'http/diagnostics'
|
|
5
9
|
|
|
6
10
|
module Datadog
|
|
7
11
|
module DI
|
|
@@ -14,46 +18,14 @@ module Datadog
|
|
|
14
18
|
class Request < Datadog::Core::Transport::Request
|
|
15
19
|
end
|
|
16
20
|
|
|
17
|
-
class Transport
|
|
18
|
-
attr_reader :client, :apis, :default_api, :current_api_id, :logger
|
|
19
|
-
|
|
20
|
-
def initialize(apis, default_api, logger:)
|
|
21
|
-
@apis = apis
|
|
22
|
-
@logger = logger
|
|
23
|
-
|
|
24
|
-
@client = HTTP::Client.new(current_api, logger: logger)
|
|
25
|
-
end
|
|
26
|
-
|
|
27
|
-
def current_api
|
|
28
|
-
@apis[HTTP::API::DIAGNOSTICS]
|
|
29
|
-
end
|
|
30
|
-
|
|
21
|
+
class Transport < Core::Transport::Transport
|
|
31
22
|
def send_diagnostics(payload)
|
|
23
|
+
# TODO use transport encoder functionality?
|
|
32
24
|
json = JSON.dump(payload)
|
|
33
25
|
parcel = EncodedParcel.new(json)
|
|
34
26
|
request = Request.new(parcel)
|
|
35
27
|
|
|
36
|
-
|
|
37
|
-
unless response.ok?
|
|
38
|
-
# TODO Datadog::Core::Transport::InternalErrorResponse
|
|
39
|
-
# does not have +code+ method, what is the actual API of
|
|
40
|
-
# these response objects?
|
|
41
|
-
raise Error::AgentCommunicationError, "send_diagnostics failed: #{begin
|
|
42
|
-
response.code
|
|
43
|
-
rescue
|
|
44
|
-
"???"
|
|
45
|
-
end}: #{response.payload}"
|
|
46
|
-
end
|
|
47
|
-
rescue Error::AgentCommunicationError
|
|
48
|
-
raise
|
|
49
|
-
# Datadog::Core::Transport does not perform any exception mapping,
|
|
50
|
-
# therefore we could have any exception here from failure to parse
|
|
51
|
-
# agent URI for example.
|
|
52
|
-
# If we ever implement retries for network errors, we should distinguish
|
|
53
|
-
# actual network errors from non-network errors that are raised by
|
|
54
|
-
# transport code.
|
|
55
|
-
rescue => exc
|
|
56
|
-
raise Error::AgentCommunicationError, "send_diagnostics failed: #{exc.class}: #{exc}"
|
|
28
|
+
client.send_request(:diagnostics, request)
|
|
57
29
|
end
|
|
58
30
|
end
|
|
59
31
|
end
|
|
@@ -1,43 +1,13 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require_relative '../../../core/transport/http/api/
|
|
4
|
-
require_relative '../../../core/transport/http/api/spec'
|
|
5
|
-
require_relative 'client'
|
|
3
|
+
require_relative '../../../core/transport/http/api/endpoint'
|
|
6
4
|
|
|
7
5
|
module Datadog
|
|
8
6
|
module DI
|
|
9
7
|
module Transport
|
|
10
8
|
module HTTP
|
|
11
9
|
module Diagnostics
|
|
12
|
-
module Client
|
|
13
|
-
def send_diagnostics_payload(request)
|
|
14
|
-
send_request(request) do |api, env|
|
|
15
|
-
api.send_diagnostics(env)
|
|
16
|
-
end
|
|
17
|
-
end
|
|
18
|
-
end
|
|
19
|
-
|
|
20
10
|
module API
|
|
21
|
-
class Instance < Core::Transport::HTTP::API::Instance
|
|
22
|
-
def send_diagnostics(env)
|
|
23
|
-
raise Core::Transport::HTTP::API::Instance::EndpointNotSupportedError.new('diagnostics', self) unless spec.is_a?(Diagnostics::API::Spec)
|
|
24
|
-
|
|
25
|
-
spec.send_diagnostics(env) do |request_env|
|
|
26
|
-
call(request_env)
|
|
27
|
-
end
|
|
28
|
-
end
|
|
29
|
-
end
|
|
30
|
-
|
|
31
|
-
class Spec < Core::Transport::HTTP::API::Spec
|
|
32
|
-
attr_accessor :diagnostics
|
|
33
|
-
|
|
34
|
-
def send_diagnostics(env, &block)
|
|
35
|
-
raise Core::Transport::HTTP::API::Spec::EndpointNotDefinedError.new('diagnostics', self) if diagnostics.nil?
|
|
36
|
-
|
|
37
|
-
diagnostics.call(env, &block)
|
|
38
|
-
end
|
|
39
|
-
end
|
|
40
|
-
|
|
41
11
|
class Endpoint < Datadog::Core::Transport::HTTP::API::Endpoint
|
|
42
12
|
attr_reader :encoder
|
|
43
13
|
|
|
@@ -57,8 +27,6 @@ module Datadog
|
|
|
57
27
|
end
|
|
58
28
|
end
|
|
59
29
|
end
|
|
60
|
-
|
|
61
|
-
HTTP::Client.include(Diagnostics::Client)
|
|
62
30
|
end
|
|
63
31
|
end
|
|
64
32
|
end
|
|
@@ -1,43 +1,13 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require_relative '../../../core/transport/http/api/
|
|
4
|
-
require_relative '../../../core/transport/http/api/spec'
|
|
5
|
-
require_relative 'client'
|
|
3
|
+
require_relative '../../../core/transport/http/api/endpoint'
|
|
6
4
|
|
|
7
5
|
module Datadog
|
|
8
6
|
module DI
|
|
9
7
|
module Transport
|
|
10
8
|
module HTTP
|
|
11
9
|
module Input
|
|
12
|
-
module Client
|
|
13
|
-
def send_input_payload(request)
|
|
14
|
-
send_request(request) do |api, env|
|
|
15
|
-
api.send_input(env)
|
|
16
|
-
end
|
|
17
|
-
end
|
|
18
|
-
end
|
|
19
|
-
|
|
20
10
|
module API
|
|
21
|
-
class Instance < Core::Transport::HTTP::API::Instance
|
|
22
|
-
def send_input(env)
|
|
23
|
-
raise Core::Transport::HTTP::API::Instance::EndpointNotSupportedError.new('input', self) unless spec.is_a?(Input::API::Spec)
|
|
24
|
-
|
|
25
|
-
spec.send_input(env) do |request_env|
|
|
26
|
-
call(request_env)
|
|
27
|
-
end
|
|
28
|
-
end
|
|
29
|
-
end
|
|
30
|
-
|
|
31
|
-
class Spec < Core::Transport::HTTP::API::Spec
|
|
32
|
-
attr_accessor :input
|
|
33
|
-
|
|
34
|
-
def send_input(env, &block)
|
|
35
|
-
raise Core::Transport::HTTP::API::Spec::EndpointNotDefinedError.new('input', self) if input.nil?
|
|
36
|
-
|
|
37
|
-
input.call(env, &block)
|
|
38
|
-
end
|
|
39
|
-
end
|
|
40
|
-
|
|
41
11
|
class Endpoint < Datadog::Core::Transport::HTTP::API::Endpoint
|
|
42
12
|
HEADER_CONTENT_TYPE = 'Content-Type'
|
|
43
13
|
|
|
@@ -69,8 +39,6 @@ module Datadog
|
|
|
69
39
|
end
|
|
70
40
|
end
|
|
71
41
|
end
|
|
72
|
-
|
|
73
|
-
HTTP::Client.include(Input::Client)
|
|
74
42
|
end
|
|
75
43
|
end
|
|
76
44
|
end
|
|
@@ -1,31 +1,46 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
+
require_relative '../../core/encoding'
|
|
4
|
+
require_relative '../../core/transport/http'
|
|
3
5
|
require_relative 'diagnostics'
|
|
4
6
|
require_relative 'input'
|
|
5
|
-
require_relative 'http/api'
|
|
6
|
-
require_relative '../../core/transport/http'
|
|
7
7
|
|
|
8
8
|
module Datadog
|
|
9
9
|
module DI
|
|
10
10
|
module Transport
|
|
11
11
|
# Namespace for HTTP transport components
|
|
12
12
|
module HTTP
|
|
13
|
-
|
|
13
|
+
DIAGNOSTICS = Diagnostics::API::Endpoint.new(
|
|
14
|
+
'/debugger/v1/diagnostics',
|
|
15
|
+
Core::Encoding::JSONEncoder,
|
|
16
|
+
)
|
|
17
|
+
|
|
18
|
+
INPUT = Input::API::Endpoint.new(
|
|
19
|
+
'/debugger/v2/input',
|
|
20
|
+
Core::Encoding::JSONEncoder,
|
|
21
|
+
)
|
|
22
|
+
|
|
23
|
+
LEGACY_INPUT = Input::API::Endpoint.new(
|
|
24
|
+
# We used to use /debugger/v1/input, but now input
|
|
25
|
+
# payloads should be going to the diagnostics endpoint
|
|
26
|
+
# which I gather performs data redaction.
|
|
27
|
+
'/debugger/v1/diagnostics',
|
|
28
|
+
Core::Encoding::JSONEncoder,
|
|
29
|
+
)
|
|
14
30
|
|
|
15
31
|
# Builds a new Transport::HTTP::Client with default settings
|
|
16
32
|
# Pass a block to override any settings.
|
|
17
|
-
def diagnostics(
|
|
33
|
+
def self.diagnostics(
|
|
18
34
|
agent_settings:,
|
|
19
35
|
logger:,
|
|
20
|
-
api_version: nil,
|
|
21
36
|
headers: nil
|
|
22
37
|
)
|
|
23
|
-
Core::Transport::HTTP.build(
|
|
38
|
+
Core::Transport::HTTP.build(
|
|
24
39
|
logger: logger,
|
|
25
|
-
agent_settings: agent_settings,
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
transport.api
|
|
40
|
+
agent_settings: agent_settings,
|
|
41
|
+
headers: headers,
|
|
42
|
+
) do |transport|
|
|
43
|
+
transport.api 'diagnostics', DIAGNOSTICS
|
|
29
44
|
|
|
30
45
|
# Call block to apply any customization, if provided
|
|
31
46
|
yield(transport) if block_given?
|
|
@@ -34,18 +49,18 @@ module Datadog
|
|
|
34
49
|
|
|
35
50
|
# Builds a new Transport::HTTP::Client with default settings
|
|
36
51
|
# Pass a block to override any settings.
|
|
37
|
-
def input(
|
|
52
|
+
def self.input(
|
|
38
53
|
agent_settings:,
|
|
39
54
|
logger:,
|
|
40
|
-
api_version: nil,
|
|
41
55
|
headers: nil
|
|
42
56
|
)
|
|
43
|
-
Core::Transport::HTTP.build(
|
|
57
|
+
Core::Transport::HTTP.build(
|
|
44
58
|
logger: logger,
|
|
45
|
-
agent_settings: agent_settings,
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
transport.api
|
|
59
|
+
agent_settings: agent_settings,
|
|
60
|
+
headers: headers,
|
|
61
|
+
) do |transport|
|
|
62
|
+
transport.api 'input', INPUT, fallback: 'legacy_input', default: true
|
|
63
|
+
transport.api 'legacy_input', LEGACY_INPUT
|
|
49
64
|
|
|
50
65
|
# Call block to apply any customization, if provided
|
|
51
66
|
yield(transport) if block_given?
|
|
@@ -1,7 +1,13 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
+
require_relative '../../core/chunker'
|
|
4
|
+
require_relative '../../core/encoding'
|
|
5
|
+
require_relative '../../core/tag_builder'
|
|
3
6
|
require_relative '../../core/transport/parcel'
|
|
4
|
-
require_relative '
|
|
7
|
+
require_relative '../../core/transport/request'
|
|
8
|
+
require_relative '../../core/transport/transport'
|
|
9
|
+
require_relative '../error'
|
|
10
|
+
require_relative 'http/input'
|
|
5
11
|
|
|
6
12
|
module Datadog
|
|
7
13
|
module DI
|
|
@@ -21,47 +27,74 @@ module Datadog
|
|
|
21
27
|
end
|
|
22
28
|
end
|
|
23
29
|
|
|
24
|
-
class Transport
|
|
25
|
-
|
|
30
|
+
class Transport < Core::Transport::Transport
|
|
31
|
+
# The limit on an individual snapshot payload, aka "log line",
|
|
32
|
+
# is 1 MB.
|
|
33
|
+
#
|
|
34
|
+
# TODO There is an RFC for snapshot pruning that should be
|
|
35
|
+
# implemented to reduce the size of snapshots to be below this
|
|
36
|
+
# limit, so that we can send a portion of the captured data
|
|
37
|
+
# rather than dropping the snapshot entirely.
|
|
38
|
+
MAX_SERIALIZED_SNAPSHOT_SIZE = 1024 * 1024
|
|
26
39
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
40
|
+
# The maximum chunk (batch) size that intake permits is 5 MB.
|
|
41
|
+
#
|
|
42
|
+
# Two bytes are for the [ and ] of JSON array syntax.
|
|
43
|
+
MAX_CHUNK_SIZE = 5 * 1024 * 1024 - 2
|
|
30
44
|
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
@apis[HTTP::API::INPUT]
|
|
36
|
-
end
|
|
45
|
+
# Try to send smaller payloads to avoid large network requests.
|
|
46
|
+
# If a payload is larger than default chunk size but is under the
|
|
47
|
+
# max chunk size, it will still get sent out.
|
|
48
|
+
DEFAULT_CHUNK_SIZE = 2 * 1024 * 1024
|
|
37
49
|
|
|
38
50
|
def send_input(payload, tags)
|
|
39
|
-
|
|
40
|
-
parcel = EncodedParcel.new(json)
|
|
51
|
+
# Tags are the same for all chunks, serialize them one time.
|
|
41
52
|
serialized_tags = Core::TagBuilder.serialize_tags(tags)
|
|
53
|
+
|
|
54
|
+
encoder = Core::Encoding::JSONEncoder
|
|
55
|
+
encoded_snapshots = Core::Utils::Array.filter_map(payload) do |snapshot|
|
|
56
|
+
encoded = encoder.encode(snapshot)
|
|
57
|
+
if encoded.length > MAX_SERIALIZED_SNAPSHOT_SIZE
|
|
58
|
+
# Drop the snapshot.
|
|
59
|
+
# TODO report via telemetry metric?
|
|
60
|
+
logger.debug { "di: dropping too big snapshot" }
|
|
61
|
+
nil
|
|
62
|
+
else
|
|
63
|
+
encoded
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
Datadog::Core::Chunker.chunk_by_size(
|
|
68
|
+
encoded_snapshots, DEFAULT_CHUNK_SIZE,
|
|
69
|
+
).each do |chunk|
|
|
70
|
+
# We drop snapshots that are too big earlier.
|
|
71
|
+
# The limit on chunked payload length here is greater
|
|
72
|
+
# than the limit on snapshot size, therefore no chunks
|
|
73
|
+
# can exceed limits here.
|
|
74
|
+
chunked_payload = encoder.join(chunk)
|
|
75
|
+
|
|
76
|
+
# We need to rescue exceptions for each chunk so that
|
|
77
|
+
# subsequent chunks are attempted to be sent.
|
|
78
|
+
begin
|
|
79
|
+
send_input_chunk(chunked_payload, serialized_tags)
|
|
80
|
+
rescue => exc
|
|
81
|
+
logger.debug { "di: failed to send snapshot chunk: #{exc.class}: #{exc} (at #{exc.backtrace.first})" }
|
|
82
|
+
end
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
payload
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
def send_input_chunk(chunked_payload, serialized_tags)
|
|
89
|
+
parcel = EncodedParcel.new(chunked_payload)
|
|
42
90
|
request = Request.new(parcel, serialized_tags)
|
|
43
91
|
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
raise Error::AgentCommunicationError, "send_input failed: #{begin
|
|
50
|
-
response.code
|
|
51
|
-
rescue
|
|
52
|
-
"???"
|
|
53
|
-
end}: #{response.payload}"
|
|
92
|
+
client.send_request(:input, request).tap do |response|
|
|
93
|
+
if downgrade?(response)
|
|
94
|
+
downgrade!
|
|
95
|
+
return send_input_chunk(chunked_payload, serialized_tags)
|
|
96
|
+
end
|
|
54
97
|
end
|
|
55
|
-
rescue Error::AgentCommunicationError
|
|
56
|
-
raise
|
|
57
|
-
# Datadog::Core::Transport does not perform any exception mapping,
|
|
58
|
-
# therefore we could have any exception here from failure to parse
|
|
59
|
-
# agent URI for example.
|
|
60
|
-
# If we ever implement retries for network errors, we should distinguish
|
|
61
|
-
# actual network errors from non-network errors that are raised by
|
|
62
|
-
# transport code.
|
|
63
|
-
rescue => exc
|
|
64
|
-
raise Error::AgentCommunicationError, "send_input failed: #{exc.class}: #{exc}"
|
|
65
98
|
end
|
|
66
99
|
end
|
|
67
100
|
end
|
data/lib/datadog/di.rb
CHANGED
|
@@ -9,16 +9,13 @@ module Datadog
|
|
|
9
9
|
#
|
|
10
10
|
# @api private
|
|
11
11
|
module DI
|
|
12
|
+
INSTRUMENTED_COUNTERS_LOCK = Mutex.new
|
|
13
|
+
|
|
12
14
|
class << self
|
|
13
15
|
def enabled?
|
|
14
16
|
Datadog.configuration.dynamic_instrumentation.enabled
|
|
15
17
|
end
|
|
16
|
-
end
|
|
17
|
-
|
|
18
|
-
# Expose DI to global shared objects
|
|
19
|
-
Extensions.activate!
|
|
20
18
|
|
|
21
|
-
class << self
|
|
22
19
|
# This method is called from DI Remote handler to issue DI operations
|
|
23
20
|
# to the probe manager (add or remove probes).
|
|
24
21
|
#
|
|
@@ -31,6 +28,65 @@ module Datadog
|
|
|
31
28
|
def component
|
|
32
29
|
Datadog.send(:components).dynamic_instrumentation
|
|
33
30
|
end
|
|
31
|
+
|
|
32
|
+
# Track how many outstanding instrumentations are in DI.
|
|
33
|
+
#
|
|
34
|
+
# It is hard to find the actual instrumentations - there is no
|
|
35
|
+
# method provided by Ruby to list all trace points, and we would
|
|
36
|
+
# need to manually track our instrumentation modules for method probes.
|
|
37
|
+
# Plus, tracking the modules could create active references to
|
|
38
|
+
# instrumentation, which is not desired.
|
|
39
|
+
#
|
|
40
|
+
# A simpler solution is to maintain a counter which is increased
|
|
41
|
+
# whenever a probe is installed and decreased when a probe is removed.
|
|
42
|
+
#
|
|
43
|
+
# This counter does not include pending probes - being not installed,
|
|
44
|
+
# those pose no concerns to customer applications.
|
|
45
|
+
def instrumented_count(kind = nil)
|
|
46
|
+
INSTRUMENTED_COUNTERS_LOCK.synchronize do
|
|
47
|
+
if defined?(@instrumented_count)
|
|
48
|
+
if kind
|
|
49
|
+
validate_kind!(kind)
|
|
50
|
+
@instrumented_count[kind] || 0
|
|
51
|
+
else
|
|
52
|
+
@instrumented_count.inject(0) do |sum, (_kind, count)|
|
|
53
|
+
sum + count
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
else
|
|
57
|
+
0
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
def instrumented_count_inc(kind)
|
|
63
|
+
validate_kind!(kind)
|
|
64
|
+
INSTRUMENTED_COUNTERS_LOCK.synchronize do
|
|
65
|
+
@instrumented_count = Hash.new(0) unless defined?(@instrumented_count)
|
|
66
|
+
@instrumented_count[kind] += 1
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
def instrumented_count_dec(kind)
|
|
71
|
+
validate_kind!(kind)
|
|
72
|
+
INSTRUMENTED_COUNTERS_LOCK.synchronize do
|
|
73
|
+
@instrumented_count = Hash.new(0) unless defined?(@instrumented_count)
|
|
74
|
+
if @instrumented_count[kind] <= 0
|
|
75
|
+
Datadog.logger.debug { "di: attempting to decrease instrumented count below zero for #{kind}" }
|
|
76
|
+
return
|
|
77
|
+
end
|
|
78
|
+
@instrumented_count[kind] -= 1
|
|
79
|
+
end
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
private def validate_kind!(kind)
|
|
83
|
+
unless %i[line method].include?(kind)
|
|
84
|
+
raise ArgumentError, "Invalid kind: #{kind}"
|
|
85
|
+
end
|
|
86
|
+
end
|
|
34
87
|
end
|
|
88
|
+
|
|
89
|
+
# Expose DI to global shared objects
|
|
90
|
+
Extensions.activate!
|
|
35
91
|
end
|
|
36
92
|
end
|
|
@@ -18,10 +18,10 @@ module Datadog
|
|
|
18
18
|
regex_match = regex.match(file_path)
|
|
19
19
|
return unless regex_match
|
|
20
20
|
|
|
21
|
-
gem_name = regex_match[1]
|
|
21
|
+
gem_name = regex_match[1] #: String
|
|
22
22
|
|
|
23
23
|
begin
|
|
24
|
-
Gem::Specification.find_by_name(gem_name)
|
|
24
|
+
Gem::Specification.find_by_name(gem_name)
|
|
25
25
|
rescue Gem::MissingSpecError
|
|
26
26
|
nil
|
|
27
27
|
end
|