datadog 2.21.0 → 2.38.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 (623) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +574 -1
  3. data/ext/LIBDATADOG_DEVELOPMENT.md +3 -0
  4. data/ext/datadog_profiling_native_extension/clock_id.h +9 -1
  5. data/ext/datadog_profiling_native_extension/clock_id_from_mach.c +66 -0
  6. data/ext/datadog_profiling_native_extension/clock_id_from_pthread.c +3 -2
  7. data/ext/datadog_profiling_native_extension/collectors_cpu_and_wall_time_worker.c +301 -82
  8. data/ext/datadog_profiling_native_extension/collectors_discrete_dynamic_sampler.c +4 -4
  9. data/ext/datadog_profiling_native_extension/collectors_gc_profiling_helper.c +3 -2
  10. data/ext/datadog_profiling_native_extension/collectors_idle_sampling_helper.c +18 -4
  11. data/ext/datadog_profiling_native_extension/collectors_stack.c +63 -32
  12. data/ext/datadog_profiling_native_extension/collectors_stack.h +7 -2
  13. data/ext/datadog_profiling_native_extension/collectors_thread_context.c +728 -436
  14. data/ext/datadog_profiling_native_extension/collectors_thread_context.h +19 -6
  15. data/ext/datadog_profiling_native_extension/crashtracking_runtime_stacks.c +239 -0
  16. data/ext/datadog_profiling_native_extension/datadog_ruby_common.c +65 -1
  17. data/ext/datadog_profiling_native_extension/datadog_ruby_common.h +40 -1
  18. data/ext/datadog_profiling_native_extension/encoded_profile.c +2 -1
  19. data/ext/datadog_profiling_native_extension/extconf.rb +41 -37
  20. data/ext/datadog_profiling_native_extension/gvl_profiling_helper.c +4 -43
  21. data/ext/datadog_profiling_native_extension/gvl_profiling_helper.h +15 -47
  22. data/ext/datadog_profiling_native_extension/heap_recorder.c +252 -103
  23. data/ext/datadog_profiling_native_extension/heap_recorder.h +12 -1
  24. data/ext/datadog_profiling_native_extension/http_transport.c +66 -68
  25. data/ext/datadog_profiling_native_extension/libdatadog_helpers.c +3 -22
  26. data/ext/datadog_profiling_native_extension/libdatadog_helpers.h +0 -5
  27. data/ext/datadog_profiling_native_extension/macos_sampler_thread.h +55 -0
  28. data/ext/datadog_profiling_native_extension/native_extension_helpers.rb +0 -13
  29. data/ext/datadog_profiling_native_extension/private_vm_api_access.c +40 -43
  30. data/ext/datadog_profiling_native_extension/private_vm_api_access.h +6 -0
  31. data/ext/datadog_profiling_native_extension/profiling.c +65 -19
  32. data/ext/datadog_profiling_native_extension/ruby_helpers.c +63 -46
  33. data/ext/datadog_profiling_native_extension/ruby_helpers.h +17 -5
  34. data/ext/datadog_profiling_native_extension/setup_signal_handler.c +32 -10
  35. data/ext/datadog_profiling_native_extension/setup_signal_handler.h +2 -1
  36. data/ext/datadog_profiling_native_extension/stack_recorder.c +110 -85
  37. data/ext/datadog_profiling_native_extension/stack_recorder.h +3 -1
  38. data/ext/datadog_profiling_native_extension/time_helpers.h +13 -7
  39. data/ext/datadog_profiling_native_extension/unsafe_api_calls_check.c +2 -1
  40. data/ext/datadog_profiling_native_extension/unsafe_api_calls_check.h +9 -4
  41. data/ext/libdatadog_api/crashtracker.c +16 -15
  42. data/ext/libdatadog_api/crashtracker_report_exception.c +126 -0
  43. data/ext/libdatadog_api/datadog_ruby_common.c +65 -1
  44. data/ext/libdatadog_api/datadog_ruby_common.h +40 -1
  45. data/ext/libdatadog_api/ddsketch.c +102 -0
  46. data/ext/libdatadog_api/di.c +203 -0
  47. data/ext/libdatadog_api/extconf.rb +18 -24
  48. data/ext/libdatadog_api/feature_flags.c +554 -0
  49. data/ext/libdatadog_api/feature_flags.h +5 -0
  50. data/ext/libdatadog_api/helpers.h +27 -0
  51. data/ext/libdatadog_api/init.c +13 -1
  52. data/ext/libdatadog_api/library_config.c +34 -25
  53. data/ext/libdatadog_api/process_discovery.c +19 -13
  54. data/ext/libdatadog_extconf_helpers.rb +94 -11
  55. data/lib/datadog/ai_guard/api_client.rb +84 -0
  56. data/lib/datadog/ai_guard/autoload.rb +10 -0
  57. data/lib/datadog/ai_guard/component.rb +44 -0
  58. data/lib/datadog/ai_guard/configuration/ext.rb +17 -0
  59. data/lib/datadog/ai_guard/configuration.rb +115 -0
  60. data/lib/datadog/ai_guard/contrib/auto_instrument.rb +24 -0
  61. data/lib/datadog/ai_guard/contrib/integration.rb +37 -0
  62. data/lib/datadog/ai_guard/contrib/rack/integration.rb +42 -0
  63. data/lib/datadog/ai_guard/contrib/rack/patcher.rb +26 -0
  64. data/lib/datadog/ai_guard/contrib/rack/request_middleware.rb +97 -0
  65. data/lib/datadog/ai_guard/contrib/rails/integration.rb +41 -0
  66. data/lib/datadog/ai_guard/contrib/rails/patcher.rb +97 -0
  67. data/lib/datadog/ai_guard/contrib/ruby_llm/chat_instrumentation.rb +80 -0
  68. data/lib/datadog/ai_guard/contrib/ruby_llm/integration.rb +41 -0
  69. data/lib/datadog/ai_guard/contrib/ruby_llm/patcher.rb +30 -0
  70. data/lib/datadog/ai_guard/evaluation/content_builder.rb +31 -0
  71. data/lib/datadog/ai_guard/evaluation/content_part.rb +36 -0
  72. data/lib/datadog/ai_guard/evaluation/message.rb +25 -0
  73. data/lib/datadog/ai_guard/evaluation/no_op_result.rb +36 -0
  74. data/lib/datadog/ai_guard/evaluation/request.rb +86 -0
  75. data/lib/datadog/ai_guard/evaluation/result.rb +45 -0
  76. data/lib/datadog/ai_guard/evaluation/tool_call.rb +18 -0
  77. data/lib/datadog/ai_guard/evaluation.rb +108 -0
  78. data/lib/datadog/ai_guard/ext.rb +29 -0
  79. data/lib/datadog/ai_guard.rb +181 -0
  80. data/lib/datadog/appsec/api_security/endpoint_collection/grape_route_serializer.rb +26 -0
  81. data/lib/datadog/appsec/api_security/endpoint_collection/rails_collector.rb +66 -0
  82. data/lib/datadog/appsec/api_security/endpoint_collection/rails_route_serializer.rb +36 -0
  83. data/lib/datadog/appsec/api_security/endpoint_collection/sinatra_route_serializer.rb +26 -0
  84. data/lib/datadog/appsec/api_security/endpoint_collection.rb +10 -0
  85. data/lib/datadog/appsec/api_security/route_extractor.rb +38 -9
  86. data/lib/datadog/appsec/api_security/sampler.rb +7 -4
  87. data/lib/datadog/appsec/assets/blocked.html +10 -1
  88. data/lib/datadog/appsec/assets/blocked.json +1 -1
  89. data/lib/datadog/appsec/assets/blocked.text +3 -1
  90. data/lib/datadog/appsec/assets/waf_rules/README.md +30 -36
  91. data/lib/datadog/appsec/assets/waf_rules/recommended.json +359 -4
  92. data/lib/datadog/appsec/assets/waf_rules/strict.json +43 -2
  93. data/lib/datadog/appsec/assets.rb +1 -1
  94. data/lib/datadog/appsec/autoload.rb +1 -1
  95. data/lib/datadog/appsec/component.rb +16 -9
  96. data/lib/datadog/appsec/compressed_json.rb +3 -3
  97. data/lib/datadog/appsec/configuration.rb +427 -1
  98. data/lib/datadog/appsec/context.rb +51 -13
  99. data/lib/datadog/appsec/contrib/active_record/instrumentation.rb +3 -1
  100. data/lib/datadog/appsec/contrib/active_record/integration.rb +1 -1
  101. data/lib/datadog/appsec/contrib/active_record/patcher.rb +4 -1
  102. data/lib/datadog/appsec/contrib/aws_lambda/gateway/watcher.rb +75 -0
  103. data/lib/datadog/appsec/contrib/aws_lambda/integration.rb +39 -0
  104. data/lib/datadog/appsec/contrib/aws_lambda/patcher.rb +30 -0
  105. data/lib/datadog/appsec/contrib/aws_lambda/waf_addresses.rb +144 -0
  106. data/lib/datadog/appsec/contrib/devise/integration.rb +1 -1
  107. data/lib/datadog/appsec/contrib/devise/patches/signin_tracking_patch.rb +2 -1
  108. data/lib/datadog/appsec/contrib/excon/integration.rb +1 -1
  109. data/lib/datadog/appsec/contrib/excon/patcher.rb +3 -1
  110. data/lib/datadog/appsec/contrib/excon/ssrf_detection_middleware.rb +152 -12
  111. data/lib/datadog/appsec/contrib/faraday/integration.rb +1 -1
  112. data/lib/datadog/appsec/contrib/faraday/patcher.rb +1 -1
  113. data/lib/datadog/appsec/contrib/faraday/ssrf_detection_middleware.rb +138 -12
  114. data/lib/datadog/appsec/contrib/graphql/gateway/multiplex.rb +74 -24
  115. data/lib/datadog/appsec/contrib/graphql/gateway/watcher.rb +4 -2
  116. data/lib/datadog/appsec/contrib/graphql/integration.rb +2 -1
  117. data/lib/datadog/appsec/contrib/rack/buffered_input.rb +83 -0
  118. data/lib/datadog/appsec/contrib/rack/ext.rb +1 -1
  119. data/lib/datadog/appsec/contrib/rack/gateway/request.rb +52 -13
  120. data/lib/datadog/appsec/contrib/rack/gateway/watcher.rb +40 -19
  121. data/lib/datadog/appsec/contrib/rack/input_peeker.rb +79 -0
  122. data/lib/datadog/appsec/contrib/rack/integration.rb +1 -1
  123. data/lib/datadog/appsec/contrib/rack/request_middleware.rb +48 -33
  124. data/lib/datadog/appsec/contrib/rack/response_body.rb +36 -0
  125. data/lib/datadog/appsec/contrib/rails/gateway/request.rb +40 -1
  126. data/lib/datadog/appsec/contrib/rails/gateway/watcher.rb +26 -5
  127. data/lib/datadog/appsec/contrib/rails/integration.rb +1 -1
  128. data/lib/datadog/appsec/contrib/rails/patcher.rb +38 -0
  129. data/lib/datadog/appsec/contrib/rails/patches/process_action_patch.rb +2 -0
  130. data/lib/datadog/appsec/contrib/rest_client/integration.rb +1 -1
  131. data/lib/datadog/appsec/contrib/rest_client/patcher.rb +3 -1
  132. data/lib/datadog/appsec/contrib/rest_client/request_ssrf_detection_patch.rb +167 -11
  133. data/lib/datadog/appsec/contrib/sinatra/gateway/watcher.rb +43 -13
  134. data/lib/datadog/appsec/contrib/sinatra/integration.rb +1 -1
  135. data/lib/datadog/appsec/contrib/sinatra/patcher.rb +4 -4
  136. data/lib/datadog/appsec/contrib/sinatra/patches/json_patch.rb +1 -1
  137. data/lib/datadog/appsec/counter_sampler.rb +25 -0
  138. data/lib/datadog/appsec/default_header_tags.rb +52 -0
  139. data/lib/datadog/appsec/event.rb +13 -31
  140. data/lib/datadog/appsec/ext.rb +3 -0
  141. data/lib/datadog/appsec/instrumentation/gateway/middleware.rb +2 -3
  142. data/lib/datadog/appsec/instrumentation/gateway.rb +2 -15
  143. data/lib/datadog/appsec/metrics/collector.rb +43 -5
  144. data/lib/datadog/appsec/metrics/exporter.rb +16 -3
  145. data/lib/datadog/appsec/metrics/telemetry.rb +20 -3
  146. data/lib/datadog/appsec/metrics/telemetry_exporter.rb +20 -1
  147. data/lib/datadog/appsec/metrics.rb +5 -5
  148. data/lib/datadog/appsec/monitor/gateway/watcher.rb +8 -6
  149. data/lib/datadog/appsec/remote.rb +44 -29
  150. data/lib/datadog/appsec/response.rb +18 -4
  151. data/lib/datadog/appsec/route_normalizer/rails_route_pattern.rb +176 -0
  152. data/lib/datadog/appsec/route_normalizer/route_pattern.rb +378 -0
  153. data/lib/datadog/appsec/route_normalizer/route_text.rb +57 -0
  154. data/lib/datadog/appsec/route_normalizer.rb +80 -0
  155. data/lib/datadog/appsec/security_engine/engine.rb +26 -5
  156. data/lib/datadog/appsec/security_engine/result.rb +29 -9
  157. data/lib/datadog/appsec/security_engine/runner.rb +20 -10
  158. data/lib/datadog/appsec/security_event.rb +5 -7
  159. data/lib/datadog/appsec/trace_keeper.rb +18 -6
  160. data/lib/datadog/appsec/utils/http/body.rb +38 -0
  161. data/lib/datadog/appsec/utils/http/body_reader.rb +61 -0
  162. data/lib/datadog/appsec/utils/http/media_range.rb +2 -1
  163. data/lib/datadog/appsec/utils/http/media_type.rb +32 -26
  164. data/lib/datadog/appsec/utils/http/url_encoded.rb +52 -0
  165. data/lib/datadog/appsec.rb +6 -3
  166. data/lib/datadog/core/configuration/agentless_settings_resolver.rb +2 -2
  167. data/lib/datadog/core/configuration/base.rb +17 -5
  168. data/lib/datadog/core/configuration/components.rb +185 -17
  169. data/lib/datadog/core/configuration/components_state.rb +6 -1
  170. data/lib/datadog/core/configuration/config_helper.rb +11 -2
  171. data/lib/datadog/core/configuration/deprecations.rb +2 -2
  172. data/lib/datadog/core/configuration/option.rb +32 -6
  173. data/lib/datadog/core/configuration/option_definition.rb +42 -14
  174. data/lib/datadog/core/configuration/options.rb +49 -12
  175. data/lib/datadog/core/configuration/settings.rb +115 -16
  176. data/lib/datadog/core/configuration/stable_config.rb +10 -0
  177. data/lib/datadog/core/configuration/supported_configurations.rb +379 -300
  178. data/lib/datadog/core/configuration.rb +3 -3
  179. data/lib/datadog/core/contrib/rails/railtie.rb +32 -0
  180. data/lib/datadog/core/contrib/rails/utils.rb +7 -3
  181. data/lib/datadog/core/crashtracking/component.rb +73 -21
  182. data/lib/datadog/core/crashtracking/tag_builder.rb +6 -0
  183. data/lib/datadog/core/ddsketch.rb +19 -0
  184. data/lib/datadog/core/diagnostics/environment_logger.rb +3 -1
  185. data/lib/datadog/core/environment/agent_info.rb +65 -1
  186. data/lib/datadog/core/environment/cgroup.rb +52 -25
  187. data/lib/datadog/core/environment/container.rb +140 -46
  188. data/lib/datadog/core/environment/ext.rb +13 -0
  189. data/lib/datadog/core/environment/identity.rb +40 -4
  190. data/lib/datadog/core/environment/process.rb +122 -0
  191. data/lib/datadog/core/environment/socket.rb +13 -0
  192. data/lib/datadog/core/environment/yjit.rb +2 -1
  193. data/lib/datadog/core/error.rb +6 -6
  194. data/lib/datadog/core/evp.rb +11 -0
  195. data/lib/datadog/core/feature_flags.rb +61 -0
  196. data/lib/datadog/core/knuth_sampler.rb +59 -0
  197. data/lib/datadog/core/logger.rb +1 -1
  198. data/lib/datadog/core/metrics/client.rb +6 -6
  199. data/lib/datadog/core/metrics/logging.rb +1 -1
  200. data/lib/datadog/core/pin.rb +8 -8
  201. data/lib/datadog/core/process_discovery.rb +21 -18
  202. data/lib/datadog/core/rate_limiter.rb +11 -1
  203. data/lib/datadog/core/remote/client/capabilities.rb +49 -6
  204. data/lib/datadog/core/remote/client.rb +15 -7
  205. data/lib/datadog/core/remote/component.rb +64 -36
  206. data/lib/datadog/core/remote/configuration/content.rb +15 -2
  207. data/lib/datadog/core/remote/configuration/digest.rb +14 -7
  208. data/lib/datadog/core/remote/configuration/repository.rb +1 -1
  209. data/lib/datadog/core/remote/configuration/target.rb +13 -6
  210. data/lib/datadog/core/remote/transport/config.rb +9 -36
  211. data/lib/datadog/core/remote/transport/http/config.rb +15 -55
  212. data/lib/datadog/core/remote/transport/http/negotiation.rb +14 -44
  213. data/lib/datadog/core/remote/transport/http.rb +15 -24
  214. data/lib/datadog/core/remote/transport/negotiation.rb +8 -33
  215. data/lib/datadog/core/remote/worker.rb +25 -37
  216. data/lib/datadog/core/runtime/metrics.rb +11 -2
  217. data/lib/datadog/core/semaphore.rb +1 -4
  218. data/lib/datadog/core/tag_builder.rb +0 -4
  219. data/lib/datadog/core/tag_normalizer.rb +84 -0
  220. data/lib/datadog/core/telemetry/component.rb +59 -15
  221. data/lib/datadog/core/telemetry/emitter.rb +6 -6
  222. data/lib/datadog/core/telemetry/event/app_client_configuration_change.rb +2 -3
  223. data/lib/datadog/core/telemetry/event/app_endpoints_loaded.rb +30 -0
  224. data/lib/datadog/core/telemetry/event/app_extended_heartbeat.rb +32 -0
  225. data/lib/datadog/core/telemetry/event/app_started.rb +177 -171
  226. data/lib/datadog/core/telemetry/event/synth_app_client_configuration_change.rb +27 -4
  227. data/lib/datadog/core/telemetry/event.rb +2 -7
  228. data/lib/datadog/core/telemetry/ext.rb +1 -0
  229. data/lib/datadog/core/telemetry/logger.rb +4 -2
  230. data/lib/datadog/core/telemetry/logging.rb +17 -5
  231. data/lib/datadog/core/telemetry/metrics_manager.rb +9 -0
  232. data/lib/datadog/core/telemetry/request.rb +17 -5
  233. data/lib/datadog/core/telemetry/transport/http/telemetry.rb +8 -34
  234. data/lib/datadog/core/telemetry/transport/http.rb +21 -16
  235. data/lib/datadog/core/telemetry/transport/telemetry.rb +8 -17
  236. data/lib/datadog/core/telemetry/worker.rb +108 -32
  237. data/lib/datadog/core/transport/ext.rb +3 -0
  238. data/lib/datadog/core/transport/http/api/endpoint.rb +9 -4
  239. data/lib/datadog/core/transport/http/api/instance.rb +4 -21
  240. data/lib/datadog/core/transport/http/builder.rb +10 -6
  241. data/lib/datadog/core/transport/http/client.rb +80 -0
  242. data/lib/datadog/core/transport/http/response.rb +4 -0
  243. data/lib/datadog/core/transport/http.rb +24 -19
  244. data/lib/datadog/core/transport/parcel.rb +61 -9
  245. data/lib/datadog/core/transport/response.rb +16 -2
  246. data/lib/datadog/core/transport/transport.rb +90 -0
  247. data/lib/datadog/core/utils/at_fork_monkey_patch.rb +2 -2
  248. data/lib/datadog/core/utils/{base64.rb → base64_codec.rb} +4 -3
  249. data/lib/datadog/core/utils/enumerable_compat.rb +29 -0
  250. data/lib/datadog/core/utils/fnv.rb +26 -0
  251. data/lib/datadog/core/utils/forking.rb +3 -1
  252. data/lib/datadog/core/utils/hash.rb +0 -23
  253. data/lib/datadog/{appsec/api_security → core/utils}/lru_cache.rb +10 -21
  254. data/lib/datadog/core/utils/network.rb +22 -1
  255. data/lib/datadog/core/utils/only_once.rb +1 -1
  256. data/lib/datadog/core/utils/only_once_successful.rb +8 -2
  257. data/lib/datadog/core/utils/safe_dup.rb +2 -2
  258. data/lib/datadog/core/utils/sequence.rb +2 -0
  259. data/lib/datadog/core/utils/spawn_monkey_patch.rb +68 -0
  260. data/lib/datadog/core/utils/time.rb +6 -2
  261. data/lib/datadog/core/utils.rb +3 -1
  262. data/lib/datadog/core/workers/async.rb +11 -2
  263. data/lib/datadog/core/workers/interval_loop.rb +51 -3
  264. data/lib/datadog/core/workers/polling.rb +2 -0
  265. data/lib/datadog/core/workers/queue.rb +96 -1
  266. data/lib/datadog/core/workers/runtime_metrics.rb +9 -1
  267. data/lib/datadog/core.rb +10 -3
  268. data/lib/datadog/data_streams/configuration.rb +50 -0
  269. data/lib/datadog/data_streams/ext.rb +11 -0
  270. data/lib/datadog/data_streams/extensions.rb +16 -0
  271. data/lib/datadog/data_streams/pathway_context.rb +169 -0
  272. data/lib/datadog/data_streams/processor.rb +511 -0
  273. data/lib/datadog/data_streams/transport/http/stats.rb +58 -0
  274. data/lib/datadog/data_streams/transport/http.rb +36 -0
  275. data/lib/datadog/data_streams/transport/stats.rb +39 -0
  276. data/lib/datadog/data_streams.rb +100 -0
  277. data/lib/datadog/di/base.rb +15 -7
  278. data/lib/datadog/di/boot.rb +7 -2
  279. data/lib/datadog/di/capture_expression.rb +21 -0
  280. data/lib/datadog/di/capture_expression_evaluator.rb +71 -0
  281. data/lib/datadog/di/capture_limits.rb +41 -0
  282. data/lib/datadog/di/code_tracker.rb +217 -15
  283. data/lib/datadog/di/component.rb +139 -51
  284. data/lib/datadog/di/configuration.rb +241 -2
  285. data/lib/datadog/di/context.rb +82 -0
  286. data/lib/datadog/di/contrib/active_record.rb +34 -5
  287. data/lib/datadog/di/el/compiler.rb +168 -0
  288. data/lib/datadog/di/el/evaluator.rb +159 -0
  289. data/lib/datadog/di/el/expression.rb +42 -0
  290. data/lib/datadog/di/el.rb +5 -0
  291. data/lib/datadog/di/error.rb +44 -0
  292. data/lib/datadog/di/fatal_exceptions.rb +26 -0
  293. data/lib/datadog/di/instrumenter.rb +623 -147
  294. data/lib/datadog/di/logger.rb +2 -2
  295. data/lib/datadog/di/probe.rb +122 -14
  296. data/lib/datadog/di/probe_builder.rb +124 -3
  297. data/lib/datadog/di/probe_file_loader/railtie.rb +1 -1
  298. data/lib/datadog/di/probe_file_loader.rb +12 -7
  299. data/lib/datadog/di/probe_manager.rb +195 -100
  300. data/lib/datadog/di/probe_notification_builder.rb +321 -90
  301. data/lib/datadog/di/probe_notifier_worker.rb +112 -36
  302. data/lib/datadog/di/probe_repository.rb +198 -0
  303. data/lib/datadog/di/proc_responder.rb +36 -0
  304. data/lib/datadog/di/redactor.rb +24 -2
  305. data/lib/datadog/di/remote.rb +258 -93
  306. data/lib/datadog/di/serializer.rb +310 -29
  307. data/lib/datadog/di/transport/diagnostics.rb +12 -42
  308. data/lib/datadog/di/transport/http/diagnostics.rb +4 -34
  309. data/lib/datadog/di/transport/http/input.rb +2 -34
  310. data/lib/datadog/di/transport/http.rb +43 -19
  311. data/lib/datadog/di/transport/input.rb +112 -38
  312. data/lib/datadog/di/utils.rb +42 -14
  313. data/lib/datadog/di.rb +204 -4
  314. data/lib/datadog/error_tracking/collector.rb +2 -1
  315. data/lib/datadog/error_tracking/component.rb +2 -2
  316. data/lib/datadog/error_tracking/configuration.rb +55 -2
  317. data/lib/datadog/error_tracking/filters.rb +2 -2
  318. data/lib/datadog/kit/appsec/events/v2.rb +60 -3
  319. data/lib/datadog/kit/enable_core_dumps.rb +1 -1
  320. data/lib/datadog/kit/tracing/method_tracer.rb +135 -0
  321. data/lib/datadog/open_feature/component.rb +100 -0
  322. data/lib/datadog/open_feature/configuration.rb +37 -0
  323. data/lib/datadog/open_feature/evaluation_engine.rb +70 -0
  324. data/lib/datadog/open_feature/exposures/batch_builder.rb +32 -0
  325. data/lib/datadog/open_feature/exposures/buffer.rb +43 -0
  326. data/lib/datadog/open_feature/exposures/deduplicator.rb +30 -0
  327. data/lib/datadog/open_feature/exposures/event.rb +60 -0
  328. data/lib/datadog/open_feature/exposures/reporter.rb +40 -0
  329. data/lib/datadog/open_feature/exposures/worker.rb +116 -0
  330. data/lib/datadog/open_feature/ext.rb +16 -0
  331. data/lib/datadog/open_feature/flag_evaluation/aggregator.rb +286 -0
  332. data/lib/datadog/open_feature/flag_evaluation/writer.rb +433 -0
  333. data/lib/datadog/open_feature/hooks/flag_eval_evp_hook.rb +101 -0
  334. data/lib/datadog/open_feature/hooks/flag_eval_metrics_hook.rb +49 -0
  335. data/lib/datadog/open_feature/metrics/flag_eval_metrics.rb +149 -0
  336. data/lib/datadog/open_feature/native_evaluator.rb +60 -0
  337. data/lib/datadog/open_feature/noop_evaluator.rb +26 -0
  338. data/lib/datadog/open_feature/provider.rb +191 -0
  339. data/lib/datadog/open_feature/remote.rb +67 -0
  340. data/lib/datadog/open_feature/resolution_details.rb +35 -0
  341. data/lib/datadog/open_feature/transport.rb +121 -0
  342. data/lib/datadog/open_feature.rb +19 -0
  343. data/lib/datadog/opentelemetry/api/baggage.rb +1 -1
  344. data/lib/datadog/opentelemetry/configuration/settings.rb +226 -0
  345. data/lib/datadog/opentelemetry/ext.rb +9 -0
  346. data/lib/datadog/opentelemetry/logs.rb +98 -0
  347. data/lib/datadog/opentelemetry/metrics.rb +90 -0
  348. data/lib/datadog/opentelemetry/sdk/configurator.rb +65 -1
  349. data/lib/datadog/opentelemetry/sdk/id_generator.rb +16 -10
  350. data/lib/datadog/opentelemetry/sdk/logs_exporter.rb +30 -0
  351. data/lib/datadog/opentelemetry/sdk/metrics_exporter.rb +28 -0
  352. data/lib/datadog/opentelemetry/sdk/propagator.rb +9 -3
  353. data/lib/datadog/opentelemetry/sdk/span_processor.rb +4 -1
  354. data/lib/datadog/opentelemetry/sdk.rb +19 -0
  355. data/lib/datadog/opentelemetry/signal_configuration.rb +53 -0
  356. data/lib/datadog/opentelemetry.rb +4 -0
  357. data/lib/datadog/profiling/collectors/code_provenance.rb +71 -12
  358. data/lib/datadog/profiling/collectors/cpu_and_wall_time_worker.rb +52 -4
  359. data/lib/datadog/profiling/collectors/idle_sampling_helper.rb +13 -5
  360. data/lib/datadog/profiling/collectors/info.rb +18 -4
  361. data/lib/datadog/profiling/collectors/thread_context.rb +10 -5
  362. data/lib/datadog/profiling/component.rb +82 -40
  363. data/lib/datadog/profiling/exporter.rb +41 -12
  364. data/lib/datadog/profiling/ext/dir_monkey_patches.rb +24 -5
  365. data/lib/datadog/profiling/ext/exec_monkey_patch.rb +32 -0
  366. data/lib/datadog/profiling/ext.rb +0 -2
  367. data/lib/datadog/profiling/flush.rb +23 -11
  368. data/lib/datadog/profiling/http_transport.rb +21 -8
  369. data/lib/datadog/profiling/load_native_extension.rb +2 -2
  370. data/lib/datadog/profiling/profiler.rb +31 -14
  371. data/lib/datadog/profiling/scheduler.rb +10 -9
  372. data/lib/datadog/profiling/stack_recorder.rb +0 -8
  373. data/lib/datadog/profiling/tag_builder.rb +37 -3
  374. data/lib/datadog/profiling/tasks/exec.rb +8 -3
  375. data/lib/datadog/profiling/tasks/help.rb +1 -0
  376. data/lib/datadog/profiling/tasks/setup.rb +2 -2
  377. data/lib/datadog/profiling.rb +1 -3
  378. data/lib/datadog/ruby_version.rb +25 -0
  379. data/lib/datadog/single_step_instrument.rb +2 -2
  380. data/lib/datadog/symbol_database/component.rb +734 -0
  381. data/lib/datadog/symbol_database/configuration.rb +73 -0
  382. data/lib/datadog/symbol_database/extensions.rb +19 -0
  383. data/lib/datadog/symbol_database/extractor.rb +1110 -0
  384. data/lib/datadog/symbol_database/file_hash.rb +48 -0
  385. data/lib/datadog/symbol_database/logger.rb +43 -0
  386. data/lib/datadog/symbol_database/remote.rb +180 -0
  387. data/lib/datadog/symbol_database/scope.rb +102 -0
  388. data/lib/datadog/symbol_database/scope_batcher.rb +292 -0
  389. data/lib/datadog/symbol_database/service_version.rb +66 -0
  390. data/lib/datadog/symbol_database/symbol.rb +69 -0
  391. data/lib/datadog/symbol_database/transport/http/endpoint.rb +28 -0
  392. data/lib/datadog/symbol_database/transport/http.rb +45 -0
  393. data/lib/datadog/symbol_database/transport.rb +54 -0
  394. data/lib/datadog/symbol_database/uploader.rb +230 -0
  395. data/lib/datadog/symbol_database.rb +71 -0
  396. data/lib/datadog/tracing/buffer.rb +3 -3
  397. data/lib/datadog/tracing/component.rb +17 -17
  398. data/lib/datadog/tracing/configuration/dynamic.rb +2 -2
  399. data/lib/datadog/tracing/configuration/ext.rb +22 -0
  400. data/lib/datadog/tracing/configuration/settings.rb +96 -4
  401. data/lib/datadog/tracing/contrib/action_cable/events/broadcast.rb +4 -1
  402. data/lib/datadog/tracing/contrib/action_cable/events/perform_action.rb +4 -1
  403. data/lib/datadog/tracing/contrib/action_cable/events/transmit.rb +4 -1
  404. data/lib/datadog/tracing/contrib/action_cable/instrumentation.rb +4 -1
  405. data/lib/datadog/tracing/contrib/action_mailer/event.rb +4 -1
  406. data/lib/datadog/tracing/contrib/action_pack/action_controller/instrumentation.rb +10 -7
  407. data/lib/datadog/tracing/contrib/action_pack/action_dispatch/instrumentation.rb +28 -0
  408. data/lib/datadog/tracing/contrib/action_pack/action_dispatch/patcher.rb +3 -1
  409. data/lib/datadog/tracing/contrib/action_pack/utils.rb +1 -2
  410. data/lib/datadog/tracing/contrib/action_view/events/render_partial.rb +4 -1
  411. data/lib/datadog/tracing/contrib/action_view/events/render_template.rb +5 -2
  412. data/lib/datadog/tracing/contrib/active_job/data_streams.rb +62 -0
  413. data/lib/datadog/tracing/contrib/active_job/events/discard.rb +5 -2
  414. data/lib/datadog/tracing/contrib/active_job/events/enqueue.rb +5 -2
  415. data/lib/datadog/tracing/contrib/active_job/events/enqueue_at.rb +5 -2
  416. data/lib/datadog/tracing/contrib/active_job/events/enqueue_retry.rb +5 -2
  417. data/lib/datadog/tracing/contrib/active_job/events/perform.rb +5 -2
  418. data/lib/datadog/tracing/contrib/active_job/events/retry_stopped.rb +5 -2
  419. data/lib/datadog/tracing/contrib/active_job/log_injection.rb +21 -7
  420. data/lib/datadog/tracing/contrib/active_job/patcher.rb +17 -1
  421. data/lib/datadog/tracing/contrib/active_model_serializers/events/render.rb +1 -1
  422. data/lib/datadog/tracing/contrib/active_model_serializers/events/serialize.rb +3 -4
  423. data/lib/datadog/tracing/contrib/active_record/configuration/resolver.rb +2 -2
  424. data/lib/datadog/tracing/contrib/active_record/events/instantiation.rb +1 -1
  425. data/lib/datadog/tracing/contrib/active_record/events/sql.rb +2 -5
  426. data/lib/datadog/tracing/contrib/active_record/utils.rb +1 -1
  427. data/lib/datadog/tracing/contrib/active_support/cache/events/cache.rb +2 -5
  428. data/lib/datadog/tracing/contrib/active_support/cache/instrumentation.rb +1 -4
  429. data/lib/datadog/tracing/contrib/active_support/notifications/subscription.rb +2 -2
  430. data/lib/datadog/tracing/contrib/aws/instrumentation.rb +6 -8
  431. data/lib/datadog/tracing/contrib/component.rb +3 -3
  432. data/lib/datadog/tracing/contrib/configurable.rb +18 -3
  433. data/lib/datadog/tracing/contrib/configuration/resolver.rb +14 -4
  434. data/lib/datadog/tracing/contrib/dalli/instrumentation.rb +1 -5
  435. data/lib/datadog/tracing/contrib/dalli/integration.rb +4 -1
  436. data/lib/datadog/tracing/contrib/dalli/quantize.rb +1 -1
  437. data/lib/datadog/tracing/contrib/delayed_job/plugin.rb +2 -0
  438. data/lib/datadog/tracing/contrib/delayed_job/server_internal_tracer/worker.rb +1 -0
  439. data/lib/datadog/tracing/contrib/elasticsearch/patcher.rb +2 -6
  440. data/lib/datadog/tracing/contrib/elasticsearch/quantize.rb +2 -2
  441. data/lib/datadog/tracing/contrib/ethon/configuration/settings.rb +5 -1
  442. data/lib/datadog/tracing/contrib/ethon/easy_patch.rb +5 -6
  443. data/lib/datadog/tracing/contrib/ethon/ext.rb +1 -0
  444. data/lib/datadog/tracing/contrib/ethon/multi_patch.rb +1 -8
  445. data/lib/datadog/tracing/contrib/excon/configuration/settings.rb +16 -5
  446. data/lib/datadog/tracing/contrib/excon/ext.rb +1 -0
  447. data/lib/datadog/tracing/contrib/excon/middleware.rb +3 -7
  448. data/lib/datadog/tracing/contrib/ext.rb +3 -1
  449. data/lib/datadog/tracing/contrib/extensions.rb +19 -2
  450. data/lib/datadog/tracing/contrib/faraday/configuration/settings.rb +16 -9
  451. data/lib/datadog/tracing/contrib/faraday/ext.rb +1 -0
  452. data/lib/datadog/tracing/contrib/faraday/middleware.rb +3 -7
  453. data/lib/datadog/tracing/contrib/grape/configuration/settings.rb +7 -3
  454. data/lib/datadog/tracing/contrib/grape/endpoint.rb +10 -7
  455. data/lib/datadog/tracing/contrib/grape/instrumentation.rb +13 -8
  456. data/lib/datadog/tracing/contrib/grape/patcher.rb +6 -1
  457. data/lib/datadog/tracing/contrib/graphql/configuration/settings.rb +7 -0
  458. data/lib/datadog/tracing/contrib/graphql/ext.rb +1 -0
  459. data/lib/datadog/tracing/contrib/graphql/unified_trace.rb +75 -44
  460. data/lib/datadog/tracing/contrib/grpc/configuration/settings.rb +5 -2
  461. data/lib/datadog/tracing/contrib/grpc/datadog_interceptor/client.rb +3 -7
  462. data/lib/datadog/tracing/contrib/grpc/datadog_interceptor/server.rb +3 -7
  463. data/lib/datadog/tracing/contrib/grpc/distributed/propagation.rb +2 -0
  464. data/lib/datadog/tracing/contrib/grpc/ext.rb +1 -0
  465. data/lib/datadog/tracing/contrib/grpc.rb +1 -0
  466. data/lib/datadog/tracing/contrib/hanami/action_tracer.rb +1 -0
  467. data/lib/datadog/tracing/contrib/hanami/renderer_policy_tracing.rb +1 -0
  468. data/lib/datadog/tracing/contrib/hanami/router_tracing.rb +1 -0
  469. data/lib/datadog/tracing/contrib/http/configuration/settings.rb +16 -5
  470. data/lib/datadog/tracing/contrib/http/distributed/propagation.rb +2 -0
  471. data/lib/datadog/tracing/contrib/http/ext.rb +1 -0
  472. data/lib/datadog/tracing/contrib/http/instrumentation.rb +4 -8
  473. data/lib/datadog/tracing/contrib/http/integration.rb +0 -2
  474. data/lib/datadog/tracing/contrib/http.rb +1 -0
  475. data/lib/datadog/tracing/contrib/httpclient/configuration/settings.rb +16 -5
  476. data/lib/datadog/tracing/contrib/httpclient/ext.rb +1 -0
  477. data/lib/datadog/tracing/contrib/httpclient/instrumentation.rb +7 -7
  478. data/lib/datadog/tracing/contrib/httprb/configuration/settings.rb +16 -5
  479. data/lib/datadog/tracing/contrib/httprb/ext.rb +1 -0
  480. data/lib/datadog/tracing/contrib/httprb/instrumentation.rb +4 -8
  481. data/lib/datadog/tracing/contrib/kafka/event.rb +1 -0
  482. data/lib/datadog/tracing/contrib/kafka/instrumentation/consumer.rb +66 -0
  483. data/lib/datadog/tracing/contrib/kafka/instrumentation/producer.rb +66 -0
  484. data/lib/datadog/tracing/contrib/kafka/patcher.rb +14 -0
  485. data/lib/datadog/tracing/contrib/karafka/configuration/settings.rb +5 -1
  486. data/lib/datadog/tracing/contrib/karafka/distributed/propagation.rb +2 -0
  487. data/lib/datadog/tracing/contrib/karafka/ext.rb +1 -0
  488. data/lib/datadog/tracing/contrib/karafka/framework.rb +30 -0
  489. data/lib/datadog/tracing/contrib/karafka/monitor.rb +11 -0
  490. data/lib/datadog/tracing/contrib/karafka/patcher.rb +35 -4
  491. data/lib/datadog/tracing/contrib/karafka.rb +1 -0
  492. data/lib/datadog/tracing/contrib/mongodb/parsers.rb +5 -5
  493. data/lib/datadog/tracing/contrib/mongodb/subscribers.rb +5 -8
  494. data/lib/datadog/tracing/contrib/mysql2/configuration/settings.rb +6 -0
  495. data/lib/datadog/tracing/contrib/mysql2/instrumentation.rb +3 -6
  496. data/lib/datadog/tracing/contrib/opensearch/patcher.rb +2 -6
  497. data/lib/datadog/tracing/contrib/opensearch/quantize.rb +2 -2
  498. data/lib/datadog/tracing/contrib/pg/configuration/settings.rb +6 -0
  499. data/lib/datadog/tracing/contrib/pg/instrumentation.rb +15 -18
  500. data/lib/datadog/tracing/contrib/presto/instrumentation.rb +6 -8
  501. data/lib/datadog/tracing/contrib/propagation/sql_comment/ext.rb +13 -0
  502. data/lib/datadog/tracing/contrib/propagation/sql_comment/mode.rb +6 -2
  503. data/lib/datadog/tracing/contrib/propagation/sql_comment.rb +24 -0
  504. data/lib/datadog/tracing/contrib/que/configuration/settings.rb +5 -2
  505. data/lib/datadog/tracing/contrib/que/ext.rb +1 -0
  506. data/lib/datadog/tracing/contrib/que/tracer.rb +1 -0
  507. data/lib/datadog/tracing/contrib/racecar/event.rb +1 -5
  508. data/lib/datadog/tracing/contrib/rack/configuration/settings.rb +11 -1
  509. data/lib/datadog/tracing/contrib/rack/ext.rb +28 -0
  510. data/lib/datadog/tracing/contrib/rack/header_tagging.rb +23 -0
  511. data/lib/datadog/tracing/contrib/rack/middlewares.rb +62 -27
  512. data/lib/datadog/tracing/contrib/rack/patcher.rb +2 -2
  513. data/lib/datadog/tracing/contrib/rack/request_queue.rb +1 -1
  514. data/lib/datadog/tracing/contrib/rack/route_inference.rb +67 -0
  515. data/lib/datadog/tracing/contrib/rack/trace_proxy_middleware.rb +119 -1
  516. data/lib/datadog/tracing/contrib/rails/configuration/settings.rb +5 -2
  517. data/lib/datadog/tracing/contrib/rails/ext.rb +1 -0
  518. data/lib/datadog/tracing/contrib/rails/log_injection.rb +1 -1
  519. data/lib/datadog/tracing/contrib/rails/middlewares.rb +2 -2
  520. data/lib/datadog/tracing/contrib/rails/patcher.rb +0 -1
  521. data/lib/datadog/tracing/contrib/rails/runner.rb +3 -1
  522. data/lib/datadog/tracing/contrib/rake/instrumentation.rb +6 -4
  523. data/lib/datadog/tracing/contrib/redis/quantize.rb +1 -1
  524. data/lib/datadog/tracing/contrib/redis/tags.rb +1 -6
  525. data/lib/datadog/tracing/contrib/redis/trace_middleware.rb +2 -0
  526. data/lib/datadog/tracing/contrib/registerable.rb +11 -0
  527. data/lib/datadog/tracing/contrib/resque/resque_job.rb +1 -0
  528. data/lib/datadog/tracing/contrib/rest_client/configuration/settings.rb +5 -2
  529. data/lib/datadog/tracing/contrib/rest_client/ext.rb +1 -0
  530. data/lib/datadog/tracing/contrib/rest_client/request_patch.rb +5 -6
  531. data/lib/datadog/tracing/contrib/roda/ext.rb +1 -0
  532. data/lib/datadog/tracing/contrib/roda/instrumentation.rb +7 -2
  533. data/lib/datadog/tracing/contrib/sequel/database.rb +1 -0
  534. data/lib/datadog/tracing/contrib/sequel/dataset.rb +1 -0
  535. data/lib/datadog/tracing/contrib/sequel/utils.rb +2 -7
  536. data/lib/datadog/tracing/contrib/shoryuken/tracer.rb +1 -0
  537. data/lib/datadog/tracing/contrib/sidekiq/client_tracer.rb +1 -0
  538. data/lib/datadog/tracing/contrib/sidekiq/configuration/settings.rb +5 -1
  539. data/lib/datadog/tracing/contrib/sidekiq/distributed/propagation.rb +2 -0
  540. data/lib/datadog/tracing/contrib/sidekiq/ext.rb +1 -0
  541. data/lib/datadog/tracing/contrib/sidekiq/server_internal_tracer/heartbeat.rb +2 -0
  542. data/lib/datadog/tracing/contrib/sidekiq/server_internal_tracer/job_fetch.rb +1 -0
  543. data/lib/datadog/tracing/contrib/sidekiq/server_internal_tracer/redis_info.rb +1 -0
  544. data/lib/datadog/tracing/contrib/sidekiq/server_internal_tracer/scheduled_poller.rb +2 -0
  545. data/lib/datadog/tracing/contrib/sidekiq/server_internal_tracer/stop.rb +1 -0
  546. data/lib/datadog/tracing/contrib/sidekiq/server_tracer.rb +3 -2
  547. data/lib/datadog/tracing/contrib/sidekiq/utils.rb +1 -1
  548. data/lib/datadog/tracing/contrib/sidekiq.rb +1 -0
  549. data/lib/datadog/tracing/contrib/sinatra/configuration/settings.rb +5 -1
  550. data/lib/datadog/tracing/contrib/sinatra/ext.rb +1 -0
  551. data/lib/datadog/tracing/contrib/sinatra/framework.rb +1 -1
  552. data/lib/datadog/tracing/contrib/sinatra/tracer.rb +1 -0
  553. data/lib/datadog/tracing/contrib/sinatra/tracer_middleware.rb +4 -1
  554. data/lib/datadog/tracing/contrib/sneakers/integration.rb +15 -4
  555. data/lib/datadog/tracing/contrib/sneakers/tracer.rb +1 -0
  556. data/lib/datadog/tracing/contrib/status_range_matcher.rb +13 -1
  557. data/lib/datadog/tracing/contrib/stripe/request.rb +1 -1
  558. data/lib/datadog/tracing/contrib/sucker_punch/instrumentation.rb +1 -0
  559. data/lib/datadog/tracing/contrib/trilogy/configuration/settings.rb +6 -0
  560. data/lib/datadog/tracing/contrib/trilogy/instrumentation.rb +4 -6
  561. data/lib/datadog/tracing/contrib/utils/quantization/{hash.rb → hash_formatter.rb} +4 -2
  562. data/lib/datadog/tracing/contrib/waterdrop/configuration/settings.rb +31 -0
  563. data/lib/datadog/tracing/contrib/waterdrop/distributed/propagation.rb +50 -0
  564. data/lib/datadog/tracing/contrib/waterdrop/ext.rb +18 -0
  565. data/lib/datadog/tracing/contrib/waterdrop/integration.rb +43 -0
  566. data/lib/datadog/tracing/contrib/waterdrop/middleware.rb +46 -0
  567. data/lib/datadog/tracing/contrib/waterdrop/patcher.rb +49 -0
  568. data/lib/datadog/tracing/contrib/waterdrop/producer.rb +50 -0
  569. data/lib/datadog/tracing/contrib/waterdrop.rb +42 -0
  570. data/lib/datadog/tracing/contrib.rb +9 -0
  571. data/lib/datadog/tracing/diagnostics/environment_logger.rb +4 -2
  572. data/lib/datadog/tracing/distributed/baggage.rb +64 -8
  573. data/lib/datadog/tracing/distributed/datadog.rb +13 -11
  574. data/lib/datadog/tracing/distributed/datadog_tags_codec.rb +1 -14
  575. data/lib/datadog/tracing/distributed/propagation.rb +35 -3
  576. data/lib/datadog/tracing/distributed/trace_context.rb +85 -62
  577. data/lib/datadog/tracing/event.rb +1 -1
  578. data/lib/datadog/tracing/ext.rb +9 -0
  579. data/lib/datadog/tracing/metadata/ext.rb +23 -1
  580. data/lib/datadog/tracing/metadata/tagging.rb +2 -2
  581. data/lib/datadog/tracing/pipeline.rb +1 -1
  582. data/lib/datadog/tracing/remote.rb +36 -13
  583. data/lib/datadog/tracing/sampling/ext.rb +2 -0
  584. data/lib/datadog/tracing/sampling/priority_sampler.rb +16 -1
  585. data/lib/datadog/tracing/sampling/rate_sampler.rb +8 -19
  586. data/lib/datadog/tracing/sampling/rule.rb +1 -1
  587. data/lib/datadog/tracing/sampling/rule_sampler.rb +54 -25
  588. data/lib/datadog/tracing/sampling/span/rule_parser.rb +2 -2
  589. data/lib/datadog/tracing/span.rb +1 -1
  590. data/lib/datadog/tracing/span_event.rb +2 -2
  591. data/lib/datadog/tracing/span_operation.rb +34 -10
  592. data/lib/datadog/tracing/sync_writer.rb +0 -1
  593. data/lib/datadog/tracing/trace_digest.rb +7 -0
  594. data/lib/datadog/tracing/trace_operation.rb +123 -16
  595. data/lib/datadog/tracing/tracer.rb +82 -23
  596. data/lib/datadog/tracing/transport/http/client.rb +12 -26
  597. data/lib/datadog/tracing/transport/http/traces.rb +2 -50
  598. data/lib/datadog/tracing/transport/http.rb +15 -9
  599. data/lib/datadog/tracing/transport/io/client.rb +6 -9
  600. data/lib/datadog/tracing/transport/io/traces.rb +28 -34
  601. data/lib/datadog/tracing/transport/trace_formatter.rb +22 -0
  602. data/lib/datadog/tracing/transport/traces.rb +13 -81
  603. data/lib/datadog/tracing/workers.rb +2 -1
  604. data/lib/datadog/tracing/writer.rb +1 -1
  605. data/lib/datadog/version.rb +2 -2
  606. data/lib/datadog.rb +8 -1
  607. metadata +185 -36
  608. data/ext/datadog_profiling_native_extension/clock_id_noop.c +0 -21
  609. data/ext/libdatadog_api/macos_development.md +0 -26
  610. data/lib/datadog/appsec/configuration/settings.rb +0 -400
  611. data/lib/datadog/appsec/contrib/rails/ext.rb +0 -13
  612. data/lib/datadog/core/remote/transport/http/api.rb +0 -53
  613. data/lib/datadog/core/remote/transport/http/client.rb +0 -49
  614. data/lib/datadog/core/telemetry/transport/http/api.rb +0 -43
  615. data/lib/datadog/core/telemetry/transport/http/client.rb +0 -49
  616. data/lib/datadog/core/transport/http/api/spec.rb +0 -36
  617. data/lib/datadog/di/configuration/settings.rb +0 -212
  618. data/lib/datadog/di/transport/http/api.rb +0 -42
  619. data/lib/datadog/di/transport/http/client.rb +0 -47
  620. data/lib/datadog/error_tracking/configuration/settings.rb +0 -63
  621. data/lib/datadog/opentelemetry/api/baggage.rbs +0 -26
  622. data/lib/datadog/tracing/transport/http/api.rb +0 -44
  623. data/lib/datadog/tracing/workers/trace_writer.rb +0 -199
@@ -101,7 +101,7 @@ module Datadog
101
101
  statsd.count(stat, value, metric_options(options))
102
102
  rescue => e
103
103
  logger.error(
104
- "Failed to send count stat. Cause: #{e.class.name} #{e.message} Source: #{Array(e.backtrace).first}"
104
+ "Failed to send count stat. Cause: #{e.class}: #{e.message} Source: #{Array(e.backtrace).first}"
105
105
  )
106
106
  telemetry.report(e, description: 'Failed to send count stat')
107
107
  end
@@ -115,7 +115,7 @@ module Datadog
115
115
  statsd.distribution(stat, value, metric_options(options))
116
116
  rescue => e
117
117
  logger.error(
118
- "Failed to send distribution stat. Cause: #{e.class.name} #{e.message} Source: #{Array(e.backtrace).first}"
118
+ "Failed to send distribution stat. Cause: #{e.class}: #{e.message} Source: #{Array(e.backtrace).first}"
119
119
  )
120
120
  telemetry.report(e, description: 'Failed to send distribution stat')
121
121
  end
@@ -128,7 +128,7 @@ module Datadog
128
128
  statsd.increment(stat, metric_options(options))
129
129
  rescue => e
130
130
  logger.error(
131
- "Failed to send increment stat. Cause: #{e.class.name} #{e.message} Source: #{Array(e.backtrace).first}"
131
+ "Failed to send increment stat. Cause: #{e.class}: #{e.message} Source: #{Array(e.backtrace).first}"
132
132
  )
133
133
  telemetry.report(e, description: 'Failed to send increment stat')
134
134
  end
@@ -142,7 +142,7 @@ module Datadog
142
142
  statsd.gauge(stat, value, metric_options(options))
143
143
  rescue => e
144
144
  logger.error(
145
- "Failed to send gauge stat. Cause: #{e.class.name} #{e.message} Source: #{Array(e.backtrace).first}"
145
+ "Failed to send gauge stat. Cause: #{e.class}: #{e.message} Source: #{Array(e.backtrace).first}"
146
146
  )
147
147
  telemetry.report(e, description: 'Failed to send gauge stat')
148
148
  end
@@ -157,12 +157,12 @@ module Datadog
157
157
  begin
158
158
  if send_stats? && !start.nil?
159
159
  finished = Utils::Time.get_time
160
- distribution(stat, ((finished - start) * 1000), options)
160
+ distribution(stat, (finished - start) * 1000, options)
161
161
  end
162
162
  rescue => e
163
163
  # TODO: Likely to be redundant, since `distribution` handles its own errors.
164
164
  logger.error(
165
- "Failed to send time stat. Cause: #{e.class.name} #{e.message} Source: #{Array(e.backtrace).first}"
165
+ "Failed to send time stat. Cause: #{e.class}: #{e.message} Source: #{Array(e.backtrace).first}"
166
166
  )
167
167
  telemetry.report(e, description: 'Failed to send time stat')
168
168
  end
@@ -12,7 +12,7 @@ module Datadog
12
12
  attr_accessor :logger
13
13
 
14
14
  def initialize(logger = nil)
15
- @logger = logger || Logger.new($stdout).tap do |l|
15
+ @logger = logger || Logger.new($stderr).tap do |l|
16
16
  l.level = ::Logger::INFO
17
17
  l.progname = nil
18
18
  l.formatter = proc do |_severity, datetime, _progname, msg|
@@ -43,18 +43,18 @@ module Datadog
43
43
  # rubocop:disable Style/TrivialAccessors
44
44
  def onto(obj)
45
45
  unless obj.respond_to? :datadog_pin=
46
- obj.instance_exec do
47
- def datadog_pin=(pin)
48
- @datadog_pin = pin
49
- end
46
+ obj.define_singleton_method(:datadog_pin=) do |pin|
47
+ # Steep: https://github.com/soutaro/steep/issues/380
48
+ # @type self: PinnedObject
49
+ @datadog_pin = pin
50
50
  end
51
51
  end
52
52
 
53
53
  unless obj.respond_to? :datadog_pin
54
- obj.instance_exec do
55
- def datadog_pin
56
- @datadog_pin
57
- end
54
+ obj.define_singleton_method(:datadog_pin) do
55
+ # Steep: https://github.com/soutaro/steep/issues/380
56
+ # @type self: PinnedObject
57
+ @datadog_pin
58
58
  end
59
59
  end
60
60
 
@@ -1,25 +1,25 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'datadog/core/process_discovery/tracer_memfd'
4
-
5
- require_relative 'utils/at_fork_monkey_patch'
6
- require_relative 'utils/only_once'
3
+ require_relative 'process_discovery/tracer_memfd'
4
+ require_relative 'environment/process'
5
+ require_relative 'environment/container'
7
6
 
8
7
  module Datadog
9
8
  module Core
10
9
  # Class used to store tracer metadata in a native file descriptor.
11
10
  module ProcessDiscovery
12
- ONLY_ONCE = Core::Utils::OnlyOnce.new
13
-
14
11
  class << self
15
12
  def publish(settings)
13
+ if RUBY_PLATFORM.include?("darwin")
14
+ Datadog.logger.debug { "Skipping process discovery, not yet supported on macOS" }
15
+ return
16
+ end
17
+
16
18
  if (libdatadog_api_failure = Datadog::Core::LIBDATADOG_API_FAILURE)
17
19
  Datadog.logger.debug { "Cannot enable process discovery: #{libdatadog_api_failure}" }
18
20
  return
19
21
  end
20
22
 
21
- ONLY_ONCE.run { apply_at_fork_patch }
22
-
23
23
  metadata = get_metadata(settings)
24
24
 
25
25
  shutdown!
@@ -27,8 +27,15 @@ module Datadog
27
27
  end
28
28
 
29
29
  def shutdown!
30
- @file_descriptor&.shutdown!(Datadog.logger)
31
- @file_descriptor = nil
30
+ if defined?(@file_descriptor)
31
+ @file_descriptor&.shutdown!(Datadog.logger)
32
+ @file_descriptor = nil
33
+ end
34
+ end
35
+
36
+ def after_fork
37
+ # The runtime-id changes after a fork. We call publish to ensure that the runtime-id is updated.
38
+ publish(Datadog.configuration)
32
39
  end
33
40
 
34
41
  private
@@ -37,22 +44,18 @@ module Datadog
37
44
  # In the C method exposed by ddcommon, memfd_create replaces empty strings by None for these fields.
38
45
  def get_metadata(settings)
39
46
  {
40
- schema_version: 1,
41
47
  runtime_id: Core::Environment::Identity.id,
42
48
  tracer_language: Core::Environment::Identity.lang,
43
49
  tracer_version: Core::Environment::Identity.gem_datadog_version_semver2,
44
50
  hostname: Core::Environment::Socket.hostname,
45
51
  service_name: settings.service || '',
46
52
  service_env: settings.env || '',
47
- service_version: settings.version || ''
53
+ service_version: settings.version || '',
54
+ # Follows Java: https://github.com/DataDog/dd-trace-java/blob/2ebc964340ac530342cc389ba68ff0f5070d5f9f/dd-trace-core/src/main/java/datadog/trace/core/servicediscovery/ServiceDiscovery.java#L37-L38
55
+ process_tags: settings.experimental_propagate_process_tags_enabled ? Core::Environment::Process.serialized : '',
56
+ container_id: Core::Environment::Container.container_id || ''
48
57
  }
49
58
  end
50
-
51
- def apply_at_fork_patch
52
- # The runtime-id changes after a fork. We apply this patch to at_fork to ensure that the runtime-id is updated.
53
- Utils::AtForkMonkeyPatch.apply!
54
- Utils::AtForkMonkeyPatch.at_fork(:child) { publish(Datadog.configuration) }
55
- end
56
59
  end
57
60
  end
58
61
  end
@@ -14,6 +14,7 @@ module Datadog
14
14
  #
15
15
  # @return [Boolean] whether a resource conforms with the current limit
16
16
  def allow?(size = 1)
17
+ raise NotImplementedError
17
18
  end
18
19
 
19
20
  # The effective rate limiting ratio based on
@@ -21,6 +22,7 @@ module Datadog
21
22
  #
22
23
  # @return [Float] recent allowance ratio
23
24
  def effective_rate
25
+ raise NotImplementedError
24
26
  end
25
27
  end
26
28
 
@@ -81,6 +83,10 @@ module Datadog
81
83
 
82
84
  return current_window_rate if @prev_conforming_messages.nil? || @prev_total_messages.nil?
83
85
 
86
+ # Steep: Due to https://github.com/soutaro/steep/issues/477,
87
+ # the previous nil check does not narrow type to Integer
88
+ # The annotation fixes the typing error, but it takes effect in the method
89
+ # @type ivar @prev_total_messages: Integer
84
90
  (@conforming_messages.to_f + @prev_conforming_messages.to_f) / (@total_messages + @prev_total_messages)
85
91
  end
86
92
 
@@ -154,7 +160,11 @@ module Datadog
154
160
  if @current_window.nil?
155
161
  @current_window = now
156
162
  # If more than 1 second has past since last window, reset
157
- elsif now - @current_window >= 1
163
+ #
164
+ # Steep: @current_window is a Float, but for some reason annotations does not work here
165
+ # Once a fix will be out for nil checks on instance variables, we can remove the ignore comment
166
+ # https://github.com/soutaro/steep/issues/477
167
+ elsif now - @current_window >= 1 # steep:ignore UnresolvedOverloading
158
168
  @prev_conforming_messages = @conforming_messages
159
169
  @prev_total_messages = @total_messages
160
170
  @conforming_messages = 0
@@ -1,8 +1,12 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative '../../utils/base64'
3
+ require_relative '../../utils/base64_codec'
4
4
  require_relative '../../../appsec/remote'
5
5
  require_relative '../../../tracing/remote'
6
+ require_relative '../../../di/remote'
7
+ require_relative '../../../symbol_database'
8
+ require_relative '../../../symbol_database/remote'
9
+ require_relative '../../../open_feature/remote'
6
10
 
7
11
  module Datadog
8
12
  module Core
@@ -32,15 +36,54 @@ module Datadog
32
36
  register_receivers(Datadog::AppSec::Remote.receivers(@telemetry))
33
37
  end
34
38
 
35
- if settings.respond_to?(:dynamic_instrumentation) && settings.dynamic_instrumentation.enabled
39
+ # Tracing must register before DI: on a combined RC dispatch,
40
+ # the APM_TRACING handler must run first to call
41
+ # Datadog::DI::Remote.handle_rc_enablement and start the
42
+ # component before the DI receiver processes LIVE_DEBUGGING
43
+ # changes against `component.started?`. Reversing the order
44
+ # silently drops the probe — the remote client only
45
+ # redispatches on content hash changes.
46
+ register_capabilities(Datadog::Tracing::Remote.capabilities)
47
+ register_products(Datadog::Tracing::Remote.products)
48
+ register_receivers(Datadog::Tracing::Remote.receivers(@telemetry))
49
+
50
+ # Skip DI registration entirely when DI is explicitly disabled
51
+ # (DD_DYNAMIC_INSTRUMENTATION_ENABLED=false) or when the runtime
52
+ # cannot run DI (JRuby, Ruby 2.5): in either case no component will
53
+ # run, so advertising bit 38 or the LIVE_DEBUGGING product would
54
+ # invite probe configs and an enable signal the tracer must refuse.
55
+ # When the env var is unset (default) on a supported runtime, DI is
56
+ # registered so RC can enable it.
57
+ if settings.respond_to?(:dynamic_instrumentation) &&
58
+ !Datadog::DI::Remote.explicitly_disabled?(settings) &&
59
+ Datadog::DI.supported_runtime?
36
60
  register_capabilities(Datadog::DI::Remote.capabilities)
37
61
  register_products(Datadog::DI::Remote.products)
38
62
  register_receivers(Datadog::DI::Remote.receivers(@telemetry))
39
63
  end
40
64
 
41
- register_capabilities(Datadog::Tracing::Remote.capabilities)
42
- register_products(Datadog::Tracing::Remote.products)
43
- register_receivers(Datadog::Tracing::Remote.receivers(@telemetry))
65
+ # Skip symbol database registration on runtimes that cannot run it
66
+ # (JRuby, Ruby < 2.7): DI supports Ruby 2.6 but Symbol Database does
67
+ # not, so advertising LIVE_DEBUGGING_SYMBOL_DB there would invite
68
+ # symbol-upload configs the component can never serve.
69
+ if settings.respond_to?(:symbol_database) && Datadog::SymbolDatabase.supported_runtime?
70
+ # Symbol database follows DI: when unset it advertises whenever DI
71
+ # advertises (mirror the DI branch above, including the unset/default
72
+ # case that RC may enable). An explicit symbol_database.enabled wins.
73
+ di_enabled = settings.respond_to?(:dynamic_instrumentation) &&
74
+ !Datadog::DI::Remote.explicitly_disabled?(settings)
75
+ if Datadog::SymbolDatabase.resolve_enabled(settings.symbol_database.enabled, di_enabled)
76
+ register_capabilities(Datadog::SymbolDatabase::Remote.capabilities)
77
+ register_products(Datadog::SymbolDatabase::Remote.products)
78
+ register_receivers(Datadog::SymbolDatabase::Remote.receivers(@telemetry))
79
+ end
80
+ end
81
+
82
+ if settings.respond_to?(:open_feature) && settings.open_feature.enabled
83
+ register_capabilities(Datadog::OpenFeature::Remote.capabilities)
84
+ register_products(Datadog::OpenFeature::Remote.products)
85
+ register_receivers(Datadog::OpenFeature::Remote.receivers(@telemetry))
86
+ end
44
87
  end
45
88
 
46
89
  def register_capabilities(capabilities)
@@ -61,7 +104,7 @@ module Datadog
61
104
  cap_to_hexs = capabilities.reduce(:|).to_s(16).tap { |s| s.size.odd? && s.prepend('0') }.scan(/\h\h/)
62
105
  binary = cap_to_hexs.each_with_object([]) { |hex, acc| acc << hex }.map { |e| e.to_i(16) }.pack('C*')
63
106
 
64
- Datadog::Core::Utils::Base64.strict_encode64(binary)
107
+ Datadog::Core::Utils::Base64Codec.strict_encode64(binary)
65
108
  end
66
109
  end
67
110
  end
@@ -14,10 +14,11 @@ module Datadog
14
14
 
15
15
  class SyncError < StandardError; end
16
16
 
17
- attr_reader :transport, :repository, :id, :dispatcher, :logger
17
+ attr_reader :transport, :repository, :id, :dispatcher, :settings, :logger
18
18
 
19
- def initialize(transport, capabilities, logger: Datadog.logger, repository: Configuration::Repository.new)
19
+ def initialize(transport, capabilities, settings:, logger:, repository: Configuration::Repository.new)
20
20
  @transport = transport
21
+ @settings = settings
21
22
  @logger = logger
22
23
 
23
24
  @repository = repository
@@ -56,7 +57,7 @@ module Datadog
56
57
 
57
58
  contents = Configuration::ContentList.parse(response.target_files)
58
59
  rescue Remote::Configuration::Path::ParseError => e
59
- raise SyncError, e.message
60
+ raise SyncError, "#{e.class}: #{e.message}"
60
61
  end
61
62
 
62
63
  # To make sure steep does not complain
@@ -97,7 +98,9 @@ module Datadog
97
98
  content = contents.find_content(path, target)
98
99
 
99
100
  # abort entirely if matching content not found
100
- raise SyncError, "no valid content for target at path '#{path}'" if content.nil?
101
+ if content.nil?
102
+ raise SyncError, "no valid content for target at path '#{path}'"
103
+ end
101
104
 
102
105
  # to be added or updated << config
103
106
  # TODO: metadata (hash, version, etc...)
@@ -153,14 +156,19 @@ module Datadog
153
156
  language: Core::Environment::Identity.lang,
154
157
  tracer_version: tracer_version,
155
158
  service: service_name,
156
- env: Datadog.configuration.env,
159
+ env: settings.env,
157
160
  tags: client_tracer_tags,
158
161
  }
159
162
 
160
- app_version = Datadog.configuration.version
163
+ app_version = settings.version
161
164
 
162
165
  client_tracer[:app_version] = app_version if app_version
163
166
 
167
+ if settings.experimental_propagate_process_tags_enabled
168
+ process_tags = Core::Environment::Process.tags
169
+ client_tracer[:process_tags] = process_tags if process_tags.any?
170
+ end
171
+
164
172
  {
165
173
  client: {
166
174
  state: {
@@ -184,7 +192,7 @@ module Datadog
184
192
  end
185
193
 
186
194
  def service_name
187
- Datadog.configuration.remote.service || Datadog.configuration.service
195
+ settings.remote.service || settings.service
188
196
  end
189
197
 
190
198
  def tracer_version
@@ -11,21 +11,26 @@ module Datadog
11
11
  module Core
12
12
  module Remote
13
13
  # Configures the HTTP transport to communicate with the agent
14
- # to fetch and sync the remote configuration
14
+ # to fetch and sync the remote configuration.
15
+ #
16
+ # @api private
15
17
  class Component
16
- attr_reader :logger, :client, :healthy
18
+ attr_reader :logger, :client, :healthy, :worker
17
19
 
18
20
  def initialize(settings, capabilities, agent_settings, logger:)
19
21
  @logger = logger
22
+ @settings = settings
23
+ @capabilities = capabilities
24
+ @agent_settings = agent_settings
20
25
 
21
26
  negotiation = Negotiation.new(settings, agent_settings, logger: logger)
22
- transport_v7 = Datadog::Core::Remote::Transport::HTTP.v7(agent_settings: agent_settings, logger: logger)
27
+ @transport = Datadog::Core::Remote::Transport::HTTP.v7(agent_settings: agent_settings, logger: logger)
23
28
 
24
29
  @barrier = Barrier.new(settings.remote.boot_timeout_seconds)
25
30
 
26
- @client = Client.new(transport_v7, capabilities, logger: logger)
31
+ @client = Client.new(@transport, @capabilities, settings: settings, logger: logger)
27
32
  @healthy = false
28
- logger.debug { "new remote configuration client: #{@client.id}" }
33
+ logger.debug { "new remote configuration client: #{@client.id} products: #{@capabilities.products.sort.join(', ')}" }
29
34
 
30
35
  @worker = Worker.new(interval: settings.remote.poll_interval_seconds, logger: logger) do
31
36
  unless @healthy || negotiation.endpoint?('/v0.7/config')
@@ -40,7 +45,7 @@ module Datadog
40
45
  rescue Client::SyncError => e
41
46
  # Transient errors due to network or agent. Logged the error but not via telemetry
42
47
  logger.error do
43
- "remote worker client sync error: #{e.message} location: #{Array(e.backtrace).first}. skipping sync"
48
+ "remote worker client sync error: #{e.class}: #{e.message} location: #{Array(e.backtrace).first}. skipping sync"
44
49
  end
45
50
  rescue => e
46
51
  # In case of unexpected errors, reset the negotiation object
@@ -50,14 +55,14 @@ module Datadog
50
55
 
51
56
  # Transient errors due to network or agent. Logged the error but not via telemetry
52
57
  logger.error do
53
- "remote worker error: #{e.class.name} #{e.message} location: #{Array(e.backtrace).first}. " \
58
+ "remote worker error: #{e.class}: #{e.message} location: #{Array(e.backtrace).first}. " \
54
59
  'resetting client state'
55
60
  end
56
61
 
57
62
  # client state is unknown, state might be corrupted
58
- @client = Client.new(transport_v7, capabilities, logger: logger)
63
+ @client = Client.new(@transport, @capabilities, settings: settings, logger: logger)
59
64
  @healthy = false
60
- logger.debug { "new remote configuration client: #{@client.id}" }
65
+ logger.debug { "new remote configuration client: #{@client.id} products: #{@capabilities.products.sort.join(', ')}" }
61
66
 
62
67
  # TODO: bail out if too many errors?
63
68
  end
@@ -88,10 +93,19 @@ module Datadog
88
93
  @worker.stop
89
94
  end
90
95
 
96
+ # Recreates the remote configuration client after a fork.
97
+ # This ensures each forked process has a unique client ID and fresh state.
98
+ def after_fork
99
+ @client = Client.new(@transport, @capabilities, settings: @settings, logger: @logger)
100
+ @healthy = false
101
+ logger.debug { "remote configuration client recreated after fork: #{@client.id} products: #{@capabilities.products.sort.join(', ')}" }
102
+ end
103
+
91
104
  # Barrier provides a mechanism to fence execution until a condition happens
92
105
  class Barrier
93
106
  def initialize(timeout = nil)
94
107
  @once = false
108
+ @waited = false
95
109
  @timeout = timeout
96
110
 
97
111
  @mutex = Mutex.new
@@ -99,49 +113,63 @@ module Datadog
99
113
  end
100
114
 
101
115
  # Wait for first lift to happen, otherwise don't wait
116
+ #
117
+ # Returns:
118
+ # - :lift if the barrier was lifted (worker completed a cycle)
119
+ # - :timeout if the wait timed out before the barrier was lifted
120
+ # - :pass if wait_once was already called previously
121
+ #
122
+ # Uses a separate @waited flag to distinguish "already waited" (:pass)
123
+ # from "worker lifted before we could wait" (:lift). Without this,
124
+ # a race between Worker#start and wait_once can cause the first call
125
+ # to return :pass if the worker completes before wait_once runs.
102
126
  def wait_once(timeout = nil)
103
- # TTAS (Test and Test-And-Set) optimisation
104
- # Since @once only ever goes from false to true, this is semantically valid
105
- return :pass if @once
106
-
107
- begin
108
- @mutex.lock
109
-
110
- return :pass if @once
111
-
112
- timeout ||= @timeout
113
-
114
- # - starting with Ruby 3.2, ConditionVariable#wait returns nil on
115
- # timeout and an integer otherwise
116
- # - before Ruby 3.2, ConditionVariable returns itself
117
- # so we have to rely on @once having been set
118
- if RUBY_VERSION >= '3.2'
119
- lifted = @condition.wait(@mutex, timeout)
127
+ # TTAS (Test and Test-And-Set) optimisation for subsequent calls.
128
+ # @waited is only set inside the mutex and only transitions false -> true,
129
+ # so an unsynchronized read is safe: a stale `false` just falls through
130
+ # to the synchronized path which re-checks.
131
+ return :pass if @waited
132
+
133
+ @mutex.synchronize do
134
+ return :pass if @waited
135
+
136
+ if @once
137
+ # Worker lifted the barrier before we could wait.
138
+ # This is still the first call, so return :lift not :pass.
139
+ lifted = true
120
140
  else
121
- @condition.wait(@mutex, timeout)
122
- lifted = @once
141
+ timeout ||= @timeout
142
+
143
+ # - starting with Ruby 3.2, ConditionVariable#wait returns nil on
144
+ # timeout and an integer otherwise
145
+ # - before Ruby 3.2, ConditionVariable returns itself
146
+ # so we have to rely on @once having been set
147
+ if RubyVersion.is?('>= 3.2')
148
+ lifted = @condition.wait(@mutex, timeout)
149
+ else
150
+ @condition.wait(@mutex, timeout)
151
+ lifted = @once
152
+ end
123
153
  end
124
154
 
155
+ @waited = true
156
+
125
157
  if lifted
126
158
  :lift
127
159
  else
128
160
  @once = true
129
161
  :timeout
130
162
  end
131
- ensure
132
- @mutex.unlock
133
163
  end
134
164
  end
135
165
 
136
166
  # Release all current waiters
137
167
  def lift
138
- @mutex.lock
139
-
140
- @once ||= true
168
+ @mutex.synchronize do
169
+ @once ||= true
141
170
 
142
- @condition.broadcast
143
- ensure
144
- @mutex.unlock
171
+ @condition.broadcast
172
+ end
145
173
  end
146
174
  end
147
175
 
@@ -22,6 +22,18 @@ module Datadog
22
22
  attr_accessor :version
23
23
 
24
24
  def initialize(path:, data:)
25
+ if data.nil?
26
+ # +data+ is passed to Digest calculation and also is
27
+ # unconditionally taken length of by +length+ method.
28
+ # As such, the class is not written to expect +data+ to be nil.
29
+ # Detect bad incoming values here to provide earlier diagnostics
30
+ # when developing tests, for example.
31
+ raise ArgumentError, 'data must not be nil'
32
+ end
33
+ unless String === data
34
+ raise ArgumentError, "Invalid type for data: #{data.class}: expected String"
35
+ end
36
+
25
37
  @path = path
26
38
  @data = data
27
39
  @apply_state = ApplyState::UNACKNOWLEDGED
@@ -72,8 +84,9 @@ module Datadog
72
84
  private_class_method :new
73
85
  end
74
86
 
75
- # ContentList stores a list of Conetnt instances
76
- # It provides convinient methods for finding content base on Configuration::Path and Configuration::Target
87
+ # ContentList stores a list of Content instances.
88
+ # It provides convenient methods for finding content based on
89
+ # Configuration::Path and Configuration::Target.
77
90
  class ContentList < Array
78
91
  class << self
79
92
  def parse(array)
@@ -24,10 +24,21 @@ module Datadog
24
24
  class InvalidHashTypeError < StandardError; end
25
25
  attr_reader :type, :hexdigest
26
26
 
27
- DIGEST_CHUNK = 1024
28
-
29
27
  class << self
30
28
  def hexdigest(type, data)
29
+ unless String === data
30
+ # This class (Digest) passes +data+ to the Ruby standard
31
+ # library Digest routines without validating its type.
32
+ # The stdlib Digest requires a String, and the previous
33
+ # implementation of this class that used StringIO
34
+ # unconditionally read from +data+ without validating the
35
+ # type. Meaning, passing +nil+ as +data+ has never worked.
36
+ # It still doesn't work in the present implementation.
37
+ # Flag the nil data now to get earlier diagnostics when
38
+ # developing tests for example.
39
+ raise ArgumentError, "Invalid type for data: #{data.class}: expected String"
40
+ end
41
+
31
42
  d = case type
32
43
  when :sha256
33
44
  ::Digest::SHA256.new
@@ -37,13 +48,9 @@ module Datadog
37
48
  raise InvalidHashTypeError, type
38
49
  end
39
50
 
40
- while (buf = data.read(DIGEST_CHUNK))
41
- d.update(buf)
42
- end
51
+ d.update(data)
43
52
 
44
53
  d.hexdigest
45
- ensure
46
- data.rewind
47
54
  end
48
55
  end
49
56
 
@@ -185,7 +185,7 @@ module Datadog
185
185
  end
186
186
  end
187
187
 
188
- # Update existimng repository's contents
188
+ # Update existing repository's contents
189
189
  class Update
190
190
  attr_reader :path, :target, :content
191
191
 
@@ -11,8 +11,15 @@ module Datadog
11
11
  class TargetMap < Hash
12
12
  class << self
13
13
  def parse(hash)
14
- opaque_backend_state = hash['signed']['custom']['opaque_backend_state']
15
- version = hash['signed']['version']
14
+ signed = hash.fetch('signed')
15
+ # Note that the +dig+ call permits +hash['signed']+ to be
16
+ # missing the +custom+ subtree entirely.
17
+ # Previously the subtree was required but +opaque_backend_state+
18
+ # could still be missing (and obtained here as nil).
19
+ opaque_backend_state = signed.dig('custom', 'opaque_backend_state')
20
+ # The version appears to be optional to the rest of this class,
21
+ # and we have tests that do not provide it.
22
+ version = signed['version']
16
23
 
17
24
  map = new
18
25
 
@@ -21,7 +28,7 @@ module Datadog
21
28
  @version = version
22
29
  end
23
30
 
24
- hash['signed']['targets'].each_with_object(map) do |(p, t), m|
31
+ signed.fetch('targets').each_with_object(map) do |(p, t), m|
25
32
  path = Configuration::Path.parse(p)
26
33
  target = Configuration::Target.parse(t)
27
34
 
@@ -46,9 +53,9 @@ module Datadog
46
53
  class Target
47
54
  class << self
48
55
  def parse(hash)
49
- length = Integer(hash['length'])
50
- digests = Configuration::DigestList.parse(hash['hashes'])
51
- version = Integer(hash['custom']['v'])
56
+ length = Integer(hash.fetch('length'))
57
+ digests = Configuration::DigestList.parse(hash.fetch('hashes'))
58
+ version = Integer(hash.dig('custom', 'v'))
52
59
 
53
60
  new(digests: digests, length: length, version: version)
54
61
  end