datadog 2.23.0 → 2.24.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.
Files changed (112) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +44 -2
  3. data/ext/datadog_profiling_native_extension/collectors_stack.c +17 -5
  4. data/ext/datadog_profiling_native_extension/crashtracking_runtime_stacks.c +239 -0
  5. data/ext/datadog_profiling_native_extension/extconf.rb +4 -1
  6. data/ext/datadog_profiling_native_extension/private_vm_api_access.c +12 -0
  7. data/ext/datadog_profiling_native_extension/private_vm_api_access.h +4 -0
  8. data/ext/datadog_profiling_native_extension/profiling.c +2 -0
  9. data/lib/datadog/appsec/context.rb +2 -1
  10. data/lib/datadog/appsec/remote.rb +1 -9
  11. data/lib/datadog/appsec/security_engine/result.rb +2 -1
  12. data/lib/datadog/core/configuration/config_helper.rb +1 -1
  13. data/lib/datadog/core/configuration/deprecations.rb +2 -2
  14. data/lib/datadog/core/configuration/option_definition.rb +4 -2
  15. data/lib/datadog/core/configuration/options.rb +8 -5
  16. data/lib/datadog/core/configuration/settings.rb +14 -3
  17. data/lib/datadog/core/configuration/supported_configurations.rb +2 -1
  18. data/lib/datadog/core/environment/cgroup.rb +52 -25
  19. data/lib/datadog/core/environment/container.rb +140 -46
  20. data/lib/datadog/core/environment/ext.rb +1 -0
  21. data/lib/datadog/core/environment/process.rb +9 -1
  22. data/lib/datadog/core/rate_limiter.rb +9 -1
  23. data/lib/datadog/core/remote/client.rb +14 -6
  24. data/lib/datadog/core/remote/component.rb +6 -4
  25. data/lib/datadog/core/remote/configuration/content.rb +15 -2
  26. data/lib/datadog/core/remote/configuration/digest.rb +14 -7
  27. data/lib/datadog/core/remote/configuration/repository.rb +1 -1
  28. data/lib/datadog/core/remote/configuration/target.rb +13 -6
  29. data/lib/datadog/core/remote/transport/config.rb +3 -16
  30. data/lib/datadog/core/remote/transport/http/config.rb +4 -44
  31. data/lib/datadog/core/remote/transport/http/negotiation.rb +0 -39
  32. data/lib/datadog/core/remote/transport/http.rb +13 -24
  33. data/lib/datadog/core/remote/transport/negotiation.rb +7 -16
  34. data/lib/datadog/core/telemetry/component.rb +52 -13
  35. data/lib/datadog/core/telemetry/event/app_started.rb +34 -0
  36. data/lib/datadog/core/telemetry/event/synth_app_client_configuration_change.rb +27 -4
  37. data/lib/datadog/core/telemetry/metrics_manager.rb +9 -0
  38. data/lib/datadog/core/telemetry/request.rb +17 -3
  39. data/lib/datadog/core/telemetry/transport/http/telemetry.rb +2 -32
  40. data/lib/datadog/core/telemetry/transport/http.rb +21 -16
  41. data/lib/datadog/core/telemetry/transport/telemetry.rb +3 -10
  42. data/lib/datadog/core/telemetry/worker.rb +88 -32
  43. data/lib/datadog/core/transport/ext.rb +2 -0
  44. data/lib/datadog/core/transport/http/api/endpoint.rb +9 -4
  45. data/lib/datadog/core/transport/http/api/instance.rb +4 -21
  46. data/lib/datadog/core/transport/http/builder.rb +9 -5
  47. data/lib/datadog/core/transport/http/client.rb +19 -8
  48. data/lib/datadog/core/transport/http.rb +22 -19
  49. data/lib/datadog/core/transport/response.rb +9 -0
  50. data/lib/datadog/core/transport/transport.rb +90 -0
  51. data/lib/datadog/core/utils/only_once_successful.rb +2 -0
  52. data/lib/datadog/core/utils/time.rb +1 -1
  53. data/lib/datadog/core/workers/async.rb +10 -1
  54. data/lib/datadog/core/workers/interval_loop.rb +44 -3
  55. data/lib/datadog/core/workers/polling.rb +2 -0
  56. data/lib/datadog/core/workers/queue.rb +100 -1
  57. data/lib/datadog/data_streams/processor.rb +1 -1
  58. data/lib/datadog/data_streams/transport/http/stats.rb +1 -36
  59. data/lib/datadog/data_streams/transport/http.rb +5 -6
  60. data/lib/datadog/data_streams/transport/stats.rb +3 -17
  61. data/lib/datadog/di/contrib/active_record.rb +31 -5
  62. data/lib/datadog/di/el/compiler.rb +8 -4
  63. data/lib/datadog/di/error.rb +5 -0
  64. data/lib/datadog/di/instrumenter.rb +17 -4
  65. data/lib/datadog/di/probe_builder.rb +2 -1
  66. data/lib/datadog/di/probe_manager.rb +37 -31
  67. data/lib/datadog/di/probe_notification_builder.rb +15 -2
  68. data/lib/datadog/di/remote.rb +89 -84
  69. data/lib/datadog/di/transport/diagnostics.rb +7 -35
  70. data/lib/datadog/di/transport/http/diagnostics.rb +1 -31
  71. data/lib/datadog/di/transport/http/input.rb +1 -31
  72. data/lib/datadog/di/transport/http.rb +28 -17
  73. data/lib/datadog/di/transport/input.rb +7 -34
  74. data/lib/datadog/di.rb +61 -5
  75. data/lib/datadog/open_feature/evaluation_engine.rb +2 -1
  76. data/lib/datadog/open_feature/remote.rb +3 -10
  77. data/lib/datadog/open_feature/transport.rb +9 -11
  78. data/lib/datadog/opentelemetry/api/baggage.rb +1 -1
  79. data/lib/datadog/opentelemetry/configuration/settings.rb +2 -2
  80. data/lib/datadog/opentelemetry/metrics.rb +21 -14
  81. data/lib/datadog/opentelemetry/sdk/metrics_exporter.rb +5 -8
  82. data/lib/datadog/profiling/collectors/code_provenance.rb +27 -2
  83. data/lib/datadog/profiling/collectors/info.rb +2 -1
  84. data/lib/datadog/profiling/component.rb +12 -11
  85. data/lib/datadog/profiling/http_transport.rb +4 -1
  86. data/lib/datadog/tracing/contrib/extensions.rb +10 -2
  87. data/lib/datadog/tracing/contrib/karafka/patcher.rb +31 -32
  88. data/lib/datadog/tracing/contrib/status_range_matcher.rb +2 -1
  89. data/lib/datadog/tracing/contrib/utils/quantization/hash.rb +3 -1
  90. data/lib/datadog/tracing/contrib/waterdrop/patcher.rb +6 -3
  91. data/lib/datadog/tracing/diagnostics/environment_logger.rb +1 -1
  92. data/lib/datadog/tracing/remote.rb +1 -9
  93. data/lib/datadog/tracing/span_event.rb +2 -2
  94. data/lib/datadog/tracing/span_operation.rb +9 -4
  95. data/lib/datadog/tracing/trace_operation.rb +44 -6
  96. data/lib/datadog/tracing/tracer.rb +42 -16
  97. data/lib/datadog/tracing/transport/http/traces.rb +2 -50
  98. data/lib/datadog/tracing/transport/http.rb +15 -9
  99. data/lib/datadog/tracing/transport/io/client.rb +1 -1
  100. data/lib/datadog/tracing/transport/traces.rb +6 -66
  101. data/lib/datadog/tracing/workers/trace_writer.rb +5 -0
  102. data/lib/datadog/tracing/writer.rb +1 -0
  103. data/lib/datadog/version.rb +2 -2
  104. metadata +7 -13
  105. data/lib/datadog/core/remote/transport/http/api.rb +0 -53
  106. data/lib/datadog/core/telemetry/transport/http/api.rb +0 -43
  107. data/lib/datadog/core/transport/http/api/spec.rb +0 -36
  108. data/lib/datadog/data_streams/transport/http/api.rb +0 -33
  109. data/lib/datadog/data_streams/transport/http/client.rb +0 -21
  110. data/lib/datadog/di/transport/http/api.rb +0 -42
  111. data/lib/datadog/opentelemetry/api/baggage.rbs +0 -26
  112. data/lib/datadog/tracing/transport/http/api.rb +0 -44
@@ -2,11 +2,10 @@
2
2
 
3
3
  require 'json'
4
4
 
5
- require_relative '../../../transport/http/client'
5
+ require_relative '../../../transport/http/api/endpoint'
6
+ require_relative '../../../transport/http/response'
6
7
  require_relative '../../../utils/base64'
7
8
  require_relative '../../../utils/truncation'
8
- require_relative '../../../transport/http/response'
9
- require_relative '../../../transport/http/api/endpoint'
10
9
 
11
10
  module Datadog
12
11
  module Core
@@ -17,7 +16,7 @@ module Datadog
17
16
  module Config
18
17
  # Response from HTTP transport for remote configuration
19
18
  class Response
20
- include Datadog::Core::Transport::HTTP::Response
19
+ include Core::Transport::HTTP::Response
21
20
 
22
21
  def initialize(http_response, options = {}) # standard:disable Metrics/AbcSize,Metrics/CyclomaticComplexity,Metrics/MethodLength,Metrics/PerceivedComplexity
23
22
  super(http_response)
@@ -101,7 +100,7 @@ module Datadog
101
100
 
102
101
  {
103
102
  path: h[:path].freeze,
104
- content: StringIO.new(content.freeze),
103
+ content: content.freeze,
105
104
  }
106
105
  end.freeze
107
106
 
@@ -178,46 +177,7 @@ module Datadog
178
177
  end
179
178
  end
180
179
 
181
- # Remote transport HTTP client
182
- class Client < Core::Transport::HTTP::Client
183
- def send_config_payload(request)
184
- send_request(request) do |api, env|
185
- api.send_config(env)
186
- end
187
- end
188
- end
189
-
190
180
  module API
191
- # Extensions for HTTP API Spec
192
- module Spec
193
- attr_reader :config
194
-
195
- def config=(endpoint)
196
- @config = endpoint
197
- end
198
-
199
- def send_config(env, &block)
200
- raise Core::Transport::HTTP::API::Spec::EndpointNotDefinedError.new('config', self) if config.nil?
201
-
202
- config.call(env, &block)
203
- end
204
- end
205
-
206
- # Extensions for HTTP API Instance
207
- module Instance
208
- def send_config(env)
209
- unless spec.is_a?(Config::API::Spec)
210
- raise Core::Transport::HTTP::API::Instance::EndpointNotSupportedError.new(
211
- 'config', self
212
- )
213
- end
214
-
215
- spec.send_config(env) do |request_env|
216
- call(request_env)
217
- end
218
- end
219
- end
220
-
221
181
  # Endpoint for remote configuration
222
182
  class Endpoint < Datadog::Core::Transport::HTTP::API::Endpoint
223
183
  HEADER_CONTENT_TYPE = 'Content-Type'
@@ -43,46 +43,7 @@ module Datadog
43
43
  attr_reader :version, :endpoints, :config, :span_events
44
44
  end
45
45
 
46
- # Remote negotiation HTTP client
47
- class Client < Core::Transport::HTTP::Client
48
- def send_info_payload(request)
49
- send_request(request) do |api, env|
50
- api.send_info(env)
51
- end
52
- end
53
- end
54
-
55
46
  module API
56
- # Extensions for HTTP API Spec
57
- module Spec
58
- attr_reader :info
59
-
60
- def info=(endpoint)
61
- @info = endpoint
62
- end
63
-
64
- def send_info(env, &block)
65
- raise Core::Transport::HTTP::API::Spec::EndpointNotDefinedError.new('info', self) if info.nil?
66
-
67
- info.call(env, &block)
68
- end
69
- end
70
-
71
- # Extensions for HTTP API Instance
72
- module Instance
73
- def send_info(env)
74
- unless spec.is_a?(Negotiation::API::Spec)
75
- raise Core::Transport::HTTP::API::Instance::EndpointNotSupportedError.new(
76
- 'info', self
77
- )
78
- end
79
-
80
- spec.send_info(env) do |request_env|
81
- call(request_env)
82
- end
83
- end
84
- end
85
-
86
47
  # Endpoint for negotiation
87
48
  class Endpoint < Datadog::Core::Transport::HTTP::API::Endpoint
88
49
  def initialize(path)
@@ -7,16 +7,6 @@ require_relative '../../transport/http'
7
7
  require_relative 'config'
8
8
  require_relative 'negotiation'
9
9
 
10
- # TODO: Improve negotiation to allow per endpoint selection
11
- #
12
- # Since endpoint negotiation happens at the `API::Spec` level there can not be
13
- # a mix of endpoints at various versions or versionless without describing all
14
- # the possible combinations as specs. See http/api.
15
- #
16
- # Below should be:
17
- # require_relative '../../transport/http/api'
18
- require_relative 'http/api'
19
-
20
10
  # TODO: Decouple transport/http
21
11
  #
22
12
  # Because a new transport is required for every (API, Client, Transport)
@@ -29,26 +19,30 @@ module Datadog
29
19
  module Transport
30
20
  # Namespace for HTTP transport components
31
21
  module HTTP
22
+ ROOT = Negotiation::API::Endpoint.new(
23
+ '/info',
24
+ )
25
+
26
+ V7 = Config::API::Endpoint.new(
27
+ '/v0.7/config',
28
+ Core::Encoding::JSONEncoder,
29
+ )
30
+
32
31
  module_function
33
32
 
34
33
  # Builds a new Transport::HTTP::Client with default settings
35
34
  # Pass a block to override any settings.
36
35
  def root(
37
36
  agent_settings:,
38
- logger: Datadog.logger,
39
- api_version: nil,
37
+ logger:,
40
38
  headers: nil
41
39
  )
42
40
  Core::Transport::HTTP.build(
43
- api_instance_class: API::Instance,
44
41
  agent_settings: agent_settings,
45
42
  logger: logger,
46
- api_version: api_version,
47
43
  headers: headers
48
44
  ) do |transport|
49
- apis = API.defaults
50
-
51
- transport.api API::ROOT, apis[API::ROOT]
45
+ transport.api 'root', ROOT
52
46
 
53
47
  # Call block to apply any customization, if provided
54
48
  yield(transport) if block_given?
@@ -59,20 +53,15 @@ module Datadog
59
53
  # Pass a block to override any settings.
60
54
  def v7(
61
55
  agent_settings:,
62
- logger: Datadog.logger,
63
- api_version: nil,
56
+ logger:,
64
57
  headers: nil
65
58
  )
66
59
  Core::Transport::HTTP.build(
67
- api_instance_class: API::Instance,
68
60
  agent_settings: agent_settings,
69
61
  logger: logger,
70
- api_version: api_version,
71
62
  headers: headers
72
63
  ) do |transport|
73
- apis = API.defaults
74
-
75
- transport.api API::V7, apis[API::V7]
64
+ transport.api 'v7', V7
76
65
 
77
66
  # Call block to apply any customization, if provided
78
67
  yield(transport) if block_given?
@@ -1,6 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require_relative '../../../core/transport/request'
4
+ require_relative '../../../core/transport/transport'
4
5
  require_relative 'http/negotiation'
5
6
 
6
7
  # TODO: Resolve conceptual conundrum
@@ -32,24 +33,14 @@ module Datadog
32
33
  end
33
34
 
34
35
  # Negotiation transport
35
- class Transport
36
- attr_reader :client, :apis, :default_api, :current_api_id, :logger
37
-
38
- def initialize(apis, default_api, logger: Datadog.logger)
39
- @apis = apis
40
- @logger = logger
41
-
42
- @client = Remote::Transport::HTTP::Negotiation::Client.new(current_api, logger: logger)
43
- end
44
-
45
- def send_info
36
+ class Transport < Core::Transport::Transport
37
+ # TODO steep is complaining about this method, I tried to make
38
+ # it work but between module inclusions and steep diagnostics
39
+ # I don't understand what the problem is or what the steep wants.
40
+ def send_info # steep:ignore
46
41
  request = Request.new
47
42
 
48
- @client.send_info_payload(request)
49
- end
50
-
51
- def current_api
52
- @apis[HTTP::API::ROOT]
43
+ @client.send_request(:info, request)
53
44
  end
54
45
  end
55
46
  end
@@ -14,14 +14,26 @@ require_relative '../utils/forking'
14
14
  module Datadog
15
15
  module Core
16
16
  module Telemetry
17
- # Telemetry entrypoint, coordinates sending telemetry events at various points in app lifecycle.
18
- # Note: Telemetry does not spawn its worker thread in fork processes, thus no telemetry is sent in forked processes.
17
+ # Telemetry entry point, coordinates sending telemetry events at
18
+ # various points in application lifecycle.
19
19
  #
20
20
  # @api private
21
21
  class Component
22
22
  ENDPOINT_COLLECTION_MESSAGE_LIMIT = 300
23
23
 
24
- attr_reader :enabled, :logger, :transport, :worker
24
+ ONLY_ONCE = Utils::OnlyOnce.new
25
+
26
+ attr_reader :enabled
27
+ attr_reader :logger
28
+ attr_reader :transport
29
+ attr_reader :worker
30
+ attr_reader :settings
31
+ attr_reader :agent_settings
32
+ attr_reader :metrics_manager
33
+
34
+ # Alias for consistency with other components.
35
+ # TODO Remove +enabled+ method
36
+ alias_method :enabled?, :enabled
25
37
 
26
38
  include Core::Utils::Forking
27
39
  include Telemetry::Logging
@@ -50,6 +62,17 @@ module Datadog
50
62
  logger:,
51
63
  enabled:
52
64
  )
65
+ ONLY_ONCE.run do
66
+ Utils::AtForkMonkeyPatch.apply!
67
+
68
+ # All of the other at fork monkey patch callbacks reference
69
+ # globals, follow that pattern here to avoid having the component
70
+ # referenced via the at fork callbacks.
71
+ Datadog::Core::Utils::AtForkMonkeyPatch.at_fork(:child) do
72
+ Datadog.send(:components, allow_initialization: false)&.telemetry&.after_fork
73
+ end
74
+ end
75
+
53
76
  @enabled = enabled
54
77
  @log_collection_enabled = settings.telemetry.log_collection_enabled
55
78
  @logger = logger
@@ -110,7 +133,7 @@ module Datadog
110
133
  end
111
134
 
112
135
  def start(initial_event_is_change = false, components:)
113
- return if !@enabled
136
+ return unless enabled?
114
137
 
115
138
  initial_event = if initial_event_is_change
116
139
  Event::SynthAppClientConfigurationChange.new(
@@ -136,44 +159,44 @@ module Datadog
136
159
  end
137
160
 
138
161
  def emit_closing!
139
- return if !@enabled || forked?
162
+ return unless enabled?
140
163
 
141
164
  @worker.enqueue(Event::AppClosing.new)
142
165
  end
143
166
 
144
167
  def integrations_change!
145
- return if !@enabled || forked?
168
+ return unless enabled?
146
169
 
147
170
  @worker.enqueue(Event::AppIntegrationsChange.new)
148
171
  end
149
172
 
150
173
  def log!(event)
151
- return if !@enabled || forked? || !@log_collection_enabled
174
+ return unless enabled? && @log_collection_enabled
152
175
 
153
176
  @worker.enqueue(event)
154
177
  end
155
178
 
156
179
  # Wait for the worker to send out all events that have already
157
180
  # been queued, up to 15 seconds. Returns whether all events have
158
- # been flushed.
181
+ # been flushed, or nil if telemetry is disabled.
159
182
  #
160
183
  # @api private
161
- def flush
162
- return if !@enabled || forked?
184
+ def flush(timeout: nil)
185
+ return unless enabled?
163
186
 
164
- @worker.flush
187
+ @worker.flush(timeout: timeout)
165
188
  end
166
189
 
167
190
  # Report configuration changes caused by Remote Configuration.
168
191
  def client_configuration_change!(changes)
169
- return if !@enabled || forked?
192
+ return unless enabled?
170
193
 
171
194
  @worker.enqueue(Event::AppClientConfigurationChange.new(changes, 'remote_config'))
172
195
  end
173
196
 
174
197
  # Report application endpoints
175
198
  def app_endpoints_loaded(endpoints, page_size: ENDPOINT_COLLECTION_MESSAGE_LIMIT)
176
- return if !@enabled || forked?
199
+ return unless enabled?
177
200
 
178
201
  endpoints.each_slice(page_size).with_index do |endpoints_slice, i|
179
202
  @worker.enqueue(Event::AppEndpointsLoaded.new(endpoints_slice, is_first: i.zero?))
@@ -204,6 +227,22 @@ module Datadog
204
227
  def distribution(namespace, metric_name, value, tags: {}, common: true)
205
228
  @metrics_manager.distribution(namespace, metric_name, value, tags: tags, common: common)
206
229
  end
230
+
231
+ # When a fork happens, we generally need to do two things inside the
232
+ # child proess:
233
+ # 1. Restart the worker.
234
+ # 2. Discard any events and metrics that were submitted in the
235
+ # parent process (because they will be sent out in the parent
236
+ # process, sending them in the child would cause duplicate
237
+ # submission).
238
+ def after_fork
239
+ # We cannot simply create a new instance of metrics manager because
240
+ # it is referenced from other objects (e.g. the worker).
241
+ # We must reset the existing instance.
242
+ @metrics_manager.clear
243
+
244
+ worker&.send(:after_fork_monkey_patched)
245
+ end
207
246
  end
208
247
  end
209
248
  end
@@ -11,6 +11,12 @@ module Datadog
11
11
  def initialize(components:)
12
12
  # To not hold a reference to the component tree, generate
13
13
  # the event payload here in the constructor.
14
+ #
15
+ # Important: do not store data that contains (or is derived from)
16
+ # the runtime_id or sequence numbers.
17
+ # This event is reused when a process forks, but in the
18
+ # child process the runtime_id would be different and sequence
19
+ # number is reset.
14
20
  @configuration = configuration(components.settings, components.agent_settings)
15
21
  @install_signature = install_signature(components.settings)
16
22
  @products = products(components)
@@ -30,6 +36,15 @@ module Datadog
30
36
  }
31
37
  end
32
38
 
39
+ # Whether the event is actually the app-started event.
40
+ # For the app-started event we follow up by sending
41
+ # app-dependencies-loaded, if the event is
42
+ # app-client-configuration-change we don't send
43
+ # app-dependencies-loaded.
44
+ def app_started?
45
+ true
46
+ end
47
+
33
48
  private
34
49
 
35
50
  def products(components)
@@ -159,6 +174,25 @@ module Datadog
159
174
  get_telemetry_origin(settings, 'tracing.contrib.peer_service_mapping')
160
175
  )
161
176
 
177
+ # OpenTelemetry configuration options (using environment variable names)
178
+ otel_exporter_headers_string = settings.opentelemetry.exporter.headers&.map { |key, value| "#{key}=#{value}" }&.join(',')
179
+ otel_exporter_metrics_headers_string = settings.opentelemetry.metrics.headers&.map { |key, value| "#{key}=#{value}" }&.join(',')
180
+ list.push(
181
+ conf_value('OTEL_EXPORTER_OTLP_ENDPOINT', settings.opentelemetry.exporter.endpoint, seq_id, get_telemetry_origin(settings, 'opentelemetry.exporter.endpoint')),
182
+ conf_value('OTEL_EXPORTER_OTLP_HEADERS', otel_exporter_headers_string, seq_id, get_telemetry_origin(settings, 'opentelemetry.exporter.headers')),
183
+ conf_value('OTEL_EXPORTER_OTLP_PROTOCOL', settings.opentelemetry.exporter.protocol, seq_id, get_telemetry_origin(settings, 'opentelemetry.exporter.protocol')),
184
+ conf_value('OTEL_EXPORTER_OTLP_TIMEOUT', settings.opentelemetry.exporter.timeout_millis, seq_id, get_telemetry_origin(settings, 'opentelemetry.exporter.timeout_millis')),
185
+ conf_value('DD_METRICS_OTEL_ENABLED', settings.opentelemetry.metrics.enabled, seq_id, get_telemetry_origin(settings, 'opentelemetry.metrics.enabled')),
186
+ conf_value('OTEL_METRICS_EXPORTER', settings.opentelemetry.metrics.exporter, seq_id, get_telemetry_origin(settings, 'opentelemetry.metrics.exporter')),
187
+ conf_value('OTEL_EXPORTER_OTLP_METRICS_ENDPOINT', settings.opentelemetry.metrics.endpoint, seq_id, get_telemetry_origin(settings, 'opentelemetry.metrics.endpoint')),
188
+ conf_value('OTEL_EXPORTER_OTLP_METRICS_HEADERS', otel_exporter_metrics_headers_string, seq_id, get_telemetry_origin(settings, 'opentelemetry.metrics.headers')),
189
+ conf_value('OTEL_EXPORTER_OTLP_METRICS_PROTOCOL', settings.opentelemetry.metrics.protocol, seq_id, get_telemetry_origin(settings, 'opentelemetry.metrics.protocol')),
190
+ conf_value('OTEL_EXPORTER_OTLP_METRICS_TIMEOUT', settings.opentelemetry.metrics.timeout_millis, seq_id, get_telemetry_origin(settings, 'opentelemetry.metrics.timeout_millis')),
191
+ conf_value('OTEL_EXPORTER_OTLP_METRICS_TEMPORALITY_PREFERENCE', settings.opentelemetry.metrics.temporality_preference, seq_id, get_telemetry_origin(settings, 'opentelemetry.metrics.temporality_preference')),
192
+ conf_value('OTEL_METRIC_EXPORT_INTERVAL', settings.opentelemetry.metrics.export_interval_millis, seq_id, get_telemetry_origin(settings, 'opentelemetry.metrics.export_interval_millis')),
193
+ conf_value('OTEL_METRIC_EXPORT_TIMEOUT', settings.opentelemetry.metrics.export_timeout_millis, seq_id, get_telemetry_origin(settings, 'opentelemetry.metrics.export_timeout_millis')),
194
+ )
195
+
162
196
  # Whitelist of configuration options to send in additional payload object
163
197
  TARGET_OPTIONS.each do |option_path|
164
198
  split_option = option_path.split('.')
@@ -28,13 +28,36 @@ module Datadog
28
28
  # and app-closing events.
29
29
  class SynthAppClientConfigurationChange < AppStarted
30
30
  def type
31
- 'app-client-configuration-change'
31
+ if reset?
32
+ super
33
+ else
34
+ 'app-client-configuration-change'
35
+ end
32
36
  end
33
37
 
34
38
  def payload
35
- {
36
- configuration: @configuration,
37
- }
39
+ if reset?
40
+ super
41
+ else
42
+ {
43
+ configuration: @configuration,
44
+ }
45
+ end
46
+ end
47
+
48
+ def app_started?
49
+ reset?
50
+ end
51
+
52
+ # Revert this event to a "regular" AppStarted event.
53
+ #
54
+ # Used in after_fork to send the AppStarted event in child processes.
55
+ def reset!
56
+ @reset = true
57
+ end
58
+
59
+ def reset?
60
+ defined?(@reset) && !!@reset
38
61
  end
39
62
  end
40
63
  end
@@ -6,8 +6,11 @@ module Datadog
6
6
  module Core
7
7
  module Telemetry
8
8
  # MetricsManager aggregates and flushes metrics and distributions
9
+ #
10
+ # @api private
9
11
  class MetricsManager
10
12
  attr_reader :enabled
13
+ attr_reader :collections
11
14
 
12
15
  def initialize(aggregation_interval:, enabled:)
13
16
  @interval = aggregation_interval
@@ -68,6 +71,12 @@ module Datadog
68
71
  @enabled = false
69
72
  end
70
73
 
74
+ def clear
75
+ @mutex.synchronize do
76
+ @collections = {}
77
+ end
78
+ end
79
+
71
80
  private
72
81
 
73
82
  def fetch_or_create_collection(namespace)
@@ -1,6 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require_relative '../environment/platform'
4
+ require_relative '../environment/process'
4
5
  require_relative '../utils/hash'
5
6
 
6
7
  module Datadog
@@ -11,9 +12,9 @@ module Datadog
11
12
  class << self
12
13
  using Core::Utils::Hash::Refinement
13
14
 
14
- def build_payload(event, seq_id, api_version: 'v2', debug: false)
15
+ def build_payload(event, seq_id, debug: false)
15
16
  hash = {
16
- api_version: api_version,
17
+ api_version: 'v2',
17
18
  application: application,
18
19
  debug: debug,
19
20
  host: host,
@@ -43,7 +44,7 @@ module Datadog
43
44
  tracer_version = "#{tracer_version}-ci-#{::Datadog::CI::VERSION::STRING}"
44
45
  end
45
46
 
46
- {
47
+ app = {
47
48
  env: config.env,
48
49
  language_name: Core::Environment::Ext::LANG,
49
50
  language_version: Core::Environment::Ext::LANG_VERSION,
@@ -53,6 +54,10 @@ module Datadog
53
54
  service_version: config.version,
54
55
  tracer_version: tracer_version
55
56
  }
57
+
58
+ tag_process_tags!(app, config)
59
+
60
+ app
56
61
  end
57
62
 
58
63
  def host
@@ -64,6 +69,15 @@ module Datadog
64
69
  kernel_version: Core::Environment::Platform.kernel_version
65
70
  }
66
71
  end
72
+
73
+ def tag_process_tags!(app, config)
74
+ return unless config.experimental_propagate_process_tags_enabled
75
+
76
+ process_tags = Core::Environment::Process.serialized
77
+ return if process_tags.empty?
78
+
79
+ app[:process_tags] = process_tags
80
+ end
67
81
  end
68
82
  end
69
83
  end
@@ -2,7 +2,6 @@
2
2
 
3
3
  require_relative '../../../transport/http/api/endpoint'
4
4
  require_relative '../../../transport/http/api/instance'
5
- require_relative '../../../transport/http/api/spec'
6
5
  require_relative '../../../transport/http/client'
7
6
  require_relative '../../../transport/request'
8
7
 
@@ -12,36 +11,7 @@ module Datadog
12
11
  module Transport
13
12
  module HTTP
14
13
  module Telemetry
15
- class Client < Core::Transport::HTTP::Client
16
- def send_telemetry_payload(request)
17
- send_request(request) do |api, env|
18
- # TODO how to make api have the derived type for steep?
19
- api.send_telemetry(env) # steep:ignore
20
- end
21
- end
22
- end
23
-
24
14
  module API
25
- class Instance < Core::Transport::HTTP::API::Instance
26
- def send_telemetry(env)
27
- raise Core::Transport::HTTP::API::Instance::EndpointNotSupportedError.new('telemetry', self) unless spec.is_a?(Telemetry::API::Spec)
28
-
29
- spec.send_telemetry(env) do |request_env|
30
- call(request_env)
31
- end
32
- end
33
- end
34
-
35
- class Spec < Core::Transport::HTTP::API::Spec
36
- attr_accessor :telemetry
37
-
38
- def send_telemetry(env, &block)
39
- raise Core::Transport::HTTP::API::Spec::EndpointNotDefinedError.new('telemetry', self) if telemetry.nil?
40
-
41
- telemetry.call(env, &block)
42
- end
43
- end
44
-
45
15
  class Endpoint < Datadog::Core::Transport::HTTP::API::Endpoint
46
16
  HEADER_CONTENT_TYPE = 'Content-Type'
47
17
 
@@ -65,12 +35,12 @@ module Datadog
65
35
  super
66
36
  end
67
37
 
68
- def headers(request_type:, api_key:, api_version: 'v2')
38
+ def headers(request_type:, api_key:)
69
39
  {
70
40
  Core::Transport::Ext::HTTP::HEADER_DD_INTERNAL_UNTRACED_REQUEST => '1',
71
41
  # Provided by encoder
72
42
  # 'Content-Type' => 'application/json',
73
- 'DD-Telemetry-API-Version' => api_version,
43
+ 'DD-Telemetry-API-Version' => 'v2',
74
44
  'DD-Telemetry-Request-Type' => request_type,
75
45
  'DD-Client-Library-Language' => Core::Environment::Ext::LANG,
76
46
  'DD-Client-Library-Version' => Core::Environment::Identity.gem_datadog_version_semver2,