datadog 2.12.1 → 2.19.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 (346) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +243 -2
  3. data/ext/datadog_profiling_native_extension/collectors_cpu_and_wall_time_worker.c +63 -56
  4. data/ext/datadog_profiling_native_extension/collectors_stack.c +263 -76
  5. data/ext/datadog_profiling_native_extension/collectors_stack.h +20 -3
  6. data/ext/datadog_profiling_native_extension/collectors_thread_context.c +78 -26
  7. data/ext/datadog_profiling_native_extension/collectors_thread_context.h +1 -0
  8. data/ext/datadog_profiling_native_extension/datadog_ruby_common.c +1 -4
  9. data/ext/datadog_profiling_native_extension/datadog_ruby_common.h +10 -0
  10. data/ext/datadog_profiling_native_extension/encoded_profile.c +79 -0
  11. data/ext/datadog_profiling_native_extension/encoded_profile.h +8 -0
  12. data/ext/datadog_profiling_native_extension/extconf.rb +10 -0
  13. data/ext/datadog_profiling_native_extension/heap_recorder.c +247 -364
  14. data/ext/datadog_profiling_native_extension/heap_recorder.h +4 -6
  15. data/ext/datadog_profiling_native_extension/http_transport.c +60 -94
  16. data/ext/datadog_profiling_native_extension/libdatadog_helpers.c +22 -0
  17. data/ext/datadog_profiling_native_extension/libdatadog_helpers.h +8 -5
  18. data/ext/datadog_profiling_native_extension/private_vm_api_access.c +41 -21
  19. data/ext/datadog_profiling_native_extension/private_vm_api_access.h +6 -4
  20. data/ext/datadog_profiling_native_extension/profiling.c +2 -0
  21. data/ext/datadog_profiling_native_extension/ruby_helpers.c +1 -13
  22. data/ext/datadog_profiling_native_extension/ruby_helpers.h +3 -11
  23. data/ext/datadog_profiling_native_extension/stack_recorder.c +173 -76
  24. data/ext/libdatadog_api/crashtracker.c +11 -12
  25. data/ext/libdatadog_api/crashtracker.h +5 -0
  26. data/ext/libdatadog_api/datadog_ruby_common.c +1 -4
  27. data/ext/libdatadog_api/datadog_ruby_common.h +10 -0
  28. data/ext/libdatadog_api/extconf.rb +2 -2
  29. data/ext/libdatadog_api/init.c +15 -0
  30. data/ext/libdatadog_api/library_config.c +164 -0
  31. data/ext/libdatadog_api/library_config.h +25 -0
  32. data/ext/libdatadog_api/macos_development.md +3 -3
  33. data/ext/libdatadog_api/process_discovery.c +112 -0
  34. data/ext/libdatadog_api/process_discovery.h +5 -0
  35. data/ext/libdatadog_extconf_helpers.rb +2 -2
  36. data/lib/datadog/appsec/actions_handler/serializable_backtrace.rb +89 -0
  37. data/lib/datadog/appsec/actions_handler.rb +24 -2
  38. data/lib/datadog/appsec/anonymizer.rb +16 -0
  39. data/lib/datadog/appsec/api_security/lru_cache.rb +56 -0
  40. data/lib/datadog/appsec/api_security/route_extractor.rb +71 -0
  41. data/lib/datadog/appsec/api_security/sampler.rb +59 -0
  42. data/lib/datadog/appsec/api_security.rb +23 -0
  43. data/lib/datadog/appsec/assets/waf_rules/README.md +50 -5
  44. data/lib/datadog/appsec/assets/waf_rules/recommended.json +257 -85
  45. data/lib/datadog/appsec/assets/waf_rules/strict.json +10 -78
  46. data/lib/datadog/appsec/autoload.rb +1 -1
  47. data/lib/datadog/appsec/component.rb +46 -61
  48. data/lib/datadog/appsec/compressed_json.rb +40 -0
  49. data/lib/datadog/appsec/configuration/settings.rb +153 -30
  50. data/lib/datadog/appsec/context.rb +7 -7
  51. data/lib/datadog/appsec/contrib/active_record/instrumentation.rb +10 -12
  52. data/lib/datadog/appsec/contrib/active_record/integration.rb +2 -2
  53. data/lib/datadog/appsec/contrib/active_record/patcher.rb +22 -22
  54. data/lib/datadog/appsec/contrib/auto_instrument.rb +1 -1
  55. data/lib/datadog/appsec/contrib/devise/configuration.rb +7 -31
  56. data/lib/datadog/appsec/contrib/devise/data_extractor.rb +78 -0
  57. data/lib/datadog/appsec/contrib/devise/ext.rb +22 -0
  58. data/lib/datadog/appsec/contrib/devise/integration.rb +1 -2
  59. data/lib/datadog/appsec/contrib/devise/patcher.rb +34 -23
  60. data/lib/datadog/appsec/contrib/devise/patches/signin_tracking_patch.rb +102 -0
  61. data/lib/datadog/appsec/contrib/devise/patches/signup_tracking_patch.rb +69 -0
  62. data/lib/datadog/appsec/contrib/devise/{patcher/rememberable_patch.rb → patches/skip_signin_tracking_patch.rb} +2 -2
  63. data/lib/datadog/appsec/contrib/devise/tracking_middleware.rb +106 -0
  64. data/lib/datadog/appsec/contrib/excon/integration.rb +1 -1
  65. data/lib/datadog/appsec/contrib/excon/ssrf_detection_middleware.rb +9 -10
  66. data/lib/datadog/appsec/contrib/faraday/integration.rb +1 -1
  67. data/lib/datadog/appsec/contrib/faraday/ssrf_detection_middleware.rb +8 -9
  68. data/lib/datadog/appsec/contrib/graphql/gateway/watcher.rb +8 -9
  69. data/lib/datadog/appsec/contrib/graphql/integration.rb +1 -1
  70. data/lib/datadog/appsec/contrib/rack/ext.rb +34 -0
  71. data/lib/datadog/appsec/contrib/rack/gateway/watcher.rb +49 -32
  72. data/lib/datadog/appsec/contrib/rack/integration.rb +1 -1
  73. data/lib/datadog/appsec/contrib/rack/request_middleware.rb +42 -30
  74. data/lib/datadog/appsec/contrib/rails/gateway/watcher.rb +11 -13
  75. data/lib/datadog/appsec/contrib/rails/integration.rb +1 -1
  76. data/lib/datadog/appsec/contrib/rails/patcher.rb +21 -21
  77. data/lib/datadog/appsec/contrib/rest_client/integration.rb +1 -1
  78. data/lib/datadog/appsec/contrib/rest_client/request_ssrf_detection_patch.rb +10 -11
  79. data/lib/datadog/appsec/contrib/sinatra/gateway/watcher.rb +17 -23
  80. data/lib/datadog/appsec/contrib/sinatra/integration.rb +1 -1
  81. data/lib/datadog/appsec/event.rb +96 -135
  82. data/lib/datadog/appsec/ext.rb +4 -2
  83. data/lib/datadog/appsec/instrumentation/gateway/argument.rb +7 -2
  84. data/lib/datadog/appsec/instrumentation/gateway/middleware.rb +24 -0
  85. data/lib/datadog/appsec/instrumentation/gateway.rb +17 -22
  86. data/lib/datadog/appsec/metrics/telemetry.rb +1 -1
  87. data/lib/datadog/appsec/monitor/gateway/watcher.rb +49 -14
  88. data/lib/datadog/appsec/processor/rule_loader.rb +30 -33
  89. data/lib/datadog/appsec/remote.rb +31 -59
  90. data/lib/datadog/appsec/response.rb +6 -6
  91. data/lib/datadog/appsec/security_engine/engine.rb +194 -0
  92. data/lib/datadog/appsec/security_engine/runner.rb +13 -14
  93. data/lib/datadog/appsec/security_event.rb +39 -0
  94. data/lib/datadog/appsec/utils.rb +0 -2
  95. data/lib/datadog/appsec.rb +5 -8
  96. data/lib/datadog/core/buffer/random.rb +18 -2
  97. data/lib/datadog/core/configuration/agent_settings.rb +52 -0
  98. data/lib/datadog/core/configuration/agent_settings_resolver.rb +4 -46
  99. data/lib/datadog/core/configuration/agentless_settings_resolver.rb +176 -0
  100. data/lib/datadog/core/configuration/components.rb +48 -31
  101. data/lib/datadog/core/configuration/components_state.rb +23 -0
  102. data/lib/datadog/core/configuration/ext.rb +4 -0
  103. data/lib/datadog/core/configuration/option.rb +81 -45
  104. data/lib/datadog/core/configuration/option_definition.rb +4 -4
  105. data/lib/datadog/core/configuration/options.rb +3 -3
  106. data/lib/datadog/core/configuration/settings.rb +109 -44
  107. data/lib/datadog/core/configuration/stable_config.rb +22 -0
  108. data/lib/datadog/core/configuration.rb +40 -16
  109. data/lib/datadog/core/crashtracking/component.rb +3 -10
  110. data/lib/datadog/core/crashtracking/tag_builder.rb +4 -22
  111. data/lib/datadog/core/diagnostics/environment_logger.rb +1 -1
  112. data/lib/datadog/core/encoding.rb +1 -1
  113. data/lib/datadog/core/environment/agent_info.rb +4 -3
  114. data/lib/datadog/core/environment/cgroup.rb +10 -12
  115. data/lib/datadog/core/environment/container.rb +38 -40
  116. data/lib/datadog/core/environment/ext.rb +6 -6
  117. data/lib/datadog/core/environment/git.rb +1 -0
  118. data/lib/datadog/core/environment/identity.rb +3 -3
  119. data/lib/datadog/core/environment/platform.rb +3 -3
  120. data/lib/datadog/core/environment/variable_helpers.rb +1 -1
  121. data/lib/datadog/core/error.rb +11 -9
  122. data/lib/datadog/core/logger.rb +2 -2
  123. data/lib/datadog/core/metrics/client.rb +20 -21
  124. data/lib/datadog/core/metrics/logging.rb +5 -5
  125. data/lib/datadog/core/process_discovery/tracer_memfd.rb +15 -0
  126. data/lib/datadog/core/process_discovery.rb +36 -0
  127. data/lib/datadog/core/rate_limiter.rb +4 -2
  128. data/lib/datadog/core/remote/client.rb +40 -32
  129. data/lib/datadog/core/remote/component.rb +6 -9
  130. data/lib/datadog/core/remote/configuration/digest.rb +7 -7
  131. data/lib/datadog/core/remote/configuration/path.rb +1 -1
  132. data/lib/datadog/core/remote/configuration/repository.rb +14 -1
  133. data/lib/datadog/core/remote/negotiation.rb +9 -9
  134. data/lib/datadog/core/remote/transport/config.rb +4 -3
  135. data/lib/datadog/core/remote/transport/http/client.rb +5 -4
  136. data/lib/datadog/core/remote/transport/http/config.rb +27 -37
  137. data/lib/datadog/core/remote/transport/http/negotiation.rb +7 -33
  138. data/lib/datadog/core/remote/transport/http.rb +22 -57
  139. data/lib/datadog/core/remote/transport/negotiation.rb +4 -3
  140. data/lib/datadog/core/runtime/metrics.rb +12 -5
  141. data/lib/datadog/core/tag_builder.rb +56 -0
  142. data/lib/datadog/core/telemetry/component.rb +81 -52
  143. data/lib/datadog/core/telemetry/emitter.rb +23 -11
  144. data/lib/datadog/core/telemetry/event/app_client_configuration_change.rb +66 -0
  145. data/lib/datadog/core/telemetry/event/app_closing.rb +18 -0
  146. data/lib/datadog/core/telemetry/event/app_dependencies_loaded.rb +33 -0
  147. data/lib/datadog/core/telemetry/event/app_heartbeat.rb +18 -0
  148. data/lib/datadog/core/telemetry/event/app_integrations_change.rb +58 -0
  149. data/lib/datadog/core/telemetry/event/app_started.rb +287 -0
  150. data/lib/datadog/core/telemetry/event/base.rb +40 -0
  151. data/lib/datadog/core/telemetry/event/distributions.rb +18 -0
  152. data/lib/datadog/core/telemetry/event/generate_metrics.rb +43 -0
  153. data/lib/datadog/core/telemetry/event/log.rb +76 -0
  154. data/lib/datadog/core/telemetry/event/message_batch.rb +42 -0
  155. data/lib/datadog/core/telemetry/event/synth_app_client_configuration_change.rb +43 -0
  156. data/lib/datadog/core/telemetry/event.rb +17 -472
  157. data/lib/datadog/core/telemetry/http/adapters/net.rb +12 -97
  158. data/lib/datadog/core/telemetry/logger.rb +5 -4
  159. data/lib/datadog/core/telemetry/logging.rb +11 -5
  160. data/lib/datadog/core/telemetry/metric.rb +8 -8
  161. data/lib/datadog/core/telemetry/request.rb +4 -4
  162. data/lib/datadog/core/telemetry/transport/http/api.rb +43 -0
  163. data/lib/datadog/core/telemetry/transport/http/client.rb +49 -0
  164. data/lib/datadog/core/telemetry/transport/http/telemetry.rb +92 -0
  165. data/lib/datadog/core/telemetry/transport/http.rb +63 -0
  166. data/lib/datadog/core/telemetry/transport/telemetry.rb +51 -0
  167. data/lib/datadog/core/telemetry/worker.rb +90 -24
  168. data/lib/datadog/core/transport/http/adapters/net.rb +17 -2
  169. data/lib/datadog/core/transport/http/adapters/test.rb +2 -1
  170. data/lib/datadog/core/transport/http/api/instance.rb +17 -0
  171. data/lib/datadog/core/transport/http/api/spec.rb +17 -0
  172. data/lib/datadog/core/transport/http/builder.rb +19 -17
  173. data/lib/datadog/core/transport/http/env.rb +8 -0
  174. data/lib/datadog/core/transport/http.rb +39 -2
  175. data/lib/datadog/core/utils/at_fork_monkey_patch.rb +6 -6
  176. data/lib/datadog/core/utils/duration.rb +32 -32
  177. data/lib/datadog/core/utils/forking.rb +2 -2
  178. data/lib/datadog/core/utils/network.rb +6 -6
  179. data/lib/datadog/core/utils/only_once_successful.rb +16 -5
  180. data/lib/datadog/core/utils/time.rb +20 -0
  181. data/lib/datadog/core/utils/truncation.rb +21 -0
  182. data/lib/datadog/core/utils.rb +7 -0
  183. data/lib/datadog/core/vendor/multipart-post/multipart/post/composite_read_io.rb +1 -1
  184. data/lib/datadog/core/vendor/multipart-post/multipart/post/multipartable.rb +8 -8
  185. data/lib/datadog/core/vendor/multipart-post/multipart/post/parts.rb +7 -7
  186. data/lib/datadog/core/worker.rb +1 -1
  187. data/lib/datadog/core/workers/async.rb +29 -12
  188. data/lib/datadog/core/workers/interval_loop.rb +12 -1
  189. data/lib/datadog/core/workers/runtime_metrics.rb +2 -2
  190. data/lib/datadog/core.rb +8 -0
  191. data/lib/datadog/di/boot.rb +34 -0
  192. data/lib/datadog/di/component.rb +0 -2
  193. data/lib/datadog/di/instrumenter.rb +48 -5
  194. data/lib/datadog/di/probe_notification_builder.rb +38 -43
  195. data/lib/datadog/di/probe_notifier_worker.rb +25 -17
  196. data/lib/datadog/di/remote.rb +2 -0
  197. data/lib/datadog/di/serializer.rb +10 -2
  198. data/lib/datadog/di/transport/diagnostics.rb +4 -3
  199. data/lib/datadog/di/transport/http/api.rb +2 -12
  200. data/lib/datadog/di/transport/http/client.rb +4 -3
  201. data/lib/datadog/di/transport/http/diagnostics.rb +7 -34
  202. data/lib/datadog/di/transport/http/input.rb +18 -35
  203. data/lib/datadog/di/transport/http.rb +14 -62
  204. data/lib/datadog/di/transport/input.rb +14 -5
  205. data/lib/datadog/di/utils.rb +5 -0
  206. data/lib/datadog/di.rb +0 -33
  207. data/lib/datadog/error_tracking/collector.rb +87 -0
  208. data/lib/datadog/error_tracking/component.rb +167 -0
  209. data/lib/datadog/error_tracking/configuration/settings.rb +63 -0
  210. data/lib/datadog/error_tracking/configuration.rb +11 -0
  211. data/lib/datadog/error_tracking/ext.rb +18 -0
  212. data/lib/datadog/error_tracking/extensions.rb +16 -0
  213. data/lib/datadog/error_tracking/filters.rb +77 -0
  214. data/lib/datadog/error_tracking.rb +18 -0
  215. data/lib/datadog/kit/appsec/events/v2.rb +195 -0
  216. data/lib/datadog/kit/appsec/events.rb +12 -0
  217. data/lib/datadog/kit/identity.rb +5 -1
  218. data/lib/datadog/opentelemetry/api/baggage.rb +90 -0
  219. data/lib/datadog/opentelemetry/api/baggage.rbs +26 -0
  220. data/lib/datadog/opentelemetry/api/context.rb +16 -2
  221. data/lib/datadog/opentelemetry/sdk/trace/span.rb +1 -1
  222. data/lib/datadog/opentelemetry.rb +2 -1
  223. data/lib/datadog/profiling/collectors/code_provenance.rb +18 -9
  224. data/lib/datadog/profiling/collectors/cpu_and_wall_time_worker.rb +6 -0
  225. data/lib/datadog/profiling/collectors/idle_sampling_helper.rb +1 -0
  226. data/lib/datadog/profiling/collectors/info.rb +44 -0
  227. data/lib/datadog/profiling/collectors/thread_context.rb +17 -2
  228. data/lib/datadog/profiling/component.rb +8 -9
  229. data/lib/datadog/profiling/encoded_profile.rb +11 -0
  230. data/lib/datadog/profiling/exporter.rb +12 -7
  231. data/lib/datadog/profiling/ext.rb +0 -14
  232. data/lib/datadog/profiling/flush.rb +5 -8
  233. data/lib/datadog/profiling/http_transport.rb +7 -61
  234. data/lib/datadog/profiling/profiler.rb +2 -0
  235. data/lib/datadog/profiling/scheduler.rb +10 -2
  236. data/lib/datadog/profiling/sequence_tracker.rb +44 -0
  237. data/lib/datadog/profiling/stack_recorder.rb +9 -9
  238. data/lib/datadog/profiling/tag_builder.rb +7 -41
  239. data/lib/datadog/profiling/tasks/setup.rb +2 -0
  240. data/lib/datadog/profiling.rb +7 -2
  241. data/lib/datadog/single_step_instrument.rb +9 -0
  242. data/lib/datadog/tracing/analytics.rb +1 -1
  243. data/lib/datadog/tracing/component.rb +15 -12
  244. data/lib/datadog/tracing/configuration/ext.rb +7 -1
  245. data/lib/datadog/tracing/configuration/settings.rb +18 -2
  246. data/lib/datadog/tracing/context_provider.rb +1 -1
  247. data/lib/datadog/tracing/contrib/action_pack/action_controller/instrumentation.rb +15 -0
  248. data/lib/datadog/tracing/contrib/action_pack/action_dispatch/instrumentation.rb +19 -12
  249. data/lib/datadog/tracing/contrib/action_pack/ext.rb +2 -0
  250. data/lib/datadog/tracing/contrib/active_record/integration.rb +1 -1
  251. data/lib/datadog/tracing/contrib/active_support/cache/events/cache.rb +11 -2
  252. data/lib/datadog/tracing/contrib/active_support/cache/instrumentation.rb +33 -0
  253. data/lib/datadog/tracing/contrib/active_support/cache/patcher.rb +4 -0
  254. data/lib/datadog/tracing/contrib/active_support/cache/redis.rb +2 -4
  255. data/lib/datadog/tracing/contrib/active_support/configuration/settings.rb +13 -0
  256. data/lib/datadog/tracing/contrib/aws/instrumentation.rb +10 -0
  257. data/lib/datadog/tracing/contrib/aws/parsed_context.rb +5 -1
  258. data/lib/datadog/tracing/contrib/configuration/settings.rb +1 -1
  259. data/lib/datadog/tracing/contrib/ethon/easy_patch.rb +4 -5
  260. data/lib/datadog/tracing/contrib/excon/middleware.rb +5 -3
  261. data/lib/datadog/tracing/contrib/ext.rb +1 -0
  262. data/lib/datadog/tracing/contrib/faraday/middleware.rb +5 -3
  263. data/lib/datadog/tracing/contrib/grpc/datadog_interceptor/client.rb +7 -1
  264. data/lib/datadog/tracing/contrib/grpc/distributed/propagation.rb +3 -0
  265. data/lib/datadog/tracing/contrib/http/circuit_breaker.rb +0 -15
  266. data/lib/datadog/tracing/contrib/http/distributed/propagation.rb +4 -1
  267. data/lib/datadog/tracing/contrib/http/instrumentation.rb +6 -10
  268. data/lib/datadog/tracing/contrib/httpclient/instrumentation.rb +6 -16
  269. data/lib/datadog/tracing/contrib/httprb/instrumentation.rb +7 -15
  270. data/lib/datadog/tracing/contrib/karafka/configuration/settings.rb +27 -0
  271. data/lib/datadog/tracing/contrib/karafka/distributed/propagation.rb +48 -0
  272. data/lib/datadog/tracing/contrib/karafka/ext.rb +27 -0
  273. data/lib/datadog/tracing/contrib/karafka/integration.rb +45 -0
  274. data/lib/datadog/tracing/contrib/karafka/monitor.rb +66 -0
  275. data/lib/datadog/tracing/contrib/karafka/patcher.rb +71 -0
  276. data/lib/datadog/tracing/contrib/karafka.rb +37 -0
  277. data/lib/datadog/tracing/contrib/lograge/patcher.rb +4 -2
  278. data/lib/datadog/tracing/contrib/mongodb/configuration/settings.rb +8 -0
  279. data/lib/datadog/tracing/contrib/mongodb/ext.rb +1 -0
  280. data/lib/datadog/tracing/contrib/mongodb/subscribers.rb +18 -1
  281. data/lib/datadog/tracing/contrib/mysql2/instrumentation.rb +16 -6
  282. data/lib/datadog/tracing/contrib/opensearch/configuration/settings.rb +17 -0
  283. data/lib/datadog/tracing/contrib/opensearch/ext.rb +9 -0
  284. data/lib/datadog/tracing/contrib/opensearch/patcher.rb +5 -1
  285. data/lib/datadog/tracing/contrib/patcher.rb +5 -2
  286. data/lib/datadog/tracing/contrib/rack/request_queue.rb +1 -1
  287. data/lib/datadog/tracing/contrib/rails/patcher.rb +4 -1
  288. data/lib/datadog/tracing/contrib/rails/runner.rb +61 -40
  289. data/lib/datadog/tracing/contrib/rest_client/request_patch.rb +5 -3
  290. data/lib/datadog/tracing/contrib/sidekiq/client_tracer.rb +6 -1
  291. data/lib/datadog/tracing/contrib/sidekiq/distributed/propagation.rb +3 -0
  292. data/lib/datadog/tracing/contrib/sidekiq/ext.rb +1 -0
  293. data/lib/datadog/tracing/contrib/sidekiq/server_tracer.rb +5 -2
  294. data/lib/datadog/tracing/contrib/support.rb +28 -0
  295. data/lib/datadog/tracing/contrib.rb +1 -0
  296. data/lib/datadog/tracing/correlation.rb +9 -2
  297. data/lib/datadog/tracing/diagnostics/environment_logger.rb +3 -1
  298. data/lib/datadog/tracing/distributed/b3_multi.rb +1 -1
  299. data/lib/datadog/tracing/distributed/b3_single.rb +1 -1
  300. data/lib/datadog/tracing/distributed/baggage.rb +131 -0
  301. data/lib/datadog/tracing/distributed/datadog.rb +4 -2
  302. data/lib/datadog/tracing/distributed/propagation.rb +25 -4
  303. data/lib/datadog/tracing/distributed/propagation_policy.rb +42 -0
  304. data/lib/datadog/tracing/metadata/errors.rb +4 -4
  305. data/lib/datadog/tracing/metadata/ext.rb +5 -0
  306. data/lib/datadog/tracing/metadata/metastruct.rb +36 -0
  307. data/lib/datadog/tracing/metadata/metastruct_tagging.rb +42 -0
  308. data/lib/datadog/tracing/metadata.rb +2 -0
  309. data/lib/datadog/tracing/sampling/rate_sampler.rb +2 -1
  310. data/lib/datadog/tracing/sampling/span/rule.rb +0 -1
  311. data/lib/datadog/tracing/span.rb +10 -1
  312. data/lib/datadog/tracing/span_event.rb +2 -2
  313. data/lib/datadog/tracing/span_operation.rb +68 -16
  314. data/lib/datadog/tracing/sync_writer.rb +2 -3
  315. data/lib/datadog/tracing/trace_digest.rb +9 -2
  316. data/lib/datadog/tracing/trace_operation.rb +55 -27
  317. data/lib/datadog/tracing/trace_segment.rb +6 -4
  318. data/lib/datadog/tracing/tracer.rb +51 -7
  319. data/lib/datadog/tracing/transport/http/api.rb +2 -10
  320. data/lib/datadog/tracing/transport/http/client.rb +5 -4
  321. data/lib/datadog/tracing/transport/http/traces.rb +13 -41
  322. data/lib/datadog/tracing/transport/http.rb +11 -44
  323. data/lib/datadog/tracing/transport/serializable_trace.rb +3 -1
  324. data/lib/datadog/tracing/transport/trace_formatter.rb +7 -0
  325. data/lib/datadog/tracing/transport/traces.rb +26 -9
  326. data/lib/datadog/tracing/utils.rb +1 -1
  327. data/lib/datadog/tracing/workers/trace_writer.rb +2 -6
  328. data/lib/datadog/tracing/writer.rb +2 -6
  329. data/lib/datadog/tracing.rb +16 -3
  330. data/lib/datadog/version.rb +2 -2
  331. data/lib/datadog.rb +8 -2
  332. metadata +88 -23
  333. data/lib/datadog/appsec/assets/waf_rules/processors.json +0 -92
  334. data/lib/datadog/appsec/assets/waf_rules/scanners.json +0 -114
  335. data/lib/datadog/appsec/contrib/devise/event.rb +0 -54
  336. data/lib/datadog/appsec/contrib/devise/patcher/authenticatable_patch.rb +0 -72
  337. data/lib/datadog/appsec/contrib/devise/patcher/registration_controller_patch.rb +0 -47
  338. data/lib/datadog/appsec/contrib/devise/resource.rb +0 -35
  339. data/lib/datadog/appsec/contrib/devise/tracking.rb +0 -57
  340. data/lib/datadog/appsec/processor/rule_merger.rb +0 -170
  341. data/lib/datadog/appsec/processor.rb +0 -107
  342. data/lib/datadog/appsec/utils/trace_operation.rb +0 -15
  343. data/lib/datadog/core/telemetry/http/env.rb +0 -20
  344. data/lib/datadog/core/telemetry/http/ext.rb +0 -28
  345. data/lib/datadog/core/telemetry/http/response.rb +0 -70
  346. data/lib/datadog/core/telemetry/http/transport.rb +0 -90
@@ -1,7 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require_relative '../core/remote/dispatcher'
4
- require_relative 'processor/rule_merger'
5
4
  require_relative 'processor/rule_loader'
6
5
 
7
6
  module Datadog
@@ -9,20 +8,23 @@ module Datadog
9
8
  # Remote
10
9
  module Remote
11
10
  class ReadError < StandardError; end
11
+
12
12
  class NoRulesError < StandardError; end
13
13
 
14
14
  class << self
15
- CAP_ASM_RESERVED_1 = 1 << 0 # RESERVED
16
- CAP_ASM_ACTIVATION = 1 << 1 # Remote activation via ASM_FEATURES product
17
- CAP_ASM_IP_BLOCKING = 1 << 2 # accept IP blocking data from ASM_DATA product
18
- CAP_ASM_DD_RULES = 1 << 3 # read ASM rules from ASM_DD product
19
- CAP_ASM_EXCLUSIONS = 1 << 4 # exclusion filters (passlist) via ASM product
20
- CAP_ASM_REQUEST_BLOCKING = 1 << 5 # can block on request info
21
- CAP_ASM_RESPONSE_BLOCKING = 1 << 6 # can block on response info
22
- CAP_ASM_USER_BLOCKING = 1 << 7 # accept user blocking data from ASM_DATA product
23
- CAP_ASM_CUSTOM_RULES = 1 << 8 # accept custom rules
24
- CAP_ASM_CUSTOM_BLOCKING_RESPONSE = 1 << 9 # supports custom http code or redirect sa blocking response
25
- CAP_ASM_TRUSTED_IPS = 1 << 10 # supports trusted ip
15
+ CAP_ASM_RESERVED_1 = 1 << 0 # RESERVED
16
+ CAP_ASM_ACTIVATION = 1 << 1 # Remote activation via ASM_FEATURES product
17
+ CAP_ASM_IP_BLOCKING = 1 << 2 # accept IP blocking data from ASM_DATA product
18
+ CAP_ASM_DD_RULES = 1 << 3 # read ASM rules from ASM_DD product
19
+ CAP_ASM_EXCLUSIONS = 1 << 4 # exclusion filters (passlist) via ASM product
20
+ CAP_ASM_REQUEST_BLOCKING = 1 << 5 # can block on request info
21
+ CAP_ASM_RESPONSE_BLOCKING = 1 << 6 # can block on response info
22
+ CAP_ASM_USER_BLOCKING = 1 << 7 # accept user blocking data from ASM_DATA product
23
+ CAP_ASM_CUSTOM_RULES = 1 << 8 # accept custom rules
24
+ CAP_ASM_CUSTOM_BLOCKING_RESPONSE = 1 << 9 # supports custom http code or redirect sa blocking response
25
+ CAP_ASM_TRUSTED_IPS = 1 << 10 # supports trusted ip
26
+ CAP_ASM_RASP_SSRF = 1 << 23 # support for server-side request forgery exploit prevention rules
27
+ CAP_ASM_RASP_SQLI = 1 << 21 # support for SQL injection exploit prevention rules
26
28
 
27
29
  # TODO: we need to dynamically add CAP_ASM_ACTIVATION once we support it
28
30
  ASM_CAPABILITIES = [
@@ -35,6 +37,8 @@ module Datadog
35
37
  CAP_ASM_CUSTOM_RULES,
36
38
  CAP_ASM_CUSTOM_BLOCKING_RESPONSE,
37
39
  CAP_ASM_TRUSTED_IPS,
40
+ CAP_ASM_RASP_SSRF,
41
+ CAP_ASM_RASP_SQLI,
38
42
  ].freeze
39
43
 
40
44
  ASM_PRODUCTS = [
@@ -52,67 +56,35 @@ module Datadog
52
56
  remote_features_enabled? ? ASM_PRODUCTS : []
53
57
  end
54
58
 
55
- # rubocop:disable Metrics/MethodLength
56
59
  def receivers(telemetry)
57
60
  return [] unless remote_features_enabled?
58
61
 
59
62
  matcher = Core::Remote::Dispatcher::Matcher::Product.new(ASM_PRODUCTS)
60
63
  receiver = Core::Remote::Dispatcher::Receiver.new(matcher) do |repository, changes|
61
- changes.each do |change|
62
- Datadog.logger.debug { "remote config change: '#{change.path}'" }
63
- end
64
-
65
- rules = []
66
- custom_rules = []
67
- data = []
68
- overrides = []
69
- exclusions = []
70
-
71
- repository.contents.each do |content|
72
- parsed_content = parse_content(content)
73
-
74
- case content.path.product
75
- when 'ASM_DD'
76
- rules << parsed_content
77
- when 'ASM_DATA'
78
- data << parsed_content['rules_data'] if parsed_content['rules_data']
79
- when 'ASM'
80
- overrides << parsed_content['rules_override'] if parsed_content['rules_override']
81
- exclusions << parsed_content['exclusions'] if parsed_content['exclusions']
82
- custom_rules << parsed_content['custom_rules'] if parsed_content['custom_rules']
83
- end
84
- end
64
+ next unless AppSec.security_engine
85
65
 
86
- if rules.empty?
87
- settings_rules = AppSec::Processor::RuleLoader.load_rules(
88
- telemetry: telemetry,
89
- ruleset: Datadog.configuration.appsec.ruleset
90
- )
66
+ changes.each do |change|
67
+ content = repository[change.path]
68
+ next unless content || change.type == :delete
91
69
 
92
- raise NoRulesError, 'no default rules available' unless settings_rules
70
+ case change.type
71
+ when :insert, :update
72
+ AppSec.security_engine.add_or_update_config(parse_content(content), path: change.path.to_s) # steep:ignore
93
73
 
94
- rules = [settings_rules]
74
+ content.applied # steep:ignore
75
+ when :delete
76
+ AppSec.security_engine.remove_config_at_path(change.path.to_s) # steep:ignore
77
+ end
95
78
  end
96
79
 
97
- ruleset = AppSec::Processor::RuleMerger.merge(
98
- rules: rules,
99
- data: data,
100
- overrides: overrides,
101
- exclusions: exclusions,
102
- custom_rules: custom_rules,
103
- telemetry: telemetry
104
- )
105
-
106
- Datadog::AppSec.reconfigure(ruleset: ruleset, telemetry: telemetry)
107
-
108
- repository.contents.each do |content|
109
- content.applied if ASM_PRODUCTS.include?(content.path.product)
110
- end
80
+ # This is subject to change - we need to remove the reconfiguration mutex
81
+ # and track usages of each WAF handle instead, so that we know when an old
82
+ # WAF handle can be finalized.
83
+ AppSec.reconfigure!
111
84
  end
112
85
 
113
86
  [receiver]
114
87
  end
115
- # rubocop:enable Metrics/MethodLength
116
88
 
117
89
  private
118
90
 
@@ -30,13 +30,13 @@ module Datadog
30
30
 
31
31
  def block_response(interrupt_params, http_accept_header)
32
32
  content_type = case interrupt_params['type']
33
- when nil, 'auto' then content_type(http_accept_header)
34
- else FORMAT_TO_CONTENT_TYPE.fetch(interrupt_params['type'], DEFAULT_CONTENT_TYPE)
35
- end
33
+ when nil, 'auto' then content_type(http_accept_header)
34
+ else FORMAT_TO_CONTENT_TYPE.fetch(interrupt_params['type'], DEFAULT_CONTENT_TYPE)
35
+ end
36
36
 
37
37
  Response.new(
38
38
  status: interrupt_params['status_code']&.to_i || 403,
39
- headers: { 'Content-Type' => content_type },
39
+ headers: {'Content-Type' => content_type},
40
40
  body: [content(content_type)],
41
41
  )
42
42
  end
@@ -45,8 +45,8 @@ module Datadog
45
45
  status_code = interrupt_params['status_code'].to_i
46
46
 
47
47
  Response.new(
48
- status: (status_code >= 300 && status_code < 400 ? status_code : 303),
49
- headers: { 'Location' => interrupt_params.fetch('location') },
48
+ status: ((status_code >= 300 && status_code < 400) ? status_code : 303),
49
+ headers: {'Location' => interrupt_params.fetch('location')},
50
50
  body: [],
51
51
  )
52
52
  end
@@ -0,0 +1,194 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Datadog
4
+ module AppSec
5
+ module SecurityEngine
6
+ # SecurityEngine::Engine creates WAF builder and manages its configuration.
7
+ # It also rebuilds WAF handle from the WAF builder when configuration changes.
8
+ class Engine
9
+ DEFAULT_RULES_CONFIG_PATH = 'ASM_DD/default'
10
+ TELEMETRY_ACTIONS = %w[init update].freeze
11
+ DIAGNOSTICS_CONFIG_KEYS = %w[
12
+ rules
13
+ custom_rules
14
+ exclusions
15
+ actions
16
+ processors
17
+ scanners
18
+ rules_override
19
+ rules_data
20
+ exclusion_data
21
+ ].freeze
22
+
23
+ attr_reader :waf_addresses, :ruleset_version
24
+
25
+ def initialize(appsec_settings:, telemetry:)
26
+ @default_ruleset = appsec_settings.ruleset
27
+
28
+ # NOTE: replace appsec_settings argument with default_ruleset when removing these deprecated settings
29
+ @default_ip_denylist = appsec_settings.ip_denylist
30
+ @default_user_id_denylist = appsec_settings.user_id_denylist
31
+ @default_ip_passlist = appsec_settings.ip_passlist
32
+
33
+ @waf_builder = WAF::HandleBuilder.new(
34
+ obfuscator: {
35
+ key_regex: appsec_settings.obfuscator_key_regex,
36
+ value_regex: appsec_settings.obfuscator_value_regex
37
+ }
38
+ )
39
+
40
+ diagnostics = load_default_config(telemetry: telemetry)
41
+ report_configuration_diagnostics(diagnostics, action: 'init', telemetry: telemetry)
42
+
43
+ @waf_handle = @waf_builder.build_handle
44
+ @waf_addresses = @waf_handle.known_addresses
45
+ rescue WAF::Error => e
46
+ error_message = "AppSec security engine failed to initialize"
47
+
48
+ Datadog.logger.error("#{error_message}, error #{e.inspect}")
49
+ telemetry.report(e, description: error_message)
50
+
51
+ raise e
52
+ end
53
+
54
+ def finalize!
55
+ @waf_handle&.finalize!
56
+ @waf_builder&.finalize!
57
+
58
+ @waf_addresses = []
59
+ @ruleset_version = nil
60
+ end
61
+
62
+ def new_runner
63
+ SecurityEngine::Runner.new(@waf_handle.build_context)
64
+ end
65
+
66
+ def add_or_update_config(config, path:)
67
+ @is_ruleset_update = path.include?('ASM_DD')
68
+
69
+ # default config has to be removed when adding an ASM_DD config
70
+ remove_config_at_path(DEFAULT_RULES_CONFIG_PATH) if @is_ruleset_update
71
+
72
+ diagnostics = @waf_builder.add_or_update_config(config, path: path)
73
+ @ruleset_version = diagnostics['ruleset_version'] if diagnostics.key?('ruleset_version')
74
+ report_configuration_diagnostics(diagnostics, action: 'update', telemetry: AppSec.telemetry)
75
+
76
+ # we need to load default config if diagnostics contains top-level error for rules or processors
77
+ if @is_ruleset_update &&
78
+ (diagnostics.key?('error') ||
79
+ diagnostics.dig('rules', 'error') ||
80
+ diagnostics.dig('processors', 'errors'))
81
+ diagnostics = load_default_config(telemetry: AppSec.telemetry)
82
+ report_configuration_diagnostics(diagnostics, action: 'update', telemetry: AppSec.telemetry)
83
+ end
84
+
85
+ diagnostics
86
+ rescue WAF::Error => e
87
+ error_message = "libddwaf builder failed to add or update config at path: #{path}"
88
+
89
+ Datadog.logger.debug("#{error_message}, error: #{e.inspect}")
90
+ AppSec.telemetry.report(e, description: error_message)
91
+ end
92
+
93
+ def remove_config_at_path(path)
94
+ result = @waf_builder.remove_config_at_path(path)
95
+
96
+ if result && path != DEFAULT_RULES_CONFIG_PATH && path.include?('ASM_DD')
97
+ diagnostics = load_default_config(telemetry: AppSec.telemetry)
98
+ report_configuration_diagnostics(diagnostics, action: 'update', telemetry: AppSec.telemetry)
99
+ end
100
+
101
+ result
102
+ rescue WAF::Error => e
103
+ error_message = "libddwaf handle builder failed to remove config at path: #{path}"
104
+
105
+ Datadog.logger.error("#{error_message}, error: #{e.inspect}")
106
+ AppSec.telemetry.report(e, description: error_message)
107
+ end
108
+
109
+ def reconfigure!
110
+ old_waf_handle = @waf_handle
111
+
112
+ @waf_handle = @waf_builder.build_handle
113
+ @waf_addresses = @waf_handle.known_addresses
114
+
115
+ old_waf_handle&.finalize!
116
+ rescue WAF::Error => e
117
+ error_message = "AppSec security engine failed to reconfigure"
118
+
119
+ Datadog.logger.error("#{error_message}, error #{e.inspect}")
120
+ AppSec.telemetry.report(e, description: error_message)
121
+
122
+ if old_waf_handle
123
+ Datadog.logger.warn("Reverting to the previous configuration")
124
+
125
+ @waf_handle = old_waf_handle
126
+ @waf_addresses = old_waf_handle.known_addresses
127
+ end
128
+ end
129
+
130
+ private
131
+
132
+ def load_default_config(telemetry:)
133
+ config = AppSec::Processor::RuleLoader.load_rules(telemetry: telemetry, ruleset: @default_ruleset)
134
+
135
+ # deprecated - ip and user id denylists should be configured via RC
136
+ config['rules_data'] ||= AppSec::Processor::RuleLoader.load_data(
137
+ ip_denylist: @default_ip_denylist,
138
+ user_id_denylist: @default_user_id_denylist
139
+ )
140
+
141
+ # deprecated - ip passlist should be configured via RC
142
+ config['exclusions'] ||= AppSec::Processor::RuleLoader.load_exclusions(ip_passlist: @default_ip_passlist)
143
+
144
+ diagnostics = @waf_builder.add_or_update_config(config, path: DEFAULT_RULES_CONFIG_PATH)
145
+ @ruleset_version = diagnostics['ruleset_version']
146
+
147
+ diagnostics
148
+ end
149
+
150
+ def report_configuration_diagnostics(diagnostics, action:, telemetry:)
151
+ raise ArgumentError, 'action must be one of TELEMETRY_ACTIONS' unless TELEMETRY_ACTIONS.include?(action)
152
+
153
+ common_tags = {
154
+ waf_version: Datadog::AppSec::WAF::VERSION::BASE_STRING,
155
+ event_rules_version: diagnostics.fetch('ruleset_version', @ruleset_version).to_s,
156
+ action: action
157
+ }
158
+
159
+ if diagnostics['error']
160
+ telemetry.inc(
161
+ Ext::TELEMETRY_METRICS_NAMESPACE, 'waf.config_errors', 1,
162
+ tags: common_tags.merge(scope: 'top-level')
163
+ )
164
+
165
+ telemetry.error(diagnostics['error'])
166
+ end
167
+
168
+ diagnostics.each do |config_key, config_diagnostics|
169
+ next unless DIAGNOSTICS_CONFIG_KEYS.include?(config_key)
170
+ next if !config_diagnostics.key?('error') && config_diagnostics.fetch('errors', []).empty?
171
+
172
+ if config_diagnostics['error']
173
+ telemetry.error(config_diagnostics['error'])
174
+
175
+ telemetry.inc(
176
+ Ext::TELEMETRY_METRICS_NAMESPACE, 'waf.config_errors', 1,
177
+ tags: common_tags.merge(config_key: config_key, scope: 'top-level')
178
+ )
179
+ elsif config_diagnostics['errors']
180
+ config_diagnostics['errors'].each do |error, config_ids|
181
+ telemetry.error("#{error}: [#{config_ids.join(",")}]")
182
+ end
183
+
184
+ telemetry.inc(
185
+ Ext::TELEMETRY_METRICS_NAMESPACE, 'waf.config_errors', config_diagnostics['errors'].count,
186
+ tags: common_tags.merge(config_key: config_key, scope: 'item')
187
+ )
188
+ end
189
+ end
190
+ end
191
+ end
192
+ end
193
+ end
194
+ end
@@ -9,10 +9,9 @@ module Datadog
9
9
  class Runner
10
10
  SUCCESSFUL_EXECUTION_CODES = [:ok, :match].freeze
11
11
 
12
- def initialize(handle, telemetry:)
12
+ def initialize(waf_context)
13
13
  @mutex = Mutex.new
14
- @context = WAF::Context.new(handle)
15
- @telemetry = telemetry
14
+ @waf_context = waf_context
16
15
 
17
16
  @debug_tag = "libddwaf:#{WAF::VERSION::STRING} method:ddwaf_run"
18
17
  end
@@ -24,16 +23,16 @@ module Datadog
24
23
  persistent_data.reject! do |_, v|
25
24
  next false if v.is_a?(TrueClass) || v.is_a?(FalseClass)
26
25
 
27
- v.nil? ? true : v.empty?
26
+ v.nil? || v.empty?
28
27
  end
29
28
 
30
29
  ephemeral_data.reject! do |_, v|
31
30
  next false if v.is_a?(TrueClass) || v.is_a?(FalseClass)
32
31
 
33
- v.nil? ? true : v.empty?
32
+ v.nil? || v.empty?
34
33
  end
35
34
 
36
- _code, result = try_run(persistent_data, ephemeral_data, timeout)
35
+ result = try_run(persistent_data, ephemeral_data, timeout)
37
36
  stop_ns = Core::Utils::Time.get_time(:nanosecond)
38
37
 
39
38
  report_execution(result)
@@ -42,7 +41,7 @@ module Datadog
42
41
  return Result::Error.new(duration_ext_ns: stop_ns - start_ns)
43
42
  end
44
43
 
45
- klass = result.status == :match ? Result::Match : Result::Ok
44
+ klass = (result.status == :match) ? Result::Match : Result::Ok
46
45
  klass.new(
47
46
  events: result.events,
48
47
  actions: result.actions,
@@ -55,19 +54,19 @@ module Datadog
55
54
  @mutex.unlock
56
55
  end
57
56
 
58
- def finalize
59
- @context.finalize
57
+ def finalize!
58
+ @waf_context.finalize!
60
59
  end
61
60
 
62
61
  private
63
62
 
64
63
  def try_run(persistent_data, ephemeral_data, timeout)
65
- @context.run(persistent_data, ephemeral_data, timeout)
66
- rescue WAF::LibDDWAF::Error => e
64
+ @waf_context.run(persistent_data, ephemeral_data, timeout)
65
+ rescue WAF::LibDDWAFError => e
67
66
  Datadog.logger.debug { "#{@debug_tag} execution error: #{e} backtrace: #{e.backtrace&.first(3)}" }
68
- @telemetry.report(e, description: 'libddwaf-rb internal low-level error')
67
+ AppSec.telemetry.report(e, description: 'libddwaf-rb internal low-level error')
69
68
 
70
- [:err_internal, WAF::Result.new(:err_internal, [], 0, false, [], [])]
69
+ WAF::Result.new(:err_internal, [], 0, false, [], [])
71
70
  end
72
71
 
73
72
  def report_execution(result)
@@ -79,7 +78,7 @@ module Datadog
79
78
  message = "#{@debug_tag} execution error: #{result.status.inspect}"
80
79
 
81
80
  Datadog.logger.debug { message }
82
- @telemetry.error(message)
81
+ AppSec.telemetry.error(message)
83
82
  end
84
83
  end
85
84
  end
@@ -0,0 +1,39 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Datadog
4
+ module AppSec
5
+ # A class that represents a security event of any kind. It could be an event
6
+ # representing an attack or fingerprinting results as derivatives or an API
7
+ # security check with extracted schema.
8
+ class SecurityEvent
9
+ SCHEMA_KEY_PREFIX = '_dd.appsec.s.'
10
+ FINGERPRINT_KEY_PREFIX = '_dd.appsec.fp.'
11
+
12
+ attr_reader :waf_result, :trace, :span
13
+
14
+ def initialize(waf_result, trace:, span:)
15
+ @waf_result = waf_result
16
+ @trace = trace
17
+ @span = span
18
+ end
19
+
20
+ def attack?
21
+ return @is_attack if defined?(@is_attack)
22
+
23
+ @is_attack = @waf_result.is_a?(SecurityEngine::Result::Match)
24
+ end
25
+
26
+ def schema?
27
+ return @has_schema if defined?(@has_schema)
28
+
29
+ @has_schema = @waf_result.derivatives.any? { |name, _| name.start_with?(SCHEMA_KEY_PREFIX) }
30
+ end
31
+
32
+ def fingerprint?
33
+ return @has_fingerprint if defined?(@has_fingerprint)
34
+
35
+ @has_fingerprint = @waf_result.derivatives.any? { |name, _| name.start_with?(FINGERPRINT_KEY_PREFIX) }
36
+ end
37
+ end
38
+ end
39
+ end
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative 'utils/trace_operation'
4
-
5
3
  module Datadog
6
4
  module AppSec
7
5
  # Utilities for AppSec
@@ -26,15 +26,12 @@ module Datadog
26
26
  components.appsec&.telemetry
27
27
  end
28
28
 
29
- def processor
30
- components.appsec&.processor
29
+ def security_engine
30
+ components.appsec&.security_engine
31
31
  end
32
32
 
33
- def reconfigure(ruleset:, telemetry:)
34
- appsec_component = components.appsec
35
- return unless appsec_component
36
-
37
- appsec_component.reconfigure(ruleset: ruleset, telemetry: telemetry)
33
+ def reconfigure!
34
+ components.appsec&.reconfigure!
38
35
  end
39
36
 
40
37
  def reconfigure_lock(&block)
@@ -44,7 +41,7 @@ module Datadog
44
41
  appsec_component.reconfigure_lock(&block)
45
42
  end
46
43
 
47
- def api_security_enabled?
44
+ def perform_api_security_check?
48
45
  Datadog.configuration.appsec.api_security.enabled &&
49
46
  Datadog.configuration.appsec.api_security.sample_rate.sample?
50
47
  end
@@ -40,7 +40,23 @@ module Datadog
40
40
  add_all!(underflow) unless underflow.nil?
41
41
 
42
42
  # Iteratively replace items, to ensure pseudo-random replacement.
43
- overflow.each { |item| replace!(item) } unless overflow.nil?
43
+ overflow&.each { |item| replace!(item) }
44
+ end
45
+
46
+ def unshift(*items)
47
+ # TODO The existing concat implementation does not always append
48
+ # to the end of the buffer - if the buffer is full, a random
49
+ # item is deleted and the new item is added in the position of
50
+ # removed item.
51
+ # Therefore, if we want to preserve the item order, concat
52
+ # would also need to be changed to maintain order.
53
+ # With the existing implementation, the idea is to not move
54
+ # existing items around, which is what sets unshift apart from
55
+ # concat to begin with.
56
+ #
57
+ # Since this method currently delegates to +concat+, it does not
58
+ # have a matching definition in the thread-safe worker.
59
+ concat(items)
44
60
  end
45
61
 
46
62
  # Stored items are returned and the local buffer is reset.
@@ -78,7 +94,7 @@ module Datadog
78
94
  underflow = nil
79
95
  overflow = nil
80
96
 
81
- overflow_size = @max_size > 0 ? (@items.length + items.length) - @max_size : 0
97
+ overflow_size = (@max_size > 0) ? (@items.length + items.length) - @max_size : 0
82
98
 
83
99
  if overflow_size > 0
84
100
  # Items will overflow
@@ -0,0 +1,52 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'ext'
4
+
5
+ module Datadog
6
+ module Core
7
+ module Configuration
8
+ # Immutable container for the resulting settings
9
+ class AgentSettings
10
+ # IPv6 regular expression from
11
+ # https://stackoverflow.com/questions/53497/regular-expression-that-matches-valid-ipv6-addresses
12
+ # Does not match IPv4 addresses.
13
+ IPV6_REGEXP = /\A(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\z)/.freeze # rubocop:disable Layout/LineLength
14
+
15
+ attr_reader :adapter, :ssl, :hostname, :port, :uds_path, :timeout_seconds
16
+
17
+ def initialize(adapter: nil, ssl: nil, hostname: nil, port: nil, uds_path: nil, timeout_seconds: nil)
18
+ @adapter = adapter
19
+ @ssl = ssl
20
+ @hostname = hostname
21
+ @port = port
22
+ @uds_path = uds_path
23
+ @timeout_seconds = timeout_seconds
24
+ freeze
25
+ end
26
+
27
+ def url
28
+ case adapter
29
+ when Datadog::Core::Configuration::Ext::Agent::HTTP::ADAPTER
30
+ hostname = self.hostname
31
+ hostname = "[#{hostname}]" if IPV6_REGEXP.match?(hostname)
32
+ "#{ssl ? "https" : "http"}://#{hostname}:#{port}/"
33
+ when Datadog::Core::Configuration::Ext::Agent::UnixSocket::ADAPTER
34
+ "unix://#{uds_path}"
35
+ else
36
+ raise ArgumentError, "Unexpected adapter: #{adapter}"
37
+ end
38
+ end
39
+
40
+ def ==(other)
41
+ self.class == other.class &&
42
+ adapter == other.adapter &&
43
+ ssl == other.ssl &&
44
+ hostname == other.hostname &&
45
+ port == other.port &&
46
+ uds_path == other.uds_path &&
47
+ timeout_seconds == other.timeout_seconds
48
+ end
49
+ end
50
+ end
51
+ end
52
+ end