datadog 2.19.0 → 2.20.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 (271) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +27 -1
  3. data/ext/libdatadog_api/extconf.rb +3 -1
  4. data/ext/libdatadog_extconf_helpers.rb +13 -3
  5. data/lib/datadog/appsec/component.rb +3 -13
  6. data/lib/datadog/appsec/context.rb +23 -0
  7. data/lib/datadog/appsec/contrib/devise/patches/signin_tracking_patch.rb +2 -1
  8. data/lib/datadog/appsec/contrib/devise/patches/signup_tracking_patch.rb +2 -1
  9. data/lib/datadog/appsec/contrib/excon/ssrf_detection_middleware.rb +0 -1
  10. data/lib/datadog/appsec/contrib/faraday/ssrf_detection_middleware.rb +0 -1
  11. data/lib/datadog/appsec/contrib/rack/request_middleware.rb +14 -22
  12. data/lib/datadog/appsec/contrib/rails/gateway/watcher.rb +23 -2
  13. data/lib/datadog/appsec/contrib/rails/patcher.rb +14 -26
  14. data/lib/datadog/appsec/contrib/rails/patches/process_action_patch.rb +27 -0
  15. data/lib/datadog/appsec/contrib/rails/patches/render_to_body_patch.rb +33 -0
  16. data/lib/datadog/appsec/contrib/rest_client/request_ssrf_detection_patch.rb +0 -1
  17. data/lib/datadog/appsec/contrib/sinatra/gateway/watcher.rb +23 -0
  18. data/lib/datadog/appsec/contrib/sinatra/patcher.rb +8 -18
  19. data/lib/datadog/appsec/contrib/sinatra/patches/json_patch.rb +31 -0
  20. data/lib/datadog/appsec/event.rb +3 -18
  21. data/lib/datadog/appsec/instrumentation/gateway/argument.rb +16 -0
  22. data/lib/datadog/appsec/metrics/collector.rb +7 -3
  23. data/lib/datadog/appsec/metrics/telemetry.rb +1 -1
  24. data/lib/datadog/appsec/metrics/telemetry_exporter.rb +28 -0
  25. data/lib/datadog/appsec/metrics.rb +1 -0
  26. data/lib/datadog/appsec/security_engine/engine.rb +14 -32
  27. data/lib/datadog/appsec/security_engine/result.rb +16 -0
  28. data/lib/datadog/appsec/security_engine/runner.rb +18 -4
  29. data/lib/datadog/appsec/thread_safe_ref.rb +61 -0
  30. data/lib/datadog/appsec/trace_keeper.rb +24 -0
  31. data/lib/datadog/appsec/utils/hash_coercion.rb +23 -0
  32. data/lib/datadog/appsec.rb +0 -7
  33. data/lib/datadog/auto_instrument_base.rb +2 -1
  34. data/lib/datadog/core/configuration/option.rb +29 -20
  35. data/lib/datadog/core/configuration/option_definition.rb +2 -2
  36. data/lib/datadog/core/configuration/options.rb +13 -7
  37. data/lib/datadog/di/boot.rb +7 -0
  38. data/lib/datadog/di/component.rb +7 -0
  39. data/lib/datadog/di/probe_file_loader/railtie.rb +15 -0
  40. data/lib/datadog/di/probe_file_loader.rb +82 -0
  41. data/lib/datadog/di/remote.rb +3 -5
  42. data/lib/datadog/di.rb +0 -1
  43. data/lib/datadog/kit/appsec/events/v2.rb +5 -4
  44. data/lib/datadog/kit/appsec/events.rb +11 -10
  45. data/lib/datadog/kit/identity.rb +17 -11
  46. data/lib/datadog/opentelemetry/api/baggage.rb +2 -2
  47. data/lib/datadog/opentelemetry/api/context.rb +10 -9
  48. data/lib/datadog/opentelemetry/sdk/propagator.rb +4 -4
  49. data/lib/datadog/opentelemetry/sdk/span_processor.rb +8 -8
  50. data/lib/datadog/opentelemetry/sdk/trace/span.rb +14 -10
  51. data/lib/datadog/opentelemetry/trace.rb +4 -4
  52. data/lib/datadog/profiling.rb +6 -8
  53. data/lib/datadog/tracing/analytics.rb +1 -1
  54. data/lib/datadog/tracing/buffer.rb +7 -7
  55. data/lib/datadog/tracing/configuration/dynamic.rb +4 -6
  56. data/lib/datadog/tracing/configuration/ext.rb +3 -2
  57. data/lib/datadog/tracing/configuration/settings.rb +17 -0
  58. data/lib/datadog/tracing/context.rb +2 -2
  59. data/lib/datadog/tracing/contrib/action_cable/event.rb +1 -1
  60. data/lib/datadog/tracing/contrib/action_cable/integration.rb +1 -1
  61. data/lib/datadog/tracing/contrib/action_mailer/integration.rb +1 -1
  62. data/lib/datadog/tracing/contrib/action_pack/action_controller/instrumentation.rb +4 -4
  63. data/lib/datadog/tracing/contrib/action_pack/integration.rb +1 -1
  64. data/lib/datadog/tracing/contrib/action_view/events/render_template.rb +1 -1
  65. data/lib/datadog/tracing/contrib/active_job/event.rb +8 -8
  66. data/lib/datadog/tracing/contrib/active_job/events/discard.rb +1 -1
  67. data/lib/datadog/tracing/contrib/active_job/events/enqueue.rb +1 -1
  68. data/lib/datadog/tracing/contrib/active_job/events/enqueue_at.rb +1 -1
  69. data/lib/datadog/tracing/contrib/active_job/events/enqueue_retry.rb +1 -1
  70. data/lib/datadog/tracing/contrib/active_job/events/perform.rb +1 -1
  71. data/lib/datadog/tracing/contrib/active_job/events/retry_stopped.rb +1 -1
  72. data/lib/datadog/tracing/contrib/active_job/integration.rb +1 -1
  73. data/lib/datadog/tracing/contrib/active_model_serializers/events/render.rb +1 -1
  74. data/lib/datadog/tracing/contrib/active_model_serializers/events/serialize.rb +3 -3
  75. data/lib/datadog/tracing/contrib/active_model_serializers/integration.rb +1 -2
  76. data/lib/datadog/tracing/contrib/active_record/configuration/resolver.rb +1 -1
  77. data/lib/datadog/tracing/contrib/active_record/events/instantiation.rb +1 -1
  78. data/lib/datadog/tracing/contrib/active_record/events/sql.rb +5 -5
  79. data/lib/datadog/tracing/contrib/active_record/integration.rb +1 -1
  80. data/lib/datadog/tracing/contrib/active_record/utils.rb +15 -15
  81. data/lib/datadog/tracing/contrib/active_support/cache/events/cache.rb +6 -6
  82. data/lib/datadog/tracing/contrib/active_support/integration.rb +1 -1
  83. data/lib/datadog/tracing/contrib/active_support/notifications/event.rb +2 -1
  84. data/lib/datadog/tracing/contrib/active_support/notifications/subscription.rb +7 -9
  85. data/lib/datadog/tracing/contrib/aws/ext.rb +1 -1
  86. data/lib/datadog/tracing/contrib/aws/instrumentation.rb +2 -2
  87. data/lib/datadog/tracing/contrib/aws/parsed_context.rb +3 -1
  88. data/lib/datadog/tracing/contrib/aws/patcher.rb +5 -1
  89. data/lib/datadog/tracing/contrib/aws/service/base.rb +2 -1
  90. data/lib/datadog/tracing/contrib/aws/service/dynamodb.rb +1 -1
  91. data/lib/datadog/tracing/contrib/aws/service/eventbridge.rb +1 -1
  92. data/lib/datadog/tracing/contrib/aws/service/kinesis.rb +1 -1
  93. data/lib/datadog/tracing/contrib/aws/service/s3.rb +1 -1
  94. data/lib/datadog/tracing/contrib/aws/service/sns.rb +1 -1
  95. data/lib/datadog/tracing/contrib/aws/service/sqs.rb +1 -1
  96. data/lib/datadog/tracing/contrib/aws/service/states.rb +1 -1
  97. data/lib/datadog/tracing/contrib/aws/services.rb +7 -7
  98. data/lib/datadog/tracing/contrib/concurrent_ruby/async_patch.rb +1 -1
  99. data/lib/datadog/tracing/contrib/concurrent_ruby/context_composite_executor_service.rb +1 -1
  100. data/lib/datadog/tracing/contrib/concurrent_ruby/future_patch.rb +1 -1
  101. data/lib/datadog/tracing/contrib/concurrent_ruby/integration.rb +1 -1
  102. data/lib/datadog/tracing/contrib/concurrent_ruby/promises_future_patch.rb +1 -1
  103. data/lib/datadog/tracing/contrib/configurable.rb +6 -6
  104. data/lib/datadog/tracing/contrib/configuration/resolvers/pattern_resolver.rb +4 -4
  105. data/lib/datadog/tracing/contrib/dalli/ext.rb +3 -2
  106. data/lib/datadog/tracing/contrib/dalli/integration.rb +1 -1
  107. data/lib/datadog/tracing/contrib/delayed_job/integration.rb +1 -1
  108. data/lib/datadog/tracing/contrib/elasticsearch/ext.rb +3 -2
  109. data/lib/datadog/tracing/contrib/elasticsearch/integration.rb +4 -4
  110. data/lib/datadog/tracing/contrib/elasticsearch/patcher.rb +51 -53
  111. data/lib/datadog/tracing/contrib/elasticsearch/quantize.rb +5 -5
  112. data/lib/datadog/tracing/contrib/ethon/easy_patch.rb +2 -2
  113. data/lib/datadog/tracing/contrib/ethon/ext.rb +3 -2
  114. data/lib/datadog/tracing/contrib/ethon/integration.rb +1 -1
  115. data/lib/datadog/tracing/contrib/excon/ext.rb +3 -2
  116. data/lib/datadog/tracing/contrib/excon/integration.rb +1 -1
  117. data/lib/datadog/tracing/contrib/excon/middleware.rb +2 -2
  118. data/lib/datadog/tracing/contrib/ext.rb +3 -3
  119. data/lib/datadog/tracing/contrib/extensions.rb +9 -9
  120. data/lib/datadog/tracing/contrib/faraday/ext.rb +3 -2
  121. data/lib/datadog/tracing/contrib/faraday/integration.rb +1 -1
  122. data/lib/datadog/tracing/contrib/faraday/middleware.rb +4 -2
  123. data/lib/datadog/tracing/contrib/grape/endpoint.rb +8 -8
  124. data/lib/datadog/tracing/contrib/grape/integration.rb +1 -1
  125. data/lib/datadog/tracing/contrib/graphql/integration.rb +1 -1
  126. data/lib/datadog/tracing/contrib/graphql/patcher.rb +2 -2
  127. data/lib/datadog/tracing/contrib/graphql/unified_trace.rb +24 -24
  128. data/lib/datadog/tracing/contrib/grpc/datadog_interceptor/client.rb +8 -8
  129. data/lib/datadog/tracing/contrib/grpc/datadog_interceptor/server.rb +3 -3
  130. data/lib/datadog/tracing/contrib/grpc/distributed/fetcher.rb +1 -1
  131. data/lib/datadog/tracing/contrib/grpc/integration.rb +1 -1
  132. data/lib/datadog/tracing/contrib/hanami/ext.rb +2 -2
  133. data/lib/datadog/tracing/contrib/hanami/integration.rb +1 -1
  134. data/lib/datadog/tracing/contrib/hanami/renderer_policy_tracing.rb +1 -1
  135. data/lib/datadog/tracing/contrib/hanami/router_tracing.rb +9 -11
  136. data/lib/datadog/tracing/contrib/http/distributed/fetcher.rb +4 -4
  137. data/lib/datadog/tracing/contrib/http/ext.rb +3 -2
  138. data/lib/datadog/tracing/contrib/http/instrumentation.rb +5 -5
  139. data/lib/datadog/tracing/contrib/httpclient/ext.rb +3 -2
  140. data/lib/datadog/tracing/contrib/httpclient/instrumentation.rb +3 -3
  141. data/lib/datadog/tracing/contrib/httpclient/integration.rb +1 -1
  142. data/lib/datadog/tracing/contrib/httprb/ext.rb +3 -2
  143. data/lib/datadog/tracing/contrib/httprb/instrumentation.rb +4 -4
  144. data/lib/datadog/tracing/contrib/httprb/integration.rb +1 -1
  145. data/lib/datadog/tracing/contrib/kafka/event.rb +1 -1
  146. data/lib/datadog/tracing/contrib/kafka/events/connection/request.rb +1 -1
  147. data/lib/datadog/tracing/contrib/kafka/events/consumer/process_batch.rb +1 -1
  148. data/lib/datadog/tracing/contrib/kafka/events/consumer/process_message.rb +1 -1
  149. data/lib/datadog/tracing/contrib/kafka/events/consumer_group/heartbeat.rb +1 -1
  150. data/lib/datadog/tracing/contrib/kafka/events/consumer_group/join_group.rb +1 -1
  151. data/lib/datadog/tracing/contrib/kafka/events/consumer_group/leave_group.rb +1 -1
  152. data/lib/datadog/tracing/contrib/kafka/events/consumer_group/sync_group.rb +1 -1
  153. data/lib/datadog/tracing/contrib/kafka/events/produce_operation/send_messages.rb +1 -1
  154. data/lib/datadog/tracing/contrib/kafka/events/producer/deliver_messages.rb +1 -1
  155. data/lib/datadog/tracing/contrib/kafka/integration.rb +1 -1
  156. data/lib/datadog/tracing/contrib/karafka/monitor.rb +13 -13
  157. data/lib/datadog/tracing/contrib/karafka/patcher.rb +4 -4
  158. data/lib/datadog/tracing/contrib/lograge/instrumentation.rb +1 -1
  159. data/lib/datadog/tracing/contrib/lograge/integration.rb +1 -1
  160. data/lib/datadog/tracing/contrib/mongodb/configuration/settings.rb +1 -1
  161. data/lib/datadog/tracing/contrib/mongodb/ext.rb +1 -1
  162. data/lib/datadog/tracing/contrib/mongodb/integration.rb +1 -1
  163. data/lib/datadog/tracing/contrib/mongodb/parsers.rb +1 -1
  164. data/lib/datadog/tracing/contrib/mongodb/subscribers.rb +6 -6
  165. data/lib/datadog/tracing/contrib/mysql2/ext.rb +1 -1
  166. data/lib/datadog/tracing/contrib/mysql2/integration.rb +1 -1
  167. data/lib/datadog/tracing/contrib/opensearch/configuration/settings.rb +1 -1
  168. data/lib/datadog/tracing/contrib/opensearch/ext.rb +3 -2
  169. data/lib/datadog/tracing/contrib/opensearch/integration.rb +1 -2
  170. data/lib/datadog/tracing/contrib/opensearch/patcher.rb +68 -70
  171. data/lib/datadog/tracing/contrib/opensearch/quantize.rb +5 -5
  172. data/lib/datadog/tracing/contrib/patcher.rb +7 -9
  173. data/lib/datadog/tracing/contrib/pg/integration.rb +1 -1
  174. data/lib/datadog/tracing/contrib/presto/ext.rb +1 -1
  175. data/lib/datadog/tracing/contrib/presto/instrumentation.rb +3 -3
  176. data/lib/datadog/tracing/contrib/presto/integration.rb +1 -1
  177. data/lib/datadog/tracing/contrib/propagation/sql_comment/comment.rb +1 -1
  178. data/lib/datadog/tracing/contrib/propagation/sql_comment.rb +1 -1
  179. data/lib/datadog/tracing/contrib/que/integration.rb +1 -1
  180. data/lib/datadog/tracing/contrib/racecar/event.rb +1 -1
  181. data/lib/datadog/tracing/contrib/racecar/events/batch.rb +2 -2
  182. data/lib/datadog/tracing/contrib/racecar/events/consume.rb +1 -1
  183. data/lib/datadog/tracing/contrib/racecar/events/message.rb +2 -2
  184. data/lib/datadog/tracing/contrib/racecar/integration.rb +1 -1
  185. data/lib/datadog/tracing/contrib/rack/header_collection.rb +1 -1
  186. data/lib/datadog/tracing/contrib/rack/header_tagging.rb +32 -32
  187. data/lib/datadog/tracing/contrib/rack/integration.rb +1 -1
  188. data/lib/datadog/tracing/contrib/rack/middlewares.rb +21 -17
  189. data/lib/datadog/tracing/contrib/rack/patcher.rb +1 -1
  190. data/lib/datadog/tracing/contrib/rack/request_queue.rb +2 -2
  191. data/lib/datadog/tracing/contrib/rails/configuration/settings.rb +1 -1
  192. data/lib/datadog/tracing/contrib/rails/integration.rb +1 -1
  193. data/lib/datadog/tracing/contrib/rails/log_injection.rb +1 -1
  194. data/lib/datadog/tracing/contrib/rails/middlewares.rb +1 -1
  195. data/lib/datadog/tracing/contrib/rails/runner.rb +5 -4
  196. data/lib/datadog/tracing/contrib/rake/instrumentation.rb +4 -4
  197. data/lib/datadog/tracing/contrib/rake/integration.rb +1 -1
  198. data/lib/datadog/tracing/contrib/redis/configuration/resolver.rb +2 -2
  199. data/lib/datadog/tracing/contrib/redis/ext.rb +3 -2
  200. data/lib/datadog/tracing/contrib/redis/integration.rb +2 -2
  201. data/lib/datadog/tracing/contrib/redis/patcher.rb +4 -4
  202. data/lib/datadog/tracing/contrib/redis/quantize.rb +1 -1
  203. data/lib/datadog/tracing/contrib/redis/tags.rb +1 -1
  204. data/lib/datadog/tracing/contrib/redis/trace_middleware.rb +4 -4
  205. data/lib/datadog/tracing/contrib/registry.rb +1 -1
  206. data/lib/datadog/tracing/contrib/resque/integration.rb +1 -1
  207. data/lib/datadog/tracing/contrib/resque/resque_job.rb +1 -1
  208. data/lib/datadog/tracing/contrib/rest_client/ext.rb +3 -2
  209. data/lib/datadog/tracing/contrib/rest_client/integration.rb +1 -1
  210. data/lib/datadog/tracing/contrib/rest_client/request_patch.rb +3 -3
  211. data/lib/datadog/tracing/contrib/roda/instrumentation.rb +1 -1
  212. data/lib/datadog/tracing/contrib/roda/integration.rb +1 -1
  213. data/lib/datadog/tracing/contrib/semantic_logger/instrumentation.rb +1 -1
  214. data/lib/datadog/tracing/contrib/semantic_logger/integration.rb +1 -1
  215. data/lib/datadog/tracing/contrib/sequel/database.rb +5 -5
  216. data/lib/datadog/tracing/contrib/sequel/dataset.rb +1 -1
  217. data/lib/datadog/tracing/contrib/sequel/integration.rb +1 -1
  218. data/lib/datadog/tracing/contrib/sequel/utils.rb +1 -1
  219. data/lib/datadog/tracing/contrib/shoryuken/integration.rb +1 -1
  220. data/lib/datadog/tracing/contrib/sidekiq/integration.rb +1 -1
  221. data/lib/datadog/tracing/contrib/sidekiq/utils.rb +1 -1
  222. data/lib/datadog/tracing/contrib/sinatra/integration.rb +1 -1
  223. data/lib/datadog/tracing/contrib/sinatra/tracer_middleware.rb +38 -40
  224. data/lib/datadog/tracing/contrib/sneakers/integration.rb +1 -1
  225. data/lib/datadog/tracing/contrib/stripe/integration.rb +1 -1
  226. data/lib/datadog/tracing/contrib/stripe/request.rb +1 -1
  227. data/lib/datadog/tracing/contrib/sucker_punch/integration.rb +1 -1
  228. data/lib/datadog/tracing/contrib/trilogy/ext.rb +1 -1
  229. data/lib/datadog/tracing/contrib/trilogy/integration.rb +1 -1
  230. data/lib/datadog/tracing/contrib/utils/quantization/hash.rb +11 -11
  231. data/lib/datadog/tracing/contrib/utils/quantization/http.rb +6 -6
  232. data/lib/datadog/tracing/diagnostics/environment_logger.rb +5 -1
  233. data/lib/datadog/tracing/distributed/b3_single.rb +1 -1
  234. data/lib/datadog/tracing/distributed/baggage.rb +73 -8
  235. data/lib/datadog/tracing/distributed/datadog.rb +4 -5
  236. data/lib/datadog/tracing/distributed/datadog_tags_codec.rb +11 -13
  237. data/lib/datadog/tracing/distributed/helpers.rb +1 -1
  238. data/lib/datadog/tracing/distributed/none.rb +4 -2
  239. data/lib/datadog/tracing/distributed/propagation.rb +4 -1
  240. data/lib/datadog/tracing/distributed/propagation_policy.rb +1 -1
  241. data/lib/datadog/tracing/distributed/trace_context.rb +22 -16
  242. data/lib/datadog/tracing/event.rb +5 -7
  243. data/lib/datadog/tracing/flush.rb +1 -1
  244. data/lib/datadog/tracing/metadata/analytics.rb +1 -1
  245. data/lib/datadog/tracing/metadata/tagging.rb +4 -4
  246. data/lib/datadog/tracing/pipeline/span_filter.rb +3 -1
  247. data/lib/datadog/tracing/pipeline/span_processor.rb +3 -1
  248. data/lib/datadog/tracing/pipeline.rb +1 -1
  249. data/lib/datadog/tracing/sampling/ext.rb +0 -2
  250. data/lib/datadog/tracing/sampling/rule_sampler.rb +30 -30
  251. data/lib/datadog/tracing/sampling/span/rule_parser.rb +1 -1
  252. data/lib/datadog/tracing/sampling/span/sampler.rb +0 -7
  253. data/lib/datadog/tracing/span.rb +1 -1
  254. data/lib/datadog/tracing/span_event.rb +10 -10
  255. data/lib/datadog/tracing/span_link.rb +12 -12
  256. data/lib/datadog/tracing/span_operation.rb +9 -11
  257. data/lib/datadog/tracing/trace_digest.rb +21 -23
  258. data/lib/datadog/tracing/trace_operation.rb +84 -88
  259. data/lib/datadog/tracing/trace_segment.rb +2 -2
  260. data/lib/datadog/tracing/tracer.rb +36 -38
  261. data/lib/datadog/tracing/transport/http/client.rb +1 -1
  262. data/lib/datadog/tracing/transport/http/traces.rb +2 -2
  263. data/lib/datadog/tracing/transport/io/client.rb +5 -5
  264. data/lib/datadog/tracing/transport/io/traces.rb +4 -4
  265. data/lib/datadog/tracing/transport/statistics.rb +1 -1
  266. data/lib/datadog/tracing/transport/traces.rb +5 -5
  267. data/lib/datadog/tracing/workers/trace_writer.rb +12 -12
  268. data/lib/datadog/tracing/workers.rb +2 -2
  269. data/lib/datadog/tracing.rb +2 -2
  270. data/lib/datadog/version.rb +1 -1
  271. metadata +15 -6
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 9c533682b9a96989e1ad8d4eb96339af4bffdb5fd9cbfe447bd0a034bc387c03
4
- data.tar.gz: 5d7808aa6b7fd5f9c68e453fef4fff8c5345c62fb26a7f7839d630ec0da2fe9f
3
+ metadata.gz: 9b5e6a8c0374f599db43eabbbee53ea6a9e0b4079b04880e81298b8f4aa55545
4
+ data.tar.gz: ca1d8964d2e12768e405a0c70062dae7420f8a53d73b32bdb163c8b5dd38d794
5
5
  SHA512:
6
- metadata.gz: 6b35d7ef1ce2f9e565727037f9e5b329d019202ff20c01a15bb5096cf14253b3ab9812d4fc84fc23e265ec2e7e0096e34acc6a845ad510b215ef7df4093107e7
7
- data.tar.gz: 72fff247b51de201e4373638627fa419a3a679979f880dfa44c73d1c9a7c062991746045d41cbe5fa47d824b025fb9cad2f34c0139e034df1b85ddb4a07bccd9
6
+ metadata.gz: 77f707de1847f987a71dfd13401c07260fc1b33997b8033bb42c466cbe55af1177f30fb4f8aaf17d36f5aa7dec2c25b87961f7a38b013e0cbd27d62ab3e8c3fa
7
+ data.tar.gz: 4cf002b5b6fd6e2ca6dc2870409115624768f1f0b0d0556bea760117d8298d0657efff39bd8c2d1c8b23d03bbbf0e8ecb2c1735f6f1d55df2ca963359bf1631f
data/CHANGELOG.md CHANGED
@@ -2,6 +2,24 @@
2
2
 
3
3
  ## [Unreleased]
4
4
 
5
+ ## [2.20.0] - 2025-09-04
6
+
7
+ ### Added
8
+
9
+ * Tracing: Add capability to add [W3C Baggage](https://www.w3.org/TR/baggage/#example) headers to the local root span as span tags ([#4716][])
10
+ * AppSec: Add WAF analysis of the responses with JSON body ([#4848][])
11
+ * Dynamic Instrumentation: Live Debugger: Add support for specifying probes in a file via `DD_DYNAMIC_INSTRUMENTATION_PROBE_FILE` environment variable ([#4838][])
12
+
13
+ ### Changed
14
+
15
+ * Core: Expand generated warning and error messages during `libdatadog` build ([#4831][])
16
+ * AppSec: Rework handling of Remote Config updates for multi-threaded web servers ([#4833][])
17
+ * AppSec: Update security tags for Business Logic Events and User Events SDK v1 and v2 ([#4851][])
18
+
19
+ ### Fixed
20
+
21
+ * Tracing: Fix constants resolution for Rails runner ([#4863][])
22
+
5
23
  ## [2.19.0] - 2025-07-24
6
24
 
7
25
  ### Added
@@ -3297,7 +3315,8 @@ Release notes: https://github.com/DataDog/dd-trace-rb/releases/tag/v0.3.1
3297
3315
  Git diff: https://github.com/DataDog/dd-trace-rb/compare/v0.3.0...v0.3.1
3298
3316
 
3299
3317
 
3300
- [Unreleased]: https://github.com/DataDog/dd-trace-rb/compare/v2.19.0...master
3318
+ [Unreleased]: https://github.com/DataDog/dd-trace-rb/compare/v2.20.0...master
3319
+ [2.20.0]: https://github.com/DataDog/dd-trace-rb/compare/v2.19.0...v2.20.0
3301
3320
  [2.19.0]: https://github.com/DataDog/dd-trace-rb/compare/v2.18.0...v2.19.0
3302
3321
  [2.18.0]: https://github.com/DataDog/dd-trace-rb/compare/v2.17.0...v2.18.0
3303
3322
  [2.17.0]: https://github.com/DataDog/dd-trace-rb/compare/v2.16.0...v2.17.0
@@ -4863,6 +4882,7 @@ Git diff: https://github.com/DataDog/dd-trace-rb/compare/v0.3.0...v0.3.1
4863
4882
  [#4693]: https://github.com/DataDog/dd-trace-rb/issues/4693
4864
4883
  [#4697]: https://github.com/DataDog/dd-trace-rb/issues/4697
4865
4884
  [#4699]: https://github.com/DataDog/dd-trace-rb/issues/4699
4885
+ [#4716]: https://github.com/DataDog/dd-trace-rb/issues/4716
4866
4886
  [#4718]: https://github.com/DataDog/dd-trace-rb/issues/4718
4867
4887
  [#4721]: https://github.com/DataDog/dd-trace-rb/issues/4721
4868
4888
  [#4728]: https://github.com/DataDog/dd-trace-rb/issues/4728
@@ -4884,6 +4904,12 @@ Git diff: https://github.com/DataDog/dd-trace-rb/compare/v0.3.0...v0.3.1
4884
4904
  [#4813]: https://github.com/DataDog/dd-trace-rb/issues/4813
4885
4905
  [#4814]: https://github.com/DataDog/dd-trace-rb/issues/4814
4886
4906
  [#4819]: https://github.com/DataDog/dd-trace-rb/issues/4819
4907
+ [#4831]: https://github.com/DataDog/dd-trace-rb/issues/4831
4908
+ [#4833]: https://github.com/DataDog/dd-trace-rb/issues/4833
4909
+ [#4838]: https://github.com/DataDog/dd-trace-rb/issues/4838
4910
+ [#4848]: https://github.com/DataDog/dd-trace-rb/issues/4848
4911
+ [#4851]: https://github.com/DataDog/dd-trace-rb/issues/4851
4912
+ [#4863]: https://github.com/DataDog/dd-trace-rb/issues/4863
4887
4913
  [@AdrianLC]: https://github.com/AdrianLC
4888
4914
  [@Azure7111]: https://github.com/Azure7111
4889
4915
  [@BabyGroot]: https://github.com/BabyGroot
@@ -26,7 +26,9 @@ if ENV['DD_NO_EXTENSION'].to_s.strip.downcase == 'true'
26
26
  end
27
27
  skip_building_extension!('current Ruby VM is not supported') if RUBY_ENGINE != 'ruby'
28
28
  skip_building_extension!('Microsoft Windows is not supported') if Gem.win_platform?
29
- skip_building_extension!('issue setting up `libdatadog` gem') if Datadog::LibdatadogExtconfHelpers.libdatadog_issue?
29
+
30
+ libdatadog_issue = Datadog::LibdatadogExtconfHelpers.load_libdatadog_or_get_issue
31
+ skip_building_extension!("issue setting up `libdatadog` gem: #{libdatadog_issue}") if libdatadog_issue
30
32
 
31
33
  require 'mkmf'
32
34
 
@@ -5,6 +5,8 @@ require 'pathname'
5
5
 
6
6
  module Datadog
7
7
  # Contains a bunch of shared helpers that get used during building of extensions that link to libdatadog
8
+ #
9
+ # Note: Specs for this file currently live in `spec/datadog/profiling/native_extension_helpers_spec.rb`.
8
10
  module LibdatadogExtconfHelpers
9
11
  # Used to make sure the correct gem version gets loaded, as extconf.rb does not get run with "bundle exec" and thus
10
12
  # may see multiple libdatadog versions. See https://github.com/DataDog/dd-trace-rb/pull/2531 for the horror story.
@@ -122,9 +124,17 @@ module Datadog
122
124
  end
123
125
  end
124
126
 
125
- def self.libdatadog_issue?
126
- try_loading_libdatadog { |_exception| return true }
127
- Libdatadog.pkgconfig_folder.nil?
127
+ # Note: This helper is currently only used in the `libdatadog_api/extconf.rb` BUT still lives here to enable testing.
128
+ def self.load_libdatadog_or_get_issue
129
+ try_loading_libdatadog do |exception|
130
+ return "There was an error loading `libdatadog`: #{exception.class} #{exception.message}"
131
+ end
132
+
133
+ unless Libdatadog.pkgconfig_folder
134
+ "The `libdatadog` gem installed on your system is missing binaries for your platform variant. " \
135
+ "Your platform: " \
136
+ "`#{Libdatadog.current_platform}`; available binaries: `#{Libdatadog.available_binaries.join("`, `")}`"
137
+ end
128
138
  end
129
139
  end
130
140
  end
@@ -4,6 +4,7 @@ require_relative 'security_engine/engine'
4
4
  require_relative 'security_engine/runner'
5
5
  require_relative 'processor/rule_loader'
6
6
  require_relative 'actions_handler'
7
+ require_relative 'thread_safe_ref'
7
8
 
8
9
  module Datadog
9
10
  module AppSec
@@ -74,25 +75,14 @@ module Datadog
74
75
  def initialize(security_engine:, telemetry:)
75
76
  @security_engine = security_engine
76
77
  @telemetry = telemetry
77
-
78
- @mutex = Mutex.new
79
78
  end
80
79
 
81
80
  def reconfigure!
82
- @mutex.synchronize do
83
- security_engine.reconfigure!
84
- end
85
- end
86
-
87
- def reconfigure_lock(&block)
88
- @mutex.synchronize(&block)
81
+ security_engine.reconfigure!
89
82
  end
90
83
 
91
84
  def shutdown!
92
- @mutex.synchronize do
93
- security_engine.finalize!
94
- @security_engine = nil
95
- end
85
+ # no-op
96
86
  end
97
87
  end
98
88
  end
@@ -37,6 +37,7 @@ module Datadog
37
37
  @events = []
38
38
  @waf_runner = waf_runner
39
39
  @metrics = Metrics::Collector.new
40
+ @interrupted = false
40
41
  end
41
42
 
42
43
  def run_waf(persistent_data, ephemeral_data, timeout = WAF::LibDDWAF::DDWAF_RUN_TIMEOUT)
@@ -55,6 +56,22 @@ module Datadog
55
56
  result
56
57
  end
57
58
 
59
+ def mark_as_interrupted!
60
+ @interrupted = true
61
+ end
62
+
63
+ def interrupted?
64
+ @interrupted
65
+ end
66
+
67
+ def waf_runner_ruleset_version
68
+ @waf_runner.ruleset_version
69
+ end
70
+
71
+ def waf_runner_known_addresses
72
+ @waf_runner.waf_addresses
73
+ end
74
+
58
75
  def extract_schema
59
76
  @waf_runner.run({'waf.context.processor' => {'extract-schema' => true}}, {})
60
77
  end
@@ -66,6 +83,12 @@ module Datadog
66
83
  Metrics::Exporter.export_rasp_metrics(@metrics.rasp, @span)
67
84
  end
68
85
 
86
+ def export_request_telemetry
87
+ return if @trace.nil?
88
+
89
+ Metrics::TelemetryExporter.export_waf_request_metrics(@metrics.waf, self)
90
+ end
91
+
69
92
  def finalize!
70
93
  @waf_runner.finalize!
71
94
  end
@@ -3,6 +3,7 @@
3
3
  require_relative '../ext'
4
4
  require_relative '../configuration'
5
5
  require_relative '../data_extractor'
6
+ require_relative '../../../trace_keeper'
6
7
 
7
8
  module Datadog
8
9
  module AppSec
@@ -25,7 +26,7 @@ module Datadog
25
26
  return result
26
27
  end
27
28
 
28
- context.trace.keep!
29
+ TraceKeeper.keep!(context.trace)
29
30
 
30
31
  if result
31
32
  record_successful_signin(context, resource)
@@ -3,6 +3,7 @@
3
3
  require_relative '../ext'
4
4
  require_relative '../configuration'
5
5
  require_relative '../data_extractor'
6
+ require_relative '../../../trace_keeper'
6
7
 
7
8
  module Datadog
8
9
  module AppSec
@@ -26,7 +27,7 @@ module Datadog
26
27
 
27
28
  next yield(resource) if resource.new_record? && block_given?
28
29
 
29
- context.trace.keep!
30
+ TraceKeeper.keep!(context.trace)
30
31
  record_successful_signup(context, resource)
31
32
  Instrumentation.gateway.push('appsec.events.user_lifecycle', Ext::EVENT_SIGNUP)
32
33
 
@@ -1,4 +1,3 @@
1
- # rubocop:disable Naming/FileName
2
1
  # frozen_string_literal: true
3
2
 
4
3
  require 'excon'
@@ -1,4 +1,3 @@
1
- # rubocop:disable Naming/FileName
2
1
  # frozen_string_literal: true
3
2
 
4
3
  require_relative '../../event'
@@ -46,33 +46,22 @@ module Datadog
46
46
  boot = Datadog::Core::Remote::Tie.boot
47
47
  Datadog::Core::Remote::Tie::Tracing.tag(boot, active_span)
48
48
 
49
- security_engine = nil
50
- ready = false
51
- ctx = nil
52
-
53
49
  # For a given request, keep using the first Rack stack scope for
54
50
  # nested apps. Don't set `context` local variable so that on popping
55
51
  # out of this nested stack we don't finalize the parent's context
56
52
  return @app.call(env) if active_context(env)
57
53
 
58
- Datadog::AppSec.reconfigure_lock do
59
- security_engine = Datadog::AppSec.security_engine
60
-
61
- if security_engine
62
- ctx = Datadog::AppSec::Context.activate(
63
- Datadog::AppSec::Context.new(active_trace, active_span, security_engine.new_runner)
64
- )
65
-
66
- env[Datadog::AppSec::Ext::CONTEXT_KEY] = ctx
67
- ready = true
68
- end
69
- end
54
+ security_engine = Datadog::AppSec.security_engine
70
55
 
71
56
  # TODO: handle exceptions, except for @app.call
57
+ return @app.call(env) unless security_engine
72
58
 
73
- return @app.call(env) unless ready
59
+ ctx = Datadog::AppSec::Context.activate(
60
+ Datadog::AppSec::Context.new(active_trace, active_span, security_engine.new_runner)
61
+ )
62
+ env[Datadog::AppSec::Ext::CONTEXT_KEY] = ctx
74
63
 
75
- add_appsec_tags(security_engine, ctx)
64
+ add_appsec_tags(ctx)
76
65
  add_request_tags(ctx, env)
77
66
 
78
67
  http_response = nil
@@ -97,6 +86,7 @@ module Datadog
97
86
  end
98
87
 
99
88
  if interrupt_params
89
+ ctx.mark_as_interrupted!
100
90
  http_response = AppSec::Response.from_interrupt_params(interrupt_params, env['HTTP_ACCEPT']).to_rack
101
91
  end
102
92
 
@@ -128,6 +118,8 @@ module Datadog
128
118
  ensure
129
119
  if ctx
130
120
  ctx.export_metrics
121
+ ctx.export_request_telemetry
122
+
131
123
  Datadog::AppSec::Context.deactivate
132
124
  end
133
125
  end
@@ -156,7 +148,7 @@ module Datadog
156
148
  end
157
149
 
158
150
  # standard:disable Metrics/MethodLength
159
- def add_appsec_tags(security_engine, context)
151
+ def add_appsec_tags(context)
160
152
  span = context.span
161
153
  trace = context.trace
162
154
 
@@ -166,15 +158,15 @@ module Datadog
166
158
  span.set_tag('_dd.runtime_family', 'ruby')
167
159
  span.set_tag('_dd.appsec.waf.version', Datadog::AppSec::WAF::VERSION::BASE_STRING)
168
160
 
169
- if security_engine.ruleset_version
170
- span.set_tag('_dd.appsec.event_rules.version', security_engine.ruleset_version)
161
+ if context.waf_runner_ruleset_version
162
+ span.set_tag('_dd.appsec.event_rules.version', context.waf_runner_ruleset_version)
171
163
 
172
164
  unless @oneshot_tags_sent
173
165
  # Small race condition, but it's inoccuous: worst case the tags
174
166
  # are sent a couple of times more than expected
175
167
  @oneshot_tags_sent = true
176
168
 
177
- span.set_tag('_dd.appsec.event_rules.addresses', JSON.dump(security_engine.waf_addresses))
169
+ span.set_tag('_dd.appsec.event_rules.addresses', JSON.dump(context.waf_runner_known_addresses))
178
170
 
179
171
  # Ensure these tags reach the backend
180
172
  trace.keep!
@@ -16,6 +16,7 @@ module Datadog
16
16
  gateway = Instrumentation.gateway
17
17
 
18
18
  watch_request_action(gateway)
19
+ watch_response_body_json(gateway)
19
20
  end
20
21
 
21
22
  def watch_request_action(gateway = Instrumentation.gateway)
@@ -29,18 +30,38 @@ module Datadog
29
30
 
30
31
  result = context.run_waf(persistent_data, {}, Datadog.configuration.appsec.waf_timeout)
31
32
 
32
- if result.match? || !result.derivatives.empty?
33
+ if result.match?
33
34
  context.events.push(
34
35
  AppSec::SecurityEvent.new(result, trace: context.trace, span: context.span)
35
36
  )
37
+
38
+ AppSec::Event.tag_and_keep!(context, result)
39
+ AppSec::ActionsHandler.handle(result.actions)
36
40
  end
37
41
 
42
+ stack.call(gateway_request.request)
43
+ end
44
+ end
45
+
46
+ def watch_response_body_json(gateway = Instrumentation.gateway)
47
+ gateway.watch('rails.response.body.json', :appsec) do |stack, container|
48
+ context = container.context
49
+
50
+ persistent_data = {
51
+ 'server.response.body' => container.data
52
+ }
53
+ result = context.run_waf(persistent_data, {}, Datadog.configuration.appsec.waf_timeout)
54
+
38
55
  if result.match?
56
+ context.events.push(
57
+ AppSec::SecurityEvent.new(result, trace: context.trace, span: context.span)
58
+ )
59
+
39
60
  AppSec::Event.tag_and_keep!(context, result)
40
61
  AppSec::ActionsHandler.handle(result.actions)
41
62
  end
42
63
 
43
- stack.call(gateway_request.request)
64
+ stack.call(container)
44
65
  end
45
66
  end
46
67
  end
@@ -8,6 +8,8 @@ require_relative '../rack/request_middleware'
8
8
  require_relative '../rack/request_body_middleware'
9
9
  require_relative 'gateway/watcher'
10
10
  require_relative 'gateway/request'
11
+ require_relative 'patches/render_to_body_patch'
12
+ require_relative 'patches/process_action_patch'
11
13
 
12
14
  require_relative '../../../tracing/contrib/rack/middlewares'
13
15
 
@@ -17,6 +19,7 @@ module Datadog
17
19
  module Rails
18
20
  # Patcher for AppSec on Rails
19
21
  module Patcher
22
+ GUARD_ACTION_CONTROLLER_ONCE_PER_APP = Hash.new { |h, key| h[key] = Datadog::Core::Utils::OnlyOnce.new }
20
23
  BEFORE_INITIALIZE_ONLY_ONCE_PER_APP = Hash.new { |h, key| h[key] = Datadog::Core::Utils::OnlyOnce.new }
21
24
  AFTER_INITIALIZE_ONLY_ONCE_PER_APP = Hash.new { |h, key| h[key] = Datadog::Core::Utils::OnlyOnce.new }
22
25
 
@@ -34,6 +37,7 @@ module Datadog
34
37
  Gateway::Watcher.watch
35
38
  patch_before_initialize
36
39
  patch_after_initialize
40
+ patch_action_controller
37
41
 
38
42
  Patcher.instance_variable_set(:@patched, true)
39
43
  end
@@ -49,7 +53,8 @@ module Datadog
49
53
  # Middleware must be added before the application is initialized.
50
54
  # Otherwise the middleware stack will be frozen.
51
55
  add_middleware(app) if Datadog.configuration.tracing[:rails][:middleware]
52
- patch_process_action
56
+
57
+ ::ActionController::Metal.prepend(Patches::ProcessActionPatch)
53
58
  end
54
59
  end
55
60
 
@@ -65,31 +70,6 @@ module Datadog
65
70
  end
66
71
  end
67
72
 
68
- # Hook into ActionController::Instrumentation#process_action, which encompasses action filters
69
- module ProcessActionPatch
70
- def process_action(*args)
71
- env = request.env
72
-
73
- context = env[Datadog::AppSec::Ext::CONTEXT_KEY]
74
-
75
- return super unless context
76
-
77
- # TODO: handle exceptions, except for super
78
-
79
- gateway_request = Gateway::Request.new(request)
80
-
81
- http_response, _gateway_request = Instrumentation.gateway.push('rails.request.action', gateway_request) do
82
- super
83
- end
84
-
85
- http_response
86
- end
87
- end
88
-
89
- def patch_process_action
90
- ::ActionController::Metal.prepend(ProcessActionPatch)
91
- end
92
-
93
73
  def include_middleware?(middleware, app)
94
74
  found = false
95
75
 
@@ -143,6 +123,14 @@ module Datadog
143
123
  end
144
124
  end
145
125
 
126
+ def patch_action_controller
127
+ ::ActiveSupport.on_load(:action_controller) do
128
+ GUARD_ACTION_CONTROLLER_ONCE_PER_APP[self].run do
129
+ ::ActionController::Base.prepend(Patches::RenderToBodyPatch)
130
+ end
131
+ end
132
+ end
133
+
146
134
  def setup_security
147
135
  Datadog::AppSec::Contrib::Rails::Framework.setup
148
136
  end
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Datadog
4
+ module AppSec
5
+ module Contrib
6
+ module Rails
7
+ module Patches
8
+ # Hook into ActionController::Instrumentation#process_action, which encompasses action filters
9
+ module ProcessActionPatch
10
+ def process_action(*args)
11
+ context = request.env[Datadog::AppSec::Ext::CONTEXT_KEY]
12
+ return super unless context
13
+
14
+ # TODO: handle exceptions, except for super
15
+ gateway_request = Gateway::Request.new(request)
16
+ http_response, _gateway_request = Instrumentation.gateway.push('rails.request.action', gateway_request) do
17
+ super
18
+ end
19
+
20
+ http_response
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,33 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative '../../../utils/hash_coercion'
4
+ require_relative '../../../instrumentation/gateway/argument'
5
+
6
+ module Datadog
7
+ module AppSec
8
+ module Contrib
9
+ module Rails
10
+ module Patches
11
+ # A patch targeting `AbstractController::Rendering#render_to_body`
12
+ # method to capture JSON response body right before it is serialized.
13
+ module RenderToBodyPatch
14
+ def render_to_body(options = {})
15
+ return super unless options.key?(:json)
16
+
17
+ context = request.env[Datadog::AppSec::Ext::CONTEXT_KEY]
18
+ return super unless context
19
+
20
+ data = Utils::HashCoercion.coerce(options[:json])
21
+ return super unless data
22
+
23
+ container = Instrumentation::Gateway::DataContainer.new(data, context: context)
24
+ Instrumentation.gateway.push('rails.response.body.json', container)
25
+
26
+ super
27
+ end
28
+ end
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end
@@ -1,4 +1,3 @@
1
- # rubocop:disable Naming/FileName
2
1
  # frozen_string_literal: true
3
2
 
4
3
  require_relative '../../event'
@@ -17,6 +17,7 @@ module Datadog
17
17
 
18
18
  watch_request_dispatch(gateway)
19
19
  watch_request_routed(gateway)
20
+ watch_response_body_json(gateway)
20
21
  end
21
22
 
22
23
  def watch_request_dispatch(gateway = Instrumentation.gateway)
@@ -67,6 +68,28 @@ module Datadog
67
68
  stack.call(gateway_request.request)
68
69
  end
69
70
  end
71
+
72
+ def watch_response_body_json(gateway = Instrumentation.gateway)
73
+ gateway.watch('sinatra.response.body.json', :appsec) do |stack, container|
74
+ context = container.context
75
+
76
+ persistent_data = {
77
+ 'server.response.body' => container.data
78
+ }
79
+ result = context.run_waf(persistent_data, {}, Datadog.configuration.appsec.waf_timeout)
80
+
81
+ if result.match?
82
+ context.events.push(
83
+ AppSec::SecurityEvent.new(result, trace: context.trace, span: context.span)
84
+ )
85
+
86
+ AppSec::Event.tag_and_keep!(context, result)
87
+ AppSec::ActionsHandler.handle(result.actions)
88
+ end
89
+
90
+ stack.call(container)
91
+ end
92
+ end
70
93
  end
71
94
  end
72
95
  end
@@ -8,6 +8,7 @@ require_relative 'framework'
8
8
  require_relative 'gateway/watcher'
9
9
  require_relative 'gateway/route_params'
10
10
  require_relative 'gateway/request'
11
+ require_relative 'patches/json_patch'
11
12
  require_relative '../../../tracing/contrib/sinatra/framework'
12
13
 
13
14
  module Datadog
@@ -51,7 +52,6 @@ module Datadog
51
52
  module DispatchPatch
52
53
  def dispatch!
53
54
  env = @request.env
54
-
55
55
  context = env[Datadog::AppSec::Ext::CONTEXT_KEY]
56
56
 
57
57
  return super unless context
@@ -59,7 +59,6 @@ module Datadog
59
59
  # TODO: handle exceptions, except for super
60
60
 
61
61
  gateway_request = Gateway::Request.new(env)
62
-
63
62
  request_return, _gateway_request = Instrumentation.gateway.push('sinatra.request.dispatch', gateway_request) do
64
63
  super
65
64
  end
@@ -113,27 +112,18 @@ module Datadog
113
112
 
114
113
  def patch
115
114
  Gateway::Watcher.watch
116
- patch_default_middlewares
117
- patch_dispatch
118
- patch_route
119
- setup_security
120
- Patcher.instance_variable_set(:@patched, true)
121
- end
122
-
123
- def setup_security
124
- ::Sinatra::Base.singleton_class.prepend(AppSecSetupPatch)
125
- end
126
115
 
127
- def patch_default_middlewares
128
116
  ::Sinatra::Base.singleton_class.prepend(DefaultMiddlewarePatch)
129
- end
130
-
131
- def patch_dispatch
132
117
  ::Sinatra::Base.prepend(DispatchPatch)
118
+ ::Sinatra::Base.prepend(RoutePatch)
119
+ ::Sinatra::Base.prepend(Patches::JsonPatch) if patch_json?
120
+ ::Sinatra::Base.singleton_class.prepend(AppSecSetupPatch)
121
+
122
+ Patcher.instance_variable_set(:@patched, true)
133
123
  end
134
124
 
135
- def patch_route
136
- ::Sinatra::Base.prepend(RoutePatch)
125
+ def patch_json?
126
+ defined?(::Sinatra::JSON) && ::Sinatra::Base < ::Sinatra::JSON
137
127
  end
138
128
  end
139
129
  end
@@ -0,0 +1,31 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative '../../../utils/hash_coercion'
4
+ require_relative '../../../instrumentation/gateway/argument'
5
+
6
+ module Datadog
7
+ module AppSec
8
+ module Contrib
9
+ module Sinatra
10
+ module Patches
11
+ # A patch targeting `Sinatra::JSON#json` method to capture JSON response
12
+ # body right before it is serialized.
13
+ module JsonPatch
14
+ def json(object, options = {})
15
+ context = @request.env[Datadog::AppSec::Ext::CONTEXT_KEY]
16
+ return super unless context
17
+
18
+ data = Utils::HashCoercion.coerce(object)
19
+ return super unless data
20
+
21
+ container = Instrumentation::Gateway::DataContainer.new(data, context: context)
22
+ Instrumentation.gateway.push('sinatra.response.body.json', container)
23
+
24
+ super
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
30
+ end
31
+ end