datadog 2.0.0 → 2.2.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 +66 -2
- data/README.md +1 -1
- data/ext/datadog_profiling_native_extension/collectors_cpu_and_wall_time_worker.c +19 -1
- data/ext/datadog_profiling_native_extension/collectors_stack.c +41 -0
- data/ext/datadog_profiling_native_extension/collectors_thread_context.c +1 -1
- data/ext/datadog_profiling_native_extension/crashtracker.c +1 -1
- data/ext/datadog_profiling_native_extension/extconf.rb +6 -4
- data/ext/datadog_profiling_native_extension/native_extension_helpers.rb +47 -1
- data/ext/datadog_profiling_native_extension/setup_signal_handler.c +1 -1
- data/ext/datadog_profiling_native_extension/stack_recorder.c +13 -6
- data/ext/datadog_profiling_native_extension/stack_recorder.h +1 -0
- data/lib/datadog/appsec/configuration/settings.rb +5 -0
- data/lib/datadog/appsec/contrib/rack/request_middleware.rb +0 -1
- data/lib/datadog/appsec/contrib/sinatra/patcher.rb +1 -1
- data/lib/datadog/appsec/extensions.rb +1 -0
- data/lib/datadog/core/configuration/components.rb +6 -3
- data/lib/datadog/core/configuration/ext.rb +1 -0
- data/lib/datadog/core/configuration/option.rb +21 -14
- data/lib/datadog/core/configuration/options.rb +5 -1
- data/lib/datadog/core/configuration/settings.rb +68 -5
- data/lib/datadog/core/configuration.rb +3 -17
- data/lib/datadog/core/deprecations.rb +58 -0
- data/lib/datadog/core/environment/ext.rb +2 -0
- data/lib/datadog/core/environment/yjit.rb +5 -0
- data/lib/datadog/core/runtime/ext.rb +2 -0
- data/lib/datadog/core/runtime/metrics.rb +6 -0
- data/lib/datadog/core/telemetry/component.rb +107 -0
- data/lib/datadog/core/telemetry/event.rb +124 -31
- data/lib/datadog/core/telemetry/ext.rb +2 -0
- data/lib/datadog/core/telemetry/http/adapters/net.rb +1 -1
- data/lib/datadog/core/telemetry/metric.rb +167 -0
- data/lib/datadog/core/telemetry/metrics_collection.rb +81 -0
- data/lib/datadog/core/telemetry/metrics_manager.rb +81 -0
- data/lib/datadog/core/telemetry/request.rb +1 -1
- data/lib/datadog/core/telemetry/worker.rb +173 -0
- data/lib/datadog/core/utils/only_once_successful.rb +76 -0
- data/lib/datadog/core.rb +2 -19
- data/lib/datadog/opentelemetry/sdk/propagator.rb +5 -10
- data/lib/datadog/opentelemetry/sdk/span_processor.rb +5 -2
- data/lib/datadog/profiling/collectors/code_provenance.rb +18 -5
- data/lib/datadog/profiling/component.rb +18 -1
- data/lib/datadog/profiling/ext/dir_monkey_patches.rb +410 -0
- data/lib/datadog/profiling.rb +1 -0
- data/lib/datadog/tracing/configuration/ext.rb +7 -0
- data/lib/datadog/tracing/configuration/settings.rb +52 -3
- data/lib/datadog/tracing/contrib/action_cable/event.rb +1 -1
- data/lib/datadog/tracing/contrib/action_cable/events/broadcast.rb +1 -1
- data/lib/datadog/tracing/contrib/action_cable/events/perform_action.rb +1 -1
- data/lib/datadog/tracing/contrib/action_cable/events/transmit.rb +1 -1
- data/lib/datadog/tracing/contrib/action_mailer/event.rb +4 -6
- data/lib/datadog/tracing/contrib/action_mailer/events/deliver.rb +9 -4
- data/lib/datadog/tracing/contrib/action_mailer/events/process.rb +3 -2
- data/lib/datadog/tracing/contrib/action_view/events/render_partial.rb +1 -5
- 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/events/instantiation.rb +1 -1
- data/lib/datadog/tracing/contrib/active_record/events/sql.rb +1 -1
- data/lib/datadog/tracing/contrib/active_support/cache/event.rb +32 -0
- data/lib/datadog/tracing/contrib/active_support/cache/events/cache.rb +156 -0
- data/lib/datadog/tracing/contrib/active_support/cache/events.rb +34 -0
- data/lib/datadog/tracing/contrib/active_support/cache/instrumentation.rb +45 -41
- data/lib/datadog/tracing/contrib/active_support/cache/patcher.rb +17 -40
- data/lib/datadog/tracing/contrib/active_support/cache/redis.rb +4 -1
- data/lib/datadog/tracing/contrib/active_support/notifications/event.rb +29 -6
- data/lib/datadog/tracing/contrib/active_support/notifications/subscriber.rb +16 -4
- data/lib/datadog/tracing/contrib/active_support/notifications/subscription.rb +33 -29
- data/lib/datadog/tracing/contrib/analytics.rb +5 -0
- data/lib/datadog/tracing/contrib/graphql/configuration/settings.rb +5 -0
- data/lib/datadog/tracing/contrib/graphql/patcher.rb +8 -2
- data/lib/datadog/tracing/contrib/graphql/unified_trace.rb +166 -0
- data/lib/datadog/tracing/contrib/graphql/unified_trace_patcher.rb +25 -0
- data/lib/datadog/tracing/contrib/kafka/consumer_event.rb +1 -1
- data/lib/datadog/tracing/contrib/kafka/consumer_group_event.rb +1 -1
- data/lib/datadog/tracing/contrib/kafka/event.rb +1 -1
- data/lib/datadog/tracing/contrib/kafka/events/connection/request.rb +3 -3
- data/lib/datadog/tracing/contrib/kafka/events/consumer/process_batch.rb +3 -3
- data/lib/datadog/tracing/contrib/kafka/events/consumer/process_message.rb +3 -3
- data/lib/datadog/tracing/contrib/kafka/events/consumer_group/heartbeat.rb +3 -3
- data/lib/datadog/tracing/contrib/kafka/events/produce_operation/send_messages.rb +3 -3
- data/lib/datadog/tracing/contrib/kafka/events/producer/deliver_messages.rb +3 -3
- data/lib/datadog/tracing/contrib/racecar/event.rb +2 -2
- data/lib/datadog/tracing/contrib/rails/ext.rb +9 -0
- data/lib/datadog/tracing/contrib/rails/patcher.rb +7 -0
- data/lib/datadog/tracing/contrib/rails/runner.rb +95 -0
- data/lib/datadog/tracing/distributed/b3_multi.rb +1 -1
- data/lib/datadog/tracing/distributed/b3_single.rb +3 -1
- data/lib/datadog/tracing/distributed/datadog.rb +2 -2
- data/lib/datadog/tracing/distributed/propagation.rb +39 -4
- data/lib/datadog/tracing/distributed/trace_context.rb +5 -3
- data/lib/datadog/tracing/metadata/ext.rb +1 -0
- data/lib/datadog/tracing/span_operation.rb +3 -2
- data/lib/datadog/tracing/trace_operation.rb +7 -3
- data/lib/datadog/tracing/trace_segment.rb +4 -1
- data/lib/datadog/tracing/tracer.rb +9 -2
- data/lib/datadog/tracing.rb +5 -1
- data/lib/datadog/version.rb +2 -2
- metadata +21 -8
- data/lib/datadog/core/telemetry/client.rb +0 -95
- data/lib/datadog/core/telemetry/heartbeat.rb +0 -33
@@ -122,9 +122,18 @@ module Datadog
|
|
122
122
|
# @default `DD_TRACE_DEBUG` environment variable, otherwise `false`
|
123
123
|
# @return [Boolean]
|
124
124
|
option :debug do |o|
|
125
|
-
o.env Datadog::Core::Configuration::Ext::Diagnostics::ENV_DEBUG_ENABLED
|
125
|
+
o.env [Datadog::Core::Configuration::Ext::Diagnostics::ENV_DEBUG_ENABLED,
|
126
|
+
Datadog::Core::Configuration::Ext::Diagnostics::ENV_OTEL_LOG_LEVEL]
|
126
127
|
o.default false
|
127
128
|
o.type :bool
|
129
|
+
o.env_parser do |value|
|
130
|
+
if value
|
131
|
+
value = value.strip.downcase
|
132
|
+
# Debug is enabled when DD_TRACE_DEBUG is true or 1 OR
|
133
|
+
# when OTEL_LOG_LEVEL is set to debug
|
134
|
+
['true', '1', 'debug'].include?(value)
|
135
|
+
end
|
136
|
+
end
|
128
137
|
o.after_set do |enabled|
|
129
138
|
# Enable rich debug print statements.
|
130
139
|
# We do not need to unnecessarily load 'pp' unless in debugging mode.
|
@@ -388,6 +397,22 @@ module Datadog
|
|
388
397
|
end
|
389
398
|
end
|
390
399
|
|
400
|
+
# The profiler gathers data by sending `SIGPROF` unix signals to Ruby application threads.
|
401
|
+
#
|
402
|
+
# We've discovered that this can trigger a bug in a number of Ruby APIs in the `Dir` class, as
|
403
|
+
# described in https://github.com/DataDog/dd-trace-rb/issues/3450 . This workaround prevents the issue
|
404
|
+
# from happening by monkey patching the affected APIs.
|
405
|
+
#
|
406
|
+
# (In the future, once a fix lands upstream, we'll disable this workaround for Rubies that don't need it)
|
407
|
+
#
|
408
|
+
# @default `DD_PROFILING_DIR_INTERRUPTION_WORKAROUND_ENABLED` environment variable as a boolean,
|
409
|
+
# otherwise `true`
|
410
|
+
option :dir_interruption_workaround_enabled do |o|
|
411
|
+
o.env 'DD_PROFILING_DIR_INTERRUPTION_WORKAROUND_ENABLED'
|
412
|
+
o.type :bool
|
413
|
+
o.default true
|
414
|
+
end
|
415
|
+
|
391
416
|
# Configures how much wall-time overhead the profiler targets. The profiler will dynamically adjust the
|
392
417
|
# interval between samples it takes so as to try and maintain the property that it spends no longer than
|
393
418
|
# this amount of wall-clock time profiling. For example, with the default value of 2%, the profiler will
|
@@ -465,7 +490,7 @@ module Datadog
|
|
465
490
|
o.type :string, nilable: true
|
466
491
|
|
467
492
|
# NOTE: service also gets set as a side effect of tags. See the WORKAROUND note in #initialize for details.
|
468
|
-
o.env Core::Environment::Ext::ENV_SERVICE
|
493
|
+
o.env [Core::Environment::Ext::ENV_SERVICE, Core::Environment::Ext::ENV_OTEL_SERVICE]
|
469
494
|
o.default Core::Environment::Ext::FALLBACK_SERVICE_NAME
|
470
495
|
|
471
496
|
# There's a few cases where we don't want to use the fallback service name, so this helper allows us to get a
|
@@ -500,14 +525,13 @@ module Datadog
|
|
500
525
|
# @return [Hash<String,String>]
|
501
526
|
option :tags do |o|
|
502
527
|
o.type :hash, nilable: true
|
503
|
-
o.env Core::Environment::Ext::ENV_TAGS
|
528
|
+
o.env [Core::Environment::Ext::ENV_TAGS, Core::Environment::Ext::ENV_OTEL_RESOURCE_ATTRIBUTES]
|
504
529
|
o.env_parser do |env_value|
|
505
530
|
values = if env_value.include?(',')
|
506
531
|
env_value.split(',')
|
507
532
|
else
|
508
533
|
env_value.split(' ') # rubocop:disable Style/RedundantArgument
|
509
534
|
end
|
510
|
-
|
511
535
|
values.map! do |v|
|
512
536
|
v.gsub!(/\A[\s,]*|[\s,]*\Z/, '')
|
513
537
|
|
@@ -517,7 +541,23 @@ module Datadog
|
|
517
541
|
values.compact!
|
518
542
|
values.each_with_object({}) do |tag, tags|
|
519
543
|
key, value = tag.split(':', 2)
|
520
|
-
|
544
|
+
if value.nil?
|
545
|
+
# support tags/attributes delimited by the OpenTelemetry separator (`=`)
|
546
|
+
key, value = tag.split('=', 2)
|
547
|
+
end
|
548
|
+
next if value.nil? || value.empty?
|
549
|
+
|
550
|
+
# maps OpenTelemetry semantic attributes to Datadog tags
|
551
|
+
case key.downcase
|
552
|
+
when 'deployment.environment'
|
553
|
+
tags['env'] = value
|
554
|
+
when 'service.version'
|
555
|
+
tags['version'] = value
|
556
|
+
when 'service.name'
|
557
|
+
tags['service'] = value
|
558
|
+
else
|
559
|
+
tags[key] = value
|
560
|
+
end
|
521
561
|
end
|
522
562
|
end
|
523
563
|
o.setter do |new_value, old_value|
|
@@ -623,6 +663,16 @@ module Datadog
|
|
623
663
|
o.type :bool
|
624
664
|
end
|
625
665
|
|
666
|
+
# Enable metrics collection for telemetry. Metrics collection only works when telemetry is enabled and
|
667
|
+
# metrics are enabled.
|
668
|
+
# @default `DD_TELEMETRY_METRICS_ENABLED` environment variable, otherwise `true`.
|
669
|
+
# @return [Boolean]
|
670
|
+
option :metrics_enabled do |o|
|
671
|
+
o.type :bool
|
672
|
+
o.env Core::Telemetry::Ext::ENV_METRICS_ENABLED
|
673
|
+
o.default true
|
674
|
+
end
|
675
|
+
|
626
676
|
# The interval in seconds when telemetry must be sent.
|
627
677
|
#
|
628
678
|
# This method is used internally, for testing purposes only.
|
@@ -636,6 +686,19 @@ module Datadog
|
|
636
686
|
o.default 60.0
|
637
687
|
end
|
638
688
|
|
689
|
+
# The interval in seconds when telemetry metrics are aggregated.
|
690
|
+
# Should be a denominator of `heartbeat_interval_seconds`.
|
691
|
+
#
|
692
|
+
# This method is used internally, for testing purposes only.
|
693
|
+
# @default `DD_TELEMETRY_METRICS_AGGREGATION_INTERVAL` environment variable, otherwise `10`.
|
694
|
+
# @return [Float]
|
695
|
+
# @!visibility private
|
696
|
+
option :metrics_aggregation_interval_seconds do |o|
|
697
|
+
o.type :float
|
698
|
+
o.env Core::Telemetry::Ext::ENV_METRICS_AGGREGATION_INTERVAL
|
699
|
+
o.default 10.0
|
700
|
+
end
|
701
|
+
|
639
702
|
# The install id of the application.
|
640
703
|
#
|
641
704
|
# This method is used internally, by library injection.
|
@@ -84,23 +84,16 @@ module Datadog
|
|
84
84
|
configuration = self.configuration
|
85
85
|
yield(configuration)
|
86
86
|
|
87
|
-
|
88
|
-
|
89
|
-
components = safely_synchronize do |write_components|
|
87
|
+
safely_synchronize do |write_components|
|
90
88
|
write_components.call(
|
91
89
|
if components?
|
92
90
|
replace_components!(configuration, @components)
|
93
91
|
else
|
94
|
-
|
95
|
-
built_components = true
|
96
|
-
components
|
92
|
+
build_components(configuration)
|
97
93
|
end
|
98
94
|
)
|
99
95
|
end
|
100
96
|
|
101
|
-
# Should only be called the first time components are built
|
102
|
-
components.telemetry.started! if built_components
|
103
|
-
|
104
97
|
configuration
|
105
98
|
end
|
106
99
|
|
@@ -200,20 +193,13 @@ module Datadog
|
|
200
193
|
current_components = COMPONENTS_READ_LOCK.synchronize { defined?(@components) && @components }
|
201
194
|
return current_components if current_components || !allow_initialization
|
202
195
|
|
203
|
-
|
204
|
-
|
205
|
-
components = safely_synchronize do |write_components|
|
196
|
+
safely_synchronize do |write_components|
|
206
197
|
if defined?(@components) && @components
|
207
198
|
@components
|
208
199
|
else
|
209
|
-
built_components = true
|
210
200
|
write_components.call(build_components(configuration))
|
211
201
|
end
|
212
202
|
end
|
213
|
-
|
214
|
-
# Should only be called the first time components are built
|
215
|
-
components&.telemetry&.started! if built_components
|
216
|
-
components
|
217
203
|
end
|
218
204
|
|
219
205
|
private
|
@@ -0,0 +1,58 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Datadog
|
4
|
+
module Core
|
5
|
+
# Contains behavior for handling deprecated functions in the codebase.
|
6
|
+
module Deprecations
|
7
|
+
# Records the occurrence of a deprecated operation in this library.
|
8
|
+
#
|
9
|
+
# Currently, these operations are logged to `Datadog.logger` at `warn` level.
|
10
|
+
#
|
11
|
+
# `disallowed_next_major` adds a message informing that the deprecated operation
|
12
|
+
# won't be allowed in the next major release.
|
13
|
+
#
|
14
|
+
# @yieldreturn [String] a String with the lazily evaluated deprecation message.
|
15
|
+
# @param [Boolean] disallowed_next_major whether this deprecation will be enforced in the next major release.
|
16
|
+
# @param [Object] key A unique key for the deprecation. Only the first message with the same key will be logged.
|
17
|
+
def log_deprecation(disallowed_next_major: true, key: nil)
|
18
|
+
return unless log_deprecation?(key)
|
19
|
+
|
20
|
+
Datadog.logger.warn do
|
21
|
+
message = yield
|
22
|
+
message += ' This will be enforced in the next major release.' if disallowed_next_major
|
23
|
+
message
|
24
|
+
end
|
25
|
+
|
26
|
+
# Track the deprecation being logged.
|
27
|
+
deprecation_logged!(key)
|
28
|
+
|
29
|
+
nil
|
30
|
+
end
|
31
|
+
|
32
|
+
private
|
33
|
+
|
34
|
+
# Determines whether a deprecation message should be logged.
|
35
|
+
#
|
36
|
+
# Internal use only.
|
37
|
+
def log_deprecation?(key)
|
38
|
+
return true if key.nil?
|
39
|
+
|
40
|
+
# Only allow a deprecation to be logged once.
|
41
|
+
!logged_deprecations.key?(key)
|
42
|
+
end
|
43
|
+
|
44
|
+
def deprecation_logged!(key)
|
45
|
+
return if key.nil?
|
46
|
+
|
47
|
+
logged_deprecations[key] += 1
|
48
|
+
end
|
49
|
+
|
50
|
+
# Tracks what deprecation warnings have already been logged
|
51
|
+
#
|
52
|
+
# Internal use only.
|
53
|
+
def logged_deprecations
|
54
|
+
@logged_deprecations ||= Hash.new(0)
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
@@ -18,8 +18,10 @@ module Datadog
|
|
18
18
|
ENV_API_KEY = 'DD_API_KEY'
|
19
19
|
ENV_ENVIRONMENT = 'DD_ENV'
|
20
20
|
ENV_SERVICE = 'DD_SERVICE'
|
21
|
+
ENV_OTEL_SERVICE = 'OTEL_SERVICE_NAME'
|
21
22
|
ENV_SITE = 'DD_SITE'
|
22
23
|
ENV_TAGS = 'DD_TAGS'
|
24
|
+
ENV_OTEL_RESOURCE_ATTRIBUTES = 'OTEL_RESOURCE_ATTRIBUTES'
|
23
25
|
ENV_VERSION = 'DD_VERSION'
|
24
26
|
FALLBACK_SERVICE_NAME =
|
25
27
|
begin
|
@@ -47,6 +47,11 @@ module Datadog
|
|
47
47
|
::RubyVM::YJIT.runtime_stats[:object_shape_count]
|
48
48
|
end
|
49
49
|
|
50
|
+
# Size of memory Rust allocated for metadata
|
51
|
+
def yjit_alloc_size
|
52
|
+
::RubyVM::YJIT.runtime_stats[:yjit_alloc_size]
|
53
|
+
end
|
54
|
+
|
50
55
|
def available?
|
51
56
|
defined?(::RubyVM::YJIT) \
|
52
57
|
&& ::RubyVM::YJIT.enabled? \
|
@@ -13,6 +13,7 @@ module Datadog
|
|
13
13
|
# @public_api
|
14
14
|
module Metrics
|
15
15
|
ENV_ENABLED = 'DD_RUNTIME_METRICS_ENABLED'
|
16
|
+
ENV_OTEL_METRICS_EXPORTER = 'OTEL_METRICS_EXPORTER'
|
16
17
|
|
17
18
|
METRIC_CLASS_COUNT = 'runtime.ruby.class_count'
|
18
19
|
METRIC_GC_PREFIX = 'runtime.ruby.gc'
|
@@ -29,6 +30,7 @@ module Datadog
|
|
29
30
|
METRIC_YJIT_LIVE_PAGE_COUNT = 'runtime.ruby.yjit.live_page_count'
|
30
31
|
METRIC_YJIT_OBJECT_SHAPE_COUNT = 'runtime.ruby.yjit.object_shape_count'
|
31
32
|
METRIC_YJIT_OUTLINED_CODE_SIZE = 'runtime.ruby.yjit.outlined_code_size'
|
33
|
+
METRIC_YJIT_YJIT_ALLOC_SIZE = 'runtime.ruby.yjit.yjit_alloc_size'
|
32
34
|
|
33
35
|
TAG_SERVICE = 'service'
|
34
36
|
end
|
@@ -140,6 +140,7 @@ module Datadog
|
|
140
140
|
gauge(metric_name, metric_value) if metric_value
|
141
141
|
end
|
142
142
|
|
143
|
+
# rubocop:disable Metrics/MethodLength
|
143
144
|
def flush_yjit_stats
|
144
145
|
# Only on Ruby >= 3.2
|
145
146
|
try_flush do
|
@@ -176,9 +177,14 @@ module Datadog
|
|
176
177
|
Core::Runtime::Ext::Metrics::METRIC_YJIT_OUTLINED_CODE_SIZE,
|
177
178
|
Core::Environment::YJIT.outlined_code_size
|
178
179
|
)
|
180
|
+
gauge_if_not_nil(
|
181
|
+
Core::Runtime::Ext::Metrics::METRIC_YJIT_YJIT_ALLOC_SIZE,
|
182
|
+
Core::Environment::YJIT.yjit_alloc_size
|
183
|
+
)
|
179
184
|
end
|
180
185
|
end
|
181
186
|
end
|
187
|
+
# rubocop:enable Metrics/MethodLength
|
182
188
|
end
|
183
189
|
end
|
184
190
|
end
|
@@ -0,0 +1,107 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'emitter'
|
4
|
+
require_relative 'event'
|
5
|
+
require_relative 'metrics_manager'
|
6
|
+
require_relative 'worker'
|
7
|
+
require_relative '../utils/forking'
|
8
|
+
|
9
|
+
module Datadog
|
10
|
+
module Core
|
11
|
+
module Telemetry
|
12
|
+
# Telemetry entrypoint, coordinates sending telemetry events at various points in app lifecycle.
|
13
|
+
class Component
|
14
|
+
attr_reader :enabled
|
15
|
+
|
16
|
+
include Core::Utils::Forking
|
17
|
+
|
18
|
+
# @param enabled [Boolean] Determines whether telemetry events should be sent to the API
|
19
|
+
# @param metrics_enabled [Boolean] Determines whether telemetry metrics should be sent to the API
|
20
|
+
# @param heartbeat_interval_seconds [Float] How frequently heartbeats will be reported, in seconds.
|
21
|
+
# @param metrics_aggregation_interval_seconds [Float] How frequently metrics will be aggregated, in seconds.
|
22
|
+
# @param [Boolean] dependency_collection Whether to send the `app-dependencies-loaded` event
|
23
|
+
def initialize(
|
24
|
+
heartbeat_interval_seconds:,
|
25
|
+
metrics_aggregation_interval_seconds:,
|
26
|
+
dependency_collection:,
|
27
|
+
enabled: true,
|
28
|
+
metrics_enabled: true
|
29
|
+
)
|
30
|
+
@enabled = enabled
|
31
|
+
@stopped = false
|
32
|
+
|
33
|
+
@metrics_manager = MetricsManager.new(
|
34
|
+
enabled: enabled && metrics_enabled,
|
35
|
+
aggregation_interval: metrics_aggregation_interval_seconds
|
36
|
+
)
|
37
|
+
|
38
|
+
@worker = Telemetry::Worker.new(
|
39
|
+
enabled: @enabled,
|
40
|
+
heartbeat_interval_seconds: heartbeat_interval_seconds,
|
41
|
+
metrics_aggregation_interval_seconds: metrics_aggregation_interval_seconds,
|
42
|
+
emitter: Emitter.new,
|
43
|
+
metrics_manager: @metrics_manager,
|
44
|
+
dependency_collection: dependency_collection
|
45
|
+
)
|
46
|
+
@worker.start
|
47
|
+
end
|
48
|
+
|
49
|
+
def disable!
|
50
|
+
@enabled = false
|
51
|
+
@worker.enabled = false
|
52
|
+
end
|
53
|
+
|
54
|
+
def stop!
|
55
|
+
return if @stopped
|
56
|
+
|
57
|
+
@worker.stop(true)
|
58
|
+
@stopped = true
|
59
|
+
end
|
60
|
+
|
61
|
+
def emit_closing!
|
62
|
+
return if !@enabled || forked?
|
63
|
+
|
64
|
+
@worker.enqueue(Event::AppClosing.new)
|
65
|
+
end
|
66
|
+
|
67
|
+
def integrations_change!
|
68
|
+
return if !@enabled || forked?
|
69
|
+
|
70
|
+
@worker.enqueue(Event::AppIntegrationsChange.new)
|
71
|
+
end
|
72
|
+
|
73
|
+
# Report configuration changes caused by Remote Configuration.
|
74
|
+
def client_configuration_change!(changes)
|
75
|
+
return if !@enabled || forked?
|
76
|
+
|
77
|
+
@worker.enqueue(Event::AppClientConfigurationChange.new(changes, 'remote_config'))
|
78
|
+
end
|
79
|
+
|
80
|
+
# Increments a count metric.
|
81
|
+
def inc(namespace, metric_name, value, tags: {}, common: true)
|
82
|
+
@metrics_manager.inc(namespace, metric_name, value, tags: tags, common: common)
|
83
|
+
end
|
84
|
+
|
85
|
+
# Decremenets a count metric.
|
86
|
+
def dec(namespace, metric_name, value, tags: {}, common: true)
|
87
|
+
@metrics_manager.dec(namespace, metric_name, value, tags: tags, common: common)
|
88
|
+
end
|
89
|
+
|
90
|
+
# Tracks gauge metric.
|
91
|
+
def gauge(namespace, metric_name, value, tags: {}, common: true)
|
92
|
+
@metrics_manager.gauge(namespace, metric_name, value, tags: tags, common: common)
|
93
|
+
end
|
94
|
+
|
95
|
+
# Tracks rate metric.
|
96
|
+
def rate(namespace, metric_name, value, tags: {}, common: true)
|
97
|
+
@metrics_manager.rate(namespace, metric_name, value, tags: tags, common: common)
|
98
|
+
end
|
99
|
+
|
100
|
+
# Tracks distribution metric.
|
101
|
+
def distribution(namespace, metric_name, value, tags: {}, common: true)
|
102
|
+
@metrics_manager.distribution(namespace, metric_name, value, tags: tags, common: common)
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end
|
@@ -3,7 +3,16 @@
|
|
3
3
|
module Datadog
|
4
4
|
module Core
|
5
5
|
module Telemetry
|
6
|
+
# Collection of telemetry events
|
6
7
|
class Event
|
8
|
+
extend Core::Utils::Forking
|
9
|
+
|
10
|
+
# returns sequence that increments every time the configuration changes
|
11
|
+
def self.configuration_sequence
|
12
|
+
after_fork! { @sequence = Datadog::Core::Utils::Sequence.new(1) }
|
13
|
+
@sequence ||= Datadog::Core::Utils::Sequence.new(1)
|
14
|
+
end
|
15
|
+
|
7
16
|
# Base class for all Telemetry V2 events.
|
8
17
|
class Base
|
9
18
|
# The type of the event.
|
@@ -12,8 +21,7 @@ module Datadog
|
|
12
21
|
def type; end
|
13
22
|
|
14
23
|
# The JSON payload for the event.
|
15
|
-
|
16
|
-
def payload(seq_id)
|
24
|
+
def payload
|
17
25
|
{}
|
18
26
|
end
|
19
27
|
end
|
@@ -24,8 +32,7 @@ module Datadog
|
|
24
32
|
'app-started'
|
25
33
|
end
|
26
34
|
|
27
|
-
def payload
|
28
|
-
@seq_id = seq_id
|
35
|
+
def payload
|
29
36
|
{
|
30
37
|
products: products,
|
31
38
|
configuration: configuration,
|
@@ -38,6 +45,7 @@ module Datadog
|
|
38
45
|
private
|
39
46
|
|
40
47
|
def products
|
48
|
+
# @type var products: Hash[Symbol, Hash[Symbol, Object]]
|
41
49
|
products = {
|
42
50
|
appsec: {
|
43
51
|
enabled: Datadog::AppSec.enabled?,
|
@@ -79,16 +87,19 @@ module Datadog
|
|
79
87
|
].freeze
|
80
88
|
|
81
89
|
# rubocop:disable Metrics/AbcSize
|
90
|
+
# rubocop:disable Metrics/MethodLength
|
82
91
|
def configuration
|
83
92
|
config = Datadog.configuration
|
93
|
+
seq_id = Event.configuration_sequence.next
|
84
94
|
|
85
95
|
list = [
|
86
|
-
conf_value('DD_AGENT_HOST', config.agent.host),
|
87
|
-
conf_value('DD_AGENT_TRANSPORT', agent_transport(config)),
|
88
|
-
conf_value('DD_TRACE_SAMPLE_RATE', to_value(config.tracing.sampling.default_rate)),
|
96
|
+
conf_value('DD_AGENT_HOST', config.agent.host, seq_id),
|
97
|
+
conf_value('DD_AGENT_TRANSPORT', agent_transport(config), seq_id),
|
98
|
+
conf_value('DD_TRACE_SAMPLE_RATE', to_value(config.tracing.sampling.default_rate), seq_id),
|
89
99
|
conf_value(
|
90
100
|
'DD_TRACE_REMOVE_INTEGRATION_SERVICE_NAMES_ENABLED',
|
91
|
-
config.tracing.contrib.global_default_service_name.enabled
|
101
|
+
config.tracing.contrib.global_default_service_name.enabled,
|
102
|
+
seq_id
|
92
103
|
),
|
93
104
|
]
|
94
105
|
|
@@ -97,29 +108,45 @@ module Datadog
|
|
97
108
|
peer_service_mapping = config.tracing.contrib.peer_service_mapping
|
98
109
|
peer_service_mapping_str = peer_service_mapping.map { |key, value| "#{key}:#{value}" }.join(',')
|
99
110
|
end
|
100
|
-
list << conf_value('DD_TRACE_PEER_SERVICE_MAPPING', peer_service_mapping_str)
|
111
|
+
list << conf_value('DD_TRACE_PEER_SERVICE_MAPPING', peer_service_mapping_str, seq_id)
|
101
112
|
|
102
113
|
# Whitelist of configuration options to send in additional payload object
|
103
114
|
TARGET_OPTIONS.each do |option|
|
104
115
|
split_option = option.split('.')
|
105
|
-
list << conf_value(option, to_value(config.dig(*split_option)))
|
116
|
+
list << conf_value(option, to_value(config.dig(*split_option)), seq_id)
|
106
117
|
end
|
107
118
|
|
108
119
|
# Add some more custom additional payload values here
|
109
120
|
list.push(
|
110
|
-
conf_value('tracing.auto_instrument.enabled', !defined?(Datadog::AutoInstrument::LOADED).nil
|
111
|
-
conf_value(
|
112
|
-
|
113
|
-
|
121
|
+
conf_value('tracing.auto_instrument.enabled', !defined?(Datadog::AutoInstrument::LOADED).nil?, seq_id),
|
122
|
+
conf_value(
|
123
|
+
'tracing.writer_options.buffer_size',
|
124
|
+
to_value(config.tracing.writer_options[:buffer_size]),
|
125
|
+
seq_id
|
126
|
+
),
|
127
|
+
conf_value(
|
128
|
+
'tracing.writer_options.flush_interval',
|
129
|
+
to_value(config.tracing.writer_options[:flush_interval]),
|
130
|
+
seq_id
|
131
|
+
),
|
132
|
+
conf_value(
|
133
|
+
'tracing.opentelemetry.enabled',
|
134
|
+
!defined?(Datadog::OpenTelemetry::LOADED).nil?,
|
135
|
+
seq_id
|
136
|
+
),
|
114
137
|
)
|
115
|
-
list << conf_value('logger.instance', config.logger.instance.class.to_s) if config.logger.instance
|
116
|
-
|
117
|
-
|
138
|
+
list << conf_value('logger.instance', config.logger.instance.class.to_s, seq_id) if config.logger.instance
|
139
|
+
if config.respond_to?('appsec')
|
140
|
+
list << conf_value('appsec.enabled', config.dig('appsec', 'enabled'), seq_id)
|
141
|
+
list << conf_value('appsec.sca_enabled', config.dig('appsec', 'sca_enabled'), seq_id)
|
142
|
+
end
|
143
|
+
list << conf_value('ci.enabled', config.dig('ci', 'enabled'), seq_id) if config.respond_to?('ci')
|
118
144
|
|
119
145
|
list.reject! { |entry| entry[:value].nil? }
|
120
146
|
list
|
121
147
|
end
|
122
148
|
# rubocop:enable Metrics/AbcSize
|
149
|
+
# rubocop:enable Metrics/MethodLength
|
123
150
|
|
124
151
|
def agent_transport(config)
|
125
152
|
adapter = Core::Configuration::AgentSettingsResolver.call(config).adapter
|
@@ -130,12 +157,12 @@ module Datadog
|
|
130
157
|
end
|
131
158
|
end
|
132
159
|
|
133
|
-
def conf_value(name, value, origin = 'code')
|
160
|
+
def conf_value(name, value, seq_id, origin = 'code')
|
134
161
|
{
|
135
162
|
name: name,
|
136
163
|
value: value,
|
137
164
|
origin: origin,
|
138
|
-
seq_id:
|
165
|
+
seq_id: seq_id,
|
139
166
|
}
|
140
167
|
end
|
141
168
|
|
@@ -165,7 +192,7 @@ module Datadog
|
|
165
192
|
'app-dependencies-loaded'
|
166
193
|
end
|
167
194
|
|
168
|
-
def payload
|
195
|
+
def payload
|
169
196
|
{ dependencies: dependencies }
|
170
197
|
end
|
171
198
|
|
@@ -188,7 +215,7 @@ module Datadog
|
|
188
215
|
'app-integrations-change'
|
189
216
|
end
|
190
217
|
|
191
|
-
def payload
|
218
|
+
def payload
|
192
219
|
{ integrations: integrations }
|
193
220
|
end
|
194
221
|
|
@@ -241,16 +268,33 @@ module Datadog
|
|
241
268
|
@origin = origin
|
242
269
|
end
|
243
270
|
|
244
|
-
def payload
|
245
|
-
{
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
|
271
|
+
def payload
|
272
|
+
{ configuration: configuration }
|
273
|
+
end
|
274
|
+
|
275
|
+
def configuration
|
276
|
+
config = Datadog.configuration
|
277
|
+
seq_id = Event.configuration_sequence.next
|
278
|
+
|
279
|
+
res = @changes.map do |name, value|
|
280
|
+
{
|
281
|
+
name: name,
|
282
|
+
value: value,
|
283
|
+
origin: @origin,
|
284
|
+
seq_id: seq_id,
|
285
|
+
}
|
286
|
+
end
|
287
|
+
|
288
|
+
unless config.dig('appsec', 'sca_enabled').nil?
|
289
|
+
res << {
|
290
|
+
name: 'appsec.sca_enabled',
|
291
|
+
value: config.appsec.sca_enabled,
|
292
|
+
origin: 'code',
|
293
|
+
seq_id: seq_id,
|
294
|
+
}
|
295
|
+
end
|
296
|
+
|
297
|
+
res
|
254
298
|
end
|
255
299
|
end
|
256
300
|
|
@@ -267,6 +311,55 @@ module Datadog
|
|
267
311
|
'app-closing'
|
268
312
|
end
|
269
313
|
end
|
314
|
+
|
315
|
+
# Telemetry class for the 'generate-metrics' event
|
316
|
+
class GenerateMetrics < Base
|
317
|
+
def type
|
318
|
+
'generate-metrics'
|
319
|
+
end
|
320
|
+
|
321
|
+
def initialize(namespace, metric_series)
|
322
|
+
super()
|
323
|
+
@namespace = namespace
|
324
|
+
@metric_series = metric_series
|
325
|
+
end
|
326
|
+
|
327
|
+
def payload
|
328
|
+
{
|
329
|
+
namespace: @namespace,
|
330
|
+
series: @metric_series.map(&:to_h)
|
331
|
+
}
|
332
|
+
end
|
333
|
+
end
|
334
|
+
|
335
|
+
# Telemetry class for the 'distributions' event
|
336
|
+
class Distributions < GenerateMetrics
|
337
|
+
def type
|
338
|
+
'distributions'
|
339
|
+
end
|
340
|
+
end
|
341
|
+
|
342
|
+
# Telemetry class for the 'message-batch' event
|
343
|
+
class MessageBatch
|
344
|
+
attr_reader :events
|
345
|
+
|
346
|
+
def type
|
347
|
+
'message-batch'
|
348
|
+
end
|
349
|
+
|
350
|
+
def initialize(events)
|
351
|
+
@events = events
|
352
|
+
end
|
353
|
+
|
354
|
+
def payload
|
355
|
+
@events.map do |event|
|
356
|
+
{
|
357
|
+
request_type: event.type,
|
358
|
+
payload: event.payload,
|
359
|
+
}
|
360
|
+
end
|
361
|
+
end
|
362
|
+
end
|
270
363
|
end
|
271
364
|
end
|
272
365
|
end
|
@@ -5,7 +5,9 @@ module Datadog
|
|
5
5
|
module Telemetry
|
6
6
|
module Ext
|
7
7
|
ENV_ENABLED = 'DD_INSTRUMENTATION_TELEMETRY_ENABLED'
|
8
|
+
ENV_METRICS_ENABLED = 'DD_TELEMETRY_METRICS_ENABLED'
|
8
9
|
ENV_HEARTBEAT_INTERVAL = 'DD_TELEMETRY_HEARTBEAT_INTERVAL'
|
10
|
+
ENV_METRICS_AGGREGATION_INTERVAL = 'DD_TELEMETRY_METRICS_AGGREGATION_INTERVAL'
|
9
11
|
ENV_DEPENDENCY_COLLECTION = 'DD_TELEMETRY_DEPENDENCY_COLLECTION_ENABLED'
|
10
12
|
ENV_INSTALL_ID = 'DD_INSTRUMENTATION_INSTALL_ID'
|
11
13
|
ENV_INSTALL_TYPE = 'DD_INSTRUMENTATION_INSTALL_TYPE'
|