ddtrace 1.12.1 → 1.13.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (264) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +109 -9
  3. data/ext/ddtrace_profiling_native_extension/collectors_thread_context.c +97 -14
  4. data/ext/ddtrace_profiling_native_extension/extconf.rb +6 -0
  5. data/ext/ddtrace_profiling_native_extension/http_transport.c +19 -6
  6. data/ext/ddtrace_profiling_native_extension/native_extension_helpers.rb +1 -1
  7. data/ext/ddtrace_profiling_native_extension/private_vm_api_access.c +41 -2
  8. data/ext/ddtrace_profiling_native_extension/private_vm_api_access.h +6 -0
  9. data/ext/ddtrace_profiling_native_extension/stack_recorder.c +6 -10
  10. data/ext/ddtrace_profiling_native_extension/time_helpers.c +40 -4
  11. data/ext/ddtrace_profiling_native_extension/time_helpers.h +14 -0
  12. data/lib/datadog/appsec/component.rb +9 -0
  13. data/lib/datadog/appsec/configuration/settings.rb +104 -195
  14. data/lib/datadog/appsec/configuration.rb +0 -79
  15. data/lib/datadog/appsec/contrib/auto_instrument.rb +2 -4
  16. data/lib/datadog/appsec/contrib/devise/event.rb +57 -0
  17. data/lib/datadog/appsec/contrib/devise/ext.rb +13 -0
  18. data/lib/datadog/appsec/contrib/devise/integration.rb +42 -0
  19. data/lib/datadog/appsec/contrib/devise/patcher/authenticatable_patch.rb +76 -0
  20. data/lib/datadog/appsec/contrib/devise/patcher/registration_controller_patch.rb +52 -0
  21. data/lib/datadog/appsec/contrib/devise/patcher.rb +45 -0
  22. data/lib/datadog/appsec/contrib/devise/resource.rb +35 -0
  23. data/lib/datadog/appsec/contrib/devise/tracking.rb +49 -0
  24. data/lib/datadog/appsec/contrib/rack/ext.rb +2 -1
  25. data/lib/datadog/appsec/contrib/rack/reactive/request.rb +1 -1
  26. data/lib/datadog/appsec/contrib/rack/reactive/request_body.rb +1 -1
  27. data/lib/datadog/appsec/contrib/rack/reactive/response.rb +1 -1
  28. data/lib/datadog/appsec/contrib/rack/request_middleware.rb +12 -7
  29. data/lib/datadog/appsec/contrib/rails/ext.rb +3 -2
  30. data/lib/datadog/appsec/contrib/rails/framework.rb +1 -3
  31. data/lib/datadog/appsec/contrib/rails/patcher.rb +8 -8
  32. data/lib/datadog/appsec/contrib/rails/reactive/action.rb +1 -1
  33. data/lib/datadog/appsec/contrib/sinatra/ext.rb +2 -1
  34. data/lib/datadog/appsec/contrib/sinatra/framework.rb +1 -3
  35. data/lib/datadog/appsec/contrib/sinatra/reactive/routed.rb +1 -1
  36. data/lib/datadog/appsec/event.rb +1 -1
  37. data/lib/datadog/appsec/extensions.rb +1 -130
  38. data/lib/datadog/appsec/monitor/reactive/set_user.rb +1 -1
  39. data/lib/datadog/appsec/processor.rb +1 -1
  40. data/lib/datadog/appsec/rate_limiter.rb +1 -1
  41. data/lib/datadog/appsec/remote.rb +1 -1
  42. data/lib/datadog/appsec.rb +1 -2
  43. data/lib/datadog/ci/configuration/settings.rb +6 -8
  44. data/lib/datadog/ci/contrib/cucumber/configuration/settings.rb +7 -5
  45. data/lib/datadog/ci/contrib/cucumber/ext.rb +10 -8
  46. data/lib/datadog/ci/contrib/minitest/configuration/settings.rb +35 -0
  47. data/lib/datadog/ci/contrib/minitest/ext.rb +21 -0
  48. data/lib/datadog/ci/contrib/minitest/integration.rb +49 -0
  49. data/lib/datadog/ci/contrib/minitest/patcher.rb +27 -0
  50. data/lib/datadog/ci/contrib/minitest/test_helper.rb +68 -0
  51. data/lib/datadog/ci/contrib/rspec/configuration/settings.rb +7 -5
  52. data/lib/datadog/ci/contrib/rspec/ext.rb +9 -7
  53. data/lib/datadog/ci.rb +1 -0
  54. data/lib/datadog/core/backport.rb +51 -0
  55. data/lib/datadog/core/configuration/base.rb +5 -5
  56. data/lib/datadog/core/configuration/components.rb +6 -1
  57. data/lib/datadog/core/configuration/ext.rb +7 -5
  58. data/lib/datadog/core/configuration/option.rb +269 -19
  59. data/lib/datadog/core/configuration/option_definition.rb +76 -11
  60. data/lib/datadog/core/configuration/options.rb +22 -10
  61. data/lib/datadog/core/configuration/settings.rb +116 -61
  62. data/lib/datadog/core/environment/ext.rb +13 -11
  63. data/lib/datadog/core/environment/yjit.rb +58 -0
  64. data/lib/datadog/core/git/ext.rb +24 -22
  65. data/lib/datadog/core/logging/ext.rb +3 -1
  66. data/lib/datadog/core/metrics/ext.rb +7 -5
  67. data/lib/datadog/core/remote/client/capabilities.rb +5 -0
  68. data/lib/datadog/core/remote/client.rb +3 -0
  69. data/lib/datadog/core/remote/component.rb +25 -34
  70. data/lib/datadog/core/remote/configuration/content.rb +28 -1
  71. data/lib/datadog/core/remote/configuration/repository.rb +3 -1
  72. data/lib/datadog/core/remote/ext.rb +1 -1
  73. data/lib/datadog/core/remote/negotiation.rb +17 -4
  74. data/lib/datadog/core/runtime/ext.rb +22 -12
  75. data/lib/datadog/core/runtime/metrics.rb +43 -0
  76. data/lib/datadog/core/telemetry/client.rb +12 -2
  77. data/lib/datadog/core/telemetry/emitter.rb +4 -2
  78. data/lib/datadog/core/telemetry/event.rb +19 -4
  79. data/lib/datadog/core/telemetry/ext.rb +4 -1
  80. data/lib/datadog/core/telemetry/heartbeat.rb +2 -4
  81. data/lib/datadog/core/telemetry/http/ext.rb +10 -8
  82. data/lib/datadog/core/telemetry/http/transport.rb +1 -0
  83. data/lib/datadog/core/telemetry/v2/app_client_configuration_change.rb +41 -0
  84. data/lib/datadog/core/telemetry/v2/request.rb +29 -0
  85. data/lib/datadog/core/transport/http/client.rb +1 -1
  86. data/lib/datadog/core/transport/http/config.rb +10 -0
  87. data/lib/datadog/core/utils/duration.rb +52 -0
  88. data/lib/datadog/core/utils/hash.rb +47 -0
  89. data/lib/datadog/core/utils/network.rb +1 -1
  90. data/lib/datadog/core/utils/safe_dup.rb +27 -20
  91. data/lib/datadog/core/utils.rb +1 -1
  92. data/lib/datadog/core/workers/async.rb +2 -2
  93. data/lib/datadog/kit/appsec/events.rb +139 -89
  94. data/lib/datadog/kit/identity.rb +80 -65
  95. data/lib/datadog/profiling/collectors/cpu_and_wall_time_worker.rb +3 -0
  96. data/lib/datadog/profiling/collectors/idle_sampling_helper.rb +1 -0
  97. data/lib/datadog/profiling/collectors/thread_context.rb +9 -2
  98. data/lib/datadog/profiling/component.rb +41 -9
  99. data/lib/datadog/profiling/exporter.rb +5 -1
  100. data/lib/datadog/profiling/flush.rb +9 -2
  101. data/lib/datadog/profiling/http_transport.rb +4 -1
  102. data/lib/datadog/profiling/load_native_extension.rb +7 -1
  103. data/lib/datadog/profiling.rb +11 -1
  104. data/lib/datadog/tracing/component.rb +58 -6
  105. data/lib/datadog/tracing/configuration/dynamic/option.rb +71 -0
  106. data/lib/datadog/tracing/configuration/dynamic.rb +64 -0
  107. data/lib/datadog/tracing/configuration/ext.rb +35 -32
  108. data/lib/datadog/tracing/configuration/http.rb +74 -0
  109. data/lib/datadog/tracing/configuration/settings.rb +106 -92
  110. data/lib/datadog/tracing/contrib/action_cable/configuration/settings.rb +9 -6
  111. data/lib/datadog/tracing/contrib/action_cable/ext.rb +20 -18
  112. data/lib/datadog/tracing/contrib/action_mailer/configuration/settings.rb +9 -6
  113. data/lib/datadog/tracing/contrib/action_mailer/ext.rb +20 -18
  114. data/lib/datadog/tracing/contrib/action_pack/configuration/settings.rb +8 -6
  115. data/lib/datadog/tracing/contrib/action_pack/ext.rb +10 -8
  116. data/lib/datadog/tracing/contrib/action_view/configuration/settings.rb +9 -6
  117. data/lib/datadog/tracing/contrib/action_view/ext.rb +12 -10
  118. data/lib/datadog/tracing/contrib/active_job/configuration/settings.rb +13 -7
  119. data/lib/datadog/tracing/contrib/active_job/ext.rb +25 -23
  120. data/lib/datadog/tracing/contrib/active_job/log_injection.rb +1 -1
  121. data/lib/datadog/tracing/contrib/active_job/patcher.rb +1 -1
  122. data/lib/datadog/tracing/contrib/active_model_serializers/configuration/settings.rb +9 -6
  123. data/lib/datadog/tracing/contrib/active_model_serializers/ext.rb +12 -10
  124. data/lib/datadog/tracing/contrib/active_record/configuration/settings.rb +9 -7
  125. data/lib/datadog/tracing/contrib/active_record/events/sql.rb +0 -8
  126. data/lib/datadog/tracing/contrib/active_record/ext.rb +17 -15
  127. data/lib/datadog/tracing/contrib/active_support/cache/instrumentation.rb +0 -5
  128. data/lib/datadog/tracing/contrib/active_support/configuration/settings.rb +9 -7
  129. data/lib/datadog/tracing/contrib/active_support/ext.rb +18 -16
  130. data/lib/datadog/tracing/contrib/aws/configuration/settings.rb +14 -7
  131. data/lib/datadog/tracing/contrib/aws/ext.rb +37 -24
  132. data/lib/datadog/tracing/contrib/aws/instrumentation.rb +9 -5
  133. data/lib/datadog/tracing/contrib/concurrent_ruby/configuration/settings.rb +3 -2
  134. data/lib/datadog/tracing/contrib/concurrent_ruby/ext.rb +4 -2
  135. data/lib/datadog/tracing/contrib/dalli/configuration/settings.rb +14 -7
  136. data/lib/datadog/tracing/contrib/dalli/ext.rb +19 -11
  137. data/lib/datadog/tracing/contrib/dalli/instrumentation.rb +8 -6
  138. data/lib/datadog/tracing/contrib/delayed_job/configuration/settings.rb +13 -7
  139. data/lib/datadog/tracing/contrib/delayed_job/ext.rb +16 -14
  140. data/lib/datadog/tracing/contrib/elasticsearch/configuration/settings.rb +14 -7
  141. data/lib/datadog/tracing/contrib/elasticsearch/ext.rb +21 -15
  142. data/lib/datadog/tracing/contrib/elasticsearch/patcher.rb +8 -5
  143. data/lib/datadog/tracing/contrib/ethon/configuration/settings.rb +16 -9
  144. data/lib/datadog/tracing/contrib/ethon/easy_patch.rb +43 -3
  145. data/lib/datadog/tracing/contrib/ethon/ext.rb +19 -11
  146. data/lib/datadog/tracing/contrib/ethon/multi_patch.rb +0 -5
  147. data/lib/datadog/tracing/contrib/excon/configuration/settings.rb +19 -10
  148. data/lib/datadog/tracing/contrib/excon/ext.rb +16 -8
  149. data/lib/datadog/tracing/contrib/excon/middleware.rb +20 -5
  150. data/lib/datadog/tracing/contrib/ext.rb +23 -1
  151. data/lib/datadog/tracing/contrib/extensions.rb +32 -0
  152. data/lib/datadog/tracing/contrib/faraday/configuration/settings.rb +20 -10
  153. data/lib/datadog/tracing/contrib/faraday/ext.rb +16 -8
  154. data/lib/datadog/tracing/contrib/faraday/middleware.rb +16 -5
  155. data/lib/datadog/tracing/contrib/grape/configuration/settings.rb +8 -6
  156. data/lib/datadog/tracing/contrib/grape/ext.rb +16 -14
  157. data/lib/datadog/tracing/contrib/graphql/configuration/settings.rb +8 -6
  158. data/lib/datadog/tracing/contrib/graphql/ext.rb +7 -5
  159. data/lib/datadog/tracing/contrib/grpc/configuration/settings.rb +19 -9
  160. data/lib/datadog/tracing/contrib/grpc/datadog_interceptor/client.rb +29 -20
  161. data/lib/datadog/tracing/contrib/grpc/datadog_interceptor/server.rb +21 -20
  162. data/lib/datadog/tracing/contrib/grpc/ext.rb +16 -13
  163. data/lib/datadog/tracing/contrib/grpc/formatting.rb +127 -0
  164. data/lib/datadog/tracing/contrib/hanami/configuration/settings.rb +3 -2
  165. data/lib/datadog/tracing/contrib/hanami/ext.rb +10 -8
  166. data/lib/datadog/tracing/contrib/http/circuit_breaker.rb +4 -7
  167. data/lib/datadog/tracing/contrib/http/configuration/settings.rb +33 -11
  168. data/lib/datadog/tracing/contrib/http/ext.rb +16 -9
  169. data/lib/datadog/tracing/contrib/http/instrumentation.rb +17 -5
  170. data/lib/datadog/tracing/contrib/httpclient/configuration/settings.rb +33 -11
  171. data/lib/datadog/tracing/contrib/httpclient/ext.rb +17 -9
  172. data/lib/datadog/tracing/contrib/httpclient/instrumentation.rb +17 -5
  173. data/lib/datadog/tracing/contrib/httprb/configuration/settings.rb +33 -11
  174. data/lib/datadog/tracing/contrib/httprb/ext.rb +16 -9
  175. data/lib/datadog/tracing/contrib/httprb/instrumentation.rb +17 -5
  176. data/lib/datadog/tracing/contrib/kafka/configuration/settings.rb +9 -6
  177. data/lib/datadog/tracing/contrib/kafka/ext.rb +42 -39
  178. data/lib/datadog/tracing/contrib/lograge/configuration/settings.rb +3 -2
  179. data/lib/datadog/tracing/contrib/lograge/ext.rb +3 -1
  180. data/lib/datadog/tracing/contrib/lograge/instrumentation.rb +1 -0
  181. data/lib/datadog/tracing/contrib/mongodb/configuration/settings.rb +14 -7
  182. data/lib/datadog/tracing/contrib/mongodb/ext.rb +20 -16
  183. data/lib/datadog/tracing/contrib/mongodb/subscribers.rb +9 -5
  184. data/lib/datadog/tracing/contrib/mysql2/configuration/settings.rb +17 -14
  185. data/lib/datadog/tracing/contrib/mysql2/ext.rb +15 -10
  186. data/lib/datadog/tracing/contrib/mysql2/instrumentation.rb +9 -5
  187. data/lib/datadog/tracing/contrib/opensearch/configuration/settings.rb +52 -0
  188. data/lib/datadog/tracing/contrib/opensearch/ext.rb +37 -0
  189. data/lib/datadog/tracing/contrib/opensearch/integration.rb +44 -0
  190. data/lib/datadog/tracing/contrib/opensearch/patcher.rb +128 -0
  191. data/lib/datadog/tracing/contrib/opensearch/quantize.rb +81 -0
  192. data/lib/datadog/tracing/contrib/pg/configuration/settings.rb +17 -14
  193. data/lib/datadog/tracing/contrib/pg/ext.rb +22 -19
  194. data/lib/datadog/tracing/contrib/pg/instrumentation.rb +9 -5
  195. data/lib/datadog/tracing/contrib/presto/configuration/settings.rb +14 -7
  196. data/lib/datadog/tracing/contrib/presto/ext.rb +25 -20
  197. data/lib/datadog/tracing/contrib/presto/instrumentation.rb +9 -5
  198. data/lib/datadog/tracing/contrib/propagation/sql_comment/ext.rb +12 -10
  199. data/lib/datadog/tracing/contrib/qless/configuration/settings.rb +12 -8
  200. data/lib/datadog/tracing/contrib/qless/ext.rb +14 -12
  201. data/lib/datadog/tracing/contrib/que/configuration/settings.rb +21 -12
  202. data/lib/datadog/tracing/contrib/racecar/configuration/settings.rb +9 -7
  203. data/lib/datadog/tracing/contrib/racecar/event.rb +0 -5
  204. data/lib/datadog/tracing/contrib/racecar/ext.rb +20 -18
  205. data/lib/datadog/tracing/contrib/rack/configuration/settings.rb +16 -12
  206. data/lib/datadog/tracing/contrib/rack/ext.rb +18 -16
  207. data/lib/datadog/tracing/contrib/rack/header_collection.rb +3 -0
  208. data/lib/datadog/tracing/contrib/rack/header_tagging.rb +53 -0
  209. data/lib/datadog/tracing/contrib/rack/middlewares.rb +8 -49
  210. data/lib/datadog/tracing/contrib/rails/configuration/settings.rb +15 -11
  211. data/lib/datadog/tracing/contrib/rails/ext.rb +7 -5
  212. data/lib/datadog/tracing/contrib/rails/log_injection.rb +4 -10
  213. data/lib/datadog/tracing/contrib/rails/patcher.rb +10 -41
  214. data/lib/datadog/tracing/contrib/rails/railtie.rb +3 -3
  215. data/lib/datadog/tracing/contrib/rake/configuration/settings.rb +12 -9
  216. data/lib/datadog/tracing/contrib/rake/ext.rb +14 -12
  217. data/lib/datadog/tracing/contrib/redis/configuration/settings.rb +17 -9
  218. data/lib/datadog/tracing/contrib/redis/ext.rb +22 -15
  219. data/lib/datadog/tracing/contrib/redis/tags.rb +9 -5
  220. data/lib/datadog/tracing/contrib/resque/configuration/settings.rb +13 -7
  221. data/lib/datadog/tracing/contrib/resque/ext.rb +9 -7
  222. data/lib/datadog/tracing/contrib/rest_client/configuration/settings.rb +16 -9
  223. data/lib/datadog/tracing/contrib/rest_client/ext.rb +15 -8
  224. data/lib/datadog/tracing/contrib/rest_client/request_patch.rb +20 -5
  225. data/lib/datadog/tracing/contrib/roda/configuration/settings.rb +9 -6
  226. data/lib/datadog/tracing/contrib/semantic_logger/configuration/settings.rb +3 -2
  227. data/lib/datadog/tracing/contrib/semantic_logger/ext.rb +3 -1
  228. data/lib/datadog/tracing/contrib/semantic_logger/instrumentation.rb +1 -0
  229. data/lib/datadog/tracing/contrib/sequel/configuration/settings.rb +9 -6
  230. data/lib/datadog/tracing/contrib/sequel/ext.rb +10 -8
  231. data/lib/datadog/tracing/contrib/sequel/utils.rb +2 -7
  232. data/lib/datadog/tracing/contrib/shoryuken/configuration/settings.rb +14 -8
  233. data/lib/datadog/tracing/contrib/shoryuken/ext.rb +14 -12
  234. data/lib/datadog/tracing/contrib/sidekiq/configuration/settings.rb +18 -11
  235. data/lib/datadog/tracing/contrib/sidekiq/ext.rb +32 -30
  236. data/lib/datadog/tracing/contrib/sinatra/configuration/settings.rb +11 -9
  237. data/lib/datadog/tracing/contrib/sinatra/env.rb +0 -17
  238. data/lib/datadog/tracing/contrib/sinatra/ext.rb +21 -19
  239. data/lib/datadog/tracing/contrib/sinatra/tracer_middleware.rb +3 -14
  240. data/lib/datadog/tracing/contrib/sneakers/configuration/settings.rb +14 -8
  241. data/lib/datadog/tracing/contrib/sneakers/ext.rb +1 -0
  242. data/lib/datadog/tracing/contrib/sneakers/tracer.rb +1 -1
  243. data/lib/datadog/tracing/contrib/span_attribute_schema.rb +74 -10
  244. data/lib/datadog/tracing/contrib/stripe/configuration/settings.rb +9 -6
  245. data/lib/datadog/tracing/contrib/sucker_punch/configuration/settings.rb +9 -6
  246. data/lib/datadog/tracing/contrib/sucker_punch/ext.rb +15 -13
  247. data/lib/datadog/tracing/contrib/utils/database.rb +5 -3
  248. data/lib/datadog/tracing/correlation.rb +9 -12
  249. data/lib/datadog/tracing/diagnostics/ext.rb +21 -19
  250. data/lib/datadog/tracing/distributed/b3_multi.rb +2 -2
  251. data/lib/datadog/tracing/distributed/b3_single.rb +1 -1
  252. data/lib/datadog/tracing/distributed/trace_context.rb +52 -17
  253. data/lib/datadog/tracing/metadata/ext.rb +9 -6
  254. data/lib/datadog/tracing/remote.rb +78 -0
  255. data/lib/datadog/tracing/sampling/rule_sampler.rb +29 -0
  256. data/lib/datadog/tracing/span_operation.rb +3 -15
  257. data/lib/datadog/tracing/trace_operation.rb +16 -3
  258. data/lib/datadog/tracing/trace_segment.rb +5 -2
  259. data/lib/datadog/tracing/tracer.rb +10 -1
  260. data/lib/ddtrace/transport/ext.rb +15 -9
  261. data/lib/ddtrace/transport/trace_formatter.rb +9 -0
  262. data/lib/ddtrace/version.rb +9 -12
  263. metadata +38 -10
  264. data/lib/datadog/tracing/contrib/sinatra/headers.rb +0 -35
@@ -45,6 +45,11 @@ module Datadog
45
45
  "remote worker client sync error: #{e.message} location: #{Array(e.backtrace).first}. skipping sync"
46
46
  end
47
47
  rescue StandardError => e
48
+ # In case of unexpected errors, reset the negotiation object
49
+ # given external conditions have changed and the negotiation
50
+ # negotiation object stores error logging state that should be reset.
51
+ negotiation = Negotiation.new(settings, agent_settings)
52
+
48
53
  Datadog.logger.error do
49
54
  "remote worker error: #{e.class.name} #{e.message} location: #{Array(e.backtrace).first}. "\
50
55
  'reseting client state'
@@ -62,13 +67,22 @@ module Datadog
62
67
  end
63
68
  end
64
69
 
65
- def barrier(kind)
70
+ # Starts the Remote Configuration worker without waiting for first run
71
+ def start
66
72
  @worker.start
73
+ end
67
74
 
68
- case kind
69
- when :once
70
- @barrier.wait_once
71
- end
75
+ # Is the Remote Configuration worker running?
76
+ def started?
77
+ @worker.started?
78
+ end
79
+
80
+ # If the worker is not initialized, initialize it.
81
+ #
82
+ # Then, waits for one client sync to be executed if `kind` is `:once`.
83
+ def barrier(_kind)
84
+ start
85
+ @barrier.wait_once
72
86
  end
73
87
 
74
88
  def shutdown!
@@ -105,18 +119,6 @@ module Datadog
105
119
  end
106
120
  end
107
121
 
108
- # Wait for next lift to happen
109
- def wait_next(timeout = nil)
110
- @mutex.lock
111
-
112
- timeout ||= @timeout
113
-
114
- # rbs/core has a bug, timeout type is incorrectly ?Integer
115
- @condition.wait(@mutex, _ = timeout)
116
- ensure
117
- @mutex.unlock
118
- end
119
-
120
122
  # Release all current waiters
121
123
  def lift
122
124
  @mutex.lock
@@ -130,26 +132,15 @@ module Datadog
130
132
  end
131
133
 
132
134
  class << self
135
+ # Because the agent might not be available yet, we can't perform agent-specific checks yet, as they
136
+ # would prevent remote configuration from ever running.
137
+ #
138
+ # Those checks are instead performed inside the worker loop.
139
+ # This allows users to upgrade their agent while keeping their application running.
133
140
  def build(settings, agent_settings)
134
141
  return unless settings.remote.enabled
135
142
 
136
- capabilities = Client::Capabilities.new(settings)
137
-
138
- return if capabilities.products.empty?
139
-
140
- negotiation = Negotiation.new(settings, agent_settings)
141
-
142
- unless negotiation.endpoint?('/v0.7/config')
143
- Datadog.logger.error do
144
- 'endpoint unavailable: disabling remote configuration for this process.'
145
- end
146
-
147
- return
148
- end
149
-
150
- Datadog.logger.debug { 'agent reachable and reports remote configuration endpoint' }
151
-
152
- new(settings, capabilities, agent_settings)
143
+ new(settings, Client::Capabilities.new(settings), agent_settings)
153
144
  end
154
145
  end
155
146
  end
@@ -18,12 +18,14 @@ module Datadog
18
18
  end
19
19
  end
20
20
 
21
- attr_reader :path, :data, :hashes
21
+ attr_reader :path, :data, :hashes, :apply_state, :apply_error
22
22
  attr_accessor :version
23
23
 
24
24
  def initialize(path:, data:)
25
25
  @path = path
26
26
  @data = data
27
+ @apply_state = ApplyState::UNACKNOWLEDGED
28
+ @apply_error = nil
27
29
  @hashes = {}
28
30
  @version = 0
29
31
  end
@@ -36,6 +38,31 @@ module Datadog
36
38
  @length ||= @data.size
37
39
  end
38
40
 
41
+ # Sets this configuration as successfully applied.
42
+ def applied
43
+ @apply_state = ApplyState::ACKNOWLEDGED
44
+ @apply_error = nil
45
+ end
46
+
47
+ # Sets this configuration as not successfully applied, with
48
+ # a message describing the error.
49
+ def errored(error_message)
50
+ @apply_state = ApplyState::ERROR
51
+ @apply_error = error_message
52
+ end
53
+
54
+ module ApplyState
55
+ # Default state of configurations.
56
+ # Set until the component consuming the configuration has acknowledged it was applied.
57
+ UNACKNOWLEDGED = 1
58
+
59
+ # Set when the configuration has been successfully applied.
60
+ ACKNOWLEDGED = 2
61
+
62
+ # Set when the configuration has been unsuccessfully applied.
63
+ ERROR = 3
64
+ end
65
+
39
66
  private
40
67
 
41
68
  def compute_and_store_hash(type)
@@ -94,7 +94,9 @@ module Datadog
94
94
  {
95
95
  id: content.path.config_id,
96
96
  version: content.version,
97
- product: content.path.product
97
+ product: content.path.product,
98
+ apply_state: content.apply_state,
99
+ apply_error: content.apply_error,
98
100
  }
99
101
  end
100
102
  end
@@ -5,7 +5,7 @@ module Datadog
5
5
  module Remote
6
6
  module Ext
7
7
  ENV_ENABLED = 'DD_REMOTE_CONFIGURATION_ENABLED'
8
- ENV_POLL_INTERVAL_SECONDS = 'DD_REMOTE_CONFIGURATION_POLL_INTERVAL_SECONDS'
8
+ ENV_POLL_INTERVAL_SECONDS = 'DD_REMOTE_CONFIG_POLL_INTERVAL_SECONDS'
9
9
  end
10
10
  end
11
11
  end
@@ -12,31 +12,44 @@ module Datadog
12
12
  transport_options[:agent_settings] = agent_settings if agent_settings
13
13
 
14
14
  @transport_root = Datadog::Core::Transport::HTTP.root(**transport_options.dup)
15
+ @logged = {}
15
16
  end
16
17
 
17
18
  def endpoint?(path)
18
19
  res = @transport_root.send_info
19
20
 
20
21
  if res.internal_error? && network_error?(res.error)
21
- Datadog.logger.error { "agent unreachable: cannot negotiate #{path}" }
22
+ unless @logged[:agent_unreachable]
23
+ Datadog.logger.error { "agent unreachable: cannot negotiate #{path}" }
24
+ @logged[:agent_unreachable] = true
25
+ end
22
26
 
23
27
  return false
24
28
  end
25
29
 
26
30
  if res.not_found?
27
- Datadog.logger.error { "agent reachable but has no /info endpoint: cannot negotiate #{path}" }
31
+ unless @logged[:no_info_endpoint]
32
+ Datadog.logger.error { "agent reachable but has no /info endpoint: cannot negotiate #{path}" }
33
+ @logged[:no_info_endpoint] = true
34
+ end
28
35
 
29
36
  return false
30
37
  end
31
38
 
32
39
  unless res.ok?
33
- Datadog.logger.error { "agent reachable but unexpected response: cannot negotiate #{path}" }
40
+ unless @logged[:unexpected_response]
41
+ Datadog.logger.error { "agent reachable but unexpected response: cannot negotiate #{path}" }
42
+ @logged[:unexpected_response] = true
43
+ end
34
44
 
35
45
  return false
36
46
  end
37
47
 
38
48
  unless res.endpoints.include?(path)
39
- Datadog.logger.error { "agent reachable but does not report #{path}" }
49
+ unless @logged[:no_config_endpoint]
50
+ Datadog.logger.error { "agent reachable but does not report #{path}" }
51
+ @logged[:no_config_endpoint] = true
52
+ end
40
53
 
41
54
  return false
42
55
  end
@@ -1,26 +1,36 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Datadog
2
4
  module Core
3
5
  module Runtime
4
6
  # @public_api
5
7
  module Ext
6
- TAG_ID = 'runtime-id'.freeze
7
- TAG_LANG = 'language'.freeze
8
- TAG_PROCESS_ID = 'process_id'.freeze
8
+ TAG_ID = 'runtime-id'
9
+ TAG_LANG = 'language'
10
+ TAG_PROCESS_ID = 'process_id'
9
11
 
10
12
  # Metrics
11
13
  # @public_api
12
14
  module Metrics
13
- ENV_ENABLED = 'DD_RUNTIME_METRICS_ENABLED'.freeze
15
+ ENV_ENABLED = 'DD_RUNTIME_METRICS_ENABLED'
14
16
 
15
- METRIC_CLASS_COUNT = 'runtime.ruby.class_count'.freeze
16
- METRIC_GC_PREFIX = 'runtime.ruby.gc'.freeze
17
- METRIC_THREAD_COUNT = 'runtime.ruby.thread_count'.freeze
18
- METRIC_GLOBAL_CONSTANT_STATE = 'runtime.ruby.global_constant_state'.freeze
19
- METRIC_GLOBAL_METHOD_STATE = 'runtime.ruby.global_method_state'.freeze
20
- METRIC_CONSTANT_CACHE_INVALIDATIONS = 'runtime.ruby.constant_cache_invalidations'.freeze
21
- METRIC_CONSTANT_CACHE_MISSES = 'runtime.ruby.constant_cache_misses'.freeze
17
+ METRIC_CLASS_COUNT = 'runtime.ruby.class_count'
18
+ METRIC_GC_PREFIX = 'runtime.ruby.gc'
19
+ METRIC_THREAD_COUNT = 'runtime.ruby.thread_count'
20
+ METRIC_GLOBAL_CONSTANT_STATE = 'runtime.ruby.global_constant_state'
21
+ METRIC_GLOBAL_METHOD_STATE = 'runtime.ruby.global_method_state'
22
+ METRIC_CONSTANT_CACHE_INVALIDATIONS = 'runtime.ruby.constant_cache_invalidations'
23
+ METRIC_CONSTANT_CACHE_MISSES = 'runtime.ruby.constant_cache_misses'
24
+ METRIC_YJIT_CODE_GC_COUNT = 'runtime.ruby.yjit.code_gc_count'
25
+ METRIC_YJIT_CODE_REGION_SIZE = 'runtime.ruby.yjit.code_region_size'
26
+ METRIC_YJIT_FREED_CODE_SIZE = 'runtime.ruby.yjit.freed_code_size'
27
+ METRIC_YJIT_FREED_PAGE_COUNT = 'runtime.ruby.yjit.freed_page_count'
28
+ METRIC_YJIT_INLINE_CODE_SIZE = 'runtime.ruby.yjit.inline_code_size'
29
+ METRIC_YJIT_LIVE_PAGE_COUNT = 'runtime.ruby.yjit.live_page_count'
30
+ METRIC_YJIT_OBJECT_SHAPE_COUNT = 'runtime.ruby.yjit.object_shape_count'
31
+ METRIC_YJIT_OUTLINED_CODE_SIZE = 'runtime.ruby.yjit.outlined_code_size'
22
32
 
23
- TAG_SERVICE = 'service'.freeze
33
+ TAG_SERVICE = 'service'
24
34
  end
25
35
  end
26
36
  end
@@ -5,6 +5,7 @@ require_relative '../environment/class_count'
5
5
  require_relative '../environment/gc'
6
6
  require_relative '../environment/thread_count'
7
7
  require_relative '../environment/vm_cache'
8
+ require_relative '../environment/yjit'
8
9
 
9
10
  module Datadog
10
11
  module Core
@@ -78,6 +79,8 @@ module Datadog
78
79
  )
79
80
  end
80
81
  end
82
+
83
+ flush_yjit_stats
81
84
  end
82
85
 
83
86
  def gc_metrics
@@ -134,6 +137,46 @@ module Datadog
134
137
  def gauge_if_not_nil(metric_name, metric_value)
135
138
  gauge(metric_name, metric_value) if metric_value
136
139
  end
140
+
141
+ def flush_yjit_stats
142
+ # Only on Ruby >= 3.2
143
+ try_flush do
144
+ if Core::Environment::YJIT.available?
145
+ gauge_if_not_nil(
146
+ Core::Runtime::Ext::Metrics::METRIC_YJIT_CODE_GC_COUNT,
147
+ Core::Environment::YJIT.code_gc_count
148
+ )
149
+ gauge_if_not_nil(
150
+ Core::Runtime::Ext::Metrics::METRIC_YJIT_CODE_REGION_SIZE,
151
+ Core::Environment::YJIT.code_region_size
152
+ )
153
+ gauge_if_not_nil(
154
+ Core::Runtime::Ext::Metrics::METRIC_YJIT_FREED_CODE_SIZE,
155
+ Core::Environment::YJIT.freed_code_size
156
+ )
157
+ gauge_if_not_nil(
158
+ Core::Runtime::Ext::Metrics::METRIC_YJIT_FREED_PAGE_COUNT,
159
+ Core::Environment::YJIT.freed_page_count
160
+ )
161
+ gauge_if_not_nil(
162
+ Core::Runtime::Ext::Metrics::METRIC_YJIT_INLINE_CODE_SIZE,
163
+ Core::Environment::YJIT.inline_code_size
164
+ )
165
+ gauge_if_not_nil(
166
+ Core::Runtime::Ext::Metrics::METRIC_YJIT_LIVE_PAGE_COUNT,
167
+ Core::Environment::YJIT.live_page_count
168
+ )
169
+ gauge_if_not_nil(
170
+ Core::Runtime::Ext::Metrics::METRIC_YJIT_OBJECT_SHAPE_COUNT,
171
+ Core::Environment::YJIT.object_shape_count
172
+ )
173
+ gauge_if_not_nil(
174
+ Core::Runtime::Ext::Metrics::METRIC_YJIT_OUTLINED_CODE_SIZE,
175
+ Core::Environment::YJIT.outlined_code_size
176
+ )
177
+ end
178
+ end
179
+ end
137
180
  end
138
181
  end
139
182
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require_relative 'emitter'
2
4
  require_relative 'heartbeat'
3
5
  require_relative '../utils/forking'
@@ -16,12 +18,13 @@ module Datadog
16
18
  include Core::Utils::Forking
17
19
 
18
20
  # @param enabled [Boolean] Determines whether telemetry events should be sent to the API
19
- def initialize(enabled: true)
21
+ # @param heartbeat_interval_seconds [Float] How frequently heartbeats will be reported, in seconds.
22
+ def initialize(heartbeat_interval_seconds:, enabled: true)
20
23
  @enabled = enabled
21
24
  @emitter = Emitter.new
22
25
  @stopped = false
23
26
  @unsupported = false
24
- @worker = Telemetry::Heartbeat.new(enabled: @enabled) do
27
+ @worker = Telemetry::Heartbeat.new(enabled: @enabled, heartbeat_interval_seconds: heartbeat_interval_seconds) do
25
28
  heartbeat!
26
29
  end
27
30
  end
@@ -64,6 +67,13 @@ module Datadog
64
67
  @emitter.request(:'app-integrations-change')
65
68
  end
66
69
 
70
+ # Report configuration changes caused by Remote Configuration.
71
+ def client_configuration_change!(changes)
72
+ return if !@enabled || forked?
73
+
74
+ @emitter.request('app-client-configuration-change', data: { changes: changes, origin: 'remote_config' })
75
+ end
76
+
67
77
  private
68
78
 
69
79
  def heartbeat!
@@ -21,11 +21,13 @@ module Datadog
21
21
 
22
22
  # Retrieves and emits a TelemetryRequest object based on the request type specified
23
23
  # @param request_type [String] the type of telemetry request to collect data for
24
- def request(request_type)
24
+ # @param data [Object] arbitrary object to be passed to the respective `request_type` handler
25
+ def request(request_type, data: nil)
25
26
  begin
26
27
  request = Datadog::Core::Telemetry::Event.new.telemetry_request(
27
28
  request_type: request_type,
28
- seq_id: self.class.sequence.next
29
+ seq_id: self.class.sequence.next,
30
+ data: data,
29
31
  ).to_h
30
32
  @http_transport.request(request_type: request_type.to_s, payload: request.to_json)
31
33
  rescue StandardError => e
@@ -1,6 +1,9 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require_relative 'collector'
2
4
  require_relative 'v1/app_event'
3
5
  require_relative 'v1/telemetry_request'
6
+ require_relative 'v2/app_client_configuration_change'
4
7
 
5
8
  module Datadog
6
9
  module Core
@@ -9,7 +12,7 @@ module Datadog
9
12
  class Event
10
13
  include Telemetry::Collector
11
14
 
12
- API_VERSION = 'v1'.freeze
15
+ API_VERSION = 'v1'
13
16
 
14
17
  attr_reader \
15
18
  :api_version
@@ -21,12 +24,13 @@ module Datadog
21
24
  # Forms a TelemetryRequest object based on the event request_type
22
25
  # @param request_type [String] the type of telemetry request to collect data for
23
26
  # @param seq_id [Integer] the ID of the request; incremented each time a telemetry request is sent to the API
24
- def telemetry_request(request_type:, seq_id:)
27
+ # @param data [Object] arbitrary object to be passed to the respective `request_type` handler
28
+ def telemetry_request(request_type:, seq_id:, data: nil)
25
29
  Telemetry::V1::TelemetryRequest.new(
26
30
  api_version: @api_version,
27
31
  application: application,
28
32
  host: host,
29
- payload: payload(request_type),
33
+ payload: payload(request_type, data),
30
34
  request_type: request_type,
31
35
  runtime_id: runtime_id,
32
36
  seq_id: seq_id,
@@ -36,7 +40,7 @@ module Datadog
36
40
 
37
41
  private
38
42
 
39
- def payload(request_type)
43
+ def payload(request_type, data)
40
44
  case request_type
41
45
  when :'app-started'
42
46
  app_started
@@ -44,6 +48,8 @@ module Datadog
44
48
  {}
45
49
  when :'app-integrations-change'
46
50
  app_integrations_change
51
+ when 'app-client-configuration-change'
52
+ app_client_configuration_change(data)
47
53
  else
48
54
  raise ArgumentError, "Request type invalid, received request_type: #{@request_type}"
49
55
  end
@@ -61,6 +67,15 @@ module Datadog
61
67
  def app_integrations_change
62
68
  Telemetry::V1::AppEvent.new(integrations: integrations)
63
69
  end
70
+
71
+ # DEV: During the transition from V1 to V2, the backend accepts many V2
72
+ # DEV: payloads through the V1 transport protocol.
73
+ # DEV: The `app-client-configuration-change` payload is one of them.
74
+ # DEV: Once V2 is fully implemented, `Telemetry::V2::AppClientConfigurationChange`
75
+ # DEV: should be reusable without major modifications.
76
+ def app_client_configuration_change(data)
77
+ Telemetry::V2::AppClientConfigurationChange.new(data[:changes], origin: data[:origin])
78
+ end
64
79
  end
65
80
  end
66
81
  end
@@ -1,8 +1,11 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Datadog
2
4
  module Core
3
5
  module Telemetry
4
6
  module Ext
5
- ENV_ENABLED = 'DD_INSTRUMENTATION_TELEMETRY_ENABLED'.freeze
7
+ ENV_ENABLED = 'DD_INSTRUMENTATION_TELEMETRY_ENABLED'
8
+ ENV_HEARTBEAT_INTERVAL = 'DD_TELEMETRY_HEARTBEAT_INTERVAL'
6
9
  end
7
10
  end
8
11
  end
@@ -10,13 +10,11 @@ module Datadog
10
10
  class Heartbeat < Core::Worker
11
11
  include Core::Workers::Polling
12
12
 
13
- DEFAULT_INTERVAL_SECONDS = 60
14
-
15
- def initialize(enabled: true, interval: DEFAULT_INTERVAL_SECONDS, &block)
13
+ def initialize(heartbeat_interval_seconds:, enabled: true, &block)
16
14
  # Workers::Polling settings
17
15
  self.enabled = enabled
18
16
  # Workers::IntervalLoop settings
19
- self.loop_base_interval = interval
17
+ self.loop_base_interval = heartbeat_interval_seconds
20
18
  self.fork_policy = Core::Workers::Async::Thread::FORK_POLICY_STOP
21
19
  super(&block)
22
20
  start
@@ -1,18 +1,20 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Datadog
2
4
  module Core
3
5
  module Telemetry
4
6
  module Http
5
7
  module Ext
6
- HEADER_DD_API_KEY = 'DD-API-KEY'.freeze
7
- HEADER_CONTENT_TYPE = 'Content-Type'.freeze
8
- HEADER_CONTENT_LENGTH = 'Content-Length'.freeze
9
- HEADER_DD_TELEMETRY_API_VERSION = 'DD-Telemetry-API-Version'.freeze
10
- HEADER_DD_TELEMETRY_REQUEST_TYPE = 'DD-Telemetry-Request-Type'.freeze
8
+ HEADER_DD_API_KEY = 'DD-API-KEY'
9
+ HEADER_CONTENT_TYPE = 'Content-Type'
10
+ HEADER_CONTENT_LENGTH = 'Content-Length'
11
+ HEADER_DD_TELEMETRY_API_VERSION = 'DD-Telemetry-API-Version'
12
+ HEADER_DD_TELEMETRY_REQUEST_TYPE = 'DD-Telemetry-Request-Type'
11
13
 
12
- CONTENT_TYPE_APPLICATION_JSON = 'application/json'.freeze
13
- API_VERSION = 'v1'.freeze
14
+ CONTENT_TYPE_APPLICATION_JSON = 'application/json'
15
+ API_VERSION = 'v1'
14
16
 
15
- AGENT_ENDPOINT = '/telemetry/proxy/api/v2/apmtelemetry'.freeze
17
+ AGENT_ENDPOINT = '/telemetry/proxy/api/v2/apmtelemetry'
16
18
  end
17
19
  end
18
20
  end
@@ -38,6 +38,7 @@ module Datadog
38
38
 
39
39
  def headers(request_type:, api_version: Http::Ext::API_VERSION)
40
40
  {
41
+ Datadog::Transport::Ext::HTTP::HEADER_DD_INTERNAL_UNTRACED_REQUEST => '1',
41
42
  Http::Ext::HEADER_CONTENT_TYPE => Http::Ext::CONTENT_TYPE_APPLICATION_JSON,
42
43
  Http::Ext::HEADER_DD_TELEMETRY_API_VERSION => api_version,
43
44
  Http::Ext::HEADER_DD_TELEMETRY_REQUEST_TYPE => request_type,
@@ -0,0 +1,41 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'request'
4
+
5
+ module Datadog
6
+ module Core
7
+ module Telemetry
8
+ module V2
9
+ # Telemetry 'app-client-configuration-change' event.
10
+ # This request should contain client library configuration that have changes since the app-started event.
11
+ class AppClientConfigurationChange < Request
12
+ def initialize(configuration_changes, origin: 'unknown')
13
+ super('app-client-configuration-change')
14
+
15
+ @configuration_changes = configuration_changes
16
+ @origin = origin
17
+ end
18
+
19
+ # @see [Request#to_h]
20
+ def to_h
21
+ super.merge(payload: payload)
22
+ end
23
+
24
+ private
25
+
26
+ def payload
27
+ {
28
+ configuration: @configuration_changes.map do |name, value|
29
+ {
30
+ name: name,
31
+ value: value,
32
+ origin: @origin,
33
+ }
34
+ end
35
+ }
36
+ end
37
+ end
38
+ end
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,29 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Datadog
4
+ module Core
5
+ module Telemetry
6
+ module V2
7
+ # Base request object for Telemetry V2.
8
+ #
9
+ # `#to_h` is the main API, which returns a Ruby
10
+ # Hash that will be serialized as JSON.
11
+ class Request
12
+ # @param [String] request_type the Telemetry request type, which dictates how the Hash payload should be processed
13
+ def initialize(request_type)
14
+ @request_type = request_type
15
+ end
16
+
17
+ # Converts this request to a Hash that will
18
+ # be serialized as JSON.
19
+ # @return [Hash]
20
+ def to_h
21
+ {
22
+ request_type: @request_type
23
+ }
24
+ end
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
@@ -30,7 +30,7 @@ module Datadog
30
30
  "Internal error during #{self.class.name} request. Cause: #{e.class.name} #{e.message} " \
31
31
  "Location: #{Array(e.backtrace).first}"
32
32
 
33
- Datadog.logger.error(message)
33
+ Datadog.logger.debug(message)
34
34
 
35
35
  Datadog::Transport::InternalErrorResponse.new(e)
36
36
  end
@@ -126,6 +126,16 @@ module Datadog
126
126
  end.freeze
127
127
  end
128
128
 
129
+ def inspect
130
+ "#{super}, #{
131
+ {
132
+ roots: @roots,
133
+ targets: @targets,
134
+ target_files: @target_files,
135
+ client_configs: @client_configs,
136
+ }}"
137
+ end
138
+
129
139
  # When an expected key is missing
130
140
  class KeyError < StandardError
131
141
  def initialize(key)
@@ -0,0 +1,52 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Datadog
4
+ module Core
5
+ module Utils
6
+ # Helper methods for parsing string values into Numeric
7
+ module Duration
8
+ def self.call(value, base: :s)
9
+ cast = if value.include?('.')
10
+ method(:Float)
11
+ else
12
+ method(:Integer)
13
+ end
14
+
15
+ scale = case base
16
+ when :s
17
+ 1_000_000_000
18
+ when :ms
19
+ 1_000_000
20
+ when :us
21
+ 1000
22
+ when :ns
23
+ 1
24
+ else
25
+ raise ArgumentError, "invalid base: #{base.inspect}"
26
+ end
27
+
28
+ result = case value
29
+ when /^(\d+(?:\.\d+)?)h$/
30
+ cast.call(Regexp.last_match(1)) * 1_000_000_000 * 60 * 60 / scale
31
+ when /^(\d+(?:\.\d+)?)m$/
32
+ cast.call(Regexp.last_match(1)) * 1_000_000_000 * 60 / scale
33
+ when /^(\d+(?:\.\d+)?)s$/
34
+ cast.call(Regexp.last_match(1)) * 1_000_000_000 / scale
35
+ when /^(\d+(?:\.\d+)?)ms$/
36
+ cast.call(Regexp.last_match(1)) * 1_000_000 / scale
37
+ when /^(\d+(?:\.\d+)?)us$/
38
+ cast.call(Regexp.last_match(1)) * 1_000 / scale
39
+ when /^(\d+(?:\.\d+)?)ns$/
40
+ cast.call(Regexp.last_match(1)) / scale
41
+ when /^(\d+(?:\.\d+)?)$/
42
+ cast.call(Regexp.last_match(1))
43
+ else
44
+ raise ArgumentError, "invalid duration: #{value.inspect}"
45
+ end
46
+ # @type var result: Numeric
47
+ result.round
48
+ end
49
+ end
50
+ end
51
+ end
52
+ end