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
@@ -1,15 +1,27 @@
1
1
  #include <ruby.h>
2
2
 
3
3
  #include "datadog_ruby_common.h"
4
+
4
5
  #include "crashtracker.h"
5
- #include "process_discovery.h"
6
+ #include "feature_flags.h"
6
7
  #include "library_config.h"
8
+ #include "process_discovery.h"
9
+
10
+ void ddsketch_init(VALUE core_module);
11
+ void di_init(VALUE datadog_module);
7
12
 
8
13
  void DDTRACE_EXPORT Init_libdatadog_api(void) {
9
14
  VALUE datadog_module = rb_define_module("Datadog");
15
+
16
+ // MUST be called before all other initialization
17
+ datadog_ruby_common_init();
18
+
10
19
  VALUE core_module = rb_define_module_under(datadog_module, "Core");
11
20
 
12
21
  crashtracker_init(core_module);
13
22
  process_discovery_init(core_module);
14
23
  library_config_init(core_module);
24
+ ddsketch_init(core_module);
25
+ feature_flags_init(core_module);
26
+ di_init(datadog_module);
15
27
  }
@@ -11,7 +11,7 @@ static VALUE _native_configurator_get(VALUE self);
11
11
  static VALUE _native_configurator_with_local_path(DDTRACE_UNUSED VALUE _self, VALUE rb_configurator, VALUE path);
12
12
  static VALUE _native_configurator_with_fleet_path(DDTRACE_UNUSED VALUE _self, VALUE rb_configurator, VALUE path);
13
13
 
14
- static VALUE config_vec_class = Qnil;
14
+ static VALUE config_logged_result_class = Qnil;
15
15
 
16
16
  // ddog_Configurator memory management
17
17
  static void configurator_free(void *configurator_ptr) {
@@ -29,29 +29,29 @@ static const rb_data_type_t configurator_typed_data = {
29
29
  .flags = RUBY_TYPED_FREE_IMMEDIATELY
30
30
  };
31
31
 
32
- // ddog_Vec_LibraryConfig memory management
33
- static void config_vec_free(void *config_vec_ptr) {
34
- ddog_Vec_LibraryConfig *config_vec = (ddog_Vec_LibraryConfig *)config_vec_ptr;
32
+ // ddog_LibraryConfigLoggedResult memory management
33
+ static void config_logged_result_free(void *config_logged_result_ptr) {
34
+ ddog_LibraryConfigLoggedResult *config_logged_result = (ddog_LibraryConfigLoggedResult *)config_logged_result_ptr;
35
35
 
36
- ddog_library_config_drop(*config_vec);
37
- ruby_xfree(config_vec_ptr);
36
+ ddog_library_config_drop(*config_logged_result);
37
+ ruby_xfree(config_logged_result_ptr);
38
38
  }
39
39
 
40
- static const rb_data_type_t config_vec_typed_data = {
41
- .wrap_struct_name = "Datadog::Core::Configuration::StableConfigVec",
40
+ static const rb_data_type_t config_logged_result_typed_data = {
41
+ .wrap_struct_name = "Datadog::Core::Configuration::StableConfigLoggedResult",
42
42
  .function = {
43
- .dfree = config_vec_free,
43
+ .dfree = config_logged_result_free,
44
44
  .dsize = NULL,
45
45
  },
46
46
  .flags = RUBY_TYPED_FREE_IMMEDIATELY
47
47
  };
48
48
 
49
49
  void library_config_init(VALUE core_module) {
50
- rb_global_variable(&config_vec_class);
50
+ rb_global_variable(&config_logged_result_class);
51
51
  VALUE configuration_module = rb_define_module_under(core_module, "Configuration");
52
52
  VALUE stable_config_module = rb_define_module_under(configuration_module, "StableConfig");
53
53
  VALUE configurator_class = rb_define_class_under(stable_config_module, "Configurator", rb_cObject);
54
- config_vec_class = rb_define_class_under(configuration_module, "StableConfigVec", rb_cObject);
54
+ config_logged_result_class = rb_define_class_under(configuration_module, "StableConfigLoggedResult", rb_cObject);
55
55
 
56
56
  rb_define_alloc_func(configurator_class, _native_configurator_new);
57
57
  rb_define_method(configurator_class, "get", _native_configurator_get, 0);
@@ -61,11 +61,12 @@ void library_config_init(VALUE core_module) {
61
61
  rb_define_singleton_method(testing_module, "with_local_path", _native_configurator_with_local_path, 2);
62
62
  rb_define_singleton_method(testing_module, "with_fleet_path", _native_configurator_with_fleet_path, 2);
63
63
 
64
- rb_undef_alloc_func(config_vec_class); // It cannot be created from Ruby code and only serves as an intermediate object for the Ruby GC
64
+ rb_undef_alloc_func(config_logged_result_class); // It cannot be created from Ruby code and only serves as an intermediate object for the Ruby GC
65
65
  }
66
66
 
67
67
  static VALUE _native_configurator_new(VALUE klass) {
68
- ddog_Configurator *configurator = ddog_library_configurator_new(false, DDOG_CHARSLICE_C("ruby"));
68
+ // We always collect debug logs, so if DD_TRACE_DEBUG is set by stable config, we'll be able to log them.
69
+ ddog_Configurator *configurator = ddog_library_configurator_new(true, DDOG_CHARSLICE_C("ruby"));
69
70
 
70
71
  ddog_library_configurator_with_detect_process_info(configurator);
71
72
 
@@ -98,10 +99,11 @@ static VALUE _native_configurator_get(VALUE self) {
98
99
  ddog_Configurator *configurator;
99
100
  TypedData_Get_Struct(self, ddog_Configurator, &configurator_typed_data, configurator);
100
101
 
101
- ddog_Result_VecLibraryConfig configurator_result = ddog_library_configurator_get(configurator);
102
+ // We don't allocate memory here so if there is an error, we don't need to manage the memory
103
+ ddog_LibraryConfigLoggedResult before_error_result = ddog_library_configurator_get(configurator);
102
104
 
103
- if (configurator_result.tag == DDOG_RESULT_VEC_LIBRARY_CONFIG_ERR_VEC_LIBRARY_CONFIG) {
104
- ddog_Error err = configurator_result.err;
105
+ if (before_error_result.tag == DDOG_LIBRARY_CONFIG_LOGGED_RESULT_ERR) {
106
+ ddog_Error err = before_error_result.err;
105
107
  VALUE message = get_error_details_and_drop(&err);
106
108
  if (is_config_loaded()) {
107
109
  log_warning(message);
@@ -111,14 +113,20 @@ static VALUE _native_configurator_get(VALUE self) {
111
113
  return rb_hash_new();
112
114
  }
113
115
 
114
- // Wrapping config_vec into a Ruby object enables the Ruby GC to manage its memory
115
- // We need to allocate memory for config_vec because once it is out of scope, it will be freed (at the end of this function)
116
- // So we cannot reference it with &config_vec
116
+ // Wrapping config_logged_result into a Ruby object enables the Ruby GC to manage its memory
117
+ // We need to allocate memory for config_logged_result because once it is out of scope, it will be freed (at the end of this function)
117
118
  // We are doing this in case one of the ruby API raises an exception before the end of this function,
118
119
  // so the allocated memory will still be freed
119
- ddog_Vec_LibraryConfig *config_vec = ruby_xmalloc(sizeof(ddog_Vec_LibraryConfig));
120
- *config_vec = configurator_result.ok;
121
- VALUE config_vec_rb = TypedData_Wrap_Struct(config_vec_class, &config_vec_typed_data, config_vec);
120
+ ddog_LibraryConfigLoggedResult *configurator_logged_result = ruby_xcalloc(1, sizeof(ddog_LibraryConfigLoggedResult));
121
+ *configurator_logged_result = before_error_result;
122
+ VALUE config_logged_result_rb = TypedData_Wrap_Struct(config_logged_result_class, &config_logged_result_typed_data, configurator_logged_result);
123
+
124
+ VALUE logs = Qnil;
125
+ if (configurator_logged_result->ok.logs.length > 0) {
126
+ logs = rb_utf8_str_new_cstr(configurator_logged_result->ok.logs.ptr);
127
+ }
128
+
129
+ ddog_Vec_LibraryConfig config_vec = configurator_logged_result->ok.value;
122
130
 
123
131
  VALUE local_config_hash = rb_hash_new();
124
132
  VALUE fleet_config_hash = rb_hash_new();
@@ -127,8 +135,8 @@ static VALUE _native_configurator_get(VALUE self) {
127
135
  bool fleet_config_id_set = false;
128
136
  VALUE local_hash = rb_hash_new();
129
137
  VALUE fleet_hash = rb_hash_new();
130
- for (uintptr_t i = 0; i < config_vec->len; i++) {
131
- ddog_LibraryConfig config = config_vec->ptr[i];
138
+ for (uintptr_t i = 0; i < config_vec.len; i++) {
139
+ ddog_LibraryConfig config = config_vec.ptr[i];
132
140
  VALUE selected_hash;
133
141
  if (config.source == DDOG_LIBRARY_CONFIG_SOURCE_LOCAL_STABLE_CONFIG) {
134
142
  selected_hash = local_config_hash;
@@ -156,9 +164,10 @@ static VALUE _native_configurator_get(VALUE self) {
156
164
  rb_hash_aset(fleet_hash, ID2SYM(rb_intern("config")), fleet_config_hash);
157
165
 
158
166
  VALUE result = rb_hash_new();
167
+ rb_hash_aset(result, ID2SYM(rb_intern("logs")), logs);
159
168
  rb_hash_aset(result, ID2SYM(rb_intern("local")), local_hash);
160
169
  rb_hash_aset(result, ID2SYM(rb_intern("fleet")), fleet_hash);
161
170
 
162
- RB_GC_GUARD(config_vec_rb);
171
+ RB_GC_GUARD(config_logged_result_rb);
163
172
  return result;
164
173
  }
@@ -42,7 +42,6 @@ static VALUE _native_store_tracer_metadata(int argc, VALUE *argv, VALUE self) {
42
42
  rb_scan_args(argc, argv, "1:", &logger, &options);
43
43
  if (options == Qnil) options = rb_hash_new();
44
44
 
45
- VALUE schema_version = rb_hash_fetch(options, ID2SYM(rb_intern("schema_version")));
46
45
  VALUE runtime_id = rb_hash_fetch(options, ID2SYM(rb_intern("runtime_id")));
47
46
  VALUE tracer_language = rb_hash_fetch(options, ID2SYM(rb_intern("tracer_language")));
48
47
  VALUE tracer_version = rb_hash_fetch(options, ID2SYM(rb_intern("tracer_version")));
@@ -50,8 +49,9 @@ static VALUE _native_store_tracer_metadata(int argc, VALUE *argv, VALUE self) {
50
49
  VALUE service_name = rb_hash_fetch(options, ID2SYM(rb_intern("service_name")));
51
50
  VALUE service_env = rb_hash_fetch(options, ID2SYM(rb_intern("service_env")));
52
51
  VALUE service_version = rb_hash_fetch(options, ID2SYM(rb_intern("service_version")));
52
+ VALUE process_tags = rb_hash_fetch(options, ID2SYM(rb_intern("process_tags")));
53
+ VALUE container_id = rb_hash_fetch(options, ID2SYM(rb_intern("container_id")));
53
54
 
54
- ENFORCE_TYPE(schema_version, T_FIXNUM);
55
55
  ENFORCE_TYPE(runtime_id, T_STRING);
56
56
  ENFORCE_TYPE(tracer_language, T_STRING);
57
57
  ENFORCE_TYPE(tracer_version, T_STRING);
@@ -59,17 +59,23 @@ static VALUE _native_store_tracer_metadata(int argc, VALUE *argv, VALUE self) {
59
59
  ENFORCE_TYPE(service_name, T_STRING);
60
60
  ENFORCE_TYPE(service_env, T_STRING);
61
61
  ENFORCE_TYPE(service_version, T_STRING);
62
-
63
- ddog_Result_TracerMemfdHandle result = ddog_store_tracer_metadata(
64
- (uint8_t) NUM2UINT(schema_version),
65
- char_slice_from_ruby_string(runtime_id),
66
- char_slice_from_ruby_string(tracer_language),
67
- char_slice_from_ruby_string(tracer_version),
68
- char_slice_from_ruby_string(hostname),
69
- char_slice_from_ruby_string(service_name),
70
- char_slice_from_ruby_string(service_env),
71
- char_slice_from_ruby_string(service_version)
72
- );
62
+ ENFORCE_TYPE(process_tags, T_STRING);
63
+ ENFORCE_TYPE(container_id, T_STRING);
64
+
65
+ void* builder = ddog_tracer_metadata_new();
66
+
67
+ ddog_tracer_metadata_set(builder, DDOG_METADATA_KIND_RUNTIME_ID, StringValueCStr(runtime_id));
68
+ ddog_tracer_metadata_set(builder, DDOG_METADATA_KIND_TRACER_LANGUAGE, StringValueCStr(tracer_language));
69
+ ddog_tracer_metadata_set(builder, DDOG_METADATA_KIND_TRACER_VERSION, StringValueCStr(tracer_version));
70
+ ddog_tracer_metadata_set(builder, DDOG_METADATA_KIND_HOSTNAME, StringValueCStr(hostname));
71
+ ddog_tracer_metadata_set(builder, DDOG_METADATA_KIND_SERVICE_NAME, StringValueCStr(service_name));
72
+ ddog_tracer_metadata_set(builder, DDOG_METADATA_KIND_SERVICE_ENV, StringValueCStr(service_env));
73
+ ddog_tracer_metadata_set(builder, DDOG_METADATA_KIND_SERVICE_VERSION, StringValueCStr(service_version));
74
+ ddog_tracer_metadata_set(builder, DDOG_METADATA_KIND_PROCESS_TAGS, StringValueCStr(process_tags));
75
+ ddog_tracer_metadata_set(builder, DDOG_METADATA_KIND_CONTAINER_ID, StringValueCStr(container_id));
76
+
77
+ ddog_Result_TracerMemfdHandle result = ddog_tracer_metadata_store(builder);
78
+ ddog_tracer_metadata_free(builder);
73
79
 
74
80
  if (result.tag == DDOG_RESULT_TRACER_MEMFD_HANDLE_ERR_TRACER_MEMFD_HANDLE) {
75
81
  rb_funcall(logger, rb_intern("debug"), 1, rb_sprintf("Failed to store the tracer configuration in a memory file descriptor: %"PRIsVALUE, get_error_details_and_drop(&result.err)));
@@ -10,7 +10,7 @@ module Datadog
10
10
  module LibdatadogExtconfHelpers
11
11
  # Used to make sure the correct gem version gets loaded, as extconf.rb does not get run with "bundle exec" and thus
12
12
  # may see multiple libdatadog versions. See https://github.com/DataDog/dd-trace-rb/pull/2531 for the horror story.
13
- LIBDATADOG_VERSION = '~> 18.1.0.1.0'
13
+ LIBDATADOG_VERSION = '~> 36.0.0.1.0'
14
14
 
15
15
  # Used as an workaround for a limitation with how dynamic linking works in environments where the datadog gem and
16
16
  # libdatadog are moved after the extension gets compiled.
@@ -23,9 +23,9 @@ module Datadog
23
23
  # Linux: e.g. `readelf -d datadog_profiling_native_extension.2.7.3_x86_64-linux.so`.
24
24
  #
25
25
  # In older versions of the datadog gem, we only set as runpath an absolute path to libdatadog.
26
- # (This gets set automatically by the call
27
- # to `pkg_config('datadog_profiling_with_rpath')` in `extconf.rb`). This worked fine as long as libdatadog was **NOT**
28
- # moved from the folder it was present at datadog gem installation/linking time.
26
+ # (This gets set automatically by the call to `configure_libdatadog` in `extconf.rb`).
27
+ # This worked fine as long as libdatadog was **NOT** moved from the folder it was present at
28
+ # datadog gem installation/linking time.
29
29
  #
30
30
  # Unfortunately, environments such as Heroku and AWS Elastic Beanstalk move gems around in the filesystem after
31
31
  # installation. Thus, the profiling native extension could not be loaded in these environments
@@ -47,12 +47,12 @@ module Datadog
47
47
  # we could setup when doing a `require`.
48
48
  #
49
49
  def self.libdatadog_folder_relative_to_native_lib_folder(
50
- current_folder:,
50
+ extconf_folder:,
51
51
  libdatadog_pkgconfig_folder: Libdatadog.pkgconfig_folder
52
52
  )
53
53
  return unless libdatadog_pkgconfig_folder
54
54
 
55
- native_lib_folder = "#{current_folder}/../../lib/"
55
+ native_lib_folder = "#{extconf_folder}/../../lib/"
56
56
  libdatadog_lib_folder = "#{libdatadog_pkgconfig_folder}/../"
57
57
 
58
58
  Pathname.new(libdatadog_lib_folder).relative_path_from(Pathname.new(native_lib_folder)).to_s
@@ -104,13 +104,51 @@ module Datadog
104
104
  end
105
105
  end
106
106
 
107
- # mkmf sets $PKGCONFIG after the `pkg_config` gets used in extconf.rb. When `pkg_config` is unsuccessful, we use
108
- # this helper to decide if we can show more specific error message vs a generic "something went wrong".
109
- def self.pkg_config_missing?(command: $PKGCONFIG) # standard:disable Style/GlobalVars
110
- pkg_config_available = command && xsystem("#{command} --version")
107
+ # Directly configures mkmf to link against libdatadog by setting $INCFLAGS, $LDFLAGS, and $libs.
108
+ #
109
+ # This replaces the previous use of mkmf's `pkg_config("datadog_profiling_with_rpath")`, removing the need for
110
+ # the pkg-config system tool to be installed.
111
+ #
112
+ # The extconf_folder argument should be the __dir__ of the calling extconf.rb, used to compute relative rpaths.
113
+ # The logger argument is the mkmf Logging module, dependency-injected to make testing easier.
114
+ # rubocop:disable Style/GlobalVars
115
+ def self.configure_libdatadog(
116
+ extconf_folder:,
117
+ libdatadog_pkgconfig_folder: Libdatadog.pkgconfig_folder,
118
+ gem_dir: Gem.dir,
119
+ logger: Logging
120
+ )
121
+ return unless libdatadog_pkgconfig_folder
122
+
123
+ # The lib and include folders are at a fixed relative path from pkgconfig_folder
124
+ libdir = "#{libdatadog_pkgconfig_folder}/../../lib"
125
+ includedir = "#{libdatadog_pkgconfig_folder}/../../include"
126
+
127
+ # Set mkmf global variables
128
+ $INCFLAGS << " -I#{includedir}"
129
+ $LDFLAGS << " -L#{libdir} -Wl,-rpath,#{libdir}"
130
+ $libs << " -ldatadog_profiling"
131
+
132
+ # Add extra relative rpaths using $ORIGIN to handle environments where gems are moved after installation.
133
+ # The excessive escaping is needed to get these special characters through Make and the shell untouched.
134
+ extra_relative_rpaths = [
135
+ libdatadog_folder_relative_to_native_lib_folder(
136
+ extconf_folder: extconf_folder,
137
+ libdatadog_pkgconfig_folder: libdatadog_pkgconfig_folder,
138
+ ),
139
+ *libdatadog_folder_relative_to_ruby_extensions_folders(
140
+ gem_dir: gem_dir,
141
+ libdatadog_pkgconfig_folder: libdatadog_pkgconfig_folder,
142
+ ),
143
+ ]
144
+ extra_relative_rpaths.each { |folder| $LDFLAGS << " -Wl,-rpath,$$$\\\\{ORIGIN\\}/#{folder}" }
145
+
146
+ logger.message("linking with libdatadog (include=#{includedir}, lib=#{libdir})\n")
147
+ logger.message("[datadog] $LDFLAGS were set to: #{$LDFLAGS.inspect}\n")
111
148
 
112
- pkg_config_available != true
149
+ true
113
150
  end
151
+ # rubocop:enable Style/GlobalVars
114
152
 
115
153
  def self.try_loading_libdatadog
116
154
  gem 'libdatadog', LIBDATADOG_VERSION
@@ -124,6 +162,51 @@ module Datadog
124
162
  end
125
163
  end
126
164
 
165
+ # Adds a C preprocessor define with the libdatadog version used at compile time.
166
+ # This allows runtime verification that the loaded libdatadog matches what was compiled against.
167
+ # rubocop:disable Style/GlobalVars
168
+ def self.add_libdatadog_version_define
169
+ $defs << %(-DEXPECTED_LIBDATADOG_VERSION=\\"#{Libdatadog::VERSION}\\")
170
+ end
171
+ # rubocop:enable Style/GlobalVars
172
+
173
+ # When setting up the extension build fails (e.g. a missing header), the actual failure ends up in mkmf.log
174
+ # and is not printed, which is confusing and complicates debugging. To fix that, this monkey patch actually
175
+ # prints the failure.
176
+ def self.dump_mkmf_log_on_failure!
177
+ # Doesn't work on 2.5/2.6 and not worth extra complexity to support
178
+ return if RUBY_VERSION < '2.7'
179
+
180
+ MakeMakefile.prepend(DumpMkmfLogOnFailure)
181
+ end
182
+
183
+ # rubocop:disable Style/GlobalVars,Style/StderrPuts
184
+ # See `dump_mkmf_log_on_failure!` for details.
185
+ module DumpMkmfLogOnFailure
186
+ def mkmf_failed(path)
187
+ unless $makefile_created || File.exist?('Makefile')
188
+ log_path = File.expand_path('mkmf.log')
189
+ if File.exist?(log_path)
190
+ # The full log is very verbose so let's grab only the last check which should be the one that failed
191
+ entries = File.read(log_path).split(/^-{20}$\n?/)
192
+ last_entry = entries.reverse.find { |e| !e.strip.empty? } || ''
193
+
194
+ $stderr.puts(
195
+ "+------------------------------------------------------------------------------+\n" \
196
+ "| There was an issue setting up extension build: |\n" \
197
+ "+------------------------------------------------------------------------------+" \
198
+ "#{last_entry.chomp}" \
199
+ "+------------------------------------------------------------------------------+\n" \
200
+ "| Full failure log is at #{log_path}\n" \
201
+ "+------------------------------------------------------------------------------+\n" \
202
+ )
203
+ end
204
+ end
205
+ super
206
+ end
207
+ end
208
+ # rubocop:enable Style/GlobalVars,Style/StderrPuts
209
+
127
210
  # Note: This helper is currently only used in the `libdatadog_api/extconf.rb` BUT still lives here to enable testing.
128
211
  def self.load_libdatadog_or_get_issue
129
212
  try_loading_libdatadog do |exception|
@@ -0,0 +1,84 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "uri"
4
+ require "net/http"
5
+ require "json"
6
+
7
+ module Datadog
8
+ module AIGuard
9
+ # API Client for AI Guard API.
10
+ # Uses net/http to perform request. Raises on client and server errors.
11
+ class APIClient
12
+ DEFAULT_SITE = "app.datadoghq.com"
13
+ DEFAULT_PATH = "/api/v2/ai-guard"
14
+
15
+ def initialize(endpoint:, api_key:, application_key:, timeout:)
16
+ @timeout = timeout
17
+
18
+ @endpoint_uri = if endpoint
19
+ URI(endpoint) #: URI::HTTP
20
+ elsif Datadog.configuration.site
21
+ host = Datadog.configuration.site.dup
22
+ host.prepend("app.") if host.count(".") == 1
23
+
24
+ URI::HTTPS.build(host: host, path: DEFAULT_PATH)
25
+ else
26
+ URI::HTTPS.build(host: DEFAULT_SITE, path: DEFAULT_PATH)
27
+ end
28
+
29
+ @headers = {
30
+ "DD-API-KEY": api_key.to_s,
31
+ "DD-APPLICATION-KEY": application_key.to_s,
32
+ "DD-AI-GUARD-VERSION": Datadog::VERSION::STRING,
33
+ "DD-AI-GUARD-SOURCE": "SDK",
34
+ "DD-AI-GUARD-LANGUAGE": "ruby",
35
+ "content-type": "application/json"
36
+ }.freeze
37
+ end
38
+
39
+ def post(path, body:)
40
+ Net::HTTP.start(@endpoint_uri.host.to_s, @endpoint_uri.port, use_ssl: use_ssl?, read_timeout: @timeout) do |http|
41
+ request = Net::HTTP::Post.new(@endpoint_uri.request_uri + path, @headers)
42
+ request.body = body.to_json
43
+
44
+ response = http.request(request)
45
+ raise_on_http_error!(response)
46
+
47
+ parse_response_body(response.body)
48
+ end
49
+ rescue Net::ReadTimeout
50
+ raise AIGuardClientError, "Request to AI Guard timed out"
51
+ end
52
+
53
+ private
54
+
55
+ def raise_on_http_error!(response)
56
+ case response
57
+ when Net::HTTPSuccess
58
+ # do nothing
59
+ when Net::HTTPRedirection
60
+ raise AIGuardClientError, "Redirects for AI Guard API are not supported"
61
+ else
62
+ error_message = begin
63
+ parsed_body = JSON.parse(response.body)
64
+ Array(parsed_body.fetch('errors')).join(', ')
65
+ rescue JSON::ParserError, KeyError
66
+ response.body
67
+ end
68
+
69
+ raise AIGuardClientError, error_message
70
+ end
71
+ end
72
+
73
+ def parse_response_body(body)
74
+ JSON.parse(body)
75
+ rescue JSON::ParserError
76
+ raise AIGuardClientError, "Could not parse response body"
77
+ end
78
+
79
+ def use_ssl?
80
+ @endpoint_uri.scheme == 'https'
81
+ end
82
+ end
83
+ end
84
+ end
@@ -0,0 +1,10 @@
1
+ # frozen_string_literal: true
2
+
3
+ if %w[1 true].include?((Datadog::DATADOG_ENV["DD_AI_GUARD_ENABLED"] || "").downcase)
4
+ begin
5
+ require_relative "contrib/auto_instrument"
6
+ Datadog::AIGuard::Contrib::AutoInstrument.patch_all
7
+ rescue => e
8
+ Kernel.warn("[datadog] AI Guard failed to auto-instrument. error: #{e.class}: #{e.message}")
9
+ end
10
+ end
@@ -0,0 +1,44 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'api_client'
4
+ require_relative 'evaluation'
5
+ require_relative 'evaluation/request'
6
+ require_relative 'evaluation/result'
7
+ require_relative 'evaluation/no_op_result'
8
+ require_relative 'evaluation/message'
9
+ require_relative 'evaluation/tool_call'
10
+ require_relative 'evaluation/content_part'
11
+ require_relative 'evaluation/content_builder'
12
+ require_relative 'ext'
13
+
14
+ module Datadog
15
+ module AIGuard
16
+ # Component for API Guard product
17
+ class Component
18
+ attr_reader :api_client, :logger, :telemetry
19
+
20
+ def self.build(settings, logger:, telemetry:)
21
+ return unless settings.respond_to?(:ai_guard) && settings.ai_guard.enabled
22
+
23
+ api_client = APIClient.new(
24
+ endpoint: settings.ai_guard.endpoint,
25
+ api_key: settings.api_key,
26
+ application_key: settings.ai_guard.app_key,
27
+ timeout: settings.ai_guard.timeout_ms / 1_000
28
+ )
29
+
30
+ new(api_client, logger: logger, telemetry: telemetry)
31
+ end
32
+
33
+ def initialize(api_client, logger:, telemetry:)
34
+ @api_client = api_client
35
+ @logger = logger
36
+ @telemetry = telemetry
37
+ end
38
+
39
+ def shutdown!
40
+ # no-op
41
+ end
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Datadog
4
+ module AIGuard
5
+ module Configuration
6
+ # This module contains constants for AI Guard component
7
+ module Ext
8
+ ENV_AI_GUARD_ENABLED = "DD_AI_GUARD_ENABLED"
9
+ ENV_AI_GUARD_ENDPOINT = "DD_AI_GUARD_ENDPOINT"
10
+ ENV_AI_GUARD_TIMEOUT = "DD_AI_GUARD_TIMEOUT"
11
+ ENV_AI_GUARD_MAX_CONTENT_SIZE = "DD_AI_GUARD_MAX_CONTENT_SIZE"
12
+ ENV_AI_GUARD_MAX_MESSAGES_LENGTH = "DD_AI_GUARD_MAX_MESSAGES_LENGTH"
13
+ ENV_APP_KEY = "DD_APP_KEY"
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,115 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "uri"
4
+ require_relative "configuration/ext"
5
+
6
+ module Datadog
7
+ module AIGuard
8
+ # Configuration module for AI Guard
9
+ module Configuration
10
+ # AI Guard specific settings
11
+ module Settings
12
+ def self.extended(base)
13
+ base = base.singleton_class unless base.is_a?(Class)
14
+ add_settings!(base)
15
+ end
16
+
17
+ def self.add_settings!(base)
18
+ base.class_eval do
19
+ # AI Guard specific configurations.
20
+ # @public_api
21
+ #
22
+ # Steep does not update `self` for this `class_eval` block.
23
+ # @type self: Datadog::Core::Configuration::Base::_DslContext
24
+ settings :ai_guard do
25
+ # Enable AI Guard.
26
+ #
27
+ # You can use this option to skip calls to AI Guard API without having to remove library as a whole.
28
+ #
29
+ # @default `DD_AI_GUARD_ENABLED`, otherwise `false`
30
+ # @return [Boolean]
31
+ option :enabled do |o|
32
+ o.type :bool
33
+ o.env Ext::ENV_AI_GUARD_ENABLED
34
+ o.default false
35
+ end
36
+
37
+ define_method(:instrument) do |integration_name|
38
+ return unless enabled # steep:ignore
39
+
40
+ if (registered_integration = Datadog::AIGuard::Contrib::Integration.registry[integration_name])
41
+ klass = registered_integration.klass
42
+ if klass.loaded? && klass.compatible?
43
+ instance = klass.new
44
+ instance.patcher.patch unless instance.patcher.patched?
45
+ end
46
+ end
47
+ end
48
+
49
+ # AI Guard API endpoint path.
50
+ #
51
+ # @default `DD_AI_GUARD_ENDPOINT`, otherwise `nil`
52
+ # @return [String, nil]
53
+ option :endpoint do |o|
54
+ o.type :string, nilable: true
55
+ o.env Ext::ENV_AI_GUARD_ENDPOINT
56
+
57
+ o.setter do |value|
58
+ next unless value
59
+
60
+ uri = URI(value.to_s)
61
+ raise ArgumentError, "Please provide an absolute URI that includes a protocol" unless uri.absolute?
62
+
63
+ uri.to_s.delete_suffix("/")
64
+ end
65
+ end
66
+
67
+ # Datadog Application key.
68
+ #
69
+ # @default `DD_APP_KEY` environment variable, otherwise `nil`
70
+ # @return [String, nil]
71
+ option :app_key do |o|
72
+ o.type :string, nilable: true
73
+ o.env Ext::ENV_APP_KEY
74
+ o.skip_telemetry true
75
+ end
76
+
77
+ # Request timeout in milliseconds.
78
+ #
79
+ # @default `DD_AI_GUARD_TIMEOUT`, otherwise 10 000 ms
80
+ # @return [Integer]
81
+ option :timeout_ms do |o|
82
+ o.type :int
83
+ o.env Ext::ENV_AI_GUARD_TIMEOUT
84
+ o.default 10_000
85
+ end
86
+
87
+ # Maximum content size in bytes.
88
+ # Content that exceeds the maximum allowed size is truncated before
89
+ # being stored in the current span context.
90
+ #
91
+ # @default `DD_AI_GUARD_MAX_CONTENT_SIZE`, otherwise 524 228 bytes
92
+ # @return [Integer]
93
+ option :max_content_size_bytes do |o|
94
+ o.type :int
95
+ o.env Ext::ENV_AI_GUARD_MAX_CONTENT_SIZE
96
+ o.default 512 * 1024
97
+ end
98
+
99
+ # Maximum number of messages.
100
+ # Older messages are omitted once the message limit is reached.
101
+ #
102
+ # @default `DD_AI_GUARD_MAX_MESSAGES_LENGTH`, otherwise 16 messages
103
+ # @return [Integer]
104
+ option :max_messages_length do |o|
105
+ o.type :int
106
+ o.env Ext::ENV_AI_GUARD_MAX_MESSAGES_LENGTH
107
+ o.default 16
108
+ end
109
+ end
110
+ end
111
+ end
112
+ end
113
+ end
114
+ end
115
+ end
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Datadog
4
+ module AIGuard
5
+ module Contrib
6
+ # Auto-instrumentation for AI Guard integrations
7
+ module AutoInstrument
8
+ def self.patch_all
9
+ integrations = []
10
+
11
+ Datadog::AIGuard::Contrib::Integration.registry.each_value do |integration|
12
+ next unless integration.klass.auto_instrument?
13
+
14
+ integrations << integration.name
15
+ end
16
+
17
+ integrations.each do |integration_name|
18
+ Datadog.configuration.ai_guard.instrument(integration_name)
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end