datadog 2.12.2 → 2.13.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 (113) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +36 -1
  3. data/ext/datadog_profiling_native_extension/collectors_thread_context.c +14 -13
  4. data/lib/datadog/appsec/actions_handler/serializable_backtrace.rb +89 -0
  5. data/lib/datadog/appsec/actions_handler.rb +22 -1
  6. data/lib/datadog/appsec/anonymizer.rb +16 -0
  7. data/lib/datadog/appsec/configuration/settings.rb +62 -10
  8. data/lib/datadog/appsec/contrib/auto_instrument.rb +1 -1
  9. data/lib/datadog/appsec/contrib/devise/configuration.rb +7 -31
  10. data/lib/datadog/appsec/contrib/devise/data_extractor.rb +79 -0
  11. data/lib/datadog/appsec/contrib/devise/ext.rb +21 -0
  12. data/lib/datadog/appsec/contrib/devise/integration.rb +0 -1
  13. data/lib/datadog/appsec/contrib/devise/patcher.rb +36 -23
  14. data/lib/datadog/appsec/contrib/devise/patches/signin_tracking_patch.rb +102 -0
  15. data/lib/datadog/appsec/contrib/devise/patches/signup_tracking_patch.rb +69 -0
  16. data/lib/datadog/appsec/contrib/devise/{patcher/rememberable_patch.rb → patches/skip_signin_tracking_patch.rb} +2 -2
  17. data/lib/datadog/appsec/contrib/devise/tracking_middleware.rb +93 -0
  18. data/lib/datadog/appsec/contrib/rack/ext.rb +14 -0
  19. data/lib/datadog/appsec/contrib/rack/gateway/watcher.rb +10 -3
  20. data/lib/datadog/appsec/contrib/rack/request_middleware.rb +0 -2
  21. data/lib/datadog/appsec/event.rb +1 -1
  22. data/lib/datadog/appsec/ext.rb +4 -2
  23. data/lib/datadog/appsec/instrumentation/gateway/argument.rb +4 -2
  24. data/lib/datadog/appsec/monitor/gateway/watcher.rb +8 -3
  25. data/lib/datadog/appsec/security_engine/runner.rb +2 -2
  26. data/lib/datadog/appsec/utils.rb +0 -2
  27. data/lib/datadog/core/configuration/components.rb +2 -1
  28. data/lib/datadog/core/configuration/ext.rb +4 -0
  29. data/lib/datadog/core/configuration/options.rb +2 -2
  30. data/lib/datadog/core/configuration/settings.rb +53 -30
  31. data/lib/datadog/core/environment/agent_info.rb +4 -3
  32. data/lib/datadog/core/remote/component.rb +3 -6
  33. data/lib/datadog/core/remote/configuration/repository.rb +2 -1
  34. data/lib/datadog/core/remote/negotiation.rb +9 -9
  35. data/lib/datadog/core/remote/transport/config.rb +4 -3
  36. data/lib/datadog/core/remote/transport/http/client.rb +4 -3
  37. data/lib/datadog/core/remote/transport/http/config.rb +6 -32
  38. data/lib/datadog/core/remote/transport/http/negotiation.rb +6 -32
  39. data/lib/datadog/core/remote/transport/http.rb +22 -57
  40. data/lib/datadog/core/remote/transport/negotiation.rb +4 -3
  41. data/lib/datadog/core/runtime/metrics.rb +8 -1
  42. data/lib/datadog/core/telemetry/http/adapters/net.rb +1 -1
  43. data/lib/datadog/core/transport/http/api/instance.rb +17 -0
  44. data/lib/datadog/core/transport/http/api/spec.rb +17 -0
  45. data/lib/datadog/core/transport/http/builder.rb +5 -3
  46. data/lib/datadog/core/transport/http.rb +39 -2
  47. data/lib/datadog/di/component.rb +0 -2
  48. data/lib/datadog/di/probe_notifier_worker.rb +16 -16
  49. data/lib/datadog/di/transport/diagnostics.rb +4 -3
  50. data/lib/datadog/di/transport/http/api.rb +2 -12
  51. data/lib/datadog/di/transport/http/client.rb +4 -3
  52. data/lib/datadog/di/transport/http/diagnostics.rb +7 -33
  53. data/lib/datadog/di/transport/http/input.rb +7 -33
  54. data/lib/datadog/di/transport/http.rb +14 -56
  55. data/lib/datadog/di/transport/input.rb +4 -3
  56. data/lib/datadog/di/utils.rb +5 -0
  57. data/lib/datadog/kit/appsec/events.rb +9 -0
  58. data/lib/datadog/kit/identity.rb +5 -1
  59. data/lib/datadog/opentelemetry/api/baggage.rb +90 -0
  60. data/lib/datadog/opentelemetry/api/baggage.rbs +26 -0
  61. data/lib/datadog/opentelemetry/api/context.rb +16 -2
  62. data/lib/datadog/opentelemetry/sdk/trace/span.rb +1 -1
  63. data/lib/datadog/opentelemetry.rb +2 -1
  64. data/lib/datadog/profiling/collectors/thread_context.rb +1 -1
  65. data/lib/datadog/profiling.rb +5 -2
  66. data/lib/datadog/tracing/component.rb +15 -12
  67. data/lib/datadog/tracing/configuration/ext.rb +7 -1
  68. data/lib/datadog/tracing/configuration/settings.rb +18 -2
  69. data/lib/datadog/tracing/context_provider.rb +1 -1
  70. data/lib/datadog/tracing/contrib/configuration/settings.rb +1 -1
  71. data/lib/datadog/tracing/contrib/ethon/easy_patch.rb +4 -5
  72. data/lib/datadog/tracing/contrib/excon/middleware.rb +5 -3
  73. data/lib/datadog/tracing/contrib/faraday/middleware.rb +5 -3
  74. data/lib/datadog/tracing/contrib/grpc/datadog_interceptor/client.rb +7 -1
  75. data/lib/datadog/tracing/contrib/grpc/distributed/propagation.rb +3 -0
  76. data/lib/datadog/tracing/contrib/http/circuit_breaker.rb +0 -15
  77. data/lib/datadog/tracing/contrib/http/distributed/propagation.rb +4 -1
  78. data/lib/datadog/tracing/contrib/http/instrumentation.rb +5 -5
  79. data/lib/datadog/tracing/contrib/httpclient/instrumentation.rb +5 -11
  80. data/lib/datadog/tracing/contrib/httprb/instrumentation.rb +6 -10
  81. data/lib/datadog/tracing/contrib/rest_client/request_patch.rb +5 -3
  82. data/lib/datadog/tracing/contrib/sidekiq/client_tracer.rb +6 -1
  83. data/lib/datadog/tracing/contrib/sidekiq/distributed/propagation.rb +3 -0
  84. data/lib/datadog/tracing/correlation.rb +9 -2
  85. data/lib/datadog/tracing/distributed/baggage.rb +131 -0
  86. data/lib/datadog/tracing/distributed/datadog.rb +2 -0
  87. data/lib/datadog/tracing/distributed/propagation.rb +25 -4
  88. data/lib/datadog/tracing/distributed/propagation_policy.rb +42 -0
  89. data/lib/datadog/tracing/metadata/ext.rb +5 -0
  90. data/lib/datadog/tracing/sampling/span/rule.rb +0 -1
  91. data/lib/datadog/tracing/span_operation.rb +2 -1
  92. data/lib/datadog/tracing/sync_writer.rb +1 -2
  93. data/lib/datadog/tracing/trace_digest.rb +9 -2
  94. data/lib/datadog/tracing/trace_operation.rb +29 -17
  95. data/lib/datadog/tracing/trace_segment.rb +6 -4
  96. data/lib/datadog/tracing/tracer.rb +38 -2
  97. data/lib/datadog/tracing/transport/http/api.rb +2 -10
  98. data/lib/datadog/tracing/transport/http/client.rb +5 -4
  99. data/lib/datadog/tracing/transport/http/traces.rb +13 -41
  100. data/lib/datadog/tracing/transport/http.rb +11 -44
  101. data/lib/datadog/tracing/transport/trace_formatter.rb +7 -0
  102. data/lib/datadog/tracing/transport/traces.rb +21 -9
  103. data/lib/datadog/tracing/workers/trace_writer.rb +2 -6
  104. data/lib/datadog/tracing/writer.rb +2 -6
  105. data/lib/datadog/tracing.rb +16 -3
  106. data/lib/datadog/version.rb +2 -2
  107. metadata +17 -13
  108. data/lib/datadog/appsec/contrib/devise/event.rb +0 -54
  109. data/lib/datadog/appsec/contrib/devise/patcher/authenticatable_patch.rb +0 -72
  110. data/lib/datadog/appsec/contrib/devise/patcher/registration_controller_patch.rb +0 -47
  111. data/lib/datadog/appsec/contrib/devise/resource.rb +0 -35
  112. data/lib/datadog/appsec/contrib/devise/tracking.rb +0 -57
  113. data/lib/datadog/appsec/utils/trace_operation.rb +0 -15
@@ -7,11 +7,11 @@ module Datadog
7
7
  module Remote
8
8
  # Endpoint negotiation
9
9
  class Negotiation
10
- def initialize(_settings, agent_settings, suppress_logging: {})
11
- transport_options = {}
12
- transport_options[:agent_settings] = agent_settings if agent_settings
10
+ attr_reader :logger
13
11
 
14
- @transport_root = Datadog::Core::Remote::Transport::HTTP.root(**transport_options) # steep:ignore
12
+ def initialize(_settings, agent_settings, logger:, suppress_logging: {})
13
+ @logger = logger
14
+ @transport_root = Datadog::Core::Remote::Transport::HTTP.root(agent_settings: agent_settings, logger: logger)
15
15
  @logged = suppress_logging
16
16
  end
17
17
 
@@ -20,7 +20,7 @@ module Datadog
20
20
 
21
21
  if res.internal_error? && network_error?(res.error)
22
22
  unless @logged[:agent_unreachable]
23
- Datadog.logger.warn { "agent unreachable: cannot negotiate #{path}" }
23
+ logger.warn { "agent unreachable: cannot negotiate #{path}" }
24
24
  @logged[:agent_unreachable] = true
25
25
  end
26
26
 
@@ -29,7 +29,7 @@ module Datadog
29
29
 
30
30
  if res.not_found?
31
31
  unless @logged[:no_info_endpoint]
32
- Datadog.logger.warn { "agent reachable but has no /info endpoint: cannot negotiate #{path}" }
32
+ logger.warn { "agent reachable but has no /info endpoint: cannot negotiate #{path}" }
33
33
  @logged[:no_info_endpoint] = true
34
34
  end
35
35
 
@@ -38,7 +38,7 @@ module Datadog
38
38
 
39
39
  unless res.ok?
40
40
  unless @logged[:unexpected_response]
41
- Datadog.logger.warn { "agent reachable but unexpected response: cannot negotiate #{path}" }
41
+ logger.warn { "agent reachable but unexpected response: cannot negotiate #{path}" }
42
42
  @logged[:unexpected_response] = true
43
43
  end
44
44
 
@@ -47,14 +47,14 @@ module Datadog
47
47
 
48
48
  unless res.endpoints.include?(path)
49
49
  unless @logged[:no_config_endpoint]
50
- Datadog.logger.warn { "agent reachable but does not report #{path}" }
50
+ logger.warn { "agent reachable but does not report #{path}" }
51
51
  @logged[:no_config_endpoint] = true
52
52
  end
53
53
 
54
54
  return false
55
55
  end
56
56
 
57
- Datadog.logger.debug { "agent reachable and reports #{path}" }
57
+ logger.debug { "agent reachable and reports #{path}" }
58
58
 
59
59
  true
60
60
  end
@@ -32,12 +32,13 @@ module Datadog
32
32
 
33
33
  # Config transport
34
34
  class Transport
35
- attr_reader :client, :apis, :default_api, :current_api_id
35
+ attr_reader :client, :apis, :default_api, :current_api_id, :logger
36
36
 
37
- def initialize(apis, default_api)
37
+ def initialize(apis, default_api, logger)
38
38
  @apis = apis
39
+ @logger = logger
39
40
 
40
- @client = HTTP::Client.new(current_api)
41
+ @client = HTTP::Client.new(current_api, logger)
41
42
  end
42
43
 
43
44
  ##### there is only one transport! it's negotiation!
@@ -15,10 +15,11 @@ module Datadog
15
15
  module HTTP
16
16
  # Routes, encodes, and sends tracer data to the trace agent via HTTP.
17
17
  class Client
18
- attr_reader :api
18
+ attr_reader :api, :logger
19
19
 
20
- def initialize(api)
20
+ def initialize(api, logger)
21
21
  @api = api
22
+ @logger = logger
22
23
  end
23
24
 
24
25
  def send_request(request, &block)
@@ -32,7 +33,7 @@ module Datadog
32
33
  "Internal error during #{self.class.name} request. Cause: #{e.class.name} #{e.message} " \
33
34
  "Location: #{Array(e.backtrace).first}"
34
35
 
35
- Datadog.logger.debug(message)
36
+ logger.debug(message)
36
37
 
37
38
  Datadog::Core::Transport::InternalErrorResponse.new(e)
38
39
  end
@@ -177,51 +177,25 @@ module Datadog
177
177
  end
178
178
 
179
179
  def send_config(env, &block)
180
- raise NoConfigEndpointDefinedError, self if config.nil?
180
+ raise Core::Transport::HTTP::API::Spec::EndpointNotDefinedError.new('config', self) if config.nil?
181
181
 
182
182
  config.call(env, &block)
183
183
  end
184
-
185
- # Raised when traces sent but no traces endpoint is defined
186
- class NoConfigEndpointDefinedError < StandardError
187
- attr_reader :spec
188
-
189
- def initialize(spec)
190
- super()
191
-
192
- @spec = spec
193
- end
194
-
195
- def message
196
- 'No config endpoint is defined for API specification!'
197
- end
198
- end
199
184
  end
200
185
 
201
186
  # Extensions for HTTP API Instance
202
187
  module Instance
203
188
  def send_config(env)
204
- raise ConfigNotSupportedError, spec unless spec.is_a?(Config::API::Spec)
189
+ unless spec.is_a?(Config::API::Spec)
190
+ raise Core::Transport::HTTP::API::Instance::EndpointNotSupportedError.new(
191
+ 'config', self
192
+ )
193
+ end
205
194
 
206
195
  spec.send_config(env) do |request_env|
207
196
  call(request_env)
208
197
  end
209
198
  end
210
-
211
- # Raised when traces sent to API that does not support traces
212
- class ConfigNotSupportedError < StandardError
213
- attr_reader :spec
214
-
215
- def initialize(spec)
216
- super()
217
-
218
- @spec = spec
219
- end
220
-
221
- def message
222
- 'Config not supported for this API!'
223
- end
224
- end
225
199
  end
226
200
 
227
201
  # Endpoint for remote configuration
@@ -50,51 +50,25 @@ module Datadog
50
50
  end
51
51
 
52
52
  def send_info(env, &block)
53
- raise NoNegotiationEndpointDefinedError, self if info.nil?
53
+ raise Core::Transport::HTTP::API::Spec::EndpointNotDefinedError.new('info', self) if info.nil?
54
54
 
55
55
  info.call(env, &block)
56
56
  end
57
-
58
- # Raised when traces sent but no traces endpoint is defined
59
- class NoNegotiationEndpointDefinedError < StandardError
60
- attr_reader :spec
61
-
62
- def initialize(spec)
63
- super()
64
-
65
- @spec = spec
66
- end
67
-
68
- def message
69
- 'No info endpoint is defined for API specification!'
70
- end
71
- end
72
57
  end
73
58
 
74
59
  # Extensions for HTTP API Instance
75
60
  module Instance
76
61
  def send_info(env)
77
- raise NegotiationNotSupportedError, spec unless spec.is_a?(Negotiation::API::Spec)
62
+ unless spec.is_a?(Negotiation::API::Spec)
63
+ raise Core::Transport::HTTP::API::Instance::EndpointNotSupportedError.new(
64
+ 'info', self
65
+ )
66
+ end
78
67
 
79
68
  spec.send_info(env) do |request_env|
80
69
  call(request_env)
81
70
  end
82
71
  end
83
-
84
- # Raised when traces sent to API that does not support traces
85
- class NegotiationNotSupportedError < StandardError
86
- attr_reader :spec
87
-
88
- def initialize(spec)
89
- super()
90
-
91
- @spec = spec
92
- end
93
-
94
- def message
95
- 'Info not supported for this API!'
96
- end
97
- end
98
72
  end
99
73
 
100
74
  # Endpoint for negotiation
@@ -29,87 +29,52 @@ module Datadog
29
29
  module HTTP
30
30
  module_function
31
31
 
32
- # Builds a new Transport::HTTP::Client
33
- def new(klass, &block)
34
- Core::Transport::HTTP.build(
35
- api_instance_class: API::Instance, &block
36
- ).to_transport(klass)
37
- end
38
-
39
32
  # Builds a new Transport::HTTP::Client with default settings
40
33
  # Pass a block to override any settings.
41
34
  def root(
42
35
  agent_settings:,
43
- **options
36
+ logger:,
37
+ api_version: nil,
38
+ headers: nil
44
39
  )
45
- new(Core::Remote::Transport::Negotiation::Transport) do |transport|
46
- transport.adapter(agent_settings)
47
- transport.headers(default_headers)
48
-
40
+ Core::Transport::HTTP.build(
41
+ api_instance_class: API::Instance,
42
+ agent_settings: agent_settings,
43
+ logger: logger,
44
+ api_version: api_version,
45
+ headers: headers
46
+ ) do |transport|
49
47
  apis = API.defaults
50
48
 
51
49
  transport.api API::ROOT, apis[API::ROOT]
52
50
 
53
- # Apply any settings given by options
54
- unless options.empty?
55
- transport.default_api = options[:api_version] if options.key?(:api_version)
56
- transport.headers options[:headers] if options.key?(:headers)
57
- end
58
-
59
51
  # Call block to apply any customization, if provided
60
52
  yield(transport) if block_given?
61
- end
53
+ end.to_transport(Core::Remote::Transport::Negotiation::Transport)
62
54
  end
63
55
 
64
56
  # Builds a new Transport::HTTP::Client with default settings
65
57
  # Pass a block to override any settings.
66
58
  def v7(
67
59
  agent_settings:,
68
- **options
60
+ logger:,
61
+ api_version: nil,
62
+ headers: nil
69
63
  )
70
- new(Core::Remote::Transport::Config::Transport) do |transport|
71
- transport.adapter(agent_settings)
72
- transport.headers default_headers
73
-
64
+ Core::Transport::HTTP.build(
65
+ api_instance_class: API::Instance,
66
+ agent_settings: agent_settings,
67
+ logger: logger,
68
+ api_version: api_version,
69
+ headers: headers
70
+ ) do |transport|
74
71
  apis = API.defaults
75
72
 
76
73
  transport.api API::V7, apis[API::V7]
77
74
 
78
- # Apply any settings given by options
79
- unless options.empty?
80
- transport.default_api = options[:api_version] if options.key?(:api_version)
81
- transport.headers options[:headers] if options.key?(:headers)
82
- end
83
-
84
75
  # Call block to apply any customization, if provided
85
76
  yield(transport) if block_given?
86
- end
87
- end
88
-
89
- def default_headers
90
- {
91
- Datadog::Core::Transport::Ext::HTTP::HEADER_CLIENT_COMPUTED_TOP_LEVEL => '1',
92
- Datadog::Core::Transport::Ext::HTTP::HEADER_META_LANG => Datadog::Core::Environment::Ext::LANG,
93
- Datadog::Core::Transport::Ext::HTTP::HEADER_META_LANG_VERSION =>
94
- Datadog::Core::Environment::Ext::LANG_VERSION,
95
- Datadog::Core::Transport::Ext::HTTP::HEADER_META_LANG_INTERPRETER =>
96
- Datadog::Core::Environment::Ext::LANG_INTERPRETER,
97
- Datadog::Core::Transport::Ext::HTTP::HEADER_META_TRACER_VERSION =>
98
- Datadog::Core::Environment::Ext::GEM_DATADOG_VERSION
99
- }.tap do |headers|
100
- # Add container ID, if present.
101
- container_id = Datadog::Core::Environment::Container.container_id
102
- headers[Datadog::Core::Transport::Ext::HTTP::HEADER_CONTAINER_ID] = container_id unless container_id.nil?
103
- # Sending this header to the agent will disable metrics computation (and billing) on the agent side
104
- # by pretending it has already been done on the library side.
105
- if Datadog.configuration.appsec.standalone.enabled
106
- headers[Datadog::Core::Transport::Ext::HTTP::HEADER_CLIENT_COMPUTED_STATS] = 'yes'
107
- end
108
- end
109
- end
110
-
111
- def default_adapter
112
- Datadog::Core::Configuration::Ext::Agent::HTTP::ADAPTER
77
+ end.to_transport(Core::Remote::Transport::Config::Transport)
113
78
  end
114
79
  end
115
80
  end
@@ -49,12 +49,13 @@ module Datadog
49
49
 
50
50
  # Negotiation transport
51
51
  class Transport
52
- attr_reader :client, :apis, :default_api, :current_api_id
52
+ attr_reader :client, :apis, :default_api, :current_api_id, :logger
53
53
 
54
- def initialize(apis, default_api)
54
+ def initialize(apis, default_api, logger)
55
55
  @apis = apis
56
+ @logger = logger
56
57
 
57
- @client = HTTP::Client.new(current_api)
58
+ @client = HTTP::Client.new(current_api, logger)
58
59
  end
59
60
 
60
61
  def send_info
@@ -21,6 +21,9 @@ module Datadog
21
21
  @services = Set.new(options.fetch(:services, []))
22
22
  @service_tags = nil
23
23
  compile_service_tags!
24
+
25
+ # Initialize the collection of runtime-id
26
+ @runtime_id_enabled = options.fetch(:experimental_runtime_id_enabled, false)
24
27
  end
25
28
 
26
29
  # Associate service with runtime metrics
@@ -105,6 +108,9 @@ module Datadog
105
108
 
106
109
  # Add services dynamically because they might change during runtime.
107
110
  options[:tags].concat(service_tags) unless service_tags.nil?
111
+
112
+ # Add runtime-id dynamically because it might change during runtime.
113
+ options[:tags].concat(["runtime-id:#{Core::Environment::Identity.id}"]) if @runtime_id_enabled
108
114
  end
109
115
  end
110
116
 
@@ -112,7 +118,8 @@ module Datadog
112
118
 
113
119
  attr_reader \
114
120
  :service_tags,
115
- :services
121
+ :services,
122
+ :runtime_id_enabled
116
123
 
117
124
  def compile_service_tags!
118
125
  @service_tags = services.to_a.collect do |service|
@@ -21,7 +21,7 @@ module Datadog
21
21
  @hostname = hostname
22
22
  @port = port
23
23
  @timeout = timeout
24
- @ssl = ssl.nil? ? true : ssl
24
+ @ssl = ssl.nil? || ssl
25
25
  end
26
26
 
27
27
  def open(&block)
@@ -7,6 +7,23 @@ module Datadog
7
7
  module API
8
8
  # An API configured with adapter and routes
9
9
  class Instance
10
+ # Raised when an endpoint is invoked on an API that is not the
11
+ # of expected API class for that endpoint.
12
+ class EndpointNotSupportedError < StandardError
13
+ attr_reader :spec, :endpoint_name
14
+
15
+ def initialize(endpoint_name, spec)
16
+ @spec = spec
17
+ @endpoint_name = endpoint_name
18
+
19
+ super(message)
20
+ end
21
+
22
+ def message
23
+ "#{endpoint_name} not supported for this API!"
24
+ end
25
+ end
26
+
10
27
  attr_reader \
11
28
  :adapter,
12
29
  :headers,
@@ -8,6 +8,23 @@ module Datadog
8
8
  # Specification for an HTTP API
9
9
  # Defines behaviors without specific configuration details.
10
10
  class Spec
11
+ # Raised when an endpoint is invoked on an API that did not
12
+ # define that endpoint.
13
+ class EndpointNotDefinedError < StandardError
14
+ attr_reader :spec, :endpoint_name
15
+
16
+ def initialize(endpoint_name, spec)
17
+ @spec = spec
18
+ @endpoint_name = endpoint_name
19
+
20
+ super(message)
21
+ end
22
+
23
+ def message
24
+ "No #{endpoint_name} endpoint is defined for API specification!"
25
+ end
26
+ end
27
+
11
28
  def initialize
12
29
  yield(self) if block_given?
13
30
  end
@@ -18,9 +18,10 @@ module Datadog
18
18
  :api_options,
19
19
  :default_adapter,
20
20
  :default_api,
21
- :default_headers
21
+ :default_headers,
22
+ :logger
22
23
 
23
- def initialize(api_instance_class:)
24
+ def initialize(api_instance_class:, logger:)
24
25
  # Global settings
25
26
  @default_adapter = nil
26
27
  @default_headers = {}
@@ -33,6 +34,7 @@ module Datadog
33
34
  @api_options = {}
34
35
 
35
36
  @api_instance_class = api_instance_class
37
+ @logger = logger
36
38
 
37
39
  yield(self) if block_given?
38
40
  end
@@ -86,7 +88,7 @@ module Datadog
86
88
  def to_transport(klass)
87
89
  raise NoDefaultApiError if @default_api.nil?
88
90
 
89
- klass.new(to_api_instances, @default_api)
91
+ klass.new(to_api_instances, @default_api, logger)
90
92
  end
91
93
 
92
94
  def to_api_instances
@@ -29,8 +29,45 @@ module Datadog
29
29
  # Helper function that delegates to Builder.new
30
30
  # but is under HTTP namespace so that client code requires this file
31
31
  # to get the adapters configured, and not the builder directly.
32
- def build(api_instance_class:, &block)
33
- Builder.new(api_instance_class: api_instance_class, &block)
32
+ def build(api_instance_class:, agent_settings:, logger:, api_version: nil, headers: nil, &block)
33
+ Builder.new(api_instance_class: api_instance_class, logger: logger) do |transport|
34
+ transport.adapter(agent_settings)
35
+ transport.headers(default_headers)
36
+
37
+ # The caller must define APIs before we set the default API.
38
+ yield transport
39
+
40
+ # Apply any settings given by options
41
+ transport.default_api = api_version if api_version
42
+ transport.headers(headers) if headers
43
+ end
44
+ end
45
+
46
+ def default_headers
47
+ {
48
+ Datadog::Core::Transport::Ext::HTTP::HEADER_CLIENT_COMPUTED_TOP_LEVEL => '1',
49
+ Datadog::Core::Transport::Ext::HTTP::HEADER_META_LANG =>
50
+ Datadog::Core::Environment::Ext::LANG,
51
+ Datadog::Core::Transport::Ext::HTTP::HEADER_META_LANG_VERSION =>
52
+ Datadog::Core::Environment::Ext::LANG_VERSION,
53
+ Datadog::Core::Transport::Ext::HTTP::HEADER_META_LANG_INTERPRETER =>
54
+ Datadog::Core::Environment::Ext::LANG_INTERPRETER,
55
+ Datadog::Core::Transport::Ext::HTTP::HEADER_META_LANG_INTERPRETER_VENDOR =>
56
+ Core::Environment::Ext::LANG_ENGINE,
57
+ Datadog::Core::Transport::Ext::HTTP::HEADER_META_TRACER_VERSION =>
58
+ Datadog::Core::Environment::Ext::GEM_DATADOG_VERSION
59
+ }.tap do |headers|
60
+ # Add container ID, if present.
61
+ if (container_id = Datadog::Core::Environment::Container.container_id)
62
+ headers[Datadog::Core::Transport::Ext::HTTP::HEADER_CONTAINER_ID] = container_id
63
+ end
64
+ # TODO: inject configuration rather than reading from global here
65
+ unless Datadog.configuration.apm.tracing.enabled
66
+ # Sending this header to the agent will disable metrics computation (and billing) on the agent side
67
+ # by pretending it has already been done on the library side.
68
+ headers[Datadog::Core::Transport::Ext::HTTP::HEADER_CLIENT_COMPUTED_STATS] = 'yes'
69
+ end
70
+ end
34
71
  end
35
72
  end
36
73
  end
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative '../core'
4
-
5
3
  module Datadog
6
4
  module DI
7
5
  # Component for dynamic instrumentation.
@@ -171,7 +171,7 @@ module Datadog
171
171
  attr_reader :last_sent
172
172
 
173
173
  def status_transport
174
- @status_transport ||= DI::Transport::HTTP.diagnostics(agent_settings: agent_settings)
174
+ @status_transport ||= DI::Transport::HTTP.diagnostics(agent_settings: agent_settings, logger: logger)
175
175
  end
176
176
 
177
177
  def do_send_status(batch)
@@ -179,7 +179,7 @@ module Datadog
179
179
  end
180
180
 
181
181
  def snapshot_transport
182
- @snapshot_transport ||= DI::Transport::HTTP.input(agent_settings: agent_settings)
182
+ @snapshot_transport ||= DI::Transport::HTTP.input(agent_settings: agent_settings, logger: logger)
183
183
  end
184
184
 
185
185
  def do_send_snapshot(batch)
@@ -227,20 +227,6 @@ module Datadog
227
227
  start
228
228
  end
229
229
 
230
- # Determine how much longer the worker thread should sleep
231
- # so as not to send in less than min send interval since the last send.
232
- # Important: this method must be called when @lock is held.
233
- #
234
- # Returns the time remaining to sleep.
235
- def set_sleep_remaining
236
- now = Core::Utils::Time.get_time
237
- @sleep_remaining = if last_sent
238
- [last_sent + min_send_interval - now, 0].max
239
- else
240
- 0
241
- end
242
- end
243
-
244
230
  public "add_#{event_type}"
245
231
 
246
232
  # Sends pending probe statuses or snapshots.
@@ -288,6 +274,20 @@ module Datadog
288
274
  end
289
275
  end
290
276
 
277
+ # Determine how much longer the worker thread should sleep
278
+ # so as not to send in less than min send interval since the last send.
279
+ # Important: this method must be called when @lock is held.
280
+ #
281
+ # Returns the time remaining to sleep.
282
+ def set_sleep_remaining
283
+ now = Core::Utils::Time.get_time
284
+ @sleep_remaining = if last_sent
285
+ [last_sent + min_send_interval - now, 0].max
286
+ else
287
+ 0
288
+ end
289
+ end
290
+
291
291
  def maybe_send
292
292
  rv = maybe_send_status
293
293
  maybe_send_snapshot || rv
@@ -15,12 +15,13 @@ module Datadog
15
15
  end
16
16
 
17
17
  class Transport
18
- attr_reader :client, :apis, :default_api, :current_api_id
18
+ attr_reader :client, :apis, :default_api, :current_api_id, :logger
19
19
 
20
- def initialize(apis, default_api)
20
+ def initialize(apis, default_api, logger)
21
21
  @apis = apis
22
+ @logger = logger
22
23
 
23
- @client = HTTP::Client.new(current_api)
24
+ @client = HTTP::Client.new(current_api, logger)
24
25
  end
25
26
 
26
27
  def current_api
@@ -21,13 +21,13 @@ module Datadog
21
21
 
22
22
  def defaults
23
23
  Datadog::Core::Transport::HTTP::API::Map[
24
- DIAGNOSTICS => Spec.new do |s|
24
+ DIAGNOSTICS => Diagnostics::API::Spec.new do |s|
25
25
  s.diagnostics = Diagnostics::API::Endpoint.new(
26
26
  '/debugger/v1/diagnostics',
27
27
  Core::Encoding::JSONEncoder,
28
28
  )
29
29
  end,
30
- INPUT => Spec.new do |s|
30
+ INPUT => Input::API::Spec.new do |s|
31
31
  s.input = Input::API::Endpoint.new(
32
32
  '/debugger/v1/input',
33
33
  Core::Encoding::JSONEncoder,
@@ -35,16 +35,6 @@ module Datadog
35
35
  end,
36
36
  ]
37
37
  end
38
-
39
- class Instance < Core::Transport::HTTP::API::Instance
40
- include Diagnostics::API::Instance
41
- include Input::API::Instance
42
- end
43
-
44
- class Spec < Core::Transport::HTTP::API::Spec
45
- include Diagnostics::API::Spec
46
- include Input::API::Spec
47
- end
48
38
  end
49
39
  end
50
40
  end
@@ -14,10 +14,11 @@ module Datadog
14
14
  module HTTP
15
15
  # Routes, encodes, and sends DI data to the trace agent via HTTP.
16
16
  class Client
17
- attr_reader :api
17
+ attr_reader :api, :logger
18
18
 
19
- def initialize(api)
19
+ def initialize(api, logger)
20
20
  @api = api
21
+ @logger = logger
21
22
  end
22
23
 
23
24
  def send_request(request, &block)
@@ -31,7 +32,7 @@ module Datadog
31
32
  "Internal error during #{self.class.name} request. Cause: #{e.class.name} #{e.message} " \
32
33
  "Location: #{Array(e.backtrace).first}"
33
34
 
34
- Datadog.logger.debug(message)
35
+ logger.debug(message)
35
36
 
36
37
  Datadog::Core::Transport::InternalErrorResponse.new(e)
37
38
  end