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.
Files changed (91) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +181 -1
  3. data/ext/datadog_profiling_native_extension/NativeExtensionDesign.md +1 -1
  4. data/ext/datadog_profiling_native_extension/collectors_cpu_and_wall_time_worker.c +40 -32
  5. data/ext/datadog_profiling_native_extension/collectors_thread_context.c +23 -12
  6. data/ext/datadog_profiling_native_extension/crashtracker.c +108 -0
  7. data/ext/datadog_profiling_native_extension/extconf.rb +9 -23
  8. data/ext/datadog_profiling_native_extension/heap_recorder.c +81 -4
  9. data/ext/datadog_profiling_native_extension/heap_recorder.h +12 -1
  10. data/ext/datadog_profiling_native_extension/http_transport.c +1 -94
  11. data/ext/datadog_profiling_native_extension/libdatadog_helpers.c +86 -0
  12. data/ext/datadog_profiling_native_extension/libdatadog_helpers.h +4 -0
  13. data/ext/datadog_profiling_native_extension/native_extension_helpers.rb +2 -12
  14. data/ext/datadog_profiling_native_extension/private_vm_api_access.c +25 -86
  15. data/ext/datadog_profiling_native_extension/profiling.c +2 -0
  16. data/ext/datadog_profiling_native_extension/ruby_helpers.h +3 -5
  17. data/ext/datadog_profiling_native_extension/stack_recorder.c +161 -62
  18. data/lib/datadog/appsec/contrib/devise/tracking.rb +8 -0
  19. data/lib/datadog/appsec/contrib/rack/request_middleware.rb +43 -13
  20. data/lib/datadog/appsec/event.rb +2 -2
  21. data/lib/datadog/core/configuration/components.rb +2 -1
  22. data/lib/datadog/core/configuration/option.rb +7 -5
  23. data/lib/datadog/core/configuration/settings.rb +34 -79
  24. data/lib/datadog/core/configuration.rb +20 -4
  25. data/lib/datadog/core/environment/platform.rb +7 -1
  26. data/lib/datadog/core/remote/client/capabilities.rb +2 -1
  27. data/lib/datadog/core/remote/client.rb +1 -5
  28. data/lib/datadog/core/remote/configuration/repository.rb +1 -1
  29. data/lib/datadog/core/remote/dispatcher.rb +3 -3
  30. data/lib/datadog/core/remote/transport/http/config.rb +5 -5
  31. data/lib/datadog/core/telemetry/client.rb +18 -10
  32. data/lib/datadog/core/telemetry/emitter.rb +9 -13
  33. data/lib/datadog/core/telemetry/event.rb +247 -57
  34. data/lib/datadog/core/telemetry/ext.rb +1 -0
  35. data/lib/datadog/core/telemetry/heartbeat.rb +1 -3
  36. data/lib/datadog/core/telemetry/http/ext.rb +4 -1
  37. data/lib/datadog/core/telemetry/http/response.rb +4 -0
  38. data/lib/datadog/core/telemetry/http/transport.rb +9 -4
  39. data/lib/datadog/core/telemetry/request.rb +59 -0
  40. data/lib/datadog/core/utils/base64.rb +22 -0
  41. data/lib/datadog/opentelemetry/sdk/span_processor.rb +19 -2
  42. data/lib/datadog/opentelemetry/sdk/trace/span.rb +3 -17
  43. data/lib/datadog/profiling/collectors/code_provenance.rb +10 -4
  44. data/lib/datadog/profiling/collectors/cpu_and_wall_time_worker.rb +25 -0
  45. data/lib/datadog/profiling/component.rb +49 -17
  46. data/lib/datadog/profiling/crashtracker.rb +91 -0
  47. data/lib/datadog/profiling/exporter.rb +6 -3
  48. data/lib/datadog/profiling/http_transport.rb +7 -11
  49. data/lib/datadog/profiling/load_native_extension.rb +14 -1
  50. data/lib/datadog/profiling/profiler.rb +9 -2
  51. data/lib/datadog/profiling/stack_recorder.rb +6 -2
  52. data/lib/datadog/profiling.rb +12 -0
  53. data/lib/datadog/tracing/component.rb +5 -1
  54. data/lib/datadog/tracing/configuration/dynamic.rb +39 -1
  55. data/lib/datadog/tracing/configuration/settings.rb +1 -0
  56. data/lib/datadog/tracing/contrib/action_pack/integration.rb +1 -1
  57. data/lib/datadog/tracing/contrib/action_view/integration.rb +1 -1
  58. data/lib/datadog/tracing/contrib/active_record/configuration/resolver.rb +1 -0
  59. data/lib/datadog/tracing/contrib/active_record/integration.rb +11 -1
  60. data/lib/datadog/tracing/contrib/active_support/integration.rb +1 -1
  61. data/lib/datadog/tracing/contrib/configuration/resolver.rb +43 -0
  62. data/lib/datadog/tracing/contrib/grape/endpoint.rb +43 -5
  63. data/lib/datadog/tracing/contrib/trilogy/instrumentation.rb +1 -1
  64. data/lib/datadog/tracing/correlation.rb +3 -4
  65. data/lib/datadog/tracing/remote.rb +5 -1
  66. data/lib/datadog/tracing/sampling/ext.rb +5 -1
  67. data/lib/datadog/tracing/sampling/matcher.rb +75 -26
  68. data/lib/datadog/tracing/sampling/rule.rb +27 -4
  69. data/lib/datadog/tracing/sampling/rule_sampler.rb +19 -1
  70. data/lib/datadog/tracing/sampling/span/matcher.rb +13 -41
  71. data/lib/datadog/tracing/span.rb +7 -2
  72. data/lib/datadog/tracing/span_link.rb +92 -0
  73. data/lib/datadog/tracing/span_operation.rb +6 -4
  74. data/lib/datadog/tracing/trace_operation.rb +12 -0
  75. data/lib/datadog/tracing/tracer.rb +4 -3
  76. data/lib/datadog/tracing/transport/serializable_trace.rb +3 -1
  77. data/lib/datadog/tracing/utils.rb +16 -0
  78. data/lib/datadog/version.rb +1 -1
  79. metadata +10 -31
  80. data/lib/datadog/core/telemetry/collector.rb +0 -248
  81. data/lib/datadog/core/telemetry/v1/app_event.rb +0 -59
  82. data/lib/datadog/core/telemetry/v1/application.rb +0 -94
  83. data/lib/datadog/core/telemetry/v1/configuration.rb +0 -27
  84. data/lib/datadog/core/telemetry/v1/dependency.rb +0 -45
  85. data/lib/datadog/core/telemetry/v1/host.rb +0 -59
  86. data/lib/datadog/core/telemetry/v1/install_signature.rb +0 -38
  87. data/lib/datadog/core/telemetry/v1/integration.rb +0 -66
  88. data/lib/datadog/core/telemetry/v1/product.rb +0 -36
  89. data/lib/datadog/core/telemetry/v1/telemetry_request.rb +0 -108
  90. data/lib/datadog/core/telemetry/v2/app_client_configuration_change.rb +0 -41
  91. 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
- attr_reader :definition
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, default: true
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 false
276
+ o.default true
297
277
  end
298
278
 
299
- # Can be used to enable/disable the Datadog::Profiling.allocation_count feature.
279
+ # Can be used to enable/disable garbage collection profiling.
300
280
  #
301
- # @deprecated Use {:allocation_enabled} (outside of advanced section) instead.
302
- option :allocation_counting_enabled do |o|
303
- o.after_set do |_, _, precedence|
304
- unless precedence == Datadog::Core::Configuration::Option::Precedence::DEFAULT
305
- Datadog.logger.warn(
306
- 'The profiling.advanced.allocation_counting_enabled setting has been deprecated for removal and no ' \
307
- 'longer does anything. Please remove it from your Datadog.configure block. ' \
308
- 'Allocation counting is now controlled by the profiling.allocation_enabled setting instead.'
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.default false
318
- o.after_set do |_, _, precedence|
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
- safely_synchronize do |write_components|
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
- components.telemetry.started!
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
- safely_synchronize do |write_components|
199
- (defined?(@components) && @components) || write_components.call(build_components(configuration))
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
- # @return [String] name of kernel; `uname -s`
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.encode64(binary).chomp
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
@@ -164,7 +164,7 @@ module Datadog
164
164
  end
165
165
  end
166
166
 
167
- # Insert content into the reporistory contents
167
+ # Insert content into the repository contents
168
168
  class Insert
169
169
  attr_reader :path, :target, :content
170
170
 
@@ -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 produc's path
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.encode64('{}').chomp
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
- def initialize(heartbeat_interval_seconds:, enabled: true)
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(:'app-started')
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
- res
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(:'app-closing')
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(:'app-integrations-change')
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('app-client-configuration-change', data: { changes: changes, origin: 'remote_config' })
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(:'app-heartbeat')
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 'event'
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
- # @param request_type [String] the type of telemetry request to collect data for
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
- request = Datadog::Core::Telemetry::Event.new.telemetry_request(
30
- request_type: request_type,
31
- seq_id: self.class.sequence.next,
32
- data: data,
33
- ).to_h
34
- @http_transport.request(request_type: request_type.to_s, payload: request.to_json)
35
- rescue StandardError => e
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