ddtrace 1.12.1 → 1.14.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (275) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +158 -9
  3. data/ext/ddtrace_profiling_native_extension/collectors_thread_context.c +97 -14
  4. data/ext/ddtrace_profiling_native_extension/extconf.rb +6 -0
  5. data/ext/ddtrace_profiling_native_extension/http_transport.c +19 -6
  6. data/ext/ddtrace_profiling_native_extension/native_extension_helpers.rb +16 -1
  7. data/ext/ddtrace_profiling_native_extension/private_vm_api_access.c +41 -2
  8. data/ext/ddtrace_profiling_native_extension/private_vm_api_access.h +6 -0
  9. data/ext/ddtrace_profiling_native_extension/stack_recorder.c +6 -10
  10. data/ext/ddtrace_profiling_native_extension/time_helpers.c +40 -4
  11. data/ext/ddtrace_profiling_native_extension/time_helpers.h +14 -0
  12. data/lib/datadog/appsec/component.rb +9 -0
  13. data/lib/datadog/appsec/configuration/settings.rb +110 -195
  14. data/lib/datadog/appsec/configuration.rb +0 -79
  15. data/lib/datadog/appsec/contrib/auto_instrument.rb +2 -4
  16. data/lib/datadog/appsec/contrib/devise/event.rb +57 -0
  17. data/lib/datadog/appsec/contrib/devise/ext.rb +13 -0
  18. data/lib/datadog/appsec/contrib/devise/integration.rb +42 -0
  19. data/lib/datadog/appsec/contrib/devise/patcher/authenticatable_patch.rb +76 -0
  20. data/lib/datadog/appsec/contrib/devise/patcher/registration_controller_patch.rb +52 -0
  21. data/lib/datadog/appsec/contrib/devise/patcher.rb +45 -0
  22. data/lib/datadog/appsec/contrib/devise/resource.rb +35 -0
  23. data/lib/datadog/appsec/contrib/devise/tracking.rb +49 -0
  24. data/lib/datadog/appsec/contrib/rack/ext.rb +2 -1
  25. data/lib/datadog/appsec/contrib/rack/reactive/request.rb +1 -1
  26. data/lib/datadog/appsec/contrib/rack/reactive/request_body.rb +1 -1
  27. data/lib/datadog/appsec/contrib/rack/reactive/response.rb +1 -1
  28. data/lib/datadog/appsec/contrib/rack/request_middleware.rb +12 -7
  29. data/lib/datadog/appsec/contrib/rails/ext.rb +3 -2
  30. data/lib/datadog/appsec/contrib/rails/framework.rb +1 -3
  31. data/lib/datadog/appsec/contrib/rails/patcher.rb +8 -8
  32. data/lib/datadog/appsec/contrib/rails/reactive/action.rb +1 -1
  33. data/lib/datadog/appsec/contrib/sinatra/ext.rb +2 -1
  34. data/lib/datadog/appsec/contrib/sinatra/framework.rb +1 -3
  35. data/lib/datadog/appsec/contrib/sinatra/reactive/routed.rb +1 -1
  36. data/lib/datadog/appsec/event.rb +1 -1
  37. data/lib/datadog/appsec/extensions.rb +1 -130
  38. data/lib/datadog/appsec/monitor/reactive/set_user.rb +1 -1
  39. data/lib/datadog/appsec/processor.rb +1 -1
  40. data/lib/datadog/appsec/rate_limiter.rb +1 -1
  41. data/lib/datadog/appsec/remote.rb +1 -1
  42. data/lib/datadog/appsec.rb +1 -2
  43. data/lib/datadog/ci/configuration/settings.rb +6 -8
  44. data/lib/datadog/ci/contrib/cucumber/configuration/settings.rb +7 -5
  45. data/lib/datadog/ci/contrib/cucumber/ext.rb +10 -8
  46. data/lib/datadog/ci/contrib/minitest/configuration/settings.rb +35 -0
  47. data/lib/datadog/ci/contrib/minitest/ext.rb +21 -0
  48. data/lib/datadog/ci/contrib/minitest/integration.rb +49 -0
  49. data/lib/datadog/ci/contrib/minitest/patcher.rb +27 -0
  50. data/lib/datadog/ci/contrib/minitest/test_helper.rb +68 -0
  51. data/lib/datadog/ci/contrib/rspec/configuration/settings.rb +7 -5
  52. data/lib/datadog/ci/contrib/rspec/ext.rb +9 -7
  53. data/lib/datadog/ci.rb +1 -0
  54. data/lib/datadog/core/backport.rb +51 -0
  55. data/lib/datadog/core/configuration/agent_settings_resolver.rb +9 -5
  56. data/lib/datadog/core/configuration/base.rb +5 -5
  57. data/lib/datadog/core/configuration/components.rb +8 -1
  58. data/lib/datadog/core/configuration/ext.rb +7 -5
  59. data/lib/datadog/core/configuration/option.rb +269 -19
  60. data/lib/datadog/core/configuration/option_definition.rb +76 -11
  61. data/lib/datadog/core/configuration/options.rb +22 -10
  62. data/lib/datadog/core/configuration/settings.rb +139 -61
  63. data/lib/datadog/core/diagnostics/environment_logger.rb +130 -234
  64. data/lib/datadog/core/environment/execution.rb +65 -0
  65. data/lib/datadog/core/environment/ext.rb +13 -11
  66. data/lib/datadog/core/environment/yjit.rb +58 -0
  67. data/lib/datadog/core/git/ext.rb +24 -22
  68. data/lib/datadog/core/logging/ext.rb +3 -1
  69. data/lib/datadog/core/metrics/ext.rb +7 -5
  70. data/lib/datadog/core/remote/client/capabilities.rb +5 -0
  71. data/lib/datadog/core/remote/client.rb +3 -0
  72. data/lib/datadog/core/remote/component.rb +25 -34
  73. data/lib/datadog/core/remote/configuration/content.rb +28 -1
  74. data/lib/datadog/core/remote/configuration/repository.rb +3 -1
  75. data/lib/datadog/core/remote/ext.rb +1 -1
  76. data/lib/datadog/core/remote/negotiation.rb +17 -4
  77. data/lib/datadog/core/runtime/ext.rb +22 -12
  78. data/lib/datadog/core/runtime/metrics.rb +43 -0
  79. data/lib/datadog/core/telemetry/client.rb +12 -2
  80. data/lib/datadog/core/telemetry/collector.rb +10 -2
  81. data/lib/datadog/core/telemetry/emitter.rb +4 -2
  82. data/lib/datadog/core/telemetry/event.rb +19 -4
  83. data/lib/datadog/core/telemetry/ext.rb +4 -1
  84. data/lib/datadog/core/telemetry/heartbeat.rb +2 -4
  85. data/lib/datadog/core/telemetry/http/ext.rb +10 -8
  86. data/lib/datadog/core/telemetry/http/transport.rb +1 -0
  87. data/lib/datadog/core/telemetry/v2/app_client_configuration_change.rb +41 -0
  88. data/lib/datadog/core/telemetry/v2/request.rb +29 -0
  89. data/lib/datadog/core/transport/http/client.rb +1 -1
  90. data/lib/datadog/core/transport/http/config.rb +10 -0
  91. data/lib/datadog/core/utils/duration.rb +52 -0
  92. data/lib/datadog/core/utils/hash.rb +47 -0
  93. data/lib/datadog/core/utils/network.rb +1 -1
  94. data/lib/datadog/core/utils/safe_dup.rb +27 -20
  95. data/lib/datadog/core/utils.rb +1 -1
  96. data/lib/datadog/core/workers/async.rb +2 -2
  97. data/lib/datadog/kit/appsec/events.rb +139 -89
  98. data/lib/datadog/kit/identity.rb +80 -65
  99. data/lib/datadog/profiling/collectors/cpu_and_wall_time_worker.rb +3 -0
  100. data/lib/datadog/profiling/collectors/idle_sampling_helper.rb +1 -0
  101. data/lib/datadog/profiling/collectors/thread_context.rb +9 -2
  102. data/lib/datadog/profiling/component.rb +51 -9
  103. data/lib/datadog/profiling/diagnostics/environment_logger.rb +39 -0
  104. data/lib/datadog/profiling/exporter.rb +5 -1
  105. data/lib/datadog/profiling/flush.rb +7 -2
  106. data/lib/datadog/profiling/http_transport.rb +13 -3
  107. data/lib/datadog/profiling/load_native_extension.rb +7 -1
  108. data/lib/datadog/profiling.rb +12 -1
  109. data/lib/datadog/tracing/component.rb +60 -7
  110. data/lib/datadog/tracing/configuration/dynamic/option.rb +71 -0
  111. data/lib/datadog/tracing/configuration/dynamic.rb +64 -0
  112. data/lib/datadog/tracing/configuration/ext.rb +35 -32
  113. data/lib/datadog/tracing/configuration/http.rb +74 -0
  114. data/lib/datadog/tracing/configuration/settings.rb +106 -92
  115. data/lib/datadog/tracing/contrib/action_cable/configuration/settings.rb +9 -6
  116. data/lib/datadog/tracing/contrib/action_cable/ext.rb +20 -18
  117. data/lib/datadog/tracing/contrib/action_mailer/configuration/settings.rb +9 -6
  118. data/lib/datadog/tracing/contrib/action_mailer/ext.rb +20 -18
  119. data/lib/datadog/tracing/contrib/action_pack/configuration/settings.rb +8 -6
  120. data/lib/datadog/tracing/contrib/action_pack/ext.rb +10 -8
  121. data/lib/datadog/tracing/contrib/action_view/configuration/settings.rb +9 -6
  122. data/lib/datadog/tracing/contrib/action_view/ext.rb +12 -10
  123. data/lib/datadog/tracing/contrib/active_job/configuration/settings.rb +13 -7
  124. data/lib/datadog/tracing/contrib/active_job/ext.rb +25 -23
  125. data/lib/datadog/tracing/contrib/active_job/log_injection.rb +1 -1
  126. data/lib/datadog/tracing/contrib/active_job/patcher.rb +1 -1
  127. data/lib/datadog/tracing/contrib/active_model_serializers/configuration/settings.rb +9 -6
  128. data/lib/datadog/tracing/contrib/active_model_serializers/ext.rb +12 -10
  129. data/lib/datadog/tracing/contrib/active_record/configuration/resolver.rb +18 -11
  130. data/lib/datadog/tracing/contrib/active_record/configuration/settings.rb +9 -7
  131. data/lib/datadog/tracing/contrib/active_record/events/sql.rb +0 -8
  132. data/lib/datadog/tracing/contrib/active_record/ext.rb +17 -15
  133. data/lib/datadog/tracing/contrib/active_record/utils.rb +1 -1
  134. data/lib/datadog/tracing/contrib/active_support/cache/instrumentation.rb +0 -5
  135. data/lib/datadog/tracing/contrib/active_support/configuration/settings.rb +9 -7
  136. data/lib/datadog/tracing/contrib/active_support/ext.rb +18 -16
  137. data/lib/datadog/tracing/contrib/aws/configuration/settings.rb +14 -7
  138. data/lib/datadog/tracing/contrib/aws/ext.rb +37 -24
  139. data/lib/datadog/tracing/contrib/aws/instrumentation.rb +9 -5
  140. data/lib/datadog/tracing/contrib/concurrent_ruby/configuration/settings.rb +3 -2
  141. data/lib/datadog/tracing/contrib/concurrent_ruby/ext.rb +4 -2
  142. data/lib/datadog/tracing/contrib/dalli/configuration/settings.rb +14 -7
  143. data/lib/datadog/tracing/contrib/dalli/ext.rb +19 -11
  144. data/lib/datadog/tracing/contrib/dalli/instrumentation.rb +8 -6
  145. data/lib/datadog/tracing/contrib/delayed_job/configuration/settings.rb +13 -7
  146. data/lib/datadog/tracing/contrib/delayed_job/ext.rb +16 -14
  147. data/lib/datadog/tracing/contrib/elasticsearch/configuration/settings.rb +14 -7
  148. data/lib/datadog/tracing/contrib/elasticsearch/ext.rb +21 -15
  149. data/lib/datadog/tracing/contrib/elasticsearch/patcher.rb +99 -99
  150. data/lib/datadog/tracing/contrib/ethon/configuration/settings.rb +16 -9
  151. data/lib/datadog/tracing/contrib/ethon/easy_patch.rb +43 -3
  152. data/lib/datadog/tracing/contrib/ethon/ext.rb +19 -11
  153. data/lib/datadog/tracing/contrib/ethon/multi_patch.rb +0 -5
  154. data/lib/datadog/tracing/contrib/excon/configuration/settings.rb +19 -10
  155. data/lib/datadog/tracing/contrib/excon/ext.rb +16 -8
  156. data/lib/datadog/tracing/contrib/excon/middleware.rb +20 -5
  157. data/lib/datadog/tracing/contrib/ext.rb +23 -1
  158. data/lib/datadog/tracing/contrib/extensions.rb +32 -0
  159. data/lib/datadog/tracing/contrib/faraday/configuration/settings.rb +20 -10
  160. data/lib/datadog/tracing/contrib/faraday/ext.rb +16 -8
  161. data/lib/datadog/tracing/contrib/faraday/middleware.rb +16 -5
  162. data/lib/datadog/tracing/contrib/grape/configuration/settings.rb +8 -6
  163. data/lib/datadog/tracing/contrib/grape/ext.rb +16 -14
  164. data/lib/datadog/tracing/contrib/graphql/configuration/settings.rb +8 -6
  165. data/lib/datadog/tracing/contrib/graphql/ext.rb +7 -5
  166. data/lib/datadog/tracing/contrib/grpc/configuration/settings.rb +19 -9
  167. data/lib/datadog/tracing/contrib/grpc/datadog_interceptor/client.rb +29 -20
  168. data/lib/datadog/tracing/contrib/grpc/datadog_interceptor/server.rb +21 -20
  169. data/lib/datadog/tracing/contrib/grpc/ext.rb +16 -13
  170. data/lib/datadog/tracing/contrib/grpc/formatting.rb +127 -0
  171. data/lib/datadog/tracing/contrib/hanami/configuration/settings.rb +3 -2
  172. data/lib/datadog/tracing/contrib/hanami/ext.rb +10 -8
  173. data/lib/datadog/tracing/contrib/http/circuit_breaker.rb +4 -7
  174. data/lib/datadog/tracing/contrib/http/configuration/settings.rb +33 -11
  175. data/lib/datadog/tracing/contrib/http/ext.rb +16 -9
  176. data/lib/datadog/tracing/contrib/http/instrumentation.rb +22 -7
  177. data/lib/datadog/tracing/contrib/httpclient/configuration/settings.rb +33 -11
  178. data/lib/datadog/tracing/contrib/httpclient/ext.rb +17 -9
  179. data/lib/datadog/tracing/contrib/httpclient/instrumentation.rb +17 -5
  180. data/lib/datadog/tracing/contrib/httprb/configuration/settings.rb +33 -11
  181. data/lib/datadog/tracing/contrib/httprb/ext.rb +16 -9
  182. data/lib/datadog/tracing/contrib/httprb/instrumentation.rb +17 -5
  183. data/lib/datadog/tracing/contrib/kafka/configuration/settings.rb +9 -6
  184. data/lib/datadog/tracing/contrib/kafka/ext.rb +42 -39
  185. data/lib/datadog/tracing/contrib/lograge/configuration/settings.rb +3 -2
  186. data/lib/datadog/tracing/contrib/lograge/ext.rb +3 -1
  187. data/lib/datadog/tracing/contrib/lograge/instrumentation.rb +2 -17
  188. data/lib/datadog/tracing/contrib/mongodb/configuration/settings.rb +14 -7
  189. data/lib/datadog/tracing/contrib/mongodb/ext.rb +20 -16
  190. data/lib/datadog/tracing/contrib/mongodb/subscribers.rb +9 -5
  191. data/lib/datadog/tracing/contrib/mysql2/configuration/settings.rb +17 -14
  192. data/lib/datadog/tracing/contrib/mysql2/ext.rb +15 -10
  193. data/lib/datadog/tracing/contrib/mysql2/instrumentation.rb +9 -5
  194. data/lib/datadog/tracing/contrib/opensearch/configuration/settings.rb +52 -0
  195. data/lib/datadog/tracing/contrib/opensearch/ext.rb +37 -0
  196. data/lib/datadog/tracing/contrib/opensearch/integration.rb +44 -0
  197. data/lib/datadog/tracing/contrib/opensearch/patcher.rb +128 -0
  198. data/lib/datadog/tracing/contrib/opensearch/quantize.rb +81 -0
  199. data/lib/datadog/tracing/contrib/pg/configuration/settings.rb +17 -14
  200. data/lib/datadog/tracing/contrib/pg/ext.rb +22 -19
  201. data/lib/datadog/tracing/contrib/pg/instrumentation.rb +9 -5
  202. data/lib/datadog/tracing/contrib/presto/configuration/settings.rb +14 -7
  203. data/lib/datadog/tracing/contrib/presto/ext.rb +25 -20
  204. data/lib/datadog/tracing/contrib/presto/instrumentation.rb +9 -5
  205. data/lib/datadog/tracing/contrib/propagation/sql_comment/ext.rb +12 -10
  206. data/lib/datadog/tracing/contrib/qless/configuration/settings.rb +12 -8
  207. data/lib/datadog/tracing/contrib/qless/ext.rb +14 -12
  208. data/lib/datadog/tracing/contrib/que/configuration/settings.rb +21 -12
  209. data/lib/datadog/tracing/contrib/racecar/configuration/settings.rb +9 -7
  210. data/lib/datadog/tracing/contrib/racecar/event.rb +0 -5
  211. data/lib/datadog/tracing/contrib/racecar/ext.rb +20 -18
  212. data/lib/datadog/tracing/contrib/rack/configuration/settings.rb +16 -12
  213. data/lib/datadog/tracing/contrib/rack/ext.rb +18 -16
  214. data/lib/datadog/tracing/contrib/rack/header_collection.rb +3 -0
  215. data/lib/datadog/tracing/contrib/rack/header_tagging.rb +53 -0
  216. data/lib/datadog/tracing/contrib/rack/middlewares.rb +8 -49
  217. data/lib/datadog/tracing/contrib/rails/configuration/settings.rb +15 -11
  218. data/lib/datadog/tracing/contrib/rails/ext.rb +7 -5
  219. data/lib/datadog/tracing/contrib/rails/log_injection.rb +7 -10
  220. data/lib/datadog/tracing/contrib/rails/patcher.rb +10 -41
  221. data/lib/datadog/tracing/contrib/rails/railtie.rb +3 -3
  222. data/lib/datadog/tracing/contrib/rake/configuration/settings.rb +12 -9
  223. data/lib/datadog/tracing/contrib/rake/ext.rb +14 -12
  224. data/lib/datadog/tracing/contrib/redis/configuration/settings.rb +17 -9
  225. data/lib/datadog/tracing/contrib/redis/ext.rb +22 -15
  226. data/lib/datadog/tracing/contrib/redis/tags.rb +9 -5
  227. data/lib/datadog/tracing/contrib/resque/configuration/settings.rb +13 -7
  228. data/lib/datadog/tracing/contrib/resque/ext.rb +9 -7
  229. data/lib/datadog/tracing/contrib/rest_client/configuration/settings.rb +16 -9
  230. data/lib/datadog/tracing/contrib/rest_client/ext.rb +15 -8
  231. data/lib/datadog/tracing/contrib/rest_client/request_patch.rb +20 -5
  232. data/lib/datadog/tracing/contrib/roda/configuration/settings.rb +9 -6
  233. data/lib/datadog/tracing/contrib/semantic_logger/configuration/settings.rb +3 -2
  234. data/lib/datadog/tracing/contrib/semantic_logger/ext.rb +3 -1
  235. data/lib/datadog/tracing/contrib/semantic_logger/instrumentation.rb +4 -20
  236. data/lib/datadog/tracing/contrib/sequel/configuration/settings.rb +9 -6
  237. data/lib/datadog/tracing/contrib/sequel/ext.rb +10 -8
  238. data/lib/datadog/tracing/contrib/sequel/utils.rb +2 -7
  239. data/lib/datadog/tracing/contrib/shoryuken/configuration/settings.rb +14 -8
  240. data/lib/datadog/tracing/contrib/shoryuken/ext.rb +14 -12
  241. data/lib/datadog/tracing/contrib/sidekiq/configuration/settings.rb +18 -11
  242. data/lib/datadog/tracing/contrib/sidekiq/ext.rb +32 -30
  243. data/lib/datadog/tracing/contrib/sinatra/configuration/settings.rb +11 -9
  244. data/lib/datadog/tracing/contrib/sinatra/env.rb +0 -17
  245. data/lib/datadog/tracing/contrib/sinatra/ext.rb +21 -19
  246. data/lib/datadog/tracing/contrib/sinatra/tracer_middleware.rb +3 -14
  247. data/lib/datadog/tracing/contrib/sneakers/configuration/settings.rb +14 -8
  248. data/lib/datadog/tracing/contrib/sneakers/ext.rb +1 -0
  249. data/lib/datadog/tracing/contrib/sneakers/tracer.rb +1 -1
  250. data/lib/datadog/tracing/contrib/span_attribute_schema.rb +74 -10
  251. data/lib/datadog/tracing/contrib/stripe/configuration/settings.rb +9 -6
  252. data/lib/datadog/tracing/contrib/sucker_punch/configuration/settings.rb +9 -6
  253. data/lib/datadog/tracing/contrib/sucker_punch/ext.rb +15 -13
  254. data/lib/datadog/tracing/contrib/utils/database.rb +5 -3
  255. data/lib/datadog/tracing/contrib/utils/quantization/http.rb +9 -9
  256. data/lib/datadog/tracing/contrib.rb +1 -0
  257. data/lib/datadog/tracing/correlation.rb +29 -12
  258. data/lib/datadog/tracing/diagnostics/environment_logger.rb +159 -0
  259. data/lib/datadog/tracing/diagnostics/ext.rb +21 -19
  260. data/lib/datadog/tracing/distributed/b3_multi.rb +2 -2
  261. data/lib/datadog/tracing/distributed/b3_single.rb +1 -1
  262. data/lib/datadog/tracing/distributed/trace_context.rb +52 -17
  263. data/lib/datadog/tracing/metadata/ext.rb +9 -6
  264. data/lib/datadog/tracing/remote.rb +78 -0
  265. data/lib/datadog/tracing/sampling/rule_sampler.rb +29 -0
  266. data/lib/datadog/tracing/span_operation.rb +3 -15
  267. data/lib/datadog/tracing/trace_operation.rb +16 -3
  268. data/lib/datadog/tracing/trace_segment.rb +5 -2
  269. data/lib/datadog/tracing/tracer.rb +10 -1
  270. data/lib/datadog/tracing/workers/trace_writer.rb +1 -1
  271. data/lib/ddtrace/transport/ext.rb +15 -9
  272. data/lib/ddtrace/transport/trace_formatter.rb +9 -0
  273. data/lib/ddtrace/version.rb +9 -12
  274. metadata +37 -6
  275. data/lib/datadog/tracing/contrib/sinatra/headers.rb +0 -35
@@ -15,7 +15,7 @@ module Datadog
15
15
  # The MJIT header was introduced on 2.6 and removed on 3.3; for other Rubies we rely on debase-ruby_core_source
16
16
  CAN_USE_MJIT_HEADER = RUBY_VERSION.start_with?('2.6', '2.7', '3.0.', '3.1.', '3.2.')
17
17
 
18
- LIBDATADOG_VERSION = '~> 2.0.0.1.0'
18
+ LIBDATADOG_VERSION = '~> 3.0.0.1.0'
19
19
 
20
20
  def self.fail_install_if_missing_extension?
21
21
  ENV[ENV_FAIL_INSTALL_IF_MISSING_EXTENSION].to_s.strip.downcase == 'true'
@@ -87,6 +87,7 @@ module Datadog
87
87
  on_unknown_os? ||
88
88
  on_unsupported_cpu_arch? ||
89
89
  on_unsupported_ruby_version? ||
90
+ on_ruby_3_3? ||
90
91
  expected_to_use_mjit_but_mjit_is_disabled? ||
91
92
  libdatadog_not_available? ||
92
93
  libdatadog_not_usable?
@@ -269,6 +270,20 @@ module Datadog
269
270
  ruby_version_not_supported if RUBY_VERSION.start_with?('2.1.', '2.2.')
270
271
  end
271
272
 
273
+ private_class_method def self.on_ruby_3_3?
274
+ incompatible_with_3_3 = explain_issue(
275
+ 'the profiler in the current version of ddtrace does not yet support',
276
+ 'Ruby version 3.3.',
277
+ '(See https://github.com/datadog/dd-trace-rb/issues/3053 for details).',
278
+ suggested: [
279
+ 'Try upgrading to the latest ddtrace, as this issue may have been',
280
+ 'fixed by now.',
281
+ ] + CONTACT_SUPPORT,
282
+ )
283
+
284
+ incompatible_with_3_3 if RUBY_VERSION.start_with?('3.3.')
285
+ end
286
+
272
287
  # On some Rubies, we require the mjit header to be present. If Ruby was installed without MJIT support, we also skip
273
288
  # building the extension.
274
289
  private_class_method def self.expected_to_use_mjit_but_mjit_is_disabled?
@@ -302,7 +302,8 @@ VALUE thread_name_for(VALUE thread) {
302
302
  // Taken from upstream vm_backtrace.c at commit 5f10bd634fb6ae8f74a4ea730176233b0ca96954 (March 2022, Ruby 3.2 trunk)
303
303
  // Copyright (C) 1993-2012 Yukihiro Matsumoto
304
304
  // to support our custom rb_profile_frames (see below)
305
- // Modifications: None
305
+ // Modifications:
306
+ // * Support int first_lineno for Ruby 3.2.0+ (https://github.com/ruby/ruby/pull/6430)
306
307
  //
307
308
  // `node_id` gets used depending on Ruby VM compilation settings (USE_ISEQ_NODE_ID being defined).
308
309
  // To avoid getting false "unused argument" warnings in setups where it's not used, we need to do this weird dance
@@ -322,7 +323,11 @@ calc_pos(const rb_iseq_t *iseq, const VALUE *pc, int *lineno, int *node_id)
322
323
  VM_ASSERT(! ISEQ_BODY(iseq)->local_table_size);
323
324
  return 0;
324
325
  }
325
- if (lineno) *lineno = FIX2INT(ISEQ_BODY(iseq)->location.first_lineno);
326
+ # ifndef NO_INT_FIRST_LINENO // Ruby 3.2+
327
+ if (lineno) *lineno = ISEQ_BODY(iseq)->location.first_lineno;
328
+ # else
329
+ if (lineno) *lineno = FIX2INT(ISEQ_BODY(iseq)->location.first_lineno);
330
+ #endif
326
331
  #ifdef USE_ISEQ_NODE_ID
327
332
  if (node_id) *node_id = -1;
328
333
  #endif
@@ -767,3 +772,37 @@ check_method_entry(VALUE obj, int can_be_svar)
767
772
  // they're always on the main Ractor
768
773
  bool ddtrace_rb_ractor_main_p(void) { return true; }
769
774
  #endif // NO_RACTORS
775
+
776
+ // This is a tweaked and inlined version of
777
+ // threadptr_invoke_proc_location + rb_proc_location + iseq_location .
778
+ //
779
+ // It's useful to have here because not all of the methods above are accessible to extensions + to avoid the
780
+ // array allocation that iseq_location did to contain its return value.
781
+ static const rb_iseq_t *maybe_thread_invoke_proc_iseq(VALUE thread_value) {
782
+ rb_thread_t *thread = thread_struct_from_object(thread_value);
783
+
784
+ #ifndef NO_THREAD_INVOKE_ARG // Ruby 2.6+
785
+ if (thread->invoke_type != thread_invoke_type_proc) return NULL;
786
+
787
+ VALUE proc = thread->invoke_arg.proc.proc;
788
+ #else
789
+ if (thread->first_func || !thread->first_proc) return NULL;
790
+
791
+ VALUE proc = thread->first_proc;
792
+ #endif
793
+
794
+ const rb_iseq_t *iseq = rb_proc_get_iseq(proc, 0);
795
+ if (iseq == NULL) return NULL;
796
+
797
+ rb_iseq_check(iseq);
798
+ return iseq;
799
+ }
800
+
801
+ VALUE invoke_location_for(VALUE thread, int *line_location) {
802
+ const rb_iseq_t *iseq = maybe_thread_invoke_proc_iseq(thread);
803
+
804
+ if (iseq == NULL) return Qnil;
805
+
806
+ *line_location = NUM2INT(rb_iseq_first_lineno(iseq));
807
+ return rb_iseq_path(iseq);
808
+ }
@@ -43,3 +43,9 @@ bool ddtrace_rb_ractor_main_p(void);
43
43
 
44
44
  // See comment on `record_placeholder_stack_in_native_code` for a full explanation of what this means (and why we don't just return 0)
45
45
  #define PLACEHOLDER_STACK_IN_NATIVE_CODE -1
46
+
47
+ // This method provides the file and line of the "invoke location" of a thread (first file:line of the block used to
48
+ // start the thread), if any.
49
+ // This is what Ruby shows in `Thread#to_s`.
50
+ // The file is returned directly, and the line is recorded onto *line_location.
51
+ VALUE invoke_location_for(VALUE thread, int *line_location);
@@ -6,6 +6,7 @@
6
6
  #include "stack_recorder.h"
7
7
  #include "libdatadog_helpers.h"
8
8
  #include "ruby_helpers.h"
9
+ #include "time_helpers.h"
9
10
 
10
11
  // Used to wrap a ddog_prof_Profile in a Ruby object and expose Ruby-level serialization APIs
11
12
  // This file implements the native bits of the Datadog::Profiling::StackRecorder class
@@ -208,7 +209,7 @@ static VALUE _native_active_slot(DDTRACE_UNUSED VALUE _self, VALUE recorder_inst
208
209
  static VALUE _native_is_slot_one_mutex_locked(DDTRACE_UNUSED VALUE _self, VALUE recorder_instance);
209
210
  static VALUE _native_is_slot_two_mutex_locked(DDTRACE_UNUSED VALUE _self, VALUE recorder_instance);
210
211
  static VALUE test_slot_mutex_state(VALUE recorder_instance, int slot);
211
- static ddog_Timespec time_now(void);
212
+ static ddog_Timespec system_epoch_now_timespec(void);
212
213
  static VALUE _native_reset_after_fork(DDTRACE_UNUSED VALUE self, VALUE recorder_instance);
213
214
  static void serializer_set_start_timestamp_for_next_profile(struct stack_recorder_state *state, ddog_Timespec timestamp);
214
215
  static VALUE _native_record_endpoint(DDTRACE_UNUSED VALUE _self, VALUE recorder_instance, VALUE local_root_span_id, VALUE endpoint);
@@ -347,7 +348,7 @@ static VALUE _native_serialize(DDTRACE_UNUSED VALUE _self, VALUE recorder_instan
347
348
  struct stack_recorder_state *state;
348
349
  TypedData_Get_Struct(recorder_instance, struct stack_recorder_state, &stack_recorder_typed_data, state);
349
350
 
350
- ddog_Timespec finish_timestamp = time_now();
351
+ ddog_Timespec finish_timestamp = system_epoch_now_timespec();
351
352
  // Need to do this while still holding on to the Global VM Lock; see comments on method for why
352
353
  serializer_set_start_timestamp_for_next_profile(state, finish_timestamp);
353
354
 
@@ -547,14 +548,9 @@ static VALUE test_slot_mutex_state(VALUE recorder_instance, int slot) {
547
548
  }
548
549
  }
549
550
 
550
- // Note that this is using CLOCK_REALTIME (e.g. actual time since unix epoch) and not the CLOCK_MONOTONIC as we use in
551
- // monotonic_wall_time_now_ns (used in other parts of the codebase)
552
- static ddog_Timespec time_now(void) {
553
- struct timespec current_time;
554
-
555
- if (clock_gettime(CLOCK_REALTIME, &current_time) != 0) ENFORCE_SUCCESS_GVL(errno);
556
-
557
- return (ddog_Timespec) {.seconds = current_time.tv_sec, .nanoseconds = (uint32_t) current_time.tv_nsec};
551
+ static ddog_Timespec system_epoch_now_timespec(void) {
552
+ long now_ns = system_epoch_time_now_ns(RAISE_ON_FAILURE);
553
+ return (ddog_Timespec) {.seconds = now_ns / SECONDS_AS_NS(1), .nanoseconds = now_ns % SECONDS_AS_NS(1)};
558
554
  }
559
555
 
560
556
  // After the Ruby VM forks, this method gets called in the child process to clean up any leftover state from the parent.
@@ -5,13 +5,49 @@
5
5
  #include "time_helpers.h"
6
6
 
7
7
  // Safety: This function is assumed never to raise exceptions by callers when raise_on_failure == false
8
- long monotonic_wall_time_now_ns(bool raise_on_failure) {
9
- struct timespec current_monotonic;
8
+ long retrieve_clock_as_ns(clockid_t clock_id, bool raise_on_failure) {
9
+ struct timespec clock_value;
10
10
 
11
- if (clock_gettime(CLOCK_MONOTONIC, &current_monotonic) != 0) {
11
+ if (clock_gettime(clock_id, &clock_value) != 0) {
12
12
  if (raise_on_failure) ENFORCE_SUCCESS_GVL(errno);
13
13
  return 0;
14
14
  }
15
15
 
16
- return current_monotonic.tv_nsec + SECONDS_AS_NS(current_monotonic.tv_sec);
16
+ return clock_value.tv_nsec + SECONDS_AS_NS(clock_value.tv_sec);
17
+ }
18
+
19
+ long monotonic_wall_time_now_ns(bool raise_on_failure) { return retrieve_clock_as_ns(CLOCK_MONOTONIC, raise_on_failure); }
20
+ long system_epoch_time_now_ns(bool raise_on_failure) { return retrieve_clock_as_ns(CLOCK_REALTIME, raise_on_failure); }
21
+
22
+ // Design: The monotonic_to_system_epoch_state struct is kept somewhere by the caller, and MUST be initialized to
23
+ // MONOTONIC_TO_SYSTEM_EPOCH_INITIALIZER.
24
+ //
25
+ // This function is used by the ThreadContext collector to convert monotonic wall time timestamps which are used
26
+ // basically everywhere else in the codebase, into system epoch timestamps, which are needed by the timeline feature.
27
+ //
28
+ // There's a few ways we could have tackled this conversion, e.g. check the system clock on every call, or even
29
+ // use system clock timestamps elsewhere in the code.
30
+ // Using a system clock elsewhere has a few disadvantages (e.g. because it can move around if users adjust the system
31
+ // time). I also wanted to avoid calling system_epoch_time_now_ns(...) on every conversion.
32
+ //
33
+ // Thus I arrived at this solution: we calculate a delta between the monotonic clock and the system clock, and use
34
+ // that to convert the timestamps.
35
+ //
36
+ // To avoid the results of the system clock being off in cases where the system clock is adjusted while the profiler
37
+ // is running, every ~60 seconds of observed monotonic wall time we recalculate the delta. This means that worst case
38
+ // we'll have ~60 seconds of wrongly-timestamped data when the system clock jumps around, and in return we save the
39
+ // overhead of having to look up the system clock on every call to this function.
40
+ long monotonic_to_system_epoch_ns(monotonic_to_system_epoch_state *state, long monotonic_wall_time_ns) {
41
+ bool reference_needs_update =
42
+ (state->system_epoch_ns_reference == INVALID_TIME) ||
43
+ (state->delta_to_epoch_ns + monotonic_wall_time_ns > state->system_epoch_ns_reference + SECONDS_AS_NS(60));
44
+
45
+ if (reference_needs_update) {
46
+ state->system_epoch_ns_reference = system_epoch_time_now_ns(RAISE_ON_FAILURE);
47
+ long current_monotonic_wall_time_ns = monotonic_wall_time_now_ns(RAISE_ON_FAILURE);
48
+
49
+ state->delta_to_epoch_ns = state->system_epoch_ns_reference - current_monotonic_wall_time_ns;
50
+ }
51
+
52
+ return state->delta_to_epoch_ns + monotonic_wall_time_ns;
17
53
  }
@@ -6,5 +6,19 @@
6
6
  #define RAISE_ON_FAILURE true
7
7
  #define DO_NOT_RAISE_ON_FAILURE false
8
8
 
9
+ #define INVALID_TIME -1
10
+
11
+ typedef struct {
12
+ long system_epoch_ns_reference;
13
+ long delta_to_epoch_ns;
14
+ } monotonic_to_system_epoch_state;
15
+
16
+ #define MONOTONIC_TO_SYSTEM_EPOCH_INITIALIZER {.system_epoch_ns_reference = INVALID_TIME, .delta_to_epoch_ns = INVALID_TIME}
17
+
9
18
  // Safety: This function is assumed never to raise exceptions by callers when raise_on_failure == false
10
19
  long monotonic_wall_time_now_ns(bool raise_on_failure);
20
+
21
+ // Safety: This function is assumed never to raise exceptions by callers when raise_on_failure == false
22
+ long system_epoch_time_now_ns(bool raise_on_failure);
23
+
24
+ long monotonic_to_system_epoch_ns(monotonic_to_system_epoch_state *state, long monotonic_wall_time_ns);
@@ -13,6 +13,15 @@ module Datadog
13
13
  return unless settings.respond_to?(:appsec) && settings.appsec.enabled
14
14
 
15
15
  processor = create_processor(settings)
16
+ # We want to always instrument user events when AppSec is enabled.
17
+ # There could be cases in which users use the DD_APPSEC_ENABLED Env variable to
18
+ # enable AppSec, in that case, Devise is already instrumented.
19
+ # In the case that users do not use DD_APPSEC_ENABLED, we have to instrument it,
20
+ # hence the lines above.
21
+
22
+ devise_integration = Datadog::AppSec::Contrib::Devise::Integration.new
23
+ settings.appsec.instrument(:devise) unless devise_integration.patcher.patched?
24
+
16
25
  new(processor: processor)
17
26
  end
18
27
 
@@ -1,223 +1,138 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'set'
3
+ require_relative '../../core/utils/duration'
4
4
 
5
5
  module Datadog
6
6
  module AppSec
7
7
  module Configuration
8
- # Configuration settings, acting as an integration registry
9
- # TODO: as with Configuration, this is a trivial implementation
10
- class Settings
11
- class << self
12
- def boolean
13
- # @type ^(::String) -> bool
14
- ->(v) do # rubocop:disable Style/Lambda
15
- case v
16
- when /(1|true)/i
17
- true
18
- when /(0|false)/i, nil
19
- false
20
- else
21
- raise ArgumentError, "invalid boolean: #{v.inspect}"
22
- end
23
- end
24
- end
25
-
26
- # TODO: allow symbols
27
- def string
28
- # @type ^(::String) -> ::String
29
- ->(v) { v.to_s }
30
- end
31
-
32
- def integer
33
- # @type ^(::String) -> ::Integer
34
- ->(v) do # rubocop:disable Style/Lambda
35
- case v
36
- when /(\d+)/
37
- Regexp.last_match(1).to_i
38
- else
39
- raise ArgumentError, "invalid integer: #{v.inspect}"
40
- end
41
- end
42
- end
43
-
44
- # rubocop:disable Metrics/MethodLength
45
- def duration(base = :ns, type = :integer)
46
- # @type ^(::String) -> ::Integer | ::Float
47
- ->(v) do # rubocop:disable Style/Lambda
48
- cast = case type
49
- when :integer, Integer
50
- method(:Integer)
51
- when :float, Float
52
- method(:Float)
53
- else
54
- raise ArgumentError, "invalid type: #{v.inspect}"
55
- end
56
-
57
- scale = case base
58
- when :s
59
- 1_000_000_000
60
- when :ms
61
- 1_000_000
62
- when :us
63
- 1000
64
- when :ns
65
- 1
66
- else
67
- raise ArgumentError, "invalid base: #{v.inspect}"
68
- end
69
-
70
- case v
71
- when /^(\d+)h$/
72
- cast.call(Regexp.last_match(1)) * 1_000_000_000 * 60 * 60 / scale
73
- when /^(\d+)m$/
74
- cast.call(Regexp.last_match(1)) * 1_000_000_000 * 60 / scale
75
- when /^(\d+)s$/
76
- cast.call(Regexp.last_match(1)) * 1_000_000_000 / scale
77
- when /^(\d+)ms$/
78
- cast.call(Regexp.last_match(1)) * 1_000_000 / scale
79
- when /^(\d+)us$/
80
- cast.call(Regexp.last_match(1)) * 1_000 / scale
81
- when /^(\d+)ns$/
82
- cast.call(Regexp.last_match(1)) / scale
83
- when /^(\d+)$/
84
- cast.call(Regexp.last_match(1))
85
- else
86
- raise ArgumentError, "invalid duration: #{v.inspect}"
87
- end
88
- end
89
- end
90
- # rubocop:enable Metrics/MethodLength
91
- end
92
-
8
+ # Settings
9
+ module Settings
93
10
  # rubocop:disable Layout/LineLength
94
11
  DEFAULT_OBFUSCATOR_KEY_REGEX = '(?i)(?:p(?:ass)?w(?:or)?d|pass(?:_?phrase)?|secret|(?:api_?|private_?|public_?)key)|token|consumer_?(?:id|key|secret)|sign(?:ed|ature)|bearer|authorization'
95
12
  DEFAULT_OBFUSCATOR_VALUE_REGEX = '(?i)(?:p(?:ass)?w(?:or)?d|pass(?:_?phrase)?|secret|(?:api_?|private_?|public_?|access_?|secret_?)key(?:_?id)?|token|consumer_?(?:id|key|secret)|sign(?:ed|ature)?|auth(?:entication|orization)?)(?:\s*=[^;]|"\s*:\s*"[^"]+")|bearer\s+[a-z0-9\._\-]+|token:[a-z0-9]{13}|gh[opsu]_[0-9a-zA-Z]{36}|ey[I-L][\w=-]+\.ey[I-L][\w=-]+(?:\.[\w.+\/=-]+)?|[\-]{5}BEGIN[a-z\s]+PRIVATE\sKEY[\-]{5}[^\-]+[\-]{5}END[a-z\s]+PRIVATE\sKEY|ssh-rsa\s*[a-z0-9\/\.+]{100,}'
96
13
  # rubocop:enable Layout/LineLength
97
-
98
- DEFAULTS = {
99
- enabled: false,
100
- ruleset: :recommended,
101
- waf_timeout: 5_000, # us
102
- waf_debug: false,
103
- trace_rate_limit: 100, # traces/s
104
- obfuscator_key_regex: DEFAULT_OBFUSCATOR_KEY_REGEX,
105
- obfuscator_value_regex: DEFAULT_OBFUSCATOR_VALUE_REGEX,
106
- }.freeze
107
-
108
- ENVS = {
109
- 'DD_APPSEC_ENABLED' => [:enabled, Settings.boolean],
110
- 'DD_APPSEC_RULES' => [:ruleset, Settings.string],
111
- 'DD_APPSEC_WAF_TIMEOUT' => [:waf_timeout, Settings.duration(:us)],
112
- 'DD_APPSEC_WAF_DEBUG' => [:waf_debug, Settings.boolean],
113
- 'DD_APPSEC_TRACE_RATE_LIMIT' => [:trace_rate_limit, Settings.integer],
114
- 'DD_APPSEC_OBFUSCATION_PARAMETER_KEY_REGEXP' => [:obfuscator_key_regex, Settings.string],
115
- 'DD_APPSEC_OBFUSCATION_PARAMETER_VALUE_REGEXP' => [:obfuscator_value_regex, Settings.string],
116
- }.freeze
117
-
118
- # Struct constant whisker cast for Steep
119
- Integration = _ = Struct.new(:integration) # rubocop:disable Naming/ConstantName
120
-
121
- def initialize
122
- @integrations = []
123
- # Stores which options have been configured using Datadog.configure block or ENV variables
124
- @configured = Set.new
125
- @options = DEFAULTS.dup.tap do |options|
126
- ENVS.each do |env, (key, conv)|
127
- if ENV[env]
128
- options[key] = conv.call(ENV[env])
129
- @configured << key
130
- end
131
- end
132
- end
133
- end
134
-
135
- def enabled
136
- # Cast for Steep
137
- _ = @options[:enabled]
138
- end
139
-
140
- def ruleset
141
- # Cast for Steep
142
- _ = @options[:ruleset]
14
+ APPSEC_VALID_TRACK_USER_EVENTS_MODE = [
15
+ 'safe',
16
+ 'extended'
17
+ ].freeze
18
+ APPSEC_VALID_TRACK_USER_EVENTS_ENABLED_VALUES = [
19
+ '1',
20
+ 'true'
21
+ ].concat(APPSEC_VALID_TRACK_USER_EVENTS_MODE).freeze
22
+
23
+ def self.extended(base)
24
+ base = base.singleton_class unless base.is_a?(Class)
25
+ add_settings!(base)
143
26
  end
144
27
 
145
- # EXPERIMENTAL: This configurable is not meant to be publicly used, but
146
- # is very useful for testing. It may change at any point in time.
147
- def ip_denylist
148
- # Cast for Steep
149
- _ = @options[:ip_denylist] || []
150
- end
28
+ # rubocop:disable Metrics/AbcSize,Metrics/MethodLength,Metrics/BlockLength
29
+ def self.add_settings!(base)
30
+ base.class_eval do
31
+ settings :appsec do
32
+ option :enabled do |o|
33
+ o.type :bool
34
+ o.env 'DD_APPSEC_ENABLED'
35
+ o.default false
36
+ end
151
37
 
152
- # EXPERIMENTAL: This configurable is not meant to be publicly used, but
153
- # is very useful for testing. It may change at any point in time.
154
- def user_id_denylist
155
- # Cast for Steep
156
- _ = @options[:user_id_denylist] || []
157
- end
38
+ define_method(:instrument) do |integration_name|
39
+ if enabled
40
+ registered_integration = Datadog::AppSec::Contrib::Integration.registry[integration_name]
41
+ if registered_integration
42
+ klass = registered_integration.klass
43
+ if klass.loaded? && klass.compatible?
44
+ instance = klass.new
45
+ instance.patcher.patch unless instance.patcher.patched?
46
+ end
47
+ end
48
+ end
49
+ end
158
50
 
159
- def waf_timeout
160
- # Cast for Steep
161
- _ = @options[:waf_timeout]
162
- end
51
+ option :ruleset do |o|
52
+ o.env 'DD_APPSEC_RULES'
53
+ o.default :recommended
54
+ end
163
55
 
164
- def waf_debug
165
- # Cast for Steep
166
- _ = @options[:waf_debug]
167
- end
56
+ option :ip_denylist do |o|
57
+ o.type :array
58
+ o.default []
59
+ end
168
60
 
169
- def trace_rate_limit
170
- # Cast for Steep
171
- _ = @options[:trace_rate_limit]
172
- end
61
+ option :user_id_denylist do |o|
62
+ o.type :array
63
+ o.default []
64
+ end
173
65
 
174
- def obfuscator_key_regex
175
- # Cast for Steep
176
- _ = @options[:obfuscator_key_regex]
177
- end
66
+ option :waf_timeout do |o|
67
+ o.env 'DD_APPSEC_WAF_TIMEOUT' # us
68
+ o.default 5_000
69
+ o.setter do |v|
70
+ Datadog::Core::Utils::Duration.call(v.to_s, base: :us)
71
+ end
72
+ end
178
73
 
179
- def obfuscator_value_regex
180
- # Cast for Steep
181
- _ = @options[:obfuscator_value_regex]
182
- end
74
+ option :waf_debug do |o|
75
+ o.env 'DD_APPSEC_WAF_DEBUG'
76
+ o.default false
77
+ o.type :bool
78
+ end
183
79
 
184
- def merge(dsl)
185
- dsl.options.each do |k, v|
186
- unless v.nil?
187
- @options[k] = v
188
- @configured << k
189
- end
190
- end
80
+ option :trace_rate_limit do |o|
81
+ o.type :int
82
+ o.env 'DD_APPSEC_TRACE_RATE_LIMIT' # trace/s
83
+ o.default 100
84
+ end
191
85
 
192
- return self unless @options[:enabled]
86
+ option :obfuscator_key_regex do |o|
87
+ o.type :string
88
+ o.env 'DD_APPSEC_OBFUSCATION_PARAMETER_KEY_REGEXP'
89
+ o.default DEFAULT_OBFUSCATOR_KEY_REGEX
90
+ end
193
91
 
194
- # patcher.patch may call configure again, hence merge might be called again so it needs to be reentrant
195
- dsl.instruments.each do |instrument|
196
- # TODO: error handling
197
- registered_integration = Datadog::AppSec::Contrib::Integration.registry[instrument.name]
198
- @integrations << Integration.new(registered_integration)
92
+ option :obfuscator_value_regex do |o|
93
+ o.type :string
94
+ o.env 'DD_APPSEC_OBFUSCATION_PARAMETER_VALUE_REGEXP'
95
+ o.default DEFAULT_OBFUSCATOR_VALUE_REGEX
96
+ end
199
97
 
200
- # TODO: move to a separate apply step
201
- klass = registered_integration.klass
202
- if klass.loaded? && klass.compatible?
203
- instance = klass.new
204
- instance.patcher.patch
98
+ settings :track_user_events do
99
+ option :enabled do |o|
100
+ o.default true
101
+ o.type :bool
102
+ o.env 'DD_APPSEC_AUTOMATED_USER_EVENTS_TRACKING'
103
+ o.env_parser do |env_value|
104
+ if env_value == 'disabled'
105
+ false
106
+ else
107
+ APPSEC_VALID_TRACK_USER_EVENTS_ENABLED_VALUES.include?(env_value.strip.downcase)
108
+ end
109
+ end
110
+ end
111
+
112
+ option :mode do |o|
113
+ o.type :string
114
+ o.env 'DD_APPSEC_AUTOMATED_USER_EVENTS_TRACKING'
115
+ o.default 'safe'
116
+ o.setter do |v|
117
+ if APPSEC_VALID_TRACK_USER_EVENTS_MODE.include?(v)
118
+ v
119
+ elsif v == 'disabled'
120
+ 'safe'
121
+ else
122
+ Datadog.logger.warn(
123
+ 'The appsec.track_user_events.mode value provided is not supported.' \
124
+ 'Supported values are: safe | extended.' \
125
+ 'Using default value `safe`'
126
+ )
127
+ 'safe'
128
+ end
129
+ end
130
+ end
131
+ end
205
132
  end
206
133
  end
207
-
208
- self
209
- end
210
-
211
- private
212
-
213
- def default?(option)
214
- !@configured.include?(option)
215
- end
216
-
217
- # Restore to original state, for testing only.
218
- def reset!
219
- initialize
220
134
  end
135
+ # rubocop:enable Metrics/AbcSize,Metrics/MethodLength,Metrics/BlockLength
221
136
  end
222
137
  end
223
138
  end
@@ -5,86 +5,7 @@ require_relative 'configuration/settings'
5
5
  module Datadog
6
6
  module AppSec
7
7
  # Configuration for AppSec
8
- # TODO: this is a trivial implementation, check with shareable code with
9
- # tracer and other products
10
8
  module Configuration
11
- def self.included(base)
12
- base.extend(ClassMethods)
13
- end
14
-
15
- # Configuration DSL implementation
16
- class DSL
17
- # Struct constant whisker cast for Steep
18
- Instrument = _ = Struct.new(:name) # rubocop:disable Naming/ConstantName
19
-
20
- def initialize
21
- @instruments = []
22
- @options = {}
23
- end
24
-
25
- attr_reader :instruments, :options
26
-
27
- def instrument(name)
28
- @instruments << Instrument.new(name)
29
- end
30
-
31
- def enabled=(value)
32
- options[:enabled] = value
33
- end
34
-
35
- def ruleset=(value)
36
- options[:ruleset] = value
37
- end
38
-
39
- def ip_denylist=(value)
40
- options[:ip_denylist] = value
41
- end
42
-
43
- def user_id_denylist=(value)
44
- options[:user_id_denylist] = value
45
- end
46
-
47
- # in microseconds
48
- def waf_timeout=(value)
49
- options[:waf_timeout] = value
50
- end
51
-
52
- def waf_debug=(value)
53
- options[:waf_debug] = value
54
- end
55
-
56
- def trace_rate_limit=(value)
57
- options[:trace_rate_limit] = value
58
- end
59
-
60
- def obfuscator_key_regex=(value)
61
- options[:obfuscator_key_regex] = value
62
- end
63
-
64
- def obfuscator_value_regex=(value)
65
- options[:obfuscator_value_regex] = value
66
- end
67
- end
68
-
69
- # class-level methods for Configuration
70
- module ClassMethods
71
- def configure
72
- dsl = DSL.new
73
- yield dsl
74
- settings.merge(dsl)
75
- settings
76
- end
77
-
78
- def settings
79
- @settings ||= Settings.new
80
- end
81
-
82
- private
83
-
84
- def default_setting?(setting)
85
- settings.send(:default?, setting)
86
- end
87
- end
88
9
  end
89
10
  end
90
11
  end