datadog 2.31.0 → 2.32.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/ext/datadog_profiling_native_extension/collectors_cpu_and_wall_time_worker.c +17 -7
- data/ext/datadog_profiling_native_extension/collectors_thread_context.c +11 -4
- data/ext/datadog_profiling_native_extension/collectors_thread_context.h +6 -0
- data/ext/datadog_profiling_native_extension/extconf.rb +5 -4
- data/ext/datadog_profiling_native_extension/http_transport.c +10 -5
- data/ext/libdatadog_api/di.c +48 -0
- data/ext/libdatadog_api/extconf.rb +7 -4
- data/ext/libdatadog_extconf_helpers.rb +37 -0
- data/lib/datadog/ai_guard/configuration.rb +105 -2
- data/lib/datadog/ai_guard/evaluation.rb +1 -0
- data/lib/datadog/ai_guard/ext.rb +1 -0
- data/lib/datadog/appsec/autoload.rb +1 -1
- data/lib/datadog/appsec/component.rb +1 -1
- data/lib/datadog/appsec/configuration.rb +414 -1
- data/lib/datadog/appsec/contrib/devise/patches/signin_tracking_patch.rb +2 -1
- data/lib/datadog/appsec/contrib/rack/gateway/request.rb +1 -1
- data/lib/datadog/appsec/contrib/rails/patcher.rb +2 -2
- data/lib/datadog/appsec/metrics/telemetry.rb +13 -1
- data/lib/datadog/appsec/security_engine/runner.rb +1 -1
- data/lib/datadog/appsec/trace_keeper.rb +18 -6
- data/lib/datadog/appsec/utils/http/url_encoded.rb +2 -2
- data/lib/datadog/core/configuration/components.rb +1 -1
- data/lib/datadog/core/configuration/settings.rb +3 -0
- data/lib/datadog/core/configuration/supported_configurations.rb +2 -0
- data/lib/datadog/core/configuration.rb +1 -1
- data/lib/datadog/core/contrib/rails/utils.rb +1 -1
- data/lib/datadog/core/crashtracking/component.rb +3 -3
- data/lib/datadog/core/diagnostics/environment_logger.rb +3 -1
- data/lib/datadog/core/environment/container.rb +2 -2
- data/lib/datadog/core/feature_flags.rb +1 -1
- data/lib/datadog/core/metrics/client.rb +5 -5
- data/lib/datadog/core/remote/client.rb +1 -1
- data/lib/datadog/core/remote/component.rb +2 -2
- data/lib/datadog/core/runtime/metrics.rb +1 -1
- data/lib/datadog/core/telemetry/emitter.rb +1 -1
- data/lib/datadog/core/telemetry/event/app_started.rb +2 -2
- data/lib/datadog/core/transport/http.rb +2 -0
- data/lib/datadog/core/utils.rb +1 -1
- data/lib/datadog/core/workers/async.rb +1 -1
- data/lib/datadog/core.rb +1 -1
- data/lib/datadog/data_streams/configuration.rb +40 -1
- data/lib/datadog/data_streams/pathway_context.rb +1 -1
- data/lib/datadog/data_streams/processor.rb +1 -1
- data/lib/datadog/data_streams.rb +1 -1
- data/lib/datadog/di/base.rb +8 -5
- data/lib/datadog/di/code_tracker.rb +179 -1
- data/lib/datadog/di/component.rb +1 -1
- data/lib/datadog/di/configuration.rb +235 -2
- data/lib/datadog/di/instrumenter.rb +46 -26
- data/lib/datadog/di/probe_builder.rb +1 -1
- data/lib/datadog/di/probe_file_loader.rb +2 -2
- data/lib/datadog/di/probe_manager.rb +6 -6
- data/lib/datadog/di/probe_notification_builder.rb +1 -1
- data/lib/datadog/di/probe_notifier_worker.rb +2 -2
- data/lib/datadog/di/remote.rb +6 -6
- data/lib/datadog/di/serializer.rb +1 -1
- data/lib/datadog/di/transport/input.rb +3 -3
- data/lib/datadog/error_tracking/configuration.rb +55 -2
- data/lib/datadog/kit/enable_core_dumps.rb +1 -1
- data/lib/datadog/open_feature/component.rb +18 -1
- data/lib/datadog/open_feature/evaluation_engine.rb +3 -3
- data/lib/datadog/open_feature/exposures/reporter.rb +1 -1
- data/lib/datadog/open_feature/exposures/worker.rb +1 -1
- data/lib/datadog/open_feature/hooks/flag_eval_hook.rb +49 -0
- data/lib/datadog/open_feature/metrics/flag_eval_metrics.rb +149 -0
- data/lib/datadog/open_feature/provider.rb +19 -1
- data/lib/datadog/open_feature/remote.rb +1 -1
- data/lib/datadog/open_feature/transport.rb +1 -1
- data/lib/datadog/opentelemetry/metrics.rb +3 -3
- data/lib/datadog/opentelemetry/sdk/configurator.rb +1 -1
- data/lib/datadog/opentelemetry/sdk/metrics_exporter.rb +1 -1
- data/lib/datadog/profiling/collectors/code_provenance.rb +35 -9
- data/lib/datadog/profiling/collectors/cpu_and_wall_time_worker.rb +31 -2
- data/lib/datadog/profiling/collectors/idle_sampling_helper.rb +8 -2
- data/lib/datadog/profiling/collectors/info.rb +16 -3
- data/lib/datadog/profiling/component.rb +3 -5
- data/lib/datadog/profiling/exporter.rb +37 -12
- data/lib/datadog/profiling/ext.rb +0 -2
- data/lib/datadog/profiling/flush.rb +21 -12
- data/lib/datadog/profiling/http_transport.rb +12 -1
- data/lib/datadog/profiling/load_native_extension.rb +1 -1
- data/lib/datadog/profiling/profiler.rb +13 -1
- data/lib/datadog/profiling/scheduler.rb +2 -2
- data/lib/datadog/profiling/tasks/exec.rb +8 -3
- data/lib/datadog/profiling/tasks/help.rb +1 -0
- data/lib/datadog/profiling/tasks/setup.rb +2 -2
- data/lib/datadog/single_step_instrument.rb +1 -1
- data/lib/datadog/symbol_database/configuration.rb +65 -0
- data/lib/datadog/symbol_database/extractor.rb +915 -0
- data/lib/datadog/symbol_database/file_hash.rb +46 -0
- data/lib/datadog/symbol_database/logger.rb +43 -0
- data/lib/datadog/symbol_database/scope.rb +98 -0
- data/lib/datadog/symbol_database/service_version.rb +57 -0
- data/lib/datadog/symbol_database/symbol.rb +66 -0
- data/lib/datadog/symbol_database/transport/http/endpoint.rb +28 -0
- data/lib/datadog/symbol_database/transport/http.rb +45 -0
- data/lib/datadog/symbol_database/transport.rb +54 -0
- data/lib/datadog/symbol_database/uploader.rb +166 -0
- data/lib/datadog/symbol_database.rb +49 -0
- data/lib/datadog/tracing/buffer.rb +3 -3
- data/lib/datadog/tracing/configuration/settings.rb +1 -1
- data/lib/datadog/tracing/contrib/action_pack/action_controller/instrumentation.rb +5 -3
- data/lib/datadog/tracing/contrib/action_view/events/render_template.rb +1 -1
- data/lib/datadog/tracing/contrib/active_job/events/discard.rb +1 -1
- data/lib/datadog/tracing/contrib/active_job/events/enqueue.rb +1 -1
- data/lib/datadog/tracing/contrib/active_job/events/enqueue_at.rb +1 -1
- data/lib/datadog/tracing/contrib/active_job/events/enqueue_retry.rb +1 -1
- data/lib/datadog/tracing/contrib/active_job/events/perform.rb +1 -1
- data/lib/datadog/tracing/contrib/active_job/events/retry_stopped.rb +1 -1
- data/lib/datadog/tracing/contrib/active_model_serializers/events/render.rb +1 -1
- data/lib/datadog/tracing/contrib/active_model_serializers/events/serialize.rb +1 -1
- data/lib/datadog/tracing/contrib/active_record/configuration/resolver.rb +2 -2
- data/lib/datadog/tracing/contrib/active_record/events/instantiation.rb +1 -1
- data/lib/datadog/tracing/contrib/active_record/events/sql.rb +1 -1
- data/lib/datadog/tracing/contrib/active_record/utils.rb +1 -1
- data/lib/datadog/tracing/contrib/active_support/cache/events/cache.rb +1 -1
- data/lib/datadog/tracing/contrib/active_support/notifications/subscription.rb +2 -2
- data/lib/datadog/tracing/contrib/aws/instrumentation.rb +1 -1
- data/lib/datadog/tracing/contrib/component.rb +1 -1
- data/lib/datadog/tracing/contrib/configuration/resolver.rb +7 -4
- data/lib/datadog/tracing/contrib/dalli/quantize.rb +1 -1
- data/lib/datadog/tracing/contrib/elasticsearch/patcher.rb +1 -1
- data/lib/datadog/tracing/contrib/excon/middleware.rb +2 -2
- data/lib/datadog/tracing/contrib/extensions.rb +9 -0
- data/lib/datadog/tracing/contrib/faraday/middleware.rb +2 -2
- data/lib/datadog/tracing/contrib/grape/endpoint.rb +5 -5
- data/lib/datadog/tracing/contrib/grpc/datadog_interceptor/client.rb +2 -2
- data/lib/datadog/tracing/contrib/grpc/datadog_interceptor/server.rb +2 -2
- data/lib/datadog/tracing/contrib/http/instrumentation.rb +2 -2
- data/lib/datadog/tracing/contrib/httpclient/instrumentation.rb +6 -2
- data/lib/datadog/tracing/contrib/httprb/instrumentation.rb +2 -2
- data/lib/datadog/tracing/contrib/kafka/instrumentation/consumer.rb +2 -2
- data/lib/datadog/tracing/contrib/kafka/instrumentation/producer.rb +2 -2
- data/lib/datadog/tracing/contrib/karafka/patcher.rb +1 -1
- data/lib/datadog/tracing/contrib/mongodb/subscribers.rb +3 -3
- data/lib/datadog/tracing/contrib/opensearch/patcher.rb +1 -1
- data/lib/datadog/tracing/contrib/presto/instrumentation.rb +3 -3
- data/lib/datadog/tracing/contrib/rack/patcher.rb +1 -1
- data/lib/datadog/tracing/contrib/rack/request_queue.rb +1 -1
- data/lib/datadog/tracing/contrib/rails/log_injection.rb +1 -1
- data/lib/datadog/tracing/contrib/rails/runner.rb +1 -1
- data/lib/datadog/tracing/contrib/rake/instrumentation.rb +2 -2
- data/lib/datadog/tracing/contrib/redis/quantize.rb +1 -1
- data/lib/datadog/tracing/contrib/redis/tags.rb +1 -1
- data/lib/datadog/tracing/contrib/sidekiq/utils.rb +1 -1
- data/lib/datadog/tracing/contrib/stripe/request.rb +1 -1
- data/lib/datadog/tracing/contrib.rb +8 -0
- data/lib/datadog/tracing/diagnostics/environment_logger.rb +3 -1
- data/lib/datadog/tracing/distributed/baggage.rb +59 -5
- data/lib/datadog/tracing/distributed/datadog.rb +11 -11
- data/lib/datadog/tracing/distributed/datadog_tags_codec.rb +1 -1
- data/lib/datadog/tracing/distributed/propagation.rb +2 -2
- data/lib/datadog/tracing/distributed/trace_context.rb +74 -32
- data/lib/datadog/tracing/event.rb +1 -1
- data/lib/datadog/tracing/metadata/tagging.rb +2 -2
- data/lib/datadog/tracing/pipeline.rb +1 -1
- data/lib/datadog/tracing/remote.rb +1 -1
- data/lib/datadog/tracing/sampling/rule.rb +1 -1
- data/lib/datadog/tracing/sampling/rule_sampler.rb +2 -2
- data/lib/datadog/tracing/sampling/span/rule_parser.rb +2 -2
- data/lib/datadog/tracing/span_operation.rb +3 -3
- data/lib/datadog/tracing/trace_operation.rb +4 -4
- data/lib/datadog/tracing/tracer.rb +5 -5
- data/lib/datadog/tracing/transport/io/client.rb +1 -1
- data/lib/datadog/tracing/workers.rb +2 -1
- data/lib/datadog/version.rb +1 -1
- metadata +18 -9
- data/lib/datadog/ai_guard/configuration/settings.rb +0 -113
- data/lib/datadog/appsec/configuration/settings.rb +0 -423
- data/lib/datadog/data_streams/configuration/settings.rb +0 -49
- data/lib/datadog/di/configuration/settings.rb +0 -243
- data/lib/datadog/error_tracking/configuration/settings.rb +0 -63
|
@@ -14,11 +14,18 @@ module Datadog
|
|
|
14
14
|
# could be seen as overkill for this case but it allows us to centralize information
|
|
15
15
|
# gathering and easily support more flexible/dynamic info collection in the future.
|
|
16
16
|
class Info
|
|
17
|
+
# @rbs @info: ::Hash[::Symbol, ::Hash[::Symbol, untyped]]
|
|
18
|
+
# @rbs @platform_info: ::Hash[::Symbol, untyped]
|
|
19
|
+
# @rbs @runtime_info: ::Hash[::Symbol, untyped]
|
|
20
|
+
# @rbs @application_info: ::Hash[::Symbol, untyped]
|
|
21
|
+
# @rbs @profiler_info: ::Hash[::Symbol, untyped]?
|
|
22
|
+
# @rbs @gc_tuning_info: ::Hash[::Symbol, ::String]
|
|
23
|
+
|
|
24
|
+
#: (untyped) -> void
|
|
17
25
|
def initialize(settings)
|
|
18
26
|
@profiler_info = nil
|
|
19
27
|
|
|
20
|
-
|
|
21
|
-
@info = { # steep:ignore IncompatibleAssignment
|
|
28
|
+
@info = {
|
|
22
29
|
platform: collect_platform_info,
|
|
23
30
|
runtime: collect_runtime_info,
|
|
24
31
|
application: collect_application_info(settings),
|
|
@@ -26,7 +33,7 @@ module Datadog
|
|
|
26
33
|
}.freeze
|
|
27
34
|
end
|
|
28
35
|
|
|
29
|
-
attr_reader :info
|
|
36
|
+
attr_reader :info #: ::Hash[::Symbol, ::Hash[::Symbol, untyped]]
|
|
30
37
|
|
|
31
38
|
private
|
|
32
39
|
|
|
@@ -69,6 +76,7 @@ module Datadog
|
|
|
69
76
|
# gets initialized before a user has a chance to configure the library.
|
|
70
77
|
START_TIME = Time.now.utc.freeze
|
|
71
78
|
|
|
79
|
+
#: () -> ::Hash[::Symbol, untyped]
|
|
72
80
|
def collect_platform_info
|
|
73
81
|
@platform_info ||= {
|
|
74
82
|
container_id: Datadog::Core::Environment::Container.container_id,
|
|
@@ -79,6 +87,7 @@ module Datadog
|
|
|
79
87
|
}.freeze
|
|
80
88
|
end
|
|
81
89
|
|
|
90
|
+
#: () -> ::Hash[::Symbol, untyped]
|
|
82
91
|
def collect_runtime_info
|
|
83
92
|
@runtime_info ||= {
|
|
84
93
|
engine: Datadog::Core::Environment::Identity.lang_engine,
|
|
@@ -88,6 +97,7 @@ module Datadog
|
|
|
88
97
|
}.freeze
|
|
89
98
|
end
|
|
90
99
|
|
|
100
|
+
#: (untyped) -> ::Hash[::Symbol, untyped]
|
|
91
101
|
def collect_application_info(settings)
|
|
92
102
|
@application_info ||= {
|
|
93
103
|
start_time: START_TIME.iso8601,
|
|
@@ -97,6 +107,7 @@ module Datadog
|
|
|
97
107
|
}.freeze
|
|
98
108
|
end
|
|
99
109
|
|
|
110
|
+
#: (untyped) -> ::Hash[::Symbol, untyped]
|
|
100
111
|
def collect_profiler_info(settings)
|
|
101
112
|
@profiler_info ||= begin
|
|
102
113
|
lib_datadog_gem = ::Gem.loaded_specs["libdatadog"]
|
|
@@ -123,6 +134,7 @@ module Datadog
|
|
|
123
134
|
# instances without proper serialization.
|
|
124
135
|
# This method navigates a settings object recursively, converting
|
|
125
136
|
# it into more basic types that are trivially convertible to JSON.
|
|
137
|
+
#: (untyped) -> untyped
|
|
126
138
|
def collect_settings_recursively(v)
|
|
127
139
|
v = v.options_hash if v.respond_to?(:options_hash)
|
|
128
140
|
|
|
@@ -143,6 +155,7 @@ module Datadog
|
|
|
143
155
|
end
|
|
144
156
|
end
|
|
145
157
|
|
|
158
|
+
#: () -> ::Hash[::Symbol, ::String]
|
|
146
159
|
def collect_gc_tuning_info
|
|
147
160
|
return @gc_tuning_info if defined?(@gc_tuning_info)
|
|
148
161
|
|
|
@@ -10,8 +10,6 @@ module Datadog
|
|
|
10
10
|
# * Profiling in the trace viewer, as well as scoping a profile down to a span
|
|
11
11
|
# * Endpoint aggregation in the profiler UX, including normalization (resource per endpoint call)
|
|
12
12
|
def self.build_profiler_component(settings:, agent_settings:, optional_tracer:, logger:) # rubocop:disable Metrics/MethodLength
|
|
13
|
-
return [nil, {profiling_enabled: false}] unless settings.profiling.enabled
|
|
14
|
-
|
|
15
13
|
# Workaround for weird dependency direction: the Core::Configuration::Components class currently has a
|
|
16
14
|
# dependency on individual products, in this case the Profiler.
|
|
17
15
|
# (Note "currently": in the future we want to change this so core classes don't depend on specific products)
|
|
@@ -31,7 +29,7 @@ module Datadog
|
|
|
31
29
|
# no-op if profiling is already loaded).
|
|
32
30
|
require_relative "../profiling"
|
|
33
31
|
|
|
34
|
-
return [nil, {profiling_enabled: false}] unless Profiling.supported?
|
|
32
|
+
return [nil, {profiling_enabled: false}] unless settings.profiling.enabled && Profiling.supported?
|
|
35
33
|
|
|
36
34
|
# Activate forking extensions
|
|
37
35
|
Profiling::Tasks::Setup.new.run
|
|
@@ -94,7 +92,7 @@ module Datadog
|
|
|
94
92
|
[profiler, {profiling_enabled: true}]
|
|
95
93
|
rescue Exception => e # rubocop:disable Lint/RescueException
|
|
96
94
|
logger.warn do
|
|
97
|
-
"Failed to initialize profiling: #{e.class}: #{e} " \
|
|
95
|
+
"Failed to initialize profiling: #{e.class}: #{e.message} " \
|
|
98
96
|
"Location: #{Array(e.backtrace).first}"
|
|
99
97
|
end
|
|
100
98
|
Datadog::Core::Telemetry::Logger.report(e, description: "Failed to initialize profiling")
|
|
@@ -378,7 +376,7 @@ module Datadog
|
|
|
378
376
|
rescue StandardError, LoadError => e
|
|
379
377
|
logger.warn(
|
|
380
378
|
"Failed to probe `mysql2` gem information. " \
|
|
381
|
-
"Cause: #{e.class}: #{e} Location: #{Array(e.backtrace).first}"
|
|
379
|
+
"Cause: #{e.class}: #{e.message} Location: #{Array(e.backtrace).first}"
|
|
382
380
|
)
|
|
383
381
|
|
|
384
382
|
true
|
|
@@ -13,24 +13,35 @@ module Datadog
|
|
|
13
13
|
# recorders, so I've decided to make it specific until we actually need to support more recorders.
|
|
14
14
|
#
|
|
15
15
|
class Exporter
|
|
16
|
+
# @rbs @worker: Datadog::Profiling::Collectors::CpuAndWallTimeWorker
|
|
17
|
+
|
|
16
18
|
# Profiles with duration less than this will not be reported
|
|
17
19
|
PROFILE_DURATION_THRESHOLD_SECONDS = 1
|
|
18
20
|
|
|
19
21
|
private
|
|
20
22
|
|
|
21
|
-
attr_reader
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
23
|
+
attr_reader :pprof_recorder #: Datadog::Profiling::StackRecorder
|
|
24
|
+
# The code provenance collector acts both as collector and as a recorder
|
|
25
|
+
attr_reader :code_provenance_collector #: Datadog::Profiling::Collectors::CodeProvenance?
|
|
26
|
+
attr_reader :minimum_duration_seconds #: ::Integer
|
|
27
|
+
attr_reader :time_provider #: singleton(::Time)
|
|
28
|
+
attr_reader :last_flush_finish_at #: ::Time?
|
|
29
|
+
attr_reader :created_at #: ::Time
|
|
30
|
+
attr_reader :internal_metadata #: ::Hash[::Symbol, untyped]
|
|
31
|
+
attr_reader :info_json #: ::String
|
|
32
|
+
attr_reader :sequence_tracker #: singleton(Datadog::Profiling::SequenceTracker)
|
|
31
33
|
|
|
32
34
|
public
|
|
33
35
|
|
|
36
|
+
# @rbs pprof_recorder: Datadog::Profiling::StackRecorder
|
|
37
|
+
# @rbs worker: Datadog::Profiling::Collectors::CpuAndWallTimeWorker
|
|
38
|
+
# @rbs info_collector: Datadog::Profiling::Collectors::Info
|
|
39
|
+
# @rbs code_provenance_collector: Datadog::Profiling::Collectors::CodeProvenance?
|
|
40
|
+
# @rbs internal_metadata: ::Hash[::Symbol, untyped]
|
|
41
|
+
# @rbs minimum_duration_seconds: ::Integer
|
|
42
|
+
# @rbs time_provider: singleton(::Time)
|
|
43
|
+
# @rbs sequence_tracker: singleton(Datadog::Profiling::SequenceTracker)
|
|
44
|
+
# @rbs return: void
|
|
34
45
|
def initialize(
|
|
35
46
|
pprof_recorder:,
|
|
36
47
|
worker:,
|
|
@@ -55,6 +66,7 @@ module Datadog
|
|
|
55
66
|
@sequence_tracker = sequence_tracker
|
|
56
67
|
end
|
|
57
68
|
|
|
69
|
+
#: () -> Datadog::Profiling::Flush?
|
|
58
70
|
def flush
|
|
59
71
|
worker_stats = @worker.stats_and_reset_not_thread_safe
|
|
60
72
|
serialization_result = pprof_recorder.serialize
|
|
@@ -68,7 +80,17 @@ module Datadog
|
|
|
68
80
|
return
|
|
69
81
|
end
|
|
70
82
|
|
|
71
|
-
uncompressed_code_provenance =
|
|
83
|
+
uncompressed_code_provenance =
|
|
84
|
+
if (collector = code_provenance_collector)
|
|
85
|
+
collector.refresh.generate_json
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
metrics = [] #: Array[[::String, ::Numeric]]
|
|
89
|
+
|
|
90
|
+
# The key is always there, but the value might be nil if GVL profiling is disabled.
|
|
91
|
+
# We delete it to avoid reporting the same data point twice.
|
|
92
|
+
gvl_waiting_time_ns_total = worker_stats.delete(:gvl_waiting_time_ns_total)
|
|
93
|
+
metrics << ["ruby_global_lock_wait_time_total", gvl_waiting_time_ns_total] if gvl_waiting_time_ns_total
|
|
72
94
|
|
|
73
95
|
process_tags = Datadog.configuration.experimental_propagate_process_tags_enabled ?
|
|
74
96
|
Core::Environment::Process.serialized : ''
|
|
@@ -77,8 +99,8 @@ module Datadog
|
|
|
77
99
|
start: start,
|
|
78
100
|
finish: finish,
|
|
79
101
|
encoded_profile: encoded_profile,
|
|
80
|
-
code_provenance_file_name: Datadog::Profiling::Ext::Transport::HTTP::CODE_PROVENANCE_FILENAME,
|
|
81
102
|
code_provenance_data: uncompressed_code_provenance,
|
|
103
|
+
metrics: metrics,
|
|
82
104
|
tags_as_array: Datadog::Profiling::TagBuilder.call(
|
|
83
105
|
settings: Datadog.configuration,
|
|
84
106
|
profile_seq: sequence_tracker.get_next,
|
|
@@ -96,10 +118,12 @@ module Datadog
|
|
|
96
118
|
)
|
|
97
119
|
end
|
|
98
120
|
|
|
121
|
+
#: () -> bool
|
|
99
122
|
def can_flush?
|
|
100
123
|
!duration_below_threshold?(last_flush_finish_at || created_at, time_provider.now.utc)
|
|
101
124
|
end
|
|
102
125
|
|
|
126
|
+
#: () -> void
|
|
103
127
|
def reset_after_fork
|
|
104
128
|
@last_flush_finish_at = time_provider.now.utc
|
|
105
129
|
nil
|
|
@@ -107,6 +131,7 @@ module Datadog
|
|
|
107
131
|
|
|
108
132
|
private
|
|
109
133
|
|
|
134
|
+
#: (::Time, ::Time) -> bool
|
|
110
135
|
def duration_below_threshold?(start, finish)
|
|
111
136
|
(finish - start) < minimum_duration_seconds
|
|
112
137
|
end
|
|
@@ -6,23 +6,32 @@ module Datadog
|
|
|
6
6
|
module Profiling
|
|
7
7
|
# Entity class used to represent metadata for a given profile
|
|
8
8
|
class Flush
|
|
9
|
-
attr_reader
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
:info_json
|
|
9
|
+
attr_reader :start #: ::Time
|
|
10
|
+
attr_reader :finish #: ::Time
|
|
11
|
+
attr_reader :encoded_profile #: Datadog::Profiling::EncodedProfile
|
|
12
|
+
attr_reader :code_provenance_data #: ::String?
|
|
13
|
+
attr_reader :metrics #: ::String
|
|
14
|
+
attr_reader :tags_as_array #: Array[[::String, ::String]]
|
|
15
|
+
attr_reader :process_tags #: ::String
|
|
16
|
+
attr_reader :internal_metadata_json #: ::String
|
|
17
|
+
attr_reader :info_json #: ::String
|
|
19
18
|
|
|
19
|
+
# @rbs start: ::Time
|
|
20
|
+
# @rbs finish: ::Time
|
|
21
|
+
# @rbs encoded_profile: Datadog::Profiling::EncodedProfile
|
|
22
|
+
# @rbs code_provenance_data: ::String?
|
|
23
|
+
# @rbs metrics: Array[[::String, ::Numeric]]
|
|
24
|
+
# @rbs tags_as_array: Array[[::String, ::String]]
|
|
25
|
+
# @rbs process_tags: ::String
|
|
26
|
+
# @rbs internal_metadata: ::Hash[::Symbol, ::String | bool | ::Numeric]
|
|
27
|
+
# @rbs info_json: ::String
|
|
28
|
+
# @rbs return: void
|
|
20
29
|
def initialize(
|
|
21
30
|
start:,
|
|
22
31
|
finish:,
|
|
23
32
|
encoded_profile:,
|
|
24
|
-
code_provenance_file_name:,
|
|
25
33
|
code_provenance_data:,
|
|
34
|
+
metrics:,
|
|
26
35
|
tags_as_array:,
|
|
27
36
|
process_tags:,
|
|
28
37
|
internal_metadata:,
|
|
@@ -31,8 +40,8 @@ module Datadog
|
|
|
31
40
|
@start = start
|
|
32
41
|
@finish = finish
|
|
33
42
|
@encoded_profile = encoded_profile
|
|
34
|
-
@code_provenance_file_name = code_provenance_file_name
|
|
35
43
|
@code_provenance_data = code_provenance_data
|
|
44
|
+
@metrics = JSON.generate(metrics)
|
|
36
45
|
@tags_as_array = tags_as_array
|
|
37
46
|
@process_tags = process_tags
|
|
38
47
|
@internal_metadata_json = JSON.generate(internal_metadata)
|
|
@@ -8,8 +8,16 @@ module Datadog
|
|
|
8
8
|
# Used to report profiling data to Datadog.
|
|
9
9
|
# Methods prefixed with _native_ are implemented in `http_transport.c`
|
|
10
10
|
class HttpTransport
|
|
11
|
-
|
|
11
|
+
# @rbs @exporter_configuration: exporter_configuration_array
|
|
12
12
|
|
|
13
|
+
attr_reader :exporter_configuration #: exporter_configuration_array
|
|
14
|
+
|
|
15
|
+
# @rbs agent_settings: Datadog::Core::Configuration::AgentSettings
|
|
16
|
+
# @rbs site: ::String?
|
|
17
|
+
# @rbs api_key: ::String?
|
|
18
|
+
# @rbs upload_timeout_seconds: ::Integer
|
|
19
|
+
# @rbs use_system_dns: bool
|
|
20
|
+
# @rbs return: void
|
|
13
21
|
def initialize(agent_settings:, site:, api_key:, upload_timeout_seconds:, use_system_dns:)
|
|
14
22
|
timeout_milliseconds = (upload_timeout_seconds * 1_000).to_i
|
|
15
23
|
|
|
@@ -28,6 +36,7 @@ module Datadog
|
|
|
28
36
|
raise(ArgumentError, "Failed to initialize transport: #{result}") if status == :error
|
|
29
37
|
end
|
|
30
38
|
|
|
39
|
+
#: (Datadog::Profiling::Flush) -> bool
|
|
31
40
|
def export(flush)
|
|
32
41
|
status, result = self.class._native_do_export(
|
|
33
42
|
exporter_configuration,
|
|
@@ -57,10 +66,12 @@ module Datadog
|
|
|
57
66
|
|
|
58
67
|
private
|
|
59
68
|
|
|
69
|
+
#: (::String?, ::String?) -> bool?
|
|
60
70
|
def agentless?(site, api_key)
|
|
61
71
|
site && api_key && %w[1 true].include?(ENV[Profiling::Ext::ENV_AGENTLESS] || '') # rubocop:disable CustomCops/EnvUsageCop
|
|
62
72
|
end
|
|
63
73
|
|
|
74
|
+
#: () -> ::String
|
|
64
75
|
def config_without_api_key
|
|
65
76
|
"#{exporter_configuration[0]}: #{exporter_configuration[3]}"
|
|
66
77
|
end
|
|
@@ -8,15 +8,20 @@ module Datadog
|
|
|
8
8
|
|
|
9
9
|
private
|
|
10
10
|
|
|
11
|
-
attr_reader :worker
|
|
11
|
+
attr_reader :worker #: Datadog::Profiling::Collectors::CpuAndWallTimeWorker
|
|
12
|
+
attr_reader :scheduler #: Datadog::Profiling::Scheduler
|
|
12
13
|
|
|
13
14
|
public
|
|
14
15
|
|
|
16
|
+
# @rbs worker: Datadog::Profiling::Collectors::CpuAndWallTimeWorker
|
|
17
|
+
# @rbs scheduler: Datadog::Profiling::Scheduler
|
|
18
|
+
# @rbs return: void
|
|
15
19
|
def initialize(worker:, scheduler:)
|
|
16
20
|
@worker = worker
|
|
17
21
|
@scheduler = scheduler
|
|
18
22
|
end
|
|
19
23
|
|
|
24
|
+
#: () -> void
|
|
20
25
|
def start
|
|
21
26
|
after_fork! do
|
|
22
27
|
worker.reset_after_fork
|
|
@@ -32,6 +37,8 @@ module Datadog
|
|
|
32
37
|
scheduler.start(on_failure_proc: proc { component_failed(:scheduler) })
|
|
33
38
|
end
|
|
34
39
|
|
|
40
|
+
# @rbs report_last_profile: bool
|
|
41
|
+
# @rbs return: void
|
|
35
42
|
def shutdown!(report_last_profile: true)
|
|
36
43
|
Datadog.logger.debug("Shutting down profiler")
|
|
37
44
|
|
|
@@ -42,15 +49,20 @@ module Datadog
|
|
|
42
49
|
|
|
43
50
|
private
|
|
44
51
|
|
|
52
|
+
#: () -> void
|
|
45
53
|
def stop_worker
|
|
46
54
|
worker.stop
|
|
47
55
|
end
|
|
48
56
|
|
|
57
|
+
#: () -> void
|
|
49
58
|
def stop_scheduler
|
|
50
59
|
scheduler.enabled = false
|
|
51
60
|
scheduler.stop(true)
|
|
52
61
|
end
|
|
53
62
|
|
|
63
|
+
# @rbs failed_component: :worker | :scheduler | ::Symbol
|
|
64
|
+
# @rbs log_failure: bool
|
|
65
|
+
# @rbs return: void
|
|
54
66
|
def component_failed(failed_component, log_failure: true)
|
|
55
67
|
if log_failure
|
|
56
68
|
Datadog.logger.warn(
|
|
@@ -65,7 +65,7 @@ module Datadog
|
|
|
65
65
|
rescue Exception => e # rubocop:disable Lint/RescueException
|
|
66
66
|
Datadog.logger.warn(
|
|
67
67
|
"Profiling::Scheduler thread error. " \
|
|
68
|
-
"Cause: #{e.class}: #{e} Location: #{Array(e.backtrace).first}"
|
|
68
|
+
"Cause: #{e.class}: #{e.message} Location: #{Array(e.backtrace).first}"
|
|
69
69
|
)
|
|
70
70
|
on_failure_proc&.call
|
|
71
71
|
Datadog::Core::Telemetry::Logger.report(e, description: "Profiling::Scheduler thread error")
|
|
@@ -136,7 +136,7 @@ module Datadog
|
|
|
136
136
|
transport.export(flush)
|
|
137
137
|
rescue => e
|
|
138
138
|
Datadog.logger.warn(
|
|
139
|
-
"Unable to report profile. Cause: #{e.class}: #{e} Location: #{Array(e.backtrace).first}"
|
|
139
|
+
"Unable to report profile. Cause: #{e.class}: #{e.message} Location: #{Array(e.backtrace).first}"
|
|
140
140
|
)
|
|
141
141
|
Datadog::Core::Telemetry::Logger.report(e, description: "Unable to report profile")
|
|
142
142
|
end
|
|
@@ -5,17 +5,20 @@ module Datadog
|
|
|
5
5
|
module Tasks
|
|
6
6
|
# Wraps command with Datadog profiling
|
|
7
7
|
class Exec
|
|
8
|
-
attr_reader :args
|
|
8
|
+
attr_reader :args #: untyped
|
|
9
9
|
|
|
10
|
+
#: (untyped) -> void
|
|
10
11
|
def initialize(args)
|
|
11
12
|
@args = args
|
|
12
13
|
end
|
|
13
14
|
|
|
15
|
+
#: () -> untyped
|
|
14
16
|
def run
|
|
15
17
|
set_rubyopt!
|
|
16
18
|
exec_with_error_handling(args)
|
|
17
19
|
end
|
|
18
20
|
|
|
21
|
+
#: () -> ::Array["-rdatadog/profiling/preload"]
|
|
19
22
|
def rubyopts
|
|
20
23
|
[
|
|
21
24
|
"-rdatadog/profiling/preload"
|
|
@@ -24,6 +27,7 @@ module Datadog
|
|
|
24
27
|
|
|
25
28
|
private
|
|
26
29
|
|
|
30
|
+
#: () -> untyped
|
|
27
31
|
def set_rubyopt!
|
|
28
32
|
existing_rubyopt = ENV["RUBYOPT"] # rubocop:disable CustomCops/EnvUsageCop
|
|
29
33
|
|
|
@@ -35,13 +39,14 @@ module Datadog
|
|
|
35
39
|
# See also:
|
|
36
40
|
# * https://www.gnu.org/software/bash/manual/html_node/Exit-Status.html
|
|
37
41
|
# * https://github.com/rubygems/rubygems/blob/dd93966cac224532035deda533cba2685dfa30cc/bundler/lib/bundler/cli/exec.rb#L45
|
|
42
|
+
#: (untyped) -> untyped
|
|
38
43
|
def exec_with_error_handling(args)
|
|
39
44
|
Kernel.exec(*args)
|
|
40
45
|
rescue Errno::ENOENT => e
|
|
41
|
-
Kernel.warn "ddprofrb exec failed: #{e.class}: #{e} (command was '#{args.join(" ")}')"
|
|
46
|
+
Kernel.warn "ddprofrb exec failed: #{e.class}: #{e.message} (command was '#{args.join(" ")}')"
|
|
42
47
|
Kernel.exit 127
|
|
43
48
|
rescue Errno::EACCES, Errno::ENOEXEC => e
|
|
44
|
-
Kernel.warn "ddprofrb exec failed: #{e.class}: #{e} (command was '#{args.join(" ")}')"
|
|
49
|
+
Kernel.warn "ddprofrb exec failed: #{e.class}: #{e.message} (command was '#{args.join(" ")}')"
|
|
45
50
|
Kernel.exit 126
|
|
46
51
|
end
|
|
47
52
|
end
|
|
@@ -16,7 +16,7 @@ module Datadog
|
|
|
16
16
|
setup_at_fork_hooks
|
|
17
17
|
rescue StandardError, ScriptError => e
|
|
18
18
|
Datadog.logger.warn do
|
|
19
|
-
"Profiler extensions unavailable. Cause: #{e.class}: #{e} " \
|
|
19
|
+
"Profiler extensions unavailable. Cause: #{e.class}: #{e.message} " \
|
|
20
20
|
"Location: #{Array(e.backtrace).first}"
|
|
21
21
|
end
|
|
22
22
|
Datadog::Core::Telemetry::Logger.report(e, description: "Profiler extensions unavailable")
|
|
@@ -31,7 +31,7 @@ module Datadog
|
|
|
31
31
|
Profiling.start_if_enabled
|
|
32
32
|
rescue => e
|
|
33
33
|
Datadog.logger.warn do
|
|
34
|
-
"Error during post-fork hooks. Cause: #{e.class}: #{e} " \
|
|
34
|
+
"Error during post-fork hooks. Cause: #{e.class}: #{e.message} " \
|
|
35
35
|
"Location: #{Array(e.backtrace).first}"
|
|
36
36
|
end
|
|
37
37
|
Datadog::Core::Telemetry::Logger.report(e, description: "Error during post-fork hooks")
|
|
@@ -17,5 +17,5 @@ begin
|
|
|
17
17
|
require_relative 'auto_instrument'
|
|
18
18
|
Datadog::SingleStepInstrument.const_set(:LOADED, true)
|
|
19
19
|
rescue StandardError, LoadError => e
|
|
20
|
-
warn "Single step instrumentation failed: #{e.class}: #{e}\n\tSource:\n\t#{Array(e.backtrace).join("\n\t")}"
|
|
20
|
+
warn "Single step instrumentation failed: #{e.class}: #{e.message}\n\tSource:\n\t#{Array(e.backtrace).join("\n\t")}"
|
|
21
21
|
end
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Datadog
|
|
4
|
+
module SymbolDatabase
|
|
5
|
+
# Configuration for symbol database
|
|
6
|
+
module Configuration
|
|
7
|
+
# Configuration settings for symbol database upload feature.
|
|
8
|
+
#
|
|
9
|
+
# Public environment variable:
|
|
10
|
+
# - DD_SYMBOL_DATABASE_UPLOAD_ENABLED (default: true) - Feature gate
|
|
11
|
+
#
|
|
12
|
+
# Extended into: Core::Configuration::Settings (via extend)
|
|
13
|
+
# Accessed as: Datadog.configuration.symbol_database.enabled
|
|
14
|
+
# Used by: Component.build (checks if feature enabled)
|
|
15
|
+
module Settings
|
|
16
|
+
# Hook called when this module is extended into a class.
|
|
17
|
+
# @param base [Class, Module] The class or module being extended
|
|
18
|
+
# @return [void]
|
|
19
|
+
def self.extended(base)
|
|
20
|
+
base = base.singleton_class unless base.is_a?(Class)
|
|
21
|
+
add_settings!(base)
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
# Add symbol_database settings block to base class.
|
|
25
|
+
# @param base [Class] Base class
|
|
26
|
+
# @return [void]
|
|
27
|
+
def self.add_settings!(base)
|
|
28
|
+
base.class_eval do
|
|
29
|
+
# steep:ignore:start
|
|
30
|
+
settings :symbol_database do
|
|
31
|
+
option :enabled do |o|
|
|
32
|
+
o.type :bool
|
|
33
|
+
o.env 'DD_SYMBOL_DATABASE_UPLOAD_ENABLED'
|
|
34
|
+
o.default true
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
# Settings in the 'internal' group are for internal Datadog
|
|
38
|
+
# use only, and are needed to test symbol database or
|
|
39
|
+
# experiment with features not released to customers.
|
|
40
|
+
settings :internal do
|
|
41
|
+
# Bypass remote config — start extraction immediately.
|
|
42
|
+
# Matches Java's DD_INTERNAL_FORCE_SYMBOL_DATABASE_UPLOAD
|
|
43
|
+
# and Python's private force_upload setting.
|
|
44
|
+
option :force_upload do |o|
|
|
45
|
+
o.type :bool
|
|
46
|
+
o.env 'DD_INTERNAL_FORCE_SYMBOL_DATABASE_UPLOAD'
|
|
47
|
+
o.default false
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
# Enable verbose trace-level logging for symdb operations.
|
|
51
|
+
# Activated by DD_TRACE_DEBUG (same trigger as DI trace logging).
|
|
52
|
+
option :trace_logging do |o|
|
|
53
|
+
o.type :bool
|
|
54
|
+
o.default false
|
|
55
|
+
o.env 'DD_TRACE_DEBUG'
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
# steep:ignore:end
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
end
|