datadog 2.12.1 → 2.17.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 +154 -2
- data/ext/datadog_profiling_native_extension/collectors_thread_context.c +16 -14
- 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 +3 -0
- data/ext/datadog_profiling_native_extension/heap_recorder.c +8 -1
- data/ext/datadog_profiling_native_extension/http_transport.c +60 -94
- data/ext/datadog_profiling_native_extension/private_vm_api_access.c +8 -0
- data/ext/datadog_profiling_native_extension/profiling.c +2 -0
- data/ext/datadog_profiling_native_extension/stack_recorder.c +23 -23
- data/ext/libdatadog_api/crashtracker.c +11 -12
- data/ext/libdatadog_api/crashtracker.h +5 -0
- data/ext/libdatadog_api/datadog_ruby_common.c +1 -4
- data/ext/libdatadog_api/datadog_ruby_common.h +10 -0
- data/ext/libdatadog_api/init.c +15 -0
- data/ext/libdatadog_api/library_config.c +122 -0
- data/ext/libdatadog_api/library_config.h +19 -0
- data/ext/libdatadog_api/macos_development.md +3 -3
- data/ext/libdatadog_api/process_discovery.c +117 -0
- data/ext/libdatadog_api/process_discovery.h +5 -0
- data/ext/libdatadog_extconf_helpers.rb +1 -1
- data/lib/datadog/appsec/actions_handler/serializable_backtrace.rb +89 -0
- data/lib/datadog/appsec/actions_handler.rb +24 -2
- data/lib/datadog/appsec/anonymizer.rb +16 -0
- data/lib/datadog/appsec/api_security/lru_cache.rb +49 -0
- data/lib/datadog/appsec/api_security.rb +9 -0
- data/lib/datadog/appsec/assets/waf_rules/README.md +50 -5
- data/lib/datadog/appsec/assets/waf_rules/processors.json +239 -10
- data/lib/datadog/appsec/assets/waf_rules/scanners.json +926 -17
- data/lib/datadog/appsec/autoload.rb +1 -1
- data/lib/datadog/appsec/component.rb +29 -20
- data/lib/datadog/appsec/compressed_json.rb +40 -0
- data/lib/datadog/appsec/configuration/settings.rb +93 -28
- data/lib/datadog/appsec/context.rb +1 -1
- data/lib/datadog/appsec/contrib/active_record/instrumentation.rb +10 -12
- data/lib/datadog/appsec/contrib/active_record/integration.rb +2 -2
- data/lib/datadog/appsec/contrib/active_record/patcher.rb +22 -22
- data/lib/datadog/appsec/contrib/auto_instrument.rb +1 -1
- data/lib/datadog/appsec/contrib/devise/configuration.rb +7 -31
- data/lib/datadog/appsec/contrib/devise/data_extractor.rb +78 -0
- data/lib/datadog/appsec/contrib/devise/ext.rb +22 -0
- data/lib/datadog/appsec/contrib/devise/integration.rb +1 -2
- data/lib/datadog/appsec/contrib/devise/patcher.rb +34 -23
- data/lib/datadog/appsec/contrib/devise/patches/signin_tracking_patch.rb +102 -0
- data/lib/datadog/appsec/contrib/devise/patches/signup_tracking_patch.rb +69 -0
- data/lib/datadog/appsec/contrib/devise/{patcher/rememberable_patch.rb → patches/skip_signin_tracking_patch.rb} +2 -2
- data/lib/datadog/appsec/contrib/devise/tracking_middleware.rb +106 -0
- data/lib/datadog/appsec/contrib/excon/integration.rb +1 -1
- data/lib/datadog/appsec/contrib/excon/ssrf_detection_middleware.rb +9 -10
- data/lib/datadog/appsec/contrib/faraday/integration.rb +1 -1
- data/lib/datadog/appsec/contrib/faraday/ssrf_detection_middleware.rb +8 -9
- data/lib/datadog/appsec/contrib/graphql/gateway/watcher.rb +8 -9
- data/lib/datadog/appsec/contrib/graphql/integration.rb +1 -1
- data/lib/datadog/appsec/contrib/rack/ext.rb +34 -0
- data/lib/datadog/appsec/contrib/rack/gateway/watcher.rb +49 -32
- data/lib/datadog/appsec/contrib/rack/integration.rb +1 -1
- data/lib/datadog/appsec/contrib/rack/request_middleware.rb +19 -18
- data/lib/datadog/appsec/contrib/rails/gateway/watcher.rb +11 -13
- data/lib/datadog/appsec/contrib/rails/integration.rb +1 -1
- data/lib/datadog/appsec/contrib/rails/patcher.rb +21 -21
- data/lib/datadog/appsec/contrib/rest_client/integration.rb +1 -1
- data/lib/datadog/appsec/contrib/rest_client/request_ssrf_detection_patch.rb +10 -11
- data/lib/datadog/appsec/contrib/sinatra/gateway/watcher.rb +17 -23
- data/lib/datadog/appsec/contrib/sinatra/integration.rb +1 -1
- data/lib/datadog/appsec/event.rb +96 -135
- data/lib/datadog/appsec/ext.rb +4 -2
- data/lib/datadog/appsec/instrumentation/gateway/argument.rb +7 -2
- data/lib/datadog/appsec/instrumentation/gateway/middleware.rb +24 -0
- data/lib/datadog/appsec/instrumentation/gateway.rb +17 -22
- data/lib/datadog/appsec/metrics/telemetry.rb +1 -1
- data/lib/datadog/appsec/monitor/gateway/watcher.rb +49 -14
- data/lib/datadog/appsec/processor/rule_loader.rb +26 -28
- data/lib/datadog/appsec/processor/rule_merger.rb +7 -6
- data/lib/datadog/appsec/processor.rb +1 -1
- data/lib/datadog/appsec/remote.rb +23 -11
- data/lib/datadog/appsec/response.rb +6 -6
- data/lib/datadog/appsec/security_engine/runner.rb +3 -3
- data/lib/datadog/appsec/security_event.rb +39 -0
- data/lib/datadog/appsec/utils.rb +0 -2
- data/lib/datadog/appsec.rb +1 -1
- data/lib/datadog/core/buffer/random.rb +18 -2
- data/lib/datadog/core/configuration/agent_settings_resolver.rb +5 -5
- data/lib/datadog/core/configuration/agentless_settings_resolver.rb +176 -0
- data/lib/datadog/core/configuration/components.rb +50 -31
- data/lib/datadog/core/configuration/components_state.rb +23 -0
- data/lib/datadog/core/configuration/ext.rb +4 -0
- data/lib/datadog/core/configuration/option.rb +79 -43
- data/lib/datadog/core/configuration/option_definition.rb +4 -4
- data/lib/datadog/core/configuration/options.rb +3 -3
- data/lib/datadog/core/configuration/settings.rb +68 -35
- data/lib/datadog/core/configuration/stable_config.rb +23 -0
- data/lib/datadog/core/configuration.rb +40 -16
- data/lib/datadog/core/crashtracking/component.rb +3 -10
- data/lib/datadog/core/diagnostics/environment_logger.rb +1 -1
- data/lib/datadog/core/encoding.rb +1 -1
- data/lib/datadog/core/environment/agent_info.rb +4 -3
- data/lib/datadog/core/environment/cgroup.rb +10 -12
- data/lib/datadog/core/environment/container.rb +38 -40
- data/lib/datadog/core/environment/ext.rb +6 -6
- data/lib/datadog/core/environment/git.rb +1 -0
- data/lib/datadog/core/environment/identity.rb +3 -3
- data/lib/datadog/core/environment/platform.rb +3 -3
- data/lib/datadog/core/environment/variable_helpers.rb +1 -1
- data/lib/datadog/core/error.rb +11 -9
- data/lib/datadog/core/logger.rb +2 -2
- data/lib/datadog/core/metrics/client.rb +20 -21
- data/lib/datadog/core/metrics/logging.rb +5 -5
- data/lib/datadog/core/process_discovery.rb +32 -0
- data/lib/datadog/core/rate_limiter.rb +4 -2
- data/lib/datadog/core/remote/client.rb +40 -32
- data/lib/datadog/core/remote/component.rb +6 -9
- data/lib/datadog/core/remote/configuration/digest.rb +7 -7
- data/lib/datadog/core/remote/configuration/path.rb +1 -1
- data/lib/datadog/core/remote/configuration/repository.rb +2 -1
- data/lib/datadog/core/remote/negotiation.rb +9 -9
- data/lib/datadog/core/remote/transport/config.rb +4 -3
- data/lib/datadog/core/remote/transport/http/client.rb +5 -4
- data/lib/datadog/core/remote/transport/http/config.rb +27 -37
- data/lib/datadog/core/remote/transport/http/negotiation.rb +7 -33
- data/lib/datadog/core/remote/transport/http.rb +22 -57
- data/lib/datadog/core/remote/transport/negotiation.rb +4 -3
- data/lib/datadog/core/runtime/metrics.rb +12 -5
- data/lib/datadog/core/telemetry/component.rb +78 -53
- data/lib/datadog/core/telemetry/emitter.rb +23 -11
- data/lib/datadog/core/telemetry/event/app_client_configuration_change.rb +65 -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 +179 -0
- data/lib/datadog/core/telemetry/event/base.rb +40 -0
- data/lib/datadog/core/telemetry/event/distributions.rb +18 -0
- data/lib/datadog/core/telemetry/event/generate_metrics.rb +43 -0
- data/lib/datadog/core/telemetry/event/log.rb +76 -0
- data/lib/datadog/core/telemetry/event/message_batch.rb +42 -0
- data/lib/datadog/core/telemetry/event/synth_app_client_configuration_change.rb +43 -0
- data/lib/datadog/core/telemetry/event.rb +17 -472
- data/lib/datadog/core/telemetry/http/adapters/net.rb +12 -97
- data/lib/datadog/core/telemetry/logger.rb +1 -1
- data/lib/datadog/core/telemetry/metric.rb +8 -8
- data/lib/datadog/core/telemetry/request.rb +4 -4
- data/lib/datadog/core/telemetry/transport/http/api.rb +43 -0
- data/lib/datadog/core/telemetry/transport/http/client.rb +49 -0
- data/lib/datadog/core/telemetry/transport/http/telemetry.rb +92 -0
- data/lib/datadog/core/telemetry/transport/http.rb +63 -0
- data/lib/datadog/core/telemetry/transport/telemetry.rb +51 -0
- data/lib/datadog/core/telemetry/worker.rb +90 -24
- data/lib/datadog/core/transport/http/adapters/test.rb +2 -1
- data/lib/datadog/core/transport/http/api/instance.rb +17 -0
- data/lib/datadog/core/transport/http/api/spec.rb +17 -0
- data/lib/datadog/core/transport/http/builder.rb +18 -16
- data/lib/datadog/core/transport/http.rb +39 -2
- data/lib/datadog/core/utils/at_fork_monkey_patch.rb +6 -6
- data/lib/datadog/core/utils/duration.rb +32 -32
- data/lib/datadog/core/utils/forking.rb +2 -2
- data/lib/datadog/core/utils/network.rb +6 -6
- data/lib/datadog/core/utils/only_once_successful.rb +16 -5
- data/lib/datadog/core/utils/time.rb +20 -0
- data/lib/datadog/core/utils/truncation.rb +21 -0
- data/lib/datadog/core/vendor/multipart-post/multipart/post/composite_read_io.rb +1 -1
- data/lib/datadog/core/vendor/multipart-post/multipart/post/multipartable.rb +8 -8
- data/lib/datadog/core/vendor/multipart-post/multipart/post/parts.rb +7 -7
- data/lib/datadog/core/worker.rb +1 -1
- data/lib/datadog/core/workers/async.rb +29 -12
- data/lib/datadog/core/workers/interval_loop.rb +12 -1
- data/lib/datadog/core/workers/runtime_metrics.rb +2 -2
- data/lib/datadog/core.rb +8 -0
- data/lib/datadog/di/boot.rb +34 -0
- data/lib/datadog/di/component.rb +0 -2
- data/lib/datadog/di/probe_notification_builder.rb +1 -1
- data/lib/datadog/di/probe_notifier_worker.rb +16 -16
- data/lib/datadog/di/remote.rb +2 -0
- data/lib/datadog/di/transport/diagnostics.rb +4 -3
- data/lib/datadog/di/transport/http/api.rb +2 -12
- data/lib/datadog/di/transport/http/client.rb +4 -3
- data/lib/datadog/di/transport/http/diagnostics.rb +7 -34
- data/lib/datadog/di/transport/http/input.rb +7 -34
- data/lib/datadog/di/transport/http.rb +14 -62
- data/lib/datadog/di/transport/input.rb +4 -3
- data/lib/datadog/di/utils.rb +5 -0
- data/lib/datadog/di.rb +5 -32
- 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 +12 -0
- data/lib/datadog/kit/identity.rb +5 -1
- data/lib/datadog/opentelemetry/api/baggage.rb +90 -0
- data/lib/datadog/opentelemetry/api/baggage.rbs +26 -0
- data/lib/datadog/opentelemetry/api/context.rb +16 -2
- data/lib/datadog/opentelemetry/sdk/trace/span.rb +1 -1
- data/lib/datadog/opentelemetry.rb +2 -1
- data/lib/datadog/profiling/collectors/code_provenance.rb +1 -1
- data/lib/datadog/profiling/collectors/info.rb +3 -0
- data/lib/datadog/profiling/collectors/thread_context.rb +1 -1
- data/lib/datadog/profiling/encoded_profile.rb +11 -0
- data/lib/datadog/profiling/exporter.rb +3 -4
- data/lib/datadog/profiling/ext.rb +0 -2
- data/lib/datadog/profiling/flush.rb +5 -8
- data/lib/datadog/profiling/http_transport.rb +5 -59
- data/lib/datadog/profiling/scheduler.rb +8 -1
- data/lib/datadog/profiling/stack_recorder.rb +4 -4
- data/lib/datadog/profiling/tag_builder.rb +1 -5
- data/lib/datadog/profiling.rb +6 -2
- data/lib/datadog/tracing/analytics.rb +1 -1
- data/lib/datadog/tracing/component.rb +15 -12
- data/lib/datadog/tracing/configuration/ext.rb +7 -1
- data/lib/datadog/tracing/configuration/settings.rb +18 -2
- data/lib/datadog/tracing/context_provider.rb +1 -1
- data/lib/datadog/tracing/contrib/active_record/integration.rb +1 -1
- data/lib/datadog/tracing/contrib/active_support/cache/events/cache.rb +4 -1
- data/lib/datadog/tracing/contrib/active_support/cache/instrumentation.rb +33 -0
- data/lib/datadog/tracing/contrib/active_support/cache/patcher.rb +4 -0
- data/lib/datadog/tracing/contrib/active_support/cache/redis.rb +2 -4
- data/lib/datadog/tracing/contrib/aws/instrumentation.rb +10 -0
- data/lib/datadog/tracing/contrib/aws/parsed_context.rb +5 -1
- data/lib/datadog/tracing/contrib/configuration/settings.rb +1 -1
- data/lib/datadog/tracing/contrib/ethon/easy_patch.rb +4 -5
- data/lib/datadog/tracing/contrib/excon/middleware.rb +5 -3
- data/lib/datadog/tracing/contrib/ext.rb +1 -0
- data/lib/datadog/tracing/contrib/faraday/middleware.rb +5 -3
- data/lib/datadog/tracing/contrib/grpc/datadog_interceptor/client.rb +7 -1
- data/lib/datadog/tracing/contrib/grpc/distributed/propagation.rb +3 -0
- data/lib/datadog/tracing/contrib/http/circuit_breaker.rb +0 -15
- data/lib/datadog/tracing/contrib/http/distributed/propagation.rb +4 -1
- data/lib/datadog/tracing/contrib/http/instrumentation.rb +6 -10
- data/lib/datadog/tracing/contrib/httpclient/instrumentation.rb +6 -16
- data/lib/datadog/tracing/contrib/httprb/instrumentation.rb +7 -15
- data/lib/datadog/tracing/contrib/karafka/configuration/settings.rb +27 -0
- data/lib/datadog/tracing/contrib/karafka/distributed/propagation.rb +48 -0
- data/lib/datadog/tracing/contrib/karafka/ext.rb +27 -0
- data/lib/datadog/tracing/contrib/karafka/integration.rb +45 -0
- data/lib/datadog/tracing/contrib/karafka/monitor.rb +66 -0
- data/lib/datadog/tracing/contrib/karafka/patcher.rb +71 -0
- data/lib/datadog/tracing/contrib/karafka.rb +37 -0
- data/lib/datadog/tracing/contrib/mongodb/configuration/settings.rb +8 -0
- data/lib/datadog/tracing/contrib/mongodb/ext.rb +1 -0
- data/lib/datadog/tracing/contrib/mongodb/subscribers.rb +18 -1
- data/lib/datadog/tracing/contrib/opensearch/configuration/settings.rb +17 -0
- data/lib/datadog/tracing/contrib/opensearch/ext.rb +9 -0
- data/lib/datadog/tracing/contrib/opensearch/patcher.rb +5 -1
- data/lib/datadog/tracing/contrib/patcher.rb +5 -2
- data/lib/datadog/tracing/contrib/rack/request_queue.rb +1 -1
- data/lib/datadog/tracing/contrib/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/server_tracer.rb +1 -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 +10 -1
- data/lib/datadog/tracing/span_event.rb +1 -1
- data/lib/datadog/tracing/span_operation.rb +46 -16
- data/lib/datadog/tracing/sync_writer.rb +1 -2
- data/lib/datadog/tracing/trace_digest.rb +9 -2
- data/lib/datadog/tracing/trace_operation.rb +44 -24
- data/lib/datadog/tracing/trace_segment.rb +6 -4
- data/lib/datadog/tracing/tracer.rb +45 -5
- data/lib/datadog/tracing/transport/http/api.rb +2 -10
- data/lib/datadog/tracing/transport/http/client.rb +5 -4
- data/lib/datadog/tracing/transport/http/traces.rb +13 -41
- data/lib/datadog/tracing/transport/http.rb +11 -44
- data/lib/datadog/tracing/transport/serializable_trace.rb +3 -1
- data/lib/datadog/tracing/transport/trace_formatter.rb +7 -0
- data/lib/datadog/tracing/transport/traces.rb +26 -9
- data/lib/datadog/tracing/utils.rb +1 -1
- data/lib/datadog/tracing/workers/trace_writer.rb +2 -6
- data/lib/datadog/tracing/writer.rb +2 -6
- data/lib/datadog/tracing.rb +16 -3
- data/lib/datadog/version.rb +2 -2
- data/lib/datadog.rb +2 -3
- metadata +80 -19
- data/lib/datadog/appsec/contrib/devise/event.rb +0 -54
- data/lib/datadog/appsec/contrib/devise/patcher/authenticatable_patch.rb +0 -72
- data/lib/datadog/appsec/contrib/devise/patcher/registration_controller_patch.rb +0 -47
- data/lib/datadog/appsec/contrib/devise/resource.rb +0 -35
- data/lib/datadog/appsec/contrib/devise/tracking.rb +0 -57
- data/lib/datadog/appsec/utils/trace_operation.rb +0 -15
- data/lib/datadog/core/telemetry/http/env.rb +0 -20
- data/lib/datadog/core/telemetry/http/ext.rb +0 -28
- data/lib/datadog/core/telemetry/http/response.rb +0 -70
- data/lib/datadog/core/telemetry/http/transport.rb +0 -90
@@ -17,8 +17,6 @@ module Datadog
|
|
17
17
|
DEFAULT_BUFFER_MAX_SIZE = 1000
|
18
18
|
APP_STARTED_EVENT_RETRIES = 10
|
19
19
|
|
20
|
-
TELEMETRY_STARTED_ONCE = Utils::OnlyOnceSuccessful.new(APP_STARTED_EVENT_RETRIES)
|
21
|
-
|
22
20
|
def initialize(
|
23
21
|
heartbeat_interval_seconds:,
|
24
22
|
metrics_aggregation_interval_seconds:,
|
@@ -48,14 +46,25 @@ module Datadog
|
|
48
46
|
@buffer_size = buffer_size
|
49
47
|
|
50
48
|
self.buffer = buffer_klass.new(@buffer_size)
|
49
|
+
|
50
|
+
@initial_event_once = Utils::OnlyOnceSuccessful.new(APP_STARTED_EVENT_RETRIES)
|
51
51
|
end
|
52
52
|
|
53
53
|
attr_reader :logger
|
54
|
+
attr_reader :initial_event_once
|
55
|
+
attr_reader :initial_event
|
54
56
|
|
55
|
-
|
57
|
+
# Returns true if worker thread is successfully started,
|
58
|
+
# false if worker thread was not started but telemetry is enabled,
|
59
|
+
# nil if telemetry is disabled.
|
60
|
+
def start(initial_event)
|
56
61
|
return if !enabled? || forked?
|
57
62
|
|
63
|
+
@initial_event = initial_event
|
64
|
+
|
58
65
|
# starts async worker
|
66
|
+
# perform should return true if thread was actually started,
|
67
|
+
# false otherwise
|
59
68
|
perform
|
60
69
|
end
|
61
70
|
|
@@ -65,18 +74,60 @@ module Datadog
|
|
65
74
|
super
|
66
75
|
end
|
67
76
|
|
77
|
+
# Returns true if event was enqueued, nil if not.
|
78
|
+
# While returning false may seem more reasonable, the only reason
|
79
|
+
# for not enqueueing event (presently) is that telemetry is disabled
|
80
|
+
# altogether, and in this case other methods return nil.
|
68
81
|
def enqueue(event)
|
69
82
|
return if !enabled? || forked?
|
70
83
|
|
71
84
|
buffer.push(event)
|
85
|
+
true
|
86
|
+
end
|
87
|
+
|
88
|
+
def sent_initial_event?
|
89
|
+
initial_event_once.success?
|
72
90
|
end
|
73
91
|
|
74
|
-
def
|
75
|
-
|
92
|
+
def failed_initial_event?
|
93
|
+
initial_event_once.failed?
|
76
94
|
end
|
77
95
|
|
78
|
-
def
|
79
|
-
|
96
|
+
def need_initial_event?
|
97
|
+
!sent_initial_event? && !failed_initial_event?
|
98
|
+
end
|
99
|
+
|
100
|
+
# Wait for the worker to send out all events that have already
|
101
|
+
# been queued, up to 15 seconds. Returns whether all events have
|
102
|
+
# been flushed.
|
103
|
+
#
|
104
|
+
# @api private
|
105
|
+
def flush
|
106
|
+
return true unless enabled? || !run_loop?
|
107
|
+
|
108
|
+
started = Utils::Time.get_time
|
109
|
+
loop do
|
110
|
+
# The AppStarted event is triggered by the worker itself,
|
111
|
+
# from the worker thread. As such the main thread has no way
|
112
|
+
# to delay itself until that event is queued and we need some
|
113
|
+
# way to wait until that event is sent out to assert on it in
|
114
|
+
# the test suite. Check the run once flag which *should*
|
115
|
+
# indicate the event has been queued (at which point our queue
|
116
|
+
# depth check should waint until it's sent).
|
117
|
+
# This is still a hack because the flag can be overridden
|
118
|
+
# either way with or without the event being sent out.
|
119
|
+
# Note that if the AppStarted sending fails, this check
|
120
|
+
# will return false and flushing will be blocked until the
|
121
|
+
# 15 second timeout.
|
122
|
+
# Note that the first wait interval between telemetry event
|
123
|
+
# sending is 10 seconds, the timeout needs to be strictly
|
124
|
+
# greater than that.
|
125
|
+
return true if buffer.empty? && !in_iteration? && sent_initial_event?
|
126
|
+
|
127
|
+
sleep 0.5
|
128
|
+
|
129
|
+
return false if Utils::Time.get_time - started > 15
|
130
|
+
end
|
80
131
|
end
|
81
132
|
|
82
133
|
private
|
@@ -84,11 +135,26 @@ module Datadog
|
|
84
135
|
def perform(*events)
|
85
136
|
return if !enabled? || forked?
|
86
137
|
|
87
|
-
|
138
|
+
if need_initial_event?
|
139
|
+
started!
|
140
|
+
unless sent_initial_event?
|
141
|
+
# We still haven't succeeded in sending the started event,
|
142
|
+
# which will make flush_events do nothing - but the events
|
143
|
+
# given to us as the parameter have already been removed
|
144
|
+
# from the queue.
|
145
|
+
# Put the events back to the front of the queue to not
|
146
|
+
# lose them.
|
147
|
+
buffer.unshift(*events)
|
148
|
+
return
|
149
|
+
end
|
150
|
+
end
|
88
151
|
|
89
152
|
metric_events = @metrics_manager.flush!
|
90
153
|
events = [] if events.nil?
|
91
|
-
|
154
|
+
events += metric_events
|
155
|
+
if events.any?
|
156
|
+
flush_events(events)
|
157
|
+
end
|
92
158
|
|
93
159
|
@current_ticks += 1
|
94
160
|
return if @current_ticks < @ticks_per_heartbeat
|
@@ -98,9 +164,6 @@ module Datadog
|
|
98
164
|
end
|
99
165
|
|
100
166
|
def flush_events(events)
|
101
|
-
return if events.empty?
|
102
|
-
return if !enabled? || !sent_started_event?
|
103
|
-
|
104
167
|
events = deduplicate_logs(events)
|
105
168
|
|
106
169
|
logger.debug { "Sending #{events&.count} telemetry events" }
|
@@ -108,7 +171,7 @@ module Datadog
|
|
108
171
|
end
|
109
172
|
|
110
173
|
def heartbeat!
|
111
|
-
return if !enabled? || !
|
174
|
+
return if !enabled? || !sent_initial_event?
|
112
175
|
|
113
176
|
send_event(Event::AppHeartbeat.new)
|
114
177
|
end
|
@@ -116,26 +179,29 @@ module Datadog
|
|
116
179
|
def started!
|
117
180
|
return unless enabled?
|
118
181
|
|
119
|
-
|
120
|
-
|
121
|
-
disable!
|
122
|
-
return
|
123
|
-
end
|
124
|
-
|
125
|
-
TELEMETRY_STARTED_ONCE.run do
|
126
|
-
res = send_event(Event::AppStarted.new)
|
182
|
+
initial_event_once.run do
|
183
|
+
res = send_event(initial_event)
|
127
184
|
|
128
185
|
if res.ok?
|
129
|
-
logger.debug
|
186
|
+
logger.debug { "Telemetry initial event (#{initial_event.type}) is successfully sent" }
|
130
187
|
|
131
|
-
|
188
|
+
# TODO Dependencies loaded event should probably check for new
|
189
|
+
# dependencies and send the new ones.
|
190
|
+
# System tests demand only one instance of this event per
|
191
|
+
# dependency.
|
192
|
+
send_event(Event::AppDependenciesLoaded.new) if @dependency_collection && initial_event.class.eql?(Telemetry::Event::AppStarted) # standard:disable Style/ClassEqualityComparison:
|
132
193
|
|
133
194
|
true
|
134
195
|
else
|
135
|
-
logger.debug(
|
196
|
+
logger.debug("Error sending telemetry initial event (#{initial_event.type}), retry after heartbeat interval...")
|
136
197
|
false
|
137
198
|
end
|
138
199
|
end
|
200
|
+
|
201
|
+
if failed_initial_event?
|
202
|
+
logger.debug { "Telemetry initial event (#{initial_event.type}) exhausted retries, disabling telemetry worker" }
|
203
|
+
disable!
|
204
|
+
end
|
139
205
|
end
|
140
206
|
|
141
207
|
def send_event(event)
|
@@ -7,6 +7,23 @@ module Datadog
|
|
7
7
|
module API
|
8
8
|
# An API configured with adapter and routes
|
9
9
|
class Instance
|
10
|
+
# Raised when an endpoint is invoked on an API that is not the
|
11
|
+
# of expected API class for that endpoint.
|
12
|
+
class EndpointNotSupportedError < StandardError
|
13
|
+
attr_reader :spec, :endpoint_name
|
14
|
+
|
15
|
+
def initialize(endpoint_name, spec)
|
16
|
+
@spec = spec
|
17
|
+
@endpoint_name = endpoint_name
|
18
|
+
|
19
|
+
super(message)
|
20
|
+
end
|
21
|
+
|
22
|
+
def message
|
23
|
+
"#{endpoint_name} not supported for this API!"
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
10
27
|
attr_reader \
|
11
28
|
:adapter,
|
12
29
|
:headers,
|
@@ -8,6 +8,23 @@ module Datadog
|
|
8
8
|
# Specification for an HTTP API
|
9
9
|
# Defines behaviors without specific configuration details.
|
10
10
|
class Spec
|
11
|
+
# Raised when an endpoint is invoked on an API that did not
|
12
|
+
# define that endpoint.
|
13
|
+
class EndpointNotDefinedError < StandardError
|
14
|
+
attr_reader :spec, :endpoint_name
|
15
|
+
|
16
|
+
def initialize(endpoint_name, spec)
|
17
|
+
@spec = spec
|
18
|
+
@endpoint_name = endpoint_name
|
19
|
+
|
20
|
+
super(message)
|
21
|
+
end
|
22
|
+
|
23
|
+
def message
|
24
|
+
"No #{endpoint_name} endpoint is defined for API specification!"
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
11
28
|
def initialize
|
12
29
|
yield(self) if block_given?
|
13
30
|
end
|
@@ -18,9 +18,10 @@ module Datadog
|
|
18
18
|
:api_options,
|
19
19
|
:default_adapter,
|
20
20
|
:default_api,
|
21
|
-
:default_headers
|
21
|
+
:default_headers,
|
22
|
+
:logger
|
22
23
|
|
23
|
-
def initialize(api_instance_class:)
|
24
|
+
def initialize(api_instance_class:, logger: Datadog.logger)
|
24
25
|
# Global settings
|
25
26
|
@default_adapter = nil
|
26
27
|
@default_headers = {}
|
@@ -33,25 +34,26 @@ module Datadog
|
|
33
34
|
@api_options = {}
|
34
35
|
|
35
36
|
@api_instance_class = api_instance_class
|
37
|
+
@logger = logger
|
36
38
|
|
37
39
|
yield(self) if block_given?
|
38
40
|
end
|
39
41
|
|
40
42
|
def adapter(config, *args, **kwargs)
|
41
43
|
@default_adapter = case config
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
44
|
+
when Core::Configuration::AgentSettingsResolver::AgentSettings
|
45
|
+
registry_klass = REGISTRY.get(config.adapter)
|
46
|
+
raise UnknownAdapterError, config.adapter if registry_klass.nil?
|
47
|
+
|
48
|
+
registry_klass.build(config)
|
49
|
+
when Symbol
|
50
|
+
registry_klass = REGISTRY.get(config)
|
51
|
+
raise UnknownAdapterError, config if registry_klass.nil?
|
52
|
+
|
53
|
+
registry_klass.new(*args, **kwargs)
|
54
|
+
else
|
55
|
+
config
|
56
|
+
end
|
55
57
|
end
|
56
58
|
|
57
59
|
def headers(values = {})
|
@@ -86,7 +88,7 @@ module Datadog
|
|
86
88
|
def to_transport(klass)
|
87
89
|
raise NoDefaultApiError if @default_api.nil?
|
88
90
|
|
89
|
-
klass.new(to_api_instances, @default_api)
|
91
|
+
klass.new(to_api_instances, @default_api, logger: logger)
|
90
92
|
end
|
91
93
|
|
92
94
|
def to_api_instances
|
@@ -29,8 +29,45 @@ module Datadog
|
|
29
29
|
# Helper function that delegates to Builder.new
|
30
30
|
# but is under HTTP namespace so that client code requires this file
|
31
31
|
# to get the adapters configured, and not the builder directly.
|
32
|
-
def build(api_instance_class:, &block)
|
33
|
-
Builder.new(api_instance_class: api_instance_class,
|
32
|
+
def build(api_instance_class:, agent_settings:, logger: Datadog.logger, api_version: nil, headers: nil, &block)
|
33
|
+
Builder.new(api_instance_class: api_instance_class, logger: logger) do |transport|
|
34
|
+
transport.adapter(agent_settings)
|
35
|
+
transport.headers(default_headers)
|
36
|
+
|
37
|
+
# The caller must define APIs before we set the default API.
|
38
|
+
yield transport
|
39
|
+
|
40
|
+
# Apply any settings given by options
|
41
|
+
transport.default_api = api_version if api_version
|
42
|
+
transport.headers(headers) if headers
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
def default_headers
|
47
|
+
{
|
48
|
+
Datadog::Core::Transport::Ext::HTTP::HEADER_CLIENT_COMPUTED_TOP_LEVEL => '1',
|
49
|
+
Datadog::Core::Transport::Ext::HTTP::HEADER_META_LANG =>
|
50
|
+
Datadog::Core::Environment::Ext::LANG,
|
51
|
+
Datadog::Core::Transport::Ext::HTTP::HEADER_META_LANG_VERSION =>
|
52
|
+
Datadog::Core::Environment::Ext::LANG_VERSION,
|
53
|
+
Datadog::Core::Transport::Ext::HTTP::HEADER_META_LANG_INTERPRETER =>
|
54
|
+
Datadog::Core::Environment::Ext::LANG_INTERPRETER,
|
55
|
+
Datadog::Core::Transport::Ext::HTTP::HEADER_META_LANG_INTERPRETER_VENDOR =>
|
56
|
+
Core::Environment::Ext::LANG_ENGINE,
|
57
|
+
Datadog::Core::Transport::Ext::HTTP::HEADER_META_TRACER_VERSION =>
|
58
|
+
Datadog::Core::Environment::Ext::GEM_DATADOG_VERSION
|
59
|
+
}.tap do |headers|
|
60
|
+
# Add container ID, if present.
|
61
|
+
if (container_id = Datadog::Core::Environment::Container.container_id)
|
62
|
+
headers[Datadog::Core::Transport::Ext::HTTP::HEADER_CONTAINER_ID] = container_id
|
63
|
+
end
|
64
|
+
# TODO: inject configuration rather than reading from global here
|
65
|
+
unless Datadog.configuration.apm.tracing.enabled
|
66
|
+
# Sending this header to the agent will disable metrics computation (and billing) on the agent side
|
67
|
+
# by pretending it has already been done on the library side.
|
68
|
+
headers[Datadog::Core::Transport::Ext::HTTP::HEADER_CLIENT_COMPUTED_STATS] = 'yes'
|
69
|
+
end
|
70
|
+
end
|
34
71
|
end
|
35
72
|
end
|
36
73
|
end
|
@@ -51,13 +51,13 @@ module Datadog
|
|
51
51
|
def fork
|
52
52
|
# If a block is provided, it must be wrapped to trigger callbacks.
|
53
53
|
child_block = if block_given?
|
54
|
-
|
55
|
-
|
54
|
+
proc do
|
55
|
+
AtForkMonkeyPatch.run_at_fork_blocks(:child)
|
56
56
|
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
57
|
+
# Invoke original block
|
58
|
+
yield
|
59
|
+
end
|
60
|
+
end
|
61
61
|
|
62
62
|
# Start fork
|
63
63
|
# If a block is provided, use the wrapped version.
|
@@ -7,42 +7,42 @@ module Datadog
|
|
7
7
|
module Duration
|
8
8
|
def self.call(value, base: :s)
|
9
9
|
cast = if value.include?('.')
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
10
|
+
method(:Float)
|
11
|
+
else
|
12
|
+
method(:Integer)
|
13
|
+
end
|
14
14
|
|
15
15
|
scale = case base
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
16
|
+
when :s
|
17
|
+
1_000_000_000
|
18
|
+
when :ms
|
19
|
+
1_000_000
|
20
|
+
when :us
|
21
|
+
1000
|
22
|
+
when :ns
|
23
|
+
1
|
24
|
+
else
|
25
|
+
raise ArgumentError, "invalid base: #{base.inspect}"
|
26
|
+
end
|
27
27
|
|
28
28
|
result = case value
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
29
|
+
when /^(\d+(?:\.\d+)?)h$/
|
30
|
+
cast.call(Regexp.last_match(1)) * 1_000_000_000 * 60 * 60 / scale
|
31
|
+
when /^(\d+(?:\.\d+)?)m$/
|
32
|
+
cast.call(Regexp.last_match(1)) * 1_000_000_000 * 60 / scale
|
33
|
+
when /^(\d+(?:\.\d+)?)s$/
|
34
|
+
cast.call(Regexp.last_match(1)) * 1_000_000_000 / scale
|
35
|
+
when /^(\d+(?:\.\d+)?)ms$/
|
36
|
+
cast.call(Regexp.last_match(1)) * 1_000_000 / scale
|
37
|
+
when /^(\d+(?:\.\d+)?)us$/
|
38
|
+
cast.call(Regexp.last_match(1)) * 1_000 / scale
|
39
|
+
when /^(\d+(?:\.\d+)?)ns$/
|
40
|
+
cast.call(Regexp.last_match(1)) / scale
|
41
|
+
when /^(\d+(?:\.\d+)?)$/
|
42
|
+
cast.call(Regexp.last_match(1))
|
43
|
+
else
|
44
|
+
raise ArgumentError, "invalid duration: #{value.inspect}"
|
45
|
+
end
|
46
46
|
# @type var result: Numeric
|
47
47
|
result.round
|
48
48
|
end
|
@@ -47,12 +47,12 @@ module Datadog
|
|
47
47
|
# This wrapper prevents this by initializing the fork PID when the object is created.
|
48
48
|
if RUBY_VERSION >= '3'
|
49
49
|
def initialize(*args, **kwargs, &block)
|
50
|
-
super
|
50
|
+
super
|
51
51
|
update_fork_pid!
|
52
52
|
end
|
53
53
|
else
|
54
54
|
def initialize(*args, &block)
|
55
|
-
super
|
55
|
+
super
|
56
56
|
update_fork_pid!
|
57
57
|
end
|
58
58
|
end
|
@@ -32,7 +32,7 @@ module Datadog
|
|
32
32
|
def stripped_ip_from_request_headers(headers, ip_headers_to_check: DEFAULT_IP_HEADERS_NAMES)
|
33
33
|
ip = ip_header(headers, ip_headers_to_check)
|
34
34
|
|
35
|
-
ip
|
35
|
+
ip&.to_s
|
36
36
|
end
|
37
37
|
|
38
38
|
# @param [String] IP value.
|
@@ -40,7 +40,7 @@ module Datadog
|
|
40
40
|
# @return [nil] when no valid IP value found.
|
41
41
|
def stripped_ip(ip)
|
42
42
|
ip = ip_to_ipaddr(ip)
|
43
|
-
ip
|
43
|
+
ip&.to_s
|
44
44
|
end
|
45
45
|
|
46
46
|
private
|
@@ -52,10 +52,10 @@ module Datadog
|
|
52
52
|
return unless ip
|
53
53
|
|
54
54
|
clean_ip = if likely_ipv4?(ip)
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
55
|
+
strip_ipv4_port(ip)
|
56
|
+
else
|
57
|
+
strip_zone_specifier(strip_ipv6_port(ip))
|
58
|
+
end
|
59
59
|
|
60
60
|
begin
|
61
61
|
IPAddr.new(clean_ip)
|
@@ -5,14 +5,25 @@ require_relative 'only_once'
|
|
5
5
|
module Datadog
|
6
6
|
module Core
|
7
7
|
module Utils
|
8
|
-
# Helper class to execute something with only one
|
8
|
+
# Helper class to execute something with only one successful execution.
|
9
9
|
#
|
10
|
-
#
|
11
|
-
#
|
10
|
+
# If limit is not provided to the constructor, +run+ will execute the
|
11
|
+
# block an unlimited number of times until the block indicates that it
|
12
|
+
# executed successfully by returning a truthy value. After a block
|
13
|
+
# executes successfully, subsequent +run+ calls will not invoke the
|
14
|
+
# block.
|
12
15
|
#
|
13
|
-
#
|
16
|
+
# If a non-zero limit is provided to the constructor, +run+ will
|
17
|
+
# execute the block up to that many times, and will mark the instance
|
18
|
+
# of OnlyOneSuccessful as failed if none of the executions succeeded.
|
14
19
|
#
|
15
|
-
#
|
20
|
+
# One consumer of this class is sending the app-started telemetry event.
|
21
|
+
#
|
22
|
+
# Successful execution is determined by the return value of the block:
|
23
|
+
# any truthy value is considered success.
|
24
|
+
#
|
25
|
+
# This class is thread-safe (however, instances of it must also be
|
26
|
+
# created in a thread-safe manner).
|
16
27
|
#
|
17
28
|
# Note: In its current state, this class is not Ractor-safe.
|
18
29
|
# In https://github.com/DataDog/dd-trace-rb/pull/1398#issuecomment-797378810 we have a discussion of alternatives,
|
@@ -31,6 +31,16 @@ module Datadog
|
|
31
31
|
#
|
32
32
|
# @param block [Proc] block that returns a `Time` object representing the current wall time
|
33
33
|
def now_provider=(block)
|
34
|
+
class << self
|
35
|
+
# Avoid method redefinition warning.
|
36
|
+
# `rescue nil` is added in case customers remove the method
|
37
|
+
# themselves to squelch the warning.
|
38
|
+
begin
|
39
|
+
remove_method(:now)
|
40
|
+
rescue
|
41
|
+
nil
|
42
|
+
end
|
43
|
+
end
|
34
44
|
define_singleton_method(:now, &block)
|
35
45
|
end
|
36
46
|
|
@@ -43,6 +53,16 @@ module Datadog
|
|
43
53
|
#
|
44
54
|
# @param block [Proc] block that accepts unit and returns timestamp in the requested unit
|
45
55
|
def get_time_provider=(block)
|
56
|
+
class << self
|
57
|
+
# Avoid method redefinition warning
|
58
|
+
# `rescue nil` is added in case customers remove the method
|
59
|
+
# themselves to squelch the warning.
|
60
|
+
begin
|
61
|
+
remove_method(:get_time)
|
62
|
+
rescue
|
63
|
+
nil
|
64
|
+
end
|
65
|
+
end
|
46
66
|
define_singleton_method(:get_time, &block)
|
47
67
|
end
|
48
68
|
|
@@ -0,0 +1,21 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Datadog
|
4
|
+
module Core
|
5
|
+
module Utils
|
6
|
+
# Helper methods for truncating data
|
7
|
+
module Truncation
|
8
|
+
module_function
|
9
|
+
|
10
|
+
def truncate_in_middle(string, max_prefix_length, max_suffix_length)
|
11
|
+
max_length = max_prefix_length + 3 + max_suffix_length
|
12
|
+
if string.length > max_length
|
13
|
+
"#{string[0...max_prefix_length]}...#{string[-max_suffix_length..-1]}"
|
14
|
+
else
|
15
|
+
string
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -28,29 +28,29 @@ module Datadog
|
|
28
28
|
"--#{SecureRandom.uuid}"
|
29
29
|
end
|
30
30
|
|
31
|
-
def initialize(path, params, headers={}, boundary = Multipartable.secure_boundary)
|
31
|
+
def initialize(path, params, headers = {}, boundary = Multipartable.secure_boundary)
|
32
32
|
headers = headers.clone # don't want to modify the original variable
|
33
33
|
parts_headers = headers.delete(:parts) || {}
|
34
34
|
super(path, headers)
|
35
|
-
parts = params.map do |k,v|
|
35
|
+
parts = params.map do |k, v|
|
36
36
|
case v
|
37
37
|
when Array
|
38
|
-
v.map {|item| Parts::Part.new(boundary, "#{k}[]", item, parts_headers[k]) }
|
38
|
+
v.map { |item| Parts::Part.new(boundary, "#{k}[]", item, parts_headers[k]) }
|
39
39
|
else
|
40
40
|
Parts::Part.new(boundary, k, v, parts_headers[k])
|
41
41
|
end
|
42
42
|
end.flatten
|
43
43
|
parts << Parts::EpiloguePart.new(boundary)
|
44
|
-
ios = parts.map {|p| p.to_io }
|
45
|
-
|
46
|
-
|
47
|
-
self.content_length = parts.inject(0) {|sum,i| sum + i.length }
|
44
|
+
ios = parts.map { |p| p.to_io }
|
45
|
+
set_content_type(headers["Content-Type"] || "multipart/form-data",
|
46
|
+
{"boundary" => boundary})
|
47
|
+
self.content_length = parts.inject(0) { |sum, i| sum + i.length }
|
48
48
|
self.body_stream = CompositeReadIO.new(*ios)
|
49
49
|
|
50
50
|
@boundary = boundary
|
51
51
|
end
|
52
52
|
|
53
|
-
|
53
|
+
attr_reader :boundary
|
54
54
|
end
|
55
55
|
end
|
56
56
|
end
|