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
@@ -10,6 +10,7 @@ require_relative 'gateway/watcher'
10
10
  require_relative 'gateway/request'
11
11
  require_relative 'patches/render_to_body_patch'
12
12
  require_relative 'patches/process_action_patch'
13
+ require_relative '../../api_security/endpoint_collection/rails_collector'
13
14
 
14
15
  require_relative '../../../tracing/contrib/rack/middlewares'
15
16
 
@@ -20,6 +21,7 @@ module Datadog
20
21
  # Patcher for AppSec on Rails
21
22
  module Patcher
22
23
  GUARD_ACTION_CONTROLLER_ONCE_PER_APP = Hash.new { |h, key| h[key] = Datadog::Core::Utils::OnlyOnce.new }
24
+ GUARD_ROUTES_REPORTING_ONCE_PER_APP = Hash.new { |h, key| h[key] = Datadog::Core::Utils::OnlyOnce.new }
23
25
  BEFORE_INITIALIZE_ONLY_ONCE_PER_APP = Hash.new { |h, key| h[key] = Datadog::Core::Utils::OnlyOnce.new }
24
26
  AFTER_INITIALIZE_ONLY_ONCE_PER_APP = Hash.new { |h, key| h[key] = Datadog::Core::Utils::OnlyOnce.new }
25
27
 
@@ -38,6 +40,7 @@ module Datadog
38
40
  patch_before_initialize
39
41
  patch_after_initialize
40
42
  patch_action_controller
43
+ subscribe_to_routes_loaded
41
44
 
42
45
  Patcher.instance_variable_set(:@patched, true)
43
46
  end
@@ -128,7 +131,42 @@ module Datadog
128
131
  GUARD_ACTION_CONTROLLER_ONCE_PER_APP[self].run do
129
132
  ::ActionController::Base.prepend(Patches::RenderToBodyPatch)
130
133
  end
134
+
135
+ # Rails 7.1 adds `after_routes_loaded` hook
136
+ if Datadog::AppSec::Contrib::Rails::Patcher.target_version < Gem::Version.new('7.1')
137
+ Datadog::AppSec::Contrib::Rails::Patcher.report_routes_via_telemetry(::Rails.application.routes.routes)
138
+ end
139
+ rescue => e
140
+ error_message = 'Failed to get application routes'
141
+ Datadog.logger.error("#{error_message}, #{e.class}: #{e.message}")
142
+ AppSec.telemetry.report(e, description: error_message)
143
+ end
144
+ end
145
+
146
+ def subscribe_to_routes_loaded
147
+ ::ActiveSupport.on_load(:after_routes_loaded) do
148
+ Datadog::AppSec::Contrib::Rails::Patcher.report_routes_via_telemetry(::Rails.application.routes.routes)
149
+ rescue => e
150
+ error_message = 'Failed to get application routes'
151
+ Datadog.logger.error("#{error_message}, #{e.class}: #{e.message}")
152
+ AppSec.telemetry.report(e, description: error_message)
153
+ end
154
+ end
155
+
156
+ def report_routes_via_telemetry(routes)
157
+ # We do not support Rails 4.x for Endpoint Collection,
158
+ # mainly because the Route#verb was a Regexp before Rails 5.0
159
+ return if target_version < Gem::Version.new('5.0')
160
+ return unless Datadog.configuration.appsec.api_security.endpoint_collection.enabled
161
+ return unless AppSec.telemetry
162
+
163
+ GUARD_ROUTES_REPORTING_ONCE_PER_APP[::Rails.application].run do
164
+ AppSec.telemetry.app_endpoints_loaded(
165
+ APISecurity::EndpointCollection::RailsCollector.new(routes).to_enum
166
+ )
131
167
  end
168
+ rescue => e
169
+ AppSec.telemetry&.report(e, description: 'failed to report application endpoints')
132
170
  end
133
171
 
134
172
  def setup_security
@@ -11,6 +11,8 @@ module Datadog
11
11
  context = request.env[Datadog::AppSec::Ext::CONTEXT_KEY]
12
12
  return super unless context
13
13
 
14
+ context.state[:web_framework] = 'rails'
15
+
14
16
  # TODO: handle exceptions, except for super
15
17
  gateway_request = Gateway::Request.new(request)
16
18
  http_response, _gateway_request = Instrumentation.gateway.push('rails.request.action', gateway_request) do
@@ -28,7 +28,7 @@ module Datadog
28
28
  end
29
29
 
30
30
  def self.compatible?
31
- super && version >= MINIMUM_VERSION
31
+ super && !!(version&.>= MINIMUM_VERSION)
32
32
  end
33
33
 
34
34
  def self.auto_instrument?
@@ -9,7 +9,7 @@ module Datadog
9
9
  module_function
10
10
 
11
11
  def patched?
12
- Patcher.instance_variable_get(:@patched)
12
+ !!Patcher.instance_variable_get(:@patched)
13
13
  end
14
14
 
15
15
  def target_version
@@ -20,6 +20,8 @@ module Datadog
20
20
  require_relative 'request_ssrf_detection_patch'
21
21
 
22
22
  ::RestClient::Request.prepend(RequestSSRFDetectionPatch)
23
+
24
+ Patcher.instance_variable_set(:@patched, true)
23
25
  end
24
26
  end
25
27
  end
@@ -1,7 +1,11 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require_relative '../../event'
4
+ require_relative '../../trace_keeper'
4
5
  require_relative '../../security_event'
6
+ require_relative '../../utils/http/body'
7
+ require_relative '../../utils/http/body_reader'
8
+ require_relative '../../utils/http/media_type'
5
9
 
6
10
  module Datadog
7
11
  module AppSec
@@ -9,29 +13,181 @@ module Datadog
9
13
  module RestClient
10
14
  # Module that adds SSRF detection to RestClient::Request#execute
11
15
  module RequestSSRFDetectionPatch
16
+ REDIRECT_STATUS_CODES = (300..399).freeze
17
+
12
18
  def execute(&block)
13
- return super unless AppSec.rasp_enabled? && AppSec.active_context
19
+ context = AppSec.active_context
20
+ return super unless context && AppSec.rasp_enabled?
21
+
22
+ headers = normalize_request_headers
23
+ # @type var ephemeral_data: ::Datadog::AppSec::Context::input_data
24
+ ephemeral_data = {
25
+ 'server.io.net.url' => url,
26
+ 'server.io.net.request.method' => method.to_s.upcase,
27
+ 'server.io.net.request.headers' => headers
28
+ }
29
+
30
+ is_redirect = context.state[:downstream_redirect_url] == url
31
+ if is_redirect
32
+ context.state.delete(:downstream_redirect_url)
33
+ sample_body = true
34
+ else
35
+ sample_body = mark_body_sampling!(context)
36
+ end
37
+
38
+ if !is_redirect && sample_body
39
+ body = parse_request_body(payload, content_type: headers['content-type'])
40
+ ephemeral_data['server.io.net.request.body'] = body if body
41
+ end
42
+
43
+ timeout = Datadog.configuration.appsec.waf_timeout
44
+ result = context.run_rasp(Ext::RASP_SSRF, {}, ephemeral_data, timeout, phase: Ext::RASP_REQUEST_PHASE)
45
+ handle(result, context: context) if result.match?
46
+
47
+ # NOTE: RestClient raises exceptions for non-2xx responses. For POST/PUT/PATCH
48
+ # requests with 3xx redirects, RestClient raises instead of auto-following.
49
+ # We rescue to process the response before re-raising.
50
+ begin
51
+ response = super
52
+ rescue ::RestClient::Exception => e
53
+ response = e.response
54
+ process_response(response, sample_body: sample_body) if response.is_a?(::RestClient::AbstractResponse)
55
+
56
+ raise
57
+ end
58
+
59
+ process_response(response, sample_body: sample_body) if response.is_a?(::RestClient::AbstractResponse)
60
+ response
61
+ end
14
62
 
63
+ def process_response(response, sample_body:)
15
64
  context = AppSec.active_context
65
+ return unless context
66
+
67
+ headers = normalize_response_headers(response)
68
+ # @type var ephemeral_data: ::Datadog::AppSec::Context::input_data
69
+ ephemeral_data = {
70
+ 'server.io.net.response.status' => response.code.to_s,
71
+ 'server.io.net.response.headers' => headers
72
+ }
73
+
74
+ is_redirect = REDIRECT_STATUS_CODES.cover?(response.code.to_i) && headers.key?('location')
75
+ context.state[:downstream_redirect_url] = URI.join(url, headers['location']).to_s if is_redirect && sample_body
76
+
77
+ if sample_body && !is_redirect
78
+ body = parse_response_body(response.body, headers: headers, context: context)
79
+ ephemeral_data['server.io.net.response.body'] = body if body
80
+ end
81
+
82
+ timeout = Datadog.configuration.appsec.waf_timeout
83
+ result = context.run_rasp(Ext::RASP_SSRF, {}, ephemeral_data, timeout, phase: Ext::RASP_RESPONSE_PHASE)
84
+ handle(result, context: context) if result.match?
85
+ end
86
+
87
+ private
88
+
89
+ def mark_body_sampling!(context)
90
+ max = Datadog.configuration.appsec.api_security.downstream_body_analysis.max_requests
91
+ return false if context.state[:downstream_body_analyzed_count] >= max
92
+ return false unless context.downstream_body_sampler.sample?
16
93
 
17
- ephemeral_data = {'server.io.net.url' => url}
18
- result = context.run_rasp(Ext::RASP_SSRF, {}, ephemeral_data, Datadog.configuration.appsec.waf_timeout)
94
+ context.state[:downstream_body_analyzed_count] += 1
95
+ true
96
+ end
97
+
98
+ def parse_request_body(body, content_type:)
99
+ media_type = Utils::HTTP::MediaType.parse(content_type)
100
+ return unless media_type
19
101
 
20
- if result.match?
21
- AppSec::Event.tag_and_keep!(context, result)
102
+ # NOTE: Request body analysis is best-effort, non-rewindable payloads are skipped
103
+ limit = Datadog.configuration.appsec.api_security.downstream_body_analysis.max_downstream_body_bytes
104
+ content = read_body(body, limit: limit)
105
+ return if content.nil? || content.bytesize > limit
22
106
 
23
- context.events.push(
24
- AppSec::SecurityEvent.new(result, trace: context.trace, span: context.span)
25
- )
107
+ Utils::HTTP::Body.parse(content, media_type: media_type)
108
+ end
26
109
 
27
- AppSec::ActionsHandler.handle(result.actions)
110
+ def parse_response_body(body, headers:, context:)
111
+ return unless readable_body?(body)
112
+
113
+ media_type = Utils::HTTP::MediaType.parse(headers['content-type'])
114
+ if !media_type || media_type.type != 'application'
115
+ context.metrics.record_ignored_downstream_response_body(:content_type_invalid)
116
+ return
117
+ end
118
+
119
+ subtype = media_type.subtype
120
+ if subtype != 'json' && !subtype.end_with?('+json') && subtype != 'x-www-form-urlencoded'
121
+ context.metrics.record_ignored_downstream_response_body(:content_type_invalid)
122
+ return
123
+ end
124
+
125
+ content_length_value = headers['content-length']
126
+ if !content_length_value.is_a?(String) || !content_length_value.match?(/\A[1-9][0-9]*\z/)
127
+ context.metrics.record_ignored_downstream_response_body(:content_length_missing)
128
+ return
129
+ end
130
+
131
+ content_length = content_length_value.to_i
132
+ max = Datadog.configuration.appsec.api_security.downstream_body_analysis.max_downstream_body_bytes
133
+ if content_length > max
134
+ context.metrics.record_ignored_downstream_response_body(:content_length_too_big)
135
+ return
136
+ end
137
+
138
+ content = read_body(body, limit: content_length)
139
+ return if content.nil?
140
+
141
+ if content.bytesize > content_length
142
+ context.metrics.record_ignored_downstream_response_body(:content_exceed_content_length)
143
+ return
28
144
  end
29
145
 
30
- super
146
+ Utils::HTTP::Body.parse(content, media_type: media_type)
147
+ end
148
+
149
+ def readable_body?(body)
150
+ body.is_a?(String) || (body.respond_to?(:read) && body.respond_to?(:rewind))
151
+ end
152
+
153
+ def read_body(body, limit:)
154
+ Utils::HTTP::BodyReader.read(body, limit: limit, rewind_before_read: true)
155
+ rescue
156
+ nil
157
+ end
158
+
159
+ # NOTE: Starting version 2.1.0 headers are already normalized via internal
160
+ # variable `@processed_headers_lowercase`. In case it's available,
161
+ # we use it to avoid unnecessary transformation.
162
+ def normalize_request_headers
163
+ return @processed_headers_lowercase if defined?(@processed_headers_lowercase)
164
+
165
+ processed_headers.transform_keys(&:downcase)
166
+ end
167
+
168
+ # NOTE: Headers values are always an `Array` in `Net::HTTPResponse`,
169
+ # but we want to avoid accidents and will wrap them in no-op
170
+ # `Array` call just in case of a breaking change in the future
171
+ #
172
+ # FIXME: Steep has issues with `transform_values!` modifying the original
173
+ # type and it failed with "Cannot allow block body" error
174
+ def normalize_response_headers(response) # steep:ignore MethodBodyTypeMismatch
175
+ response.net_http_res.to_hash
176
+ .transform_values! { |value| Array(value).join(', ') } # steep:ignore BlockBodyTypeMismatch
177
+ end
178
+
179
+ def handle(result, context:)
180
+ AppSec::Event.tag(context, result)
181
+ TraceKeeper.keep!(context.trace) if result.keep?
182
+
183
+ context.events.push(
184
+ AppSec::SecurityEvent.new(result, trace: context.trace, span: context.span)
185
+ )
186
+
187
+ AppSec::ActionsHandler.handle(result.actions)
31
188
  end
32
189
  end
33
190
  end
34
191
  end
35
192
  end
36
193
  end
37
- # rubocop:enable Naming/FileName
@@ -1,6 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require_relative '../../../event'
4
+ require_relative '../../../trace_keeper'
4
5
  require_relative '../../../security_event'
5
6
  require_relative '../../../instrumentation/gateway'
6
7
 
@@ -21,23 +22,48 @@ module Datadog
21
22
  end
22
23
 
23
24
  def watch_request_dispatch(gateway = Instrumentation.gateway)
24
- gateway.watch('sinatra.request.dispatch', :appsec) do |stack, gateway_request|
25
- context = gateway_request.env[AppSec::Ext::CONTEXT_KEY]
25
+ gateway.watch('sinatra.request.dispatch') do |stack, gateway_request|
26
+ context = gateway_request.env[AppSec::Ext::CONTEXT_KEY] # : Context
26
27
 
27
- persistent_data = {
28
- 'server.request.body' => gateway_request.form_hash
29
- }
28
+ context.state[:web_framework] = 'sinatra'
29
+
30
+ request = gateway_request.request
31
+ next stack.call(request) unless gateway_request.collectable_body?
32
+
33
+ # NOTE: A limit of 0 disables request body collection entirely.
34
+ limit = Datadog.configuration.appsec.body_parsing_size_limit
35
+ next stack.call(request) if limit.zero?
36
+
37
+ persistent_data = {}
38
+ byte_length = gateway_request.body_bytesize(limit)
39
+
40
+ if byte_length
41
+ persistent_data['server.request.body.byte_length'] = byte_length
42
+
43
+ if byte_length <= limit
44
+ body = gateway_request.form_hash
45
+ persistent_data['server.request.body'] = body if body
46
+ end
47
+ # NOTE: Body was parsed before measurement, keep byte_length unset
48
+ elsif gateway_request.env.key?('rack.request.form_hash')
49
+ body = gateway_request.env['rack.request.form_hash']
50
+ persistent_data['server.request.body'] = body if body
51
+ end
52
+
53
+ next stack.call(request) if persistent_data.empty?
30
54
 
31
55
  result = context.run_waf(persistent_data, {}, Datadog.configuration.appsec.waf_timeout)
32
56
 
33
- if result.match? || !result.derivatives.empty?
57
+ if result.match? || !result.attributes.empty?
34
58
  context.events.push(
35
59
  AppSec::SecurityEvent.new(result, trace: context.trace, span: context.span)
36
60
  )
37
61
  end
38
62
 
39
63
  if result.match?
40
- AppSec::Event.tag_and_keep!(context, result)
64
+ AppSec::Event.tag(context, result)
65
+ TraceKeeper.keep!(context.trace) if result.keep?
66
+
41
67
  AppSec::ActionsHandler.handle(result.actions)
42
68
  end
43
69
 
@@ -46,8 +72,9 @@ module Datadog
46
72
  end
47
73
 
48
74
  def watch_request_routed(gateway = Instrumentation.gateway)
49
- gateway.watch('sinatra.request.routed', :appsec) do |stack, (gateway_request, gateway_route_params)|
50
- context = gateway_request.env[AppSec::Ext::CONTEXT_KEY]
75
+ gateway.watch('sinatra.request.routed') do |stack, args|
76
+ gateway_request, gateway_route_params = args # : [Gateway::Request, Gateway::RouteParams]
77
+ context = gateway_request.env[AppSec::Ext::CONTEXT_KEY] # : Context
51
78
 
52
79
  persistent_data = {
53
80
  'server.request.path_params' => gateway_route_params.params
@@ -56,7 +83,8 @@ module Datadog
56
83
  result = context.run_waf(persistent_data, {}, Datadog.configuration.appsec.waf_timeout)
57
84
 
58
85
  if result.match?
59
- AppSec::Event.tag_and_keep!(context, result)
86
+ AppSec::Event.tag(context, result)
87
+ TraceKeeper.keep!(context.trace) if result.keep?
60
88
 
61
89
  context.events.push(
62
90
  AppSec::SecurityEvent.new(result, trace: context.trace, span: context.span)
@@ -70,8 +98,8 @@ module Datadog
70
98
  end
71
99
 
72
100
  def watch_response_body_json(gateway = Instrumentation.gateway)
73
- gateway.watch('sinatra.response.body.json', :appsec) do |stack, container|
74
- context = container.context
101
+ gateway.watch('sinatra.response.body.json') do |stack, container|
102
+ context = container.context # : Context
75
103
 
76
104
  persistent_data = {
77
105
  'server.response.body' => container.data
@@ -83,7 +111,9 @@ module Datadog
83
111
  AppSec::SecurityEvent.new(result, trace: context.trace, span: context.span)
84
112
  )
85
113
 
86
- AppSec::Event.tag_and_keep!(context, result)
114
+ AppSec::Event.tag(context, result)
115
+ TraceKeeper.keep!(context.trace) if result.keep?
116
+
87
117
  AppSec::ActionsHandler.handle(result.actions)
88
118
  end
89
119
 
@@ -26,7 +26,7 @@ module Datadog
26
26
  end
27
27
 
28
28
  def self.compatible?
29
- super && version >= MINIMUM_VERSION
29
+ !!(super && (version&.>= MINIMUM_VERSION))
30
30
  end
31
31
 
32
32
  def self.auto_instrument?
@@ -71,7 +71,7 @@ module Datadog
71
71
  # path params are returned by pattern.params in process_route, then
72
72
  # merged with normal params, so we get both
73
73
  module RoutePatch
74
- def process_route(*)
74
+ def process_route(*args)
75
75
  env = @request.env
76
76
 
77
77
  context = env[Datadog::AppSec::Ext::CONTEXT_KEY]
@@ -83,7 +83,7 @@ module Datadog
83
83
  # Capture normal params.
84
84
  base_params = params
85
85
 
86
- super do |*args|
86
+ super do |*super_args|
87
87
  # This block is called only once the route is found.
88
88
  # At this point params has both route params and normal params.
89
89
  route_params = params.each.with_object({}) { |(k, v), h| h[k] = v unless base_params.key?(k) }
@@ -93,7 +93,7 @@ module Datadog
93
93
 
94
94
  Instrumentation.gateway.push('sinatra.request.routed', [gateway_request, gateway_route_params])
95
95
 
96
- yield(*args)
96
+ yield(*super_args)
97
97
  end
98
98
  end
99
99
  end
@@ -123,7 +123,7 @@ module Datadog
123
123
  end
124
124
 
125
125
  def patch_json?
126
- defined?(::Sinatra::JSON) && ::Sinatra::Base < ::Sinatra::JSON
126
+ !!(defined?(::Sinatra::JSON) && ::Sinatra::Base < ::Sinatra::JSON)
127
127
  end
128
128
  end
129
129
  end
@@ -12,7 +12,7 @@ module Datadog
12
12
  # body right before it is serialized.
13
13
  module JsonPatch
14
14
  def json(object, options = {})
15
- context = @request.env[Datadog::AppSec::Ext::CONTEXT_KEY]
15
+ context = @request.env[Datadog::AppSec::Ext::CONTEXT_KEY] # : Context?
16
16
  return super unless context
17
17
 
18
18
  data = Utils::HashCoercion.coerce(object)
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative '../core/knuth_sampler'
4
+
5
+ module Datadog
6
+ module AppSec
7
+ # Sampler that uses an internal counter to make deterministic sampling decisions.
8
+ #
9
+ # Each call to {#sample?} increments the counter and uses it as input to
10
+ # the underlying Knuth multiplicative hash algorithm.
11
+ #
12
+ # @api private
13
+ class CounterSampler
14
+ def initialize(rate = 1.0)
15
+ @sampler = Core::KnuthSampler.new(rate)
16
+ @counter = 0
17
+ end
18
+
19
+ def sample?
20
+ @counter += 1
21
+ @sampler.sample?(@counter)
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,52 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Datadog
4
+ module AppSec
5
+ # Sets the always-on span tags built from a fixed allowlist of request and
6
+ # response headers.
7
+ #
8
+ # NOTE: Unlike {Event#record}, which reports request headers only when
9
+ # a security event fires, these are tagged on every request/response
10
+ #
11
+ # @api private
12
+ module DefaultHeaderTags
13
+ # NOTE: Contains additional WAF vendor headers
14
+ REQUEST_HEADERS_TAGS = %w[
15
+ accept
16
+ content-type
17
+ user-agent
18
+ akamai-user-risk
19
+ x-amzn-trace-id
20
+ x-cloud-trace-context
21
+ x-appgw-trace-id
22
+ x-sigsci-requestid
23
+ x-sigsci-tags
24
+ cf-ray
25
+ cloudfront-viewer-ja3-fingerprint
26
+ ].freeze
27
+
28
+ RESPONSE_HEADERS_TAGS = %w[
29
+ content-type
30
+ content-length
31
+ content-encoding
32
+ content-language
33
+ ].freeze
34
+
35
+ module_function
36
+
37
+ def tag_request(span, headers)
38
+ REQUEST_HEADERS_TAGS.each do |name|
39
+ value = headers.get(name)
40
+ span.set_tag("http.request.headers.#{name}", value) if value
41
+ end
42
+ end
43
+
44
+ def tag_response(span, headers)
45
+ RESPONSE_HEADERS_TAGS.each do |name|
46
+ value = headers.get(name)
47
+ span.set_tag("http.response.headers.#{name}", value.to_s) if value
48
+ end
49
+ end
50
+ end
51
+ end
52
+ end
@@ -9,8 +9,8 @@ module Datadog
9
9
  module AppSec
10
10
  # AppSec event
11
11
  module Event
12
- DERIVATIVE_SCHEMA_KEY_PREFIX = '_dd.appsec.s.'
13
- DERIVATIVE_SCHEMA_MAX_COMPRESSED_SIZE = 25000
12
+ ATTRIBUTES_SCHEMA_KEY_PREFIX = '_dd.appsec.s.'
13
+ ATTRIBUTES_SCHEMA_MAX_COMPRESSED_SIZE = 25000
14
14
  ALLOWED_REQUEST_HEADERS = %w[
15
15
  x-forwarded-for
16
16
  x-client-ip
@@ -32,27 +32,18 @@ module Datadog
32
32
  accept-language
33
33
  ].freeze
34
34
 
35
- ALLOWED_RESPONSE_HEADERS = %w[
36
- content-length
37
- content-type
38
- content-encoding
39
- content-language
40
- ].freeze
41
-
42
35
  class << self
43
- def tag_and_keep!(context, waf_result)
44
- TraceKeeper.keep!(context.trace)
36
+ def tag(context, waf_result)
37
+ return if context.span.nil?
45
38
 
46
- if context.span
47
- if waf_result.actions.key?('block_request') || waf_result.actions.key?('redirect_request')
48
- context.span.set_tag('appsec.blocked', 'true')
49
- end
50
-
51
- context.span.set_tag('appsec.event', 'true')
39
+ if waf_result.actions.key?('block_request') || waf_result.actions.key?('redirect_request')
40
+ context.span.set_tag('appsec.blocked', 'true')
52
41
  end
42
+
43
+ context.span.set_tag('appsec.event', 'true')
53
44
  end
54
45
 
55
- def record(context, request: nil, response: nil)
46
+ def record(context, request: nil)
56
47
  return if context.events.empty? || context.span.nil?
57
48
 
58
49
  Datadog::AppSec::RateLimiter.thread_local.limit do
@@ -63,12 +54,11 @@ module Datadog
63
54
  end
64
55
  end
65
56
 
66
- if event_group.any? { |event| event.attack? || event.schema? }
57
+ if event_group.any? { |event| event.keep? || event.schema? }
67
58
  TraceKeeper.keep!(trace)
68
59
 
69
60
  context.span['_dd.origin'] = 'appsec'
70
61
  context.span.set_tags(request_tags(request)) if request
71
- context.span.set_tags(response_tags(response)) if response
72
62
  end
73
63
 
74
64
  context.span.set_tags(waf_tags(event_group))
@@ -92,27 +82,19 @@ module Datadog
92
82
  end
93
83
  end
94
84
 
95
- def response_tags(response)
96
- response.headers.each_with_object({}) do |(name, value), memo|
97
- next unless ALLOWED_RESPONSE_HEADERS.include?(name)
98
-
99
- memo["http.response.headers.#{name}"] = value
100
- end
101
- end
102
-
103
85
  def waf_tags(security_events)
104
86
  triggers = []
105
87
 
106
88
  tags = security_events.each_with_object({}) do |security_event, memo|
107
89
  triggers.concat(security_event.waf_result.events)
108
90
 
109
- security_event.waf_result.derivatives.each do |key, value|
110
- next memo[key] = value unless key.start_with?(DERIVATIVE_SCHEMA_KEY_PREFIX)
91
+ security_event.waf_result.attributes.each do |key, value|
92
+ next memo[key] = value unless key.start_with?(ATTRIBUTES_SCHEMA_KEY_PREFIX)
111
93
 
112
94
  value = CompressedJson.dump(value)
113
95
  next if value.nil?
114
96
 
115
- if value.size >= DERIVATIVE_SCHEMA_MAX_COMPRESSED_SIZE
97
+ if value.size >= ATTRIBUTES_SCHEMA_MAX_COMPRESSED_SIZE
116
98
  Datadog.logger.debug { "AppSec: Schema key '#{key}' will not be included into span tags due to it's size" }
117
99
  next
118
100
  end
@@ -6,6 +6,8 @@ module Datadog
6
6
  RASP_SQLI = 'sql_injection'
7
7
  RASP_LFI = 'lfi'
8
8
  RASP_SSRF = 'ssrf'
9
+ RASP_REQUEST_PHASE = 'request'
10
+ RASP_RESPONSE_PHASE = 'response'
9
11
 
10
12
  PRODUCT_BIT = 0b00000010
11
13
 
@@ -15,6 +17,7 @@ module Datadog
15
17
  EXPLOIT_PREVENTION_EVENT_CATEGORY = 'exploit'
16
18
 
17
19
  TAG_APPSEC_ENABLED = '_dd.appsec.enabled'
20
+ TAG_NORMALIZED_ROUTE = '_dd.appsec.normalized_route'
18
21
  TAG_METASTRUCT_STACK_TRACE = '_dd.stack'
19
22
 
20
23
  TELEMETRY_METRICS_NAMESPACE = 'appsec'
@@ -7,10 +7,9 @@ module Datadog
7
7
  # NOTE: This class extracted as-is and will be deprecated
8
8
  # Instrumentation gateway middleware
9
9
  class Middleware
10
- attr_reader :key, :block
10
+ attr_reader :block
11
11
 
12
- def initialize(key, &block)
13
- @key = key
12
+ def initialize(&block)
14
13
  @block = block
15
14
  end
16
15