datadog 2.0.0.beta1 → 2.0.0.rc1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +181 -1
- data/ext/datadog_profiling_native_extension/NativeExtensionDesign.md +1 -1
- data/ext/datadog_profiling_native_extension/collectors_cpu_and_wall_time_worker.c +40 -32
- data/ext/datadog_profiling_native_extension/collectors_thread_context.c +23 -12
- data/ext/datadog_profiling_native_extension/crashtracker.c +108 -0
- data/ext/datadog_profiling_native_extension/extconf.rb +9 -23
- data/ext/datadog_profiling_native_extension/heap_recorder.c +81 -4
- data/ext/datadog_profiling_native_extension/heap_recorder.h +12 -1
- data/ext/datadog_profiling_native_extension/http_transport.c +1 -94
- data/ext/datadog_profiling_native_extension/libdatadog_helpers.c +86 -0
- data/ext/datadog_profiling_native_extension/libdatadog_helpers.h +4 -0
- data/ext/datadog_profiling_native_extension/native_extension_helpers.rb +2 -12
- data/ext/datadog_profiling_native_extension/private_vm_api_access.c +25 -86
- data/ext/datadog_profiling_native_extension/profiling.c +2 -0
- data/ext/datadog_profiling_native_extension/ruby_helpers.h +3 -5
- data/ext/datadog_profiling_native_extension/stack_recorder.c +161 -62
- data/lib/datadog/appsec/contrib/devise/tracking.rb +8 -0
- data/lib/datadog/appsec/contrib/rack/request_middleware.rb +43 -13
- data/lib/datadog/appsec/event.rb +2 -2
- data/lib/datadog/core/configuration/components.rb +2 -1
- data/lib/datadog/core/configuration/option.rb +7 -5
- data/lib/datadog/core/configuration/settings.rb +34 -79
- data/lib/datadog/core/configuration.rb +20 -4
- data/lib/datadog/core/environment/platform.rb +7 -1
- data/lib/datadog/core/remote/client/capabilities.rb +2 -1
- data/lib/datadog/core/remote/client.rb +1 -5
- data/lib/datadog/core/remote/configuration/repository.rb +1 -1
- data/lib/datadog/core/remote/dispatcher.rb +3 -3
- data/lib/datadog/core/remote/transport/http/config.rb +5 -5
- data/lib/datadog/core/telemetry/client.rb +18 -10
- data/lib/datadog/core/telemetry/emitter.rb +9 -13
- data/lib/datadog/core/telemetry/event.rb +247 -57
- data/lib/datadog/core/telemetry/ext.rb +1 -0
- data/lib/datadog/core/telemetry/heartbeat.rb +1 -3
- data/lib/datadog/core/telemetry/http/ext.rb +4 -1
- data/lib/datadog/core/telemetry/http/response.rb +4 -0
- data/lib/datadog/core/telemetry/http/transport.rb +9 -4
- data/lib/datadog/core/telemetry/request.rb +59 -0
- data/lib/datadog/core/utils/base64.rb +22 -0
- data/lib/datadog/opentelemetry/sdk/span_processor.rb +19 -2
- data/lib/datadog/opentelemetry/sdk/trace/span.rb +3 -17
- data/lib/datadog/profiling/collectors/code_provenance.rb +10 -4
- data/lib/datadog/profiling/collectors/cpu_and_wall_time_worker.rb +25 -0
- data/lib/datadog/profiling/component.rb +49 -17
- data/lib/datadog/profiling/crashtracker.rb +91 -0
- data/lib/datadog/profiling/exporter.rb +6 -3
- data/lib/datadog/profiling/http_transport.rb +7 -11
- data/lib/datadog/profiling/load_native_extension.rb +14 -1
- data/lib/datadog/profiling/profiler.rb +9 -2
- data/lib/datadog/profiling/stack_recorder.rb +6 -2
- data/lib/datadog/profiling.rb +12 -0
- data/lib/datadog/tracing/component.rb +5 -1
- data/lib/datadog/tracing/configuration/dynamic.rb +39 -1
- data/lib/datadog/tracing/configuration/settings.rb +1 -0
- data/lib/datadog/tracing/contrib/action_pack/integration.rb +1 -1
- data/lib/datadog/tracing/contrib/action_view/integration.rb +1 -1
- data/lib/datadog/tracing/contrib/active_record/configuration/resolver.rb +1 -0
- data/lib/datadog/tracing/contrib/active_record/integration.rb +11 -1
- data/lib/datadog/tracing/contrib/active_support/integration.rb +1 -1
- data/lib/datadog/tracing/contrib/configuration/resolver.rb +43 -0
- data/lib/datadog/tracing/contrib/grape/endpoint.rb +43 -5
- data/lib/datadog/tracing/contrib/trilogy/instrumentation.rb +1 -1
- data/lib/datadog/tracing/correlation.rb +3 -4
- data/lib/datadog/tracing/remote.rb +5 -1
- data/lib/datadog/tracing/sampling/ext.rb +5 -1
- data/lib/datadog/tracing/sampling/matcher.rb +75 -26
- data/lib/datadog/tracing/sampling/rule.rb +27 -4
- data/lib/datadog/tracing/sampling/rule_sampler.rb +19 -1
- data/lib/datadog/tracing/sampling/span/matcher.rb +13 -41
- data/lib/datadog/tracing/span.rb +7 -2
- data/lib/datadog/tracing/span_link.rb +92 -0
- data/lib/datadog/tracing/span_operation.rb +6 -4
- data/lib/datadog/tracing/trace_operation.rb +12 -0
- data/lib/datadog/tracing/tracer.rb +4 -3
- data/lib/datadog/tracing/transport/serializable_trace.rb +3 -1
- data/lib/datadog/tracing/utils.rb +16 -0
- data/lib/datadog/version.rb +1 -1
- metadata +10 -31
- data/lib/datadog/core/telemetry/collector.rb +0 -248
- data/lib/datadog/core/telemetry/v1/app_event.rb +0 -59
- data/lib/datadog/core/telemetry/v1/application.rb +0 -94
- data/lib/datadog/core/telemetry/v1/configuration.rb +0 -27
- data/lib/datadog/core/telemetry/v1/dependency.rb +0 -45
- data/lib/datadog/core/telemetry/v1/host.rb +0 -59
- data/lib/datadog/core/telemetry/v1/install_signature.rb +0 -38
- data/lib/datadog/core/telemetry/v1/integration.rb +0 -66
- data/lib/datadog/core/telemetry/v1/product.rb +0 -36
- data/lib/datadog/core/telemetry/v1/telemetry_request.rb +0 -108
- data/lib/datadog/core/telemetry/v2/app_client_configuration_change.rb +0 -41
- data/lib/datadog/core/telemetry/v2/request.rb +0 -29
@@ -64,7 +64,8 @@ module Datadog
|
|
64
64
|
|
65
65
|
Telemetry::Client.new(
|
66
66
|
enabled: enabled,
|
67
|
-
heartbeat_interval_seconds: settings.telemetry.heartbeat_interval_seconds
|
67
|
+
heartbeat_interval_seconds: settings.telemetry.heartbeat_interval_seconds,
|
68
|
+
dependency_collection: settings.telemetry.dependency_collection
|
68
69
|
)
|
69
70
|
end
|
70
71
|
end
|
@@ -8,7 +8,13 @@ module Datadog
|
|
8
8
|
# Represents an instance of an integration configuration option
|
9
9
|
# @public_api
|
10
10
|
class Option
|
11
|
-
|
11
|
+
# @!attribute [r] definition
|
12
|
+
# The definition object that matches this option.
|
13
|
+
# @return [Configuration::OptionDefinition]
|
14
|
+
# @!attribute [r] precedence_set
|
15
|
+
# When this option was last set, what was the value precedence used?
|
16
|
+
# @return [Precedence::Value]
|
17
|
+
attr_reader :definition, :precedence_set
|
12
18
|
|
13
19
|
# Option setting precedence.
|
14
20
|
module Precedence
|
@@ -305,10 +311,6 @@ module Datadog
|
|
305
311
|
"but '#{ENV[effective_env]}' was provided"
|
306
312
|
end
|
307
313
|
|
308
|
-
# Used for testing
|
309
|
-
attr_reader :precedence_set
|
310
|
-
private :precedence_set
|
311
|
-
|
312
314
|
# Anchor object that represents a value that is not set.
|
313
315
|
# This is necessary because `nil` is a valid value to be set.
|
314
316
|
UNSET = Object.new
|
@@ -271,59 +271,25 @@ module Datadog
|
|
271
271
|
|
272
272
|
# Can be used to disable the gathering of names and versions of gems in use by the service, used to power
|
273
273
|
# grouping and categorization of stack traces.
|
274
|
-
option :code_provenance_enabled
|
275
|
-
|
276
|
-
# Forces enabling of profiling of time/resources spent in Garbage Collection.
|
277
|
-
#
|
278
|
-
# Note that setting this to "false" (or not setting it) will not prevent the feature from being
|
279
|
-
# being automatically enabled in the future.
|
280
|
-
#
|
281
|
-
# This feature defaults to off for two reasons:
|
282
|
-
# 1. Currently this feature can add a lot of overhead for GC-heavy workloads.
|
283
|
-
# 2. Although this feature is safe on Ruby 2.x, on Ruby 3.x it can break in applications that make use of
|
284
|
-
# Ractors due to two Ruby VM bugs:
|
285
|
-
# https://bugs.ruby-lang.org/issues/19112 AND https://bugs.ruby-lang.org/issues/18464.
|
286
|
-
# If you use Ruby 3.x and your application does not use Ractors (or if your Ruby has been patched), the
|
287
|
-
# feature is fully safe to enable and this toggle can be used to do so.
|
288
|
-
#
|
289
|
-
# We expect the once the above issues are overcome, we'll automatically enable the feature on fixed Ruby
|
290
|
-
# versions.
|
291
|
-
#
|
292
|
-
# @default `DD_PROFILING_FORCE_ENABLE_GC` environment variable, otherwise `false`
|
293
|
-
option :force_enable_gc_profiling do |o|
|
294
|
-
o.env 'DD_PROFILING_FORCE_ENABLE_GC'
|
274
|
+
option :code_provenance_enabled do |o|
|
295
275
|
o.type :bool
|
296
|
-
o.default
|
276
|
+
o.default true
|
297
277
|
end
|
298
278
|
|
299
|
-
# Can be used to enable/disable
|
279
|
+
# Can be used to enable/disable garbage collection profiling.
|
300
280
|
#
|
301
|
-
# @
|
302
|
-
|
303
|
-
|
304
|
-
|
305
|
-
|
306
|
-
|
307
|
-
|
308
|
-
|
309
|
-
|
310
|
-
end
|
311
|
-
end
|
312
|
-
end
|
313
|
-
|
314
|
-
# @deprecated Use {:allocation_enabled} (outside of advanced section) instead.
|
315
|
-
option :experimental_allocation_enabled do |o|
|
281
|
+
# @warn To avoid https://bugs.ruby-lang.org/issues/18464 even when enabled, GC profiling is only started
|
282
|
+
# for Ruby versions 2.x, 3.1.4+, 3.2.3+ and 3.3.0+
|
283
|
+
# (more details in {Datadog::Profiling::Component.enable_gc_profiling?})
|
284
|
+
#
|
285
|
+
# @warn Due to a VM bug in the Ractor implementation (https://bugs.ruby-lang.org/issues/19112) this feature
|
286
|
+
# stops working when Ractors get garbage collected.
|
287
|
+
#
|
288
|
+
# @default `DD_PROFILING_GC_ENABLED` environment variable, otherwise `true`
|
289
|
+
option :gc_enabled do |o|
|
316
290
|
o.type :bool
|
317
|
-
o.
|
318
|
-
o.
|
319
|
-
unless precedence == Datadog::Core::Configuration::Option::Precedence::DEFAULT
|
320
|
-
Datadog.logger.warn(
|
321
|
-
'The profiling.advanced.experimental_allocation_enabled setting has been deprecated for removal and ' \
|
322
|
-
'no longer does anything. Please remove it from your Datadog.configure block. ' \
|
323
|
-
'Allocation profiling is now controlled by the profiling.allocation_enabled setting instead.'
|
324
|
-
)
|
325
|
-
end
|
326
|
-
end
|
291
|
+
o.env 'DD_PROFILING_GC_ENABLED'
|
292
|
+
o.default true
|
327
293
|
end
|
328
294
|
|
329
295
|
# Can be used to enable/disable the collection of heap profiles.
|
@@ -353,22 +319,6 @@ module Datadog
|
|
353
319
|
o.default true # This gets ANDed with experimental_heap_enabled in the profiler component.
|
354
320
|
end
|
355
321
|
|
356
|
-
# Can be used to configure the allocation sampling rate: a sample will be collected every x allocations.
|
357
|
-
#
|
358
|
-
# This feature is now controlled via {:overhead_target_percentage}
|
359
|
-
option :experimental_allocation_sample_rate do |o|
|
360
|
-
o.after_set do |_, _, precedence|
|
361
|
-
unless precedence == Datadog::Core::Configuration::Option::Precedence::DEFAULT
|
362
|
-
Datadog.logger.warn(
|
363
|
-
'The profiling.advanced.experimental_allocation_sample_rate setting has been deprecated for removal ' \
|
364
|
-
'and no longer does anything. Please remove it from your Datadog.configure block. ' \
|
365
|
-
'Allocation sample rate is now handled by a dynamic sampler which will adjust the sampling rate to ' \
|
366
|
-
'keep to the configured `profiling.advanced.overhead_target_percentage`.'
|
367
|
-
)
|
368
|
-
end
|
369
|
-
end
|
370
|
-
end
|
371
|
-
|
372
322
|
# Can be used to configure the heap sampling rate: a heap sample will be collected for every x allocation
|
373
323
|
# samples.
|
374
324
|
#
|
@@ -396,21 +346,6 @@ module Datadog
|
|
396
346
|
o.default false
|
397
347
|
end
|
398
348
|
|
399
|
-
# Enables data collection for the timeline feature. This is still experimental and not recommended yet.
|
400
|
-
#
|
401
|
-
# @default `DD_PROFILING_EXPERIMENTAL_TIMELINE_ENABLED` environment variable as a boolean, otherwise `false`
|
402
|
-
option :experimental_timeline_enabled do |o|
|
403
|
-
o.after_set do |_, _, precedence|
|
404
|
-
unless precedence == Datadog::Core::Configuration::Option::Precedence::DEFAULT
|
405
|
-
Datadog.logger.warn(
|
406
|
-
'The profiling.advanced.experimental_timeline_enabled setting has been deprecated for removal ' \
|
407
|
-
'and no longer does anything. Please remove it from your Datadog.configure block. ' \
|
408
|
-
'The timeline feature counting is now controlled by the `timeline_enabled` setting instead.'
|
409
|
-
)
|
410
|
-
end
|
411
|
-
end
|
412
|
-
end
|
413
|
-
|
414
349
|
# Controls data collection for the timeline feature.
|
415
350
|
#
|
416
351
|
# If you needed to disable this, please tell us why on <https://github.com/DataDog/dd-trace-rb/issues/new>,
|
@@ -480,6 +415,16 @@ module Datadog
|
|
480
415
|
o.env 'DD_PROFILING_UPLOAD_PERIOD'
|
481
416
|
o.default 60
|
482
417
|
end
|
418
|
+
|
419
|
+
# Enables reporting of information when the Ruby VM crashes.
|
420
|
+
#
|
421
|
+
# @default `DD_PROFILING_EXPERIMENTAL_CRASH_TRACKING_ENABLED` environment variable as a boolean,
|
422
|
+
# otherwise `false`
|
423
|
+
option :experimental_crash_tracking_enabled do |o|
|
424
|
+
o.type :bool
|
425
|
+
o.env 'DD_PROFILING_EXPERIMENTAL_CRASH_TRACKING_ENABLED'
|
426
|
+
o.default false
|
427
|
+
end
|
483
428
|
end
|
484
429
|
|
485
430
|
# @public_api
|
@@ -646,6 +591,16 @@ module Datadog
|
|
646
591
|
# Client-side telemetry configuration
|
647
592
|
# @public_api
|
648
593
|
settings :telemetry do
|
594
|
+
# Whether the bundled Ruby gems as reported through telemetry.
|
595
|
+
#
|
596
|
+
# @default `DD_TELEMETRY_DEPENDENCY_COLLECTION_ENABLED` environment variable, otherwise `true`.
|
597
|
+
# @return [Boolean]
|
598
|
+
option :dependency_collection do |o|
|
599
|
+
o.type :bool
|
600
|
+
o.env Core::Telemetry::Ext::ENV_DEPENDENCY_COLLECTION
|
601
|
+
o.default true
|
602
|
+
end
|
603
|
+
|
649
604
|
# Enable telemetry collection. This allows telemetry events to be emitted to the telemetry API.
|
650
605
|
#
|
651
606
|
# @default `DD_INSTRUMENTATION_TELEMETRY_ENABLED` environment variable, otherwise `true`.
|
@@ -84,18 +84,23 @@ module Datadog
|
|
84
84
|
configuration = self.configuration
|
85
85
|
yield(configuration)
|
86
86
|
|
87
|
-
|
87
|
+
built_components = false
|
88
|
+
|
89
|
+
components = safely_synchronize do |write_components|
|
88
90
|
write_components.call(
|
89
91
|
if components?
|
90
92
|
replace_components!(configuration, @components)
|
91
93
|
else
|
92
94
|
components = build_components(configuration)
|
93
|
-
|
95
|
+
built_components = true
|
94
96
|
components
|
95
97
|
end
|
96
98
|
)
|
97
99
|
end
|
98
100
|
|
101
|
+
# Should only be called the first time components are built
|
102
|
+
components.telemetry.started! if built_components
|
103
|
+
|
99
104
|
configuration
|
100
105
|
end
|
101
106
|
|
@@ -195,9 +200,20 @@ module Datadog
|
|
195
200
|
current_components = COMPONENTS_READ_LOCK.synchronize { defined?(@components) && @components }
|
196
201
|
return current_components if current_components || !allow_initialization
|
197
202
|
|
198
|
-
|
199
|
-
|
203
|
+
built_components = false
|
204
|
+
|
205
|
+
components = safely_synchronize do |write_components|
|
206
|
+
if defined?(@components) && @components
|
207
|
+
@components
|
208
|
+
else
|
209
|
+
built_components = true
|
210
|
+
write_components.call(build_components(configuration))
|
211
|
+
end
|
200
212
|
end
|
213
|
+
|
214
|
+
# Should only be called the first time components are built
|
215
|
+
components&.telemetry&.started! if built_components
|
216
|
+
components
|
201
217
|
end
|
202
218
|
|
203
219
|
private
|
@@ -11,12 +11,18 @@ module Datadog
|
|
11
11
|
module Platform
|
12
12
|
module_function
|
13
13
|
|
14
|
+
# @return [String] ISA of host; `uname -m`
|
15
|
+
def architecture
|
16
|
+
Identity.lang_version >= '2.2' ? Etc.uname[:machine] : Gem::Platform.local.cpu
|
17
|
+
end
|
18
|
+
|
14
19
|
# @return [String] name of host; `uname -n`
|
15
20
|
def hostname
|
16
21
|
Identity.lang_version >= '2.2' ? Etc.uname[:nodename] : nil
|
17
22
|
end
|
18
23
|
|
19
|
-
#
|
24
|
+
# System name, normally `Linux` or `Darwin` (but 'Mac OS X' on JRuby);
|
25
|
+
# @return [String] name of kernel; `uname -s`.
|
20
26
|
def kernel_name
|
21
27
|
Identity.lang_version >= '2.2' ? Etc.uname[:sysname] : Gem::Platform.local.os.capitalize
|
22
28
|
end
|
@@ -1,5 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require_relative '../../utils/base64'
|
3
4
|
require_relative '../../../appsec/remote'
|
4
5
|
require_relative '../../../tracing/remote'
|
5
6
|
|
@@ -53,7 +54,7 @@ module Datadog
|
|
53
54
|
cap_to_hexs = capabilities.reduce(:|).to_s(16).tap { |s| s.size.odd? && s.prepend('0') }.scan(/\h\h/)
|
54
55
|
binary = cap_to_hexs.each_with_object([]) { |hex, acc| acc << hex }.map { |e| e.to_i(16) }.pack('C*')
|
55
56
|
|
56
|
-
Base64.
|
57
|
+
Datadog::Core::Utils::Base64.strict_encode64(binary)
|
57
58
|
end
|
58
59
|
end
|
59
60
|
end
|
@@ -20,12 +20,8 @@ module Datadog
|
|
20
20
|
|
21
21
|
@repository = repository
|
22
22
|
@id = SecureRandom.uuid
|
23
|
-
@dispatcher = Dispatcher.new
|
24
23
|
@capabilities = capabilities
|
25
|
-
|
26
|
-
@capabilities.receivers.each do |receiver|
|
27
|
-
dispatcher.receivers << receiver
|
28
|
-
end
|
24
|
+
@dispatcher = Dispatcher.new(@capabilities.receivers)
|
29
25
|
end
|
30
26
|
|
31
27
|
# rubocop:disable Metrics/AbcSize,Metrics/PerceivedComplexity,Metrics/MethodLength,Metrics/CyclomaticComplexity
|
@@ -7,8 +7,8 @@ module Datadog
|
|
7
7
|
class Dispatcher
|
8
8
|
attr_reader :receivers
|
9
9
|
|
10
|
-
def initialize
|
11
|
-
@receivers =
|
10
|
+
def initialize(receivers)
|
11
|
+
@receivers = receivers
|
12
12
|
end
|
13
13
|
|
14
14
|
def dispatch(changes, repository)
|
@@ -45,7 +45,7 @@ module Datadog
|
|
45
45
|
@block.call(path)
|
46
46
|
end
|
47
47
|
|
48
|
-
# Matches on the
|
48
|
+
# Matches on the product's path
|
49
49
|
class Product < Matcher
|
50
50
|
def initialize(products)
|
51
51
|
block = ->(path) { products.include?(path.product) }
|
@@ -1,10 +1,10 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require 'json'
|
4
|
-
require 'base64'
|
5
4
|
|
6
5
|
require_relative '../config'
|
7
6
|
require_relative 'client'
|
7
|
+
require_relative '../../../utils/base64'
|
8
8
|
require_relative '../../../transport/http/response'
|
9
9
|
require_relative '../../../transport/http/api/endpoint'
|
10
10
|
|
@@ -51,7 +51,7 @@ module Datadog
|
|
51
51
|
|
52
52
|
# TODO: these fallbacks should be improved
|
53
53
|
roots = payload[:roots] || []
|
54
|
-
targets = payload[:targets] || Base64.
|
54
|
+
targets = payload[:targets] || Datadog::Core::Utils::Base64.strict_encode64('{}')
|
55
55
|
target_files = payload[:target_files] || []
|
56
56
|
client_configs = payload[:client_configs] || []
|
57
57
|
|
@@ -61,7 +61,7 @@ module Datadog
|
|
61
61
|
raise TypeError.new(String, root) unless root.is_a?(String)
|
62
62
|
|
63
63
|
decoded = begin
|
64
|
-
Base64.strict_decode64(root) # TODO: unprocessed, don't symbolize_names
|
64
|
+
Datadog::Core::Utils::Base64.strict_decode64(root) # TODO: unprocessed, don't symbolize_names
|
65
65
|
rescue ArgumentError
|
66
66
|
raise DecodeError.new(:roots, root)
|
67
67
|
end
|
@@ -81,7 +81,7 @@ module Datadog
|
|
81
81
|
|
82
82
|
@targets = begin
|
83
83
|
decoded = begin
|
84
|
-
Base64.strict_decode64(targets)
|
84
|
+
Datadog::Core::Utils::Base64.strict_decode64(targets)
|
85
85
|
rescue ArgumentError
|
86
86
|
raise DecodeError.new(:targets, targets)
|
87
87
|
end
|
@@ -109,7 +109,7 @@ module Datadog
|
|
109
109
|
raise TypeError.new(String, raw) unless raw.is_a?(String)
|
110
110
|
|
111
111
|
content = begin
|
112
|
-
Base64.strict_decode64(raw)
|
112
|
+
Datadog::Core::Utils::Base64.strict_decode64(raw)
|
113
113
|
rescue ArgumentError
|
114
114
|
raise DecodeError.new(:target_files, raw)
|
115
115
|
end
|
@@ -1,6 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require_relative 'emitter'
|
4
|
+
require_relative 'event'
|
4
5
|
require_relative 'heartbeat'
|
5
6
|
require_relative '../utils/forking'
|
6
7
|
|
@@ -10,21 +11,25 @@ module Datadog
|
|
10
11
|
# Telemetry entrypoint, coordinates sending telemetry events at various points in app lifecycle.
|
11
12
|
class Client
|
12
13
|
attr_reader \
|
13
|
-
:emitter,
|
14
14
|
:enabled,
|
15
|
-
:unsupported
|
16
|
-
:worker
|
15
|
+
:unsupported
|
17
16
|
|
18
17
|
include Core::Utils::Forking
|
19
18
|
|
20
19
|
# @param enabled [Boolean] Determines whether telemetry events should be sent to the API
|
21
20
|
# @param heartbeat_interval_seconds [Float] How frequently heartbeats will be reported, in seconds.
|
22
|
-
|
21
|
+
# @param [Boolean] dependency_collection Whether to send the `app-dependencies-loaded` event
|
22
|
+
def initialize(heartbeat_interval_seconds:, dependency_collection:, enabled: true)
|
23
23
|
@enabled = enabled
|
24
24
|
@emitter = Emitter.new
|
25
25
|
@stopped = false
|
26
26
|
@unsupported = false
|
27
|
+
@started = false
|
28
|
+
@dependency_collection = dependency_collection
|
29
|
+
|
27
30
|
@worker = Telemetry::Heartbeat.new(enabled: @enabled, heartbeat_interval_seconds: heartbeat_interval_seconds) do
|
31
|
+
next unless @started # `started!` should be the first event, thus ensure that `heartbeat!` is not sent first.
|
32
|
+
|
28
33
|
heartbeat!
|
29
34
|
end
|
30
35
|
end
|
@@ -37,21 +42,24 @@ module Datadog
|
|
37
42
|
def started!
|
38
43
|
return if !@enabled || forked?
|
39
44
|
|
40
|
-
res = @emitter.request(
|
45
|
+
res = @emitter.request(Event::AppStarted.new)
|
41
46
|
|
42
47
|
if res.not_found? # Telemetry is only supported by agent versions 7.34 and up
|
43
48
|
Datadog.logger.debug('Agent does not support telemetry; disabling future telemetry events.')
|
44
49
|
disable!
|
45
50
|
@unsupported = true # Prevent telemetry from getting re-enabled
|
51
|
+
return res
|
46
52
|
end
|
47
53
|
|
48
|
-
|
54
|
+
@emitter.request(Event::AppDependenciesLoaded.new) if @dependency_collection
|
55
|
+
|
56
|
+
@started = true
|
49
57
|
end
|
50
58
|
|
51
59
|
def emit_closing!
|
52
60
|
return if !@enabled || forked?
|
53
61
|
|
54
|
-
@emitter.request(
|
62
|
+
@emitter.request(Event::AppClosing.new)
|
55
63
|
end
|
56
64
|
|
57
65
|
def stop!
|
@@ -64,14 +72,14 @@ module Datadog
|
|
64
72
|
def integrations_change!
|
65
73
|
return if !@enabled || forked?
|
66
74
|
|
67
|
-
@emitter.request(
|
75
|
+
@emitter.request(Event::AppIntegrationsChange.new)
|
68
76
|
end
|
69
77
|
|
70
78
|
# Report configuration changes caused by Remote Configuration.
|
71
79
|
def client_configuration_change!(changes)
|
72
80
|
return if !@enabled || forked?
|
73
81
|
|
74
|
-
@emitter.request(
|
82
|
+
@emitter.request(Event::AppClientConfigurationChange.new(changes, 'remote_config'))
|
75
83
|
end
|
76
84
|
|
77
85
|
private
|
@@ -79,7 +87,7 @@ module Datadog
|
|
79
87
|
def heartbeat!
|
80
88
|
return if !@enabled || forked?
|
81
89
|
|
82
|
-
@emitter.request(
|
90
|
+
@emitter.request(Event::AppHeartbeat.new)
|
83
91
|
end
|
84
92
|
end
|
85
93
|
end
|
@@ -1,6 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require_relative '
|
3
|
+
require_relative 'request'
|
4
4
|
require_relative 'http/transport'
|
5
5
|
require_relative '../utils/sequence'
|
6
6
|
require_relative '../utils/forking'
|
@@ -14,7 +14,6 @@ module Datadog
|
|
14
14
|
|
15
15
|
extend Core::Utils::Forking
|
16
16
|
|
17
|
-
# @param sequence [Datadog::Core::Utils::Sequence] Sequence object that stores and increments a counter
|
18
17
|
# @param http_transport [Datadog::Core::Telemetry::Http::Transport] Transport object that can be used to send
|
19
18
|
# telemetry requests via the agent
|
20
19
|
def initialize(http_transport: Datadog::Core::Telemetry::Http::Transport.new)
|
@@ -22,18 +21,15 @@ module Datadog
|
|
22
21
|
end
|
23
22
|
|
24
23
|
# Retrieves and emits a TelemetryRequest object based on the request type specified
|
25
|
-
|
26
|
-
# @param data [Object] arbitrary object to be passed to the respective `request_type` handler
|
27
|
-
def request(request_type, data: nil)
|
24
|
+
def request(event)
|
28
25
|
begin
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
Datadog.logger.debug("Unable to send telemetry request for event `#{request_type}`: #{e}")
|
26
|
+
seq_id = self.class.sequence.next
|
27
|
+
payload = Request.build_payload(event, seq_id)
|
28
|
+
res = @http_transport.request(request_type: event.type, payload: payload.to_json)
|
29
|
+
Datadog.logger.debug { "Telemetry sent for event `#{event.type}` (code: #{res.code.inspect})" }
|
30
|
+
res
|
31
|
+
rescue => e
|
32
|
+
Datadog.logger.debug("Unable to send telemetry request for event `#{event.type rescue 'unknown'}`: #{e}")
|
37
33
|
Telemetry::Http::InternalErrorResponse.new(e)
|
38
34
|
end
|
39
35
|
end
|