datadog 2.7.1 → 2.17.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 (417) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +310 -1
  3. data/ext/datadog_profiling_native_extension/clock_id.h +2 -2
  4. data/ext/datadog_profiling_native_extension/collectors_cpu_and_wall_time_worker.c +66 -56
  5. data/ext/datadog_profiling_native_extension/collectors_discrete_dynamic_sampler.c +1 -1
  6. data/ext/datadog_profiling_native_extension/collectors_discrete_dynamic_sampler.h +1 -1
  7. data/ext/datadog_profiling_native_extension/collectors_idle_sampling_helper.c +16 -16
  8. data/ext/datadog_profiling_native_extension/collectors_stack.c +10 -10
  9. data/ext/datadog_profiling_native_extension/collectors_stack.h +2 -2
  10. data/ext/datadog_profiling_native_extension/collectors_thread_context.c +314 -145
  11. data/ext/datadog_profiling_native_extension/datadog_ruby_common.c +1 -4
  12. data/ext/datadog_profiling_native_extension/datadog_ruby_common.h +10 -0
  13. data/ext/datadog_profiling_native_extension/encoded_profile.c +79 -0
  14. data/ext/datadog_profiling_native_extension/encoded_profile.h +8 -0
  15. data/ext/datadog_profiling_native_extension/extconf.rb +7 -8
  16. data/ext/datadog_profiling_native_extension/gvl_profiling_helper.c +2 -0
  17. data/ext/datadog_profiling_native_extension/gvl_profiling_helper.h +0 -8
  18. data/ext/datadog_profiling_native_extension/heap_recorder.c +61 -174
  19. data/ext/datadog_profiling_native_extension/heap_recorder.h +2 -2
  20. data/ext/datadog_profiling_native_extension/http_transport.c +64 -98
  21. data/ext/datadog_profiling_native_extension/private_vm_api_access.c +68 -1
  22. data/ext/datadog_profiling_native_extension/private_vm_api_access.h +10 -1
  23. data/ext/datadog_profiling_native_extension/profiling.c +19 -8
  24. data/ext/datadog_profiling_native_extension/ruby_helpers.c +8 -8
  25. data/ext/datadog_profiling_native_extension/stack_recorder.c +84 -131
  26. data/ext/datadog_profiling_native_extension/stack_recorder.h +2 -2
  27. data/ext/datadog_profiling_native_extension/time_helpers.h +1 -1
  28. data/ext/datadog_profiling_native_extension/unsafe_api_calls_check.c +47 -0
  29. data/ext/datadog_profiling_native_extension/unsafe_api_calls_check.h +31 -0
  30. data/ext/libdatadog_api/crashtracker.c +17 -15
  31. data/ext/libdatadog_api/crashtracker.h +5 -0
  32. data/ext/libdatadog_api/datadog_ruby_common.c +1 -4
  33. data/ext/libdatadog_api/datadog_ruby_common.h +10 -0
  34. data/ext/libdatadog_api/init.c +15 -0
  35. data/ext/libdatadog_api/library_config.c +122 -0
  36. data/ext/libdatadog_api/library_config.h +19 -0
  37. data/ext/libdatadog_api/macos_development.md +3 -3
  38. data/ext/libdatadog_api/process_discovery.c +117 -0
  39. data/ext/libdatadog_api/process_discovery.h +5 -0
  40. data/ext/libdatadog_extconf_helpers.rb +1 -1
  41. data/lib/datadog/appsec/actions_handler/serializable_backtrace.rb +89 -0
  42. data/lib/datadog/appsec/actions_handler.rb +49 -0
  43. data/lib/datadog/appsec/anonymizer.rb +16 -0
  44. data/lib/datadog/appsec/api_security/lru_cache.rb +49 -0
  45. data/lib/datadog/appsec/api_security.rb +9 -0
  46. data/lib/datadog/appsec/assets/waf_rules/README.md +50 -5
  47. data/lib/datadog/appsec/assets/waf_rules/processors.json +239 -10
  48. data/lib/datadog/appsec/assets/waf_rules/recommended.json +355 -157
  49. data/lib/datadog/appsec/assets/waf_rules/scanners.json +926 -17
  50. data/lib/datadog/appsec/assets/waf_rules/strict.json +62 -32
  51. data/lib/datadog/appsec/autoload.rb +1 -1
  52. data/lib/datadog/appsec/component.rb +41 -33
  53. data/lib/datadog/appsec/compressed_json.rb +40 -0
  54. data/lib/datadog/appsec/configuration/settings.rb +152 -25
  55. data/lib/datadog/appsec/context.rb +74 -0
  56. data/lib/datadog/appsec/contrib/active_record/instrumentation.rb +92 -0
  57. data/lib/datadog/appsec/contrib/active_record/integration.rb +41 -0
  58. data/lib/datadog/appsec/contrib/active_record/patcher.rb +101 -0
  59. data/lib/datadog/appsec/contrib/auto_instrument.rb +1 -1
  60. data/lib/datadog/appsec/contrib/devise/configuration.rb +52 -0
  61. data/lib/datadog/appsec/contrib/devise/data_extractor.rb +78 -0
  62. data/lib/datadog/appsec/contrib/devise/ext.rb +22 -0
  63. data/lib/datadog/appsec/contrib/devise/integration.rb +1 -2
  64. data/lib/datadog/appsec/contrib/devise/patcher.rb +33 -25
  65. data/lib/datadog/appsec/contrib/devise/patches/signin_tracking_patch.rb +102 -0
  66. data/lib/datadog/appsec/contrib/devise/patches/signup_tracking_patch.rb +69 -0
  67. data/lib/datadog/appsec/contrib/devise/{patcher/rememberable_patch.rb → patches/skip_signin_tracking_patch.rb} +3 -3
  68. data/lib/datadog/appsec/contrib/devise/tracking_middleware.rb +106 -0
  69. data/lib/datadog/appsec/contrib/excon/integration.rb +41 -0
  70. data/lib/datadog/appsec/contrib/excon/patcher.rb +28 -0
  71. data/lib/datadog/appsec/contrib/excon/ssrf_detection_middleware.rb +42 -0
  72. data/lib/datadog/appsec/contrib/faraday/connection_patch.rb +22 -0
  73. data/lib/datadog/appsec/contrib/faraday/integration.rb +42 -0
  74. data/lib/datadog/appsec/contrib/faraday/patcher.rb +53 -0
  75. data/lib/datadog/appsec/contrib/faraday/rack_builder_patch.rb +22 -0
  76. data/lib/datadog/appsec/contrib/faraday/ssrf_detection_middleware.rb +41 -0
  77. data/lib/datadog/appsec/contrib/graphql/appsec_trace.rb +1 -7
  78. data/lib/datadog/appsec/contrib/graphql/gateway/watcher.rb +17 -30
  79. data/lib/datadog/appsec/contrib/graphql/integration.rb +1 -1
  80. data/lib/datadog/appsec/contrib/graphql/patcher.rb +0 -3
  81. data/lib/datadog/appsec/contrib/rack/ext.rb +34 -0
  82. data/lib/datadog/appsec/contrib/rack/gateway/response.rb +3 -3
  83. data/lib/datadog/appsec/contrib/rack/gateway/watcher.rb +78 -98
  84. data/lib/datadog/appsec/contrib/rack/integration.rb +1 -1
  85. data/lib/datadog/appsec/contrib/rack/patcher.rb +0 -3
  86. data/lib/datadog/appsec/contrib/rack/request_body_middleware.rb +10 -11
  87. data/lib/datadog/appsec/contrib/rack/request_middleware.rb +52 -68
  88. data/lib/datadog/appsec/contrib/rails/gateway/watcher.rb +16 -33
  89. data/lib/datadog/appsec/contrib/rails/integration.rb +1 -1
  90. data/lib/datadog/appsec/contrib/rails/patcher.rb +25 -38
  91. data/lib/datadog/appsec/contrib/rest_client/integration.rb +45 -0
  92. data/lib/datadog/appsec/contrib/rest_client/patcher.rb +28 -0
  93. data/lib/datadog/appsec/contrib/rest_client/request_ssrf_detection_patch.rb +38 -0
  94. data/lib/datadog/appsec/contrib/sinatra/gateway/watcher.rb +31 -68
  95. data/lib/datadog/appsec/contrib/sinatra/integration.rb +1 -1
  96. data/lib/datadog/appsec/contrib/sinatra/patcher.rb +5 -31
  97. data/lib/datadog/appsec/event.rb +96 -135
  98. data/lib/datadog/appsec/ext.rb +12 -3
  99. data/lib/datadog/appsec/instrumentation/gateway/argument.rb +7 -2
  100. data/lib/datadog/appsec/instrumentation/gateway/middleware.rb +24 -0
  101. data/lib/datadog/appsec/instrumentation/gateway.rb +17 -22
  102. data/lib/datadog/appsec/metrics/collector.rb +38 -0
  103. data/lib/datadog/appsec/metrics/exporter.rb +35 -0
  104. data/lib/datadog/appsec/metrics/telemetry.rb +23 -0
  105. data/lib/datadog/appsec/metrics.rb +13 -0
  106. data/lib/datadog/appsec/monitor/gateway/watcher.rb +52 -32
  107. data/lib/datadog/appsec/processor/rule_loader.rb +26 -31
  108. data/lib/datadog/appsec/processor/rule_merger.rb +7 -6
  109. data/lib/datadog/appsec/processor.rb +5 -4
  110. data/lib/datadog/appsec/remote.rb +26 -12
  111. data/lib/datadog/appsec/response.rb +19 -85
  112. data/lib/datadog/appsec/security_engine/result.rb +67 -0
  113. data/lib/datadog/appsec/security_engine/runner.rb +88 -0
  114. data/lib/datadog/appsec/security_engine.rb +9 -0
  115. data/lib/datadog/appsec/security_event.rb +39 -0
  116. data/lib/datadog/appsec/utils.rb +0 -2
  117. data/lib/datadog/appsec.rb +23 -10
  118. data/lib/datadog/auto_instrument.rb +3 -0
  119. data/lib/datadog/core/buffer/random.rb +18 -2
  120. data/lib/datadog/core/configuration/agent_settings_resolver.rb +42 -14
  121. data/lib/datadog/core/configuration/agentless_settings_resolver.rb +176 -0
  122. data/lib/datadog/core/configuration/components.rb +76 -32
  123. data/lib/datadog/core/configuration/components_state.rb +23 -0
  124. data/lib/datadog/core/configuration/ext.rb +5 -1
  125. data/lib/datadog/core/configuration/option.rb +79 -43
  126. data/lib/datadog/core/configuration/option_definition.rb +6 -4
  127. data/lib/datadog/core/configuration/options.rb +3 -3
  128. data/lib/datadog/core/configuration/settings.rb +100 -41
  129. data/lib/datadog/core/configuration/stable_config.rb +23 -0
  130. data/lib/datadog/core/configuration.rb +43 -11
  131. data/lib/datadog/{tracing → core}/contrib/rails/utils.rb +1 -3
  132. data/lib/datadog/core/crashtracking/component.rb +4 -13
  133. data/lib/datadog/core/diagnostics/environment_logger.rb +1 -1
  134. data/lib/datadog/core/encoding.rb +17 -1
  135. data/lib/datadog/core/environment/agent_info.rb +78 -0
  136. data/lib/datadog/core/environment/cgroup.rb +10 -12
  137. data/lib/datadog/core/environment/container.rb +38 -40
  138. data/lib/datadog/core/environment/ext.rb +6 -6
  139. data/lib/datadog/core/environment/git.rb +1 -0
  140. data/lib/datadog/core/environment/identity.rb +3 -3
  141. data/lib/datadog/core/environment/platform.rb +3 -3
  142. data/lib/datadog/core/environment/variable_helpers.rb +1 -1
  143. data/lib/datadog/core/error.rb +11 -9
  144. data/lib/datadog/core/logger.rb +2 -2
  145. data/lib/datadog/core/metrics/client.rb +27 -27
  146. data/lib/datadog/core/metrics/logging.rb +5 -5
  147. data/lib/datadog/core/process_discovery.rb +32 -0
  148. data/lib/datadog/core/rate_limiter.rb +4 -2
  149. data/lib/datadog/core/remote/client/capabilities.rb +6 -0
  150. data/lib/datadog/core/remote/client.rb +107 -92
  151. data/lib/datadog/core/remote/component.rb +18 -19
  152. data/lib/datadog/core/remote/configuration/digest.rb +7 -7
  153. data/lib/datadog/core/remote/configuration/path.rb +1 -1
  154. data/lib/datadog/core/remote/configuration/repository.rb +2 -1
  155. data/lib/datadog/core/remote/negotiation.rb +9 -9
  156. data/lib/datadog/core/remote/transport/config.rb +4 -3
  157. data/lib/datadog/core/remote/transport/http/api.rb +13 -18
  158. data/lib/datadog/core/remote/transport/http/client.rb +5 -4
  159. data/lib/datadog/core/remote/transport/http/config.rb +27 -55
  160. data/lib/datadog/core/remote/transport/http/negotiation.rb +8 -51
  161. data/lib/datadog/core/remote/transport/http.rb +25 -94
  162. data/lib/datadog/core/remote/transport/negotiation.rb +17 -4
  163. data/lib/datadog/core/remote/worker.rb +10 -7
  164. data/lib/datadog/core/runtime/metrics.rb +12 -5
  165. data/lib/datadog/core/telemetry/component.rb +84 -49
  166. data/lib/datadog/core/telemetry/emitter.rb +23 -11
  167. data/lib/datadog/core/telemetry/event/app_client_configuration_change.rb +65 -0
  168. data/lib/datadog/core/telemetry/event/app_closing.rb +18 -0
  169. data/lib/datadog/core/telemetry/event/app_dependencies_loaded.rb +33 -0
  170. data/lib/datadog/core/telemetry/event/app_heartbeat.rb +18 -0
  171. data/lib/datadog/core/telemetry/event/app_integrations_change.rb +58 -0
  172. data/lib/datadog/core/telemetry/event/app_started.rb +179 -0
  173. data/lib/datadog/core/telemetry/event/base.rb +40 -0
  174. data/lib/datadog/core/telemetry/event/distributions.rb +18 -0
  175. data/lib/datadog/core/telemetry/event/generate_metrics.rb +43 -0
  176. data/lib/datadog/core/telemetry/event/log.rb +76 -0
  177. data/lib/datadog/core/telemetry/event/message_batch.rb +42 -0
  178. data/lib/datadog/core/telemetry/event/synth_app_client_configuration_change.rb +43 -0
  179. data/lib/datadog/core/telemetry/event.rb +17 -383
  180. data/lib/datadog/core/telemetry/ext.rb +1 -0
  181. data/lib/datadog/core/telemetry/http/adapters/net.rb +12 -97
  182. data/lib/datadog/core/telemetry/logger.rb +1 -1
  183. data/lib/datadog/core/telemetry/logging.rb +2 -2
  184. data/lib/datadog/core/telemetry/metric.rb +28 -6
  185. data/lib/datadog/core/telemetry/request.rb +4 -4
  186. data/lib/datadog/core/telemetry/transport/http/api.rb +43 -0
  187. data/lib/datadog/core/telemetry/transport/http/client.rb +49 -0
  188. data/lib/datadog/core/telemetry/transport/http/telemetry.rb +92 -0
  189. data/lib/datadog/core/telemetry/transport/http.rb +63 -0
  190. data/lib/datadog/core/telemetry/transport/telemetry.rb +51 -0
  191. data/lib/datadog/core/telemetry/worker.rb +128 -25
  192. data/lib/datadog/core/transport/http/adapters/test.rb +2 -1
  193. data/lib/datadog/core/transport/http/adapters/unix_socket.rb +1 -1
  194. data/lib/datadog/{tracing → core}/transport/http/api/instance.rb +18 -1
  195. data/lib/datadog/core/transport/http/api/spec.rb +36 -0
  196. data/lib/datadog/{tracing → core}/transport/http/builder.rb +53 -31
  197. data/lib/datadog/core/transport/http.rb +75 -0
  198. data/lib/datadog/core/transport/response.rb +4 -0
  199. data/lib/datadog/core/utils/at_fork_monkey_patch.rb +6 -6
  200. data/lib/datadog/core/utils/duration.rb +32 -32
  201. data/lib/datadog/core/utils/forking.rb +2 -2
  202. data/lib/datadog/core/utils/network.rb +6 -6
  203. data/lib/datadog/core/utils/only_once_successful.rb +16 -5
  204. data/lib/datadog/core/utils/time.rb +20 -0
  205. data/lib/datadog/core/utils/truncation.rb +21 -0
  206. data/lib/datadog/core/vendor/multipart-post/multipart/post/composite_read_io.rb +1 -1
  207. data/lib/datadog/core/vendor/multipart-post/multipart/post/multipartable.rb +8 -8
  208. data/lib/datadog/core/vendor/multipart-post/multipart/post/parts.rb +7 -7
  209. data/lib/datadog/core/worker.rb +1 -1
  210. data/lib/datadog/core/workers/async.rb +29 -12
  211. data/lib/datadog/core/workers/interval_loop.rb +12 -1
  212. data/lib/datadog/core/workers/runtime_metrics.rb +2 -2
  213. data/lib/datadog/core.rb +8 -0
  214. data/lib/datadog/di/base.rb +115 -0
  215. data/lib/datadog/di/boot.rb +34 -0
  216. data/lib/datadog/di/code_tracker.rb +26 -15
  217. data/lib/datadog/di/component.rb +23 -14
  218. data/lib/datadog/di/configuration/settings.rb +25 -1
  219. data/lib/datadog/di/contrib/active_record.rb +1 -0
  220. data/lib/datadog/di/contrib/railtie.rb +15 -0
  221. data/lib/datadog/di/contrib.rb +28 -0
  222. data/lib/datadog/di/error.rb +5 -0
  223. data/lib/datadog/di/instrumenter.rb +111 -20
  224. data/lib/datadog/di/logger.rb +30 -0
  225. data/lib/datadog/di/preload.rb +18 -0
  226. data/lib/datadog/di/probe.rb +14 -7
  227. data/lib/datadog/di/probe_builder.rb +1 -0
  228. data/lib/datadog/di/probe_manager.rb +11 -5
  229. data/lib/datadog/di/probe_notification_builder.rb +34 -8
  230. data/lib/datadog/di/probe_notifier_worker.rb +52 -26
  231. data/lib/datadog/di/redactor.rb +0 -1
  232. data/lib/datadog/di/remote.rb +147 -0
  233. data/lib/datadog/di/serializer.rb +14 -7
  234. data/lib/datadog/di/transport/diagnostics.rb +62 -0
  235. data/lib/datadog/di/transport/http/api.rb +42 -0
  236. data/lib/datadog/di/transport/http/client.rb +47 -0
  237. data/lib/datadog/di/transport/http/diagnostics.rb +65 -0
  238. data/lib/datadog/di/transport/http/input.rb +67 -0
  239. data/lib/datadog/di/transport/http.rb +57 -0
  240. data/lib/datadog/di/transport/input.rb +62 -0
  241. data/lib/datadog/di/utils.rb +103 -0
  242. data/lib/datadog/di.rb +14 -76
  243. data/lib/datadog/error_tracking/collector.rb +87 -0
  244. data/lib/datadog/error_tracking/component.rb +167 -0
  245. data/lib/datadog/error_tracking/configuration/settings.rb +63 -0
  246. data/lib/datadog/error_tracking/configuration.rb +11 -0
  247. data/lib/datadog/error_tracking/ext.rb +18 -0
  248. data/lib/datadog/error_tracking/extensions.rb +16 -0
  249. data/lib/datadog/error_tracking/filters.rb +77 -0
  250. data/lib/datadog/error_tracking.rb +18 -0
  251. data/lib/datadog/kit/appsec/events.rb +15 -3
  252. data/lib/datadog/kit/identity.rb +9 -5
  253. data/lib/datadog/opentelemetry/api/baggage.rb +90 -0
  254. data/lib/datadog/opentelemetry/api/baggage.rbs +26 -0
  255. data/lib/datadog/opentelemetry/api/context.rb +16 -2
  256. data/lib/datadog/opentelemetry/sdk/trace/span.rb +1 -1
  257. data/lib/datadog/opentelemetry.rb +2 -1
  258. data/lib/datadog/profiling/collectors/code_provenance.rb +1 -1
  259. data/lib/datadog/profiling/collectors/info.rb +3 -0
  260. data/lib/datadog/profiling/collectors/thread_context.rb +1 -1
  261. data/lib/datadog/profiling/component.rb +60 -76
  262. data/lib/datadog/profiling/encoded_profile.rb +11 -0
  263. data/lib/datadog/profiling/exporter.rb +3 -4
  264. data/lib/datadog/profiling/ext.rb +0 -2
  265. data/lib/datadog/profiling/flush.rb +5 -8
  266. data/lib/datadog/profiling/http_transport.rb +6 -85
  267. data/lib/datadog/profiling/load_native_extension.rb +1 -33
  268. data/lib/datadog/profiling/scheduler.rb +8 -1
  269. data/lib/datadog/profiling/stack_recorder.rb +4 -4
  270. data/lib/datadog/profiling/tag_builder.rb +1 -5
  271. data/lib/datadog/profiling.rb +6 -2
  272. data/lib/datadog/tracing/analytics.rb +1 -1
  273. data/lib/datadog/tracing/component.rb +16 -12
  274. data/lib/datadog/tracing/configuration/ext.rb +8 -1
  275. data/lib/datadog/tracing/configuration/settings.rb +22 -10
  276. data/lib/datadog/tracing/context_provider.rb +1 -1
  277. data/lib/datadog/tracing/contrib/action_cable/integration.rb +5 -2
  278. data/lib/datadog/tracing/contrib/action_mailer/integration.rb +6 -2
  279. data/lib/datadog/tracing/contrib/action_pack/integration.rb +5 -2
  280. data/lib/datadog/tracing/contrib/action_view/integration.rb +5 -2
  281. data/lib/datadog/tracing/contrib/active_job/integration.rb +5 -2
  282. data/lib/datadog/tracing/contrib/active_record/integration.rb +7 -3
  283. data/lib/datadog/tracing/contrib/active_support/cache/events/cache.rb +7 -2
  284. data/lib/datadog/tracing/contrib/active_support/cache/instrumentation.rb +36 -1
  285. data/lib/datadog/tracing/contrib/active_support/cache/patcher.rb +4 -0
  286. data/lib/datadog/tracing/contrib/active_support/cache/redis.rb +14 -4
  287. data/lib/datadog/tracing/contrib/active_support/configuration/settings.rb +10 -0
  288. data/lib/datadog/tracing/contrib/active_support/integration.rb +5 -2
  289. data/lib/datadog/tracing/contrib/auto_instrument.rb +2 -2
  290. data/lib/datadog/tracing/contrib/aws/instrumentation.rb +10 -0
  291. data/lib/datadog/tracing/contrib/aws/integration.rb +3 -0
  292. data/lib/datadog/tracing/contrib/aws/parsed_context.rb +5 -1
  293. data/lib/datadog/tracing/contrib/concurrent_ruby/integration.rb +3 -0
  294. data/lib/datadog/tracing/contrib/configuration/settings.rb +1 -1
  295. data/lib/datadog/tracing/contrib/elasticsearch/configuration/settings.rb +4 -0
  296. data/lib/datadog/tracing/contrib/elasticsearch/patcher.rb +6 -1
  297. data/lib/datadog/tracing/contrib/ethon/easy_patch.rb +4 -5
  298. data/lib/datadog/tracing/contrib/excon/middleware.rb +5 -3
  299. data/lib/datadog/tracing/contrib/ext.rb +1 -0
  300. data/lib/datadog/tracing/contrib/extensions.rb +29 -3
  301. data/lib/datadog/tracing/contrib/faraday/middleware.rb +5 -3
  302. data/lib/datadog/tracing/contrib/graphql/configuration/error_extension_env_parser.rb +21 -0
  303. data/lib/datadog/tracing/contrib/graphql/configuration/settings.rb +11 -0
  304. data/lib/datadog/tracing/contrib/graphql/ext.rb +5 -0
  305. data/lib/datadog/tracing/contrib/graphql/unified_trace.rb +102 -11
  306. data/lib/datadog/tracing/contrib/grpc/datadog_interceptor/client.rb +7 -1
  307. data/lib/datadog/tracing/contrib/grpc/distributed/propagation.rb +3 -0
  308. data/lib/datadog/tracing/contrib/http/circuit_breaker.rb +0 -15
  309. data/lib/datadog/tracing/contrib/http/distributed/propagation.rb +4 -1
  310. data/lib/datadog/tracing/contrib/http/instrumentation.rb +6 -10
  311. data/lib/datadog/tracing/contrib/http/integration.rb +3 -0
  312. data/lib/datadog/tracing/contrib/httpclient/instrumentation.rb +6 -16
  313. data/lib/datadog/tracing/contrib/httprb/instrumentation.rb +7 -15
  314. data/lib/datadog/tracing/contrib/httprb/integration.rb +3 -0
  315. data/lib/datadog/tracing/contrib/kafka/integration.rb +3 -0
  316. data/lib/datadog/tracing/contrib/karafka/configuration/settings.rb +27 -0
  317. data/lib/datadog/tracing/contrib/karafka/distributed/propagation.rb +48 -0
  318. data/lib/datadog/tracing/contrib/karafka/ext.rb +27 -0
  319. data/lib/datadog/tracing/contrib/karafka/integration.rb +45 -0
  320. data/lib/datadog/tracing/contrib/karafka/monitor.rb +66 -0
  321. data/lib/datadog/tracing/contrib/karafka/patcher.rb +71 -0
  322. data/lib/datadog/tracing/contrib/karafka.rb +37 -0
  323. data/lib/datadog/tracing/contrib/mongodb/configuration/settings.rb +8 -0
  324. data/lib/datadog/tracing/contrib/mongodb/ext.rb +1 -0
  325. data/lib/datadog/tracing/contrib/mongodb/integration.rb +3 -0
  326. data/lib/datadog/tracing/contrib/mongodb/subscribers.rb +18 -1
  327. data/lib/datadog/tracing/contrib/opensearch/configuration/settings.rb +17 -0
  328. data/lib/datadog/tracing/contrib/opensearch/ext.rb +9 -0
  329. data/lib/datadog/tracing/contrib/opensearch/integration.rb +3 -0
  330. data/lib/datadog/tracing/contrib/opensearch/patcher.rb +5 -1
  331. data/lib/datadog/tracing/contrib/patcher.rb +5 -2
  332. data/lib/datadog/tracing/contrib/presto/integration.rb +3 -0
  333. data/lib/datadog/tracing/contrib/rack/header_collection.rb +11 -1
  334. data/lib/datadog/tracing/contrib/rack/integration.rb +2 -2
  335. data/lib/datadog/tracing/contrib/rack/middlewares.rb +1 -1
  336. data/lib/datadog/tracing/contrib/rack/request_queue.rb +1 -1
  337. data/lib/datadog/tracing/contrib/rails/framework.rb +2 -2
  338. data/lib/datadog/tracing/contrib/rails/patcher.rb +1 -1
  339. data/lib/datadog/tracing/contrib/rest_client/integration.rb +3 -0
  340. data/lib/datadog/tracing/contrib/rest_client/request_patch.rb +5 -3
  341. data/lib/datadog/tracing/contrib/sidekiq/client_tracer.rb +6 -1
  342. data/lib/datadog/tracing/contrib/sidekiq/distributed/propagation.rb +3 -0
  343. data/lib/datadog/tracing/contrib/sidekiq/server_tracer.rb +1 -1
  344. data/lib/datadog/tracing/contrib/span_attribute_schema.rb +6 -1
  345. data/lib/datadog/tracing/contrib/support.rb +28 -0
  346. data/lib/datadog/tracing/contrib.rb +1 -0
  347. data/lib/datadog/tracing/correlation.rb +9 -2
  348. data/lib/datadog/tracing/distributed/b3_multi.rb +1 -1
  349. data/lib/datadog/tracing/distributed/b3_single.rb +1 -1
  350. data/lib/datadog/tracing/distributed/baggage.rb +131 -0
  351. data/lib/datadog/tracing/distributed/datadog.rb +4 -2
  352. data/lib/datadog/tracing/distributed/propagation.rb +25 -4
  353. data/lib/datadog/tracing/distributed/propagation_policy.rb +42 -0
  354. data/lib/datadog/tracing/metadata/errors.rb +4 -4
  355. data/lib/datadog/tracing/metadata/ext.rb +5 -0
  356. data/lib/datadog/tracing/metadata/metastruct.rb +36 -0
  357. data/lib/datadog/tracing/metadata/metastruct_tagging.rb +42 -0
  358. data/lib/datadog/tracing/metadata.rb +2 -0
  359. data/lib/datadog/tracing/sampling/rate_sampler.rb +2 -1
  360. data/lib/datadog/tracing/sampling/span/rule.rb +0 -1
  361. data/lib/datadog/tracing/span.rb +22 -5
  362. data/lib/datadog/tracing/span_event.rb +124 -4
  363. data/lib/datadog/tracing/span_operation.rb +52 -16
  364. data/lib/datadog/tracing/sync_writer.rb +9 -5
  365. data/lib/datadog/tracing/trace_digest.rb +9 -2
  366. data/lib/datadog/tracing/trace_operation.rb +44 -24
  367. data/lib/datadog/tracing/trace_segment.rb +6 -4
  368. data/lib/datadog/tracing/tracer.rb +60 -12
  369. data/lib/datadog/tracing/transport/http/api.rb +5 -4
  370. data/lib/datadog/tracing/transport/http/client.rb +5 -4
  371. data/lib/datadog/tracing/transport/http/traces.rb +13 -44
  372. data/lib/datadog/tracing/transport/http.rb +13 -70
  373. data/lib/datadog/tracing/transport/serializable_trace.rb +31 -7
  374. data/lib/datadog/tracing/transport/trace_formatter.rb +7 -0
  375. data/lib/datadog/tracing/transport/traces.rb +47 -13
  376. data/lib/datadog/tracing/utils.rb +1 -1
  377. data/lib/datadog/tracing/workers/trace_writer.rb +8 -5
  378. data/lib/datadog/tracing/workers.rb +5 -4
  379. data/lib/datadog/tracing/writer.rb +10 -6
  380. data/lib/datadog/tracing.rb +16 -3
  381. data/lib/datadog/version.rb +2 -2
  382. data/lib/datadog.rb +2 -0
  383. metadata +143 -50
  384. data/ext/datadog_profiling_loader/datadog_profiling_loader.c +0 -142
  385. data/ext/datadog_profiling_loader/extconf.rb +0 -60
  386. data/lib/datadog/appsec/contrib/devise/event.rb +0 -57
  387. data/lib/datadog/appsec/contrib/devise/patcher/authenticatable_patch.rb +0 -77
  388. data/lib/datadog/appsec/contrib/devise/patcher/registration_controller_patch.rb +0 -54
  389. data/lib/datadog/appsec/contrib/devise/resource.rb +0 -35
  390. data/lib/datadog/appsec/contrib/devise/tracking.rb +0 -57
  391. data/lib/datadog/appsec/contrib/graphql/reactive/multiplex.rb +0 -46
  392. data/lib/datadog/appsec/contrib/patcher.rb +0 -12
  393. data/lib/datadog/appsec/contrib/rack/reactive/request.rb +0 -69
  394. data/lib/datadog/appsec/contrib/rack/reactive/request_body.rb +0 -47
  395. data/lib/datadog/appsec/contrib/rack/reactive/response.rb +0 -53
  396. data/lib/datadog/appsec/contrib/rails/reactive/action.rb +0 -53
  397. data/lib/datadog/appsec/contrib/sinatra/ext.rb +0 -14
  398. data/lib/datadog/appsec/contrib/sinatra/reactive/routed.rb +0 -48
  399. data/lib/datadog/appsec/monitor/reactive/set_user.rb +0 -45
  400. data/lib/datadog/appsec/processor/actions.rb +0 -49
  401. data/lib/datadog/appsec/processor/context.rb +0 -107
  402. data/lib/datadog/appsec/reactive/address_hash.rb +0 -22
  403. data/lib/datadog/appsec/reactive/engine.rb +0 -47
  404. data/lib/datadog/appsec/reactive/operation.rb +0 -68
  405. data/lib/datadog/appsec/reactive/subscriber.rb +0 -19
  406. data/lib/datadog/appsec/scope.rb +0 -58
  407. data/lib/datadog/appsec/utils/trace_operation.rb +0 -15
  408. data/lib/datadog/core/crashtracking/agent_base_url.rb +0 -21
  409. data/lib/datadog/core/remote/transport/http/api/instance.rb +0 -39
  410. data/lib/datadog/core/remote/transport/http/api/spec.rb +0 -21
  411. data/lib/datadog/core/remote/transport/http/builder.rb +0 -219
  412. data/lib/datadog/core/telemetry/http/env.rb +0 -20
  413. data/lib/datadog/core/telemetry/http/ext.rb +0 -28
  414. data/lib/datadog/core/telemetry/http/response.rb +0 -70
  415. data/lib/datadog/core/telemetry/http/transport.rb +0 -90
  416. data/lib/datadog/di/transport.rb +0 -81
  417. data/lib/datadog/tracing/transport/http/api/spec.rb +0 -19
@@ -5,20 +5,14 @@
5
5
 
6
6
  static VALUE _native_start_or_update_on_fork(int argc, VALUE *argv, DDTRACE_UNUSED VALUE _self);
7
7
  static VALUE _native_stop(DDTRACE_UNUSED VALUE _self);
8
- static void crashtracker_init(VALUE crashtracking_module);
8
+
9
+ static bool first_init = true;
9
10
 
10
11
  // Used to report Ruby VM crashes.
11
12
  // Once initialized, segfaults will be reported automatically using libdatadog.
12
13
 
13
- void DDTRACE_EXPORT Init_libdatadog_api(void) {
14
- VALUE datadog_module = rb_define_module("Datadog");
15
- VALUE core_module = rb_define_module_under(datadog_module, "Core");
14
+ void crashtracker_init(VALUE core_module) {
16
15
  VALUE crashtracking_module = rb_define_module_under(core_module, "Crashtracking");
17
-
18
- crashtracker_init(crashtracking_module);
19
- }
20
-
21
- void crashtracker_init(VALUE crashtracking_module) {
22
16
  VALUE crashtracker_class = rb_define_class_under(crashtracking_module, "Component", rb_cObject);
23
17
 
24
18
  rb_define_singleton_method(crashtracker_class, "_native_start_or_update_on_fork", _native_start_or_update_on_fork, -1);
@@ -54,6 +48,9 @@ static VALUE _native_start_or_update_on_fork(int argc, VALUE *argv, DDTRACE_UNUS
54
48
  // Tags and endpoint are heap-allocated, so after here we can't raise exceptions otherwise we'll leak this memory
55
49
  // Start of exception-free zone to prevent leaks {{
56
50
  ddog_Endpoint *endpoint = ddog_endpoint_from_url(char_slice_from_ruby_string(agent_base_url));
51
+ if (endpoint == NULL) {
52
+ rb_raise(rb_eRuntimeError, "Failed to create endpoint from agent_base_url: %"PRIsVALUE, agent_base_url);
53
+ }
57
54
  ddog_Vec_Tag tags = convert_tags(tags_as_array);
58
55
 
59
56
  ddog_crasht_Config config = {
@@ -67,7 +64,7 @@ static VALUE _native_start_or_update_on_fork(int argc, VALUE *argv, DDTRACE_UNUS
67
64
  // "Process.kill('SEGV', Process.pid)" gets run.
68
65
  //
69
66
  // This actually changed in libdatadog 14, so I could see no issues with `create_alt_stack = true`, but not
70
- // overridding what Ruby set up seems a saner default to keep anyway.
67
+ // overriding what Ruby set up seems a saner default to keep anyway.
71
68
  .create_alt_stack = false,
72
69
  .use_alt_stack = true,
73
70
  .endpoint = endpoint,
@@ -95,17 +92,22 @@ static VALUE _native_start_or_update_on_fork(int argc, VALUE *argv, DDTRACE_UNUS
95
92
  .optional_stdout_filename = {},
96
93
  };
97
94
 
98
- ddog_crasht_Result result =
95
+ ddog_VoidResult result =
99
96
  action == start_action ?
100
- ddog_crasht_init(config, receiver_config, metadata) :
97
+ (first_init ?
98
+ ddog_crasht_init(config, receiver_config, metadata) :
99
+ ddog_crasht_reconfigure(config, receiver_config, metadata)
100
+ ) :
101
101
  ddog_crasht_update_on_fork(config, receiver_config, metadata);
102
102
 
103
+ first_init = false;
104
+
103
105
  // Clean up before potentially raising any exceptions
104
106
  ddog_Vec_Tag_drop(tags);
105
107
  ddog_endpoint_drop(endpoint);
106
108
  // }} End of exception-free zone to prevent leaks
107
109
 
108
- if (result.tag == DDOG_CRASHT_RESULT_ERR) {
110
+ if (result.tag == DDOG_VOID_RESULT_ERR) {
109
111
  rb_raise(rb_eRuntimeError, "Failed to start/update the crash tracker: %"PRIsVALUE, get_error_details_and_drop(&result.err));
110
112
  }
111
113
 
@@ -113,9 +115,9 @@ static VALUE _native_start_or_update_on_fork(int argc, VALUE *argv, DDTRACE_UNUS
113
115
  }
114
116
 
115
117
  static VALUE _native_stop(DDTRACE_UNUSED VALUE _self) {
116
- ddog_crasht_Result result = ddog_crasht_shutdown();
118
+ ddog_VoidResult result = ddog_crasht_disable();
117
119
 
118
- if (result.tag == DDOG_CRASHT_RESULT_ERR) {
120
+ if (result.tag == DDOG_VOID_RESULT_ERR) {
119
121
  rb_raise(rb_eRuntimeError, "Failed to stop the crash tracker: %"PRIsVALUE, get_error_details_and_drop(&result.err));
120
122
  }
121
123
 
@@ -0,0 +1,5 @@
1
+ #pragma once
2
+
3
+ #include "datadog_ruby_common.h"
4
+
5
+ void crashtracker_init(VALUE core_module);
@@ -29,10 +29,7 @@ VALUE datadog_gem_version(void) {
29
29
  }
30
30
 
31
31
  static VALUE log_failure_to_process_tag(VALUE err_details) {
32
- VALUE datadog_module = rb_const_get(rb_cObject, rb_intern("Datadog"));
33
- VALUE logger = rb_funcall(datadog_module, rb_intern("logger"), 0);
34
-
35
- return rb_funcall(logger, rb_intern("warn"), 1, rb_sprintf("Failed to convert tag: %"PRIsVALUE, err_details));
32
+ return log_warning(rb_sprintf("Failed to convert tag: %"PRIsVALUE, err_details));
36
33
  }
37
34
 
38
35
  __attribute__((warn_unused_result))
@@ -27,6 +27,9 @@
27
27
  #define ENFORCE_BOOLEAN(value) \
28
28
  { if (RB_UNLIKELY(value != Qtrue && value != Qfalse)) raise_unexpected_type(value, ADD_QUOTES(value), "true or false", __FILE__, __LINE__, __func__); }
29
29
 
30
+ #define ENFORCE_TYPED_DATA(value, type) \
31
+ { if (RB_UNLIKELY(!rb_typeddata_is_kind_of(value, type))) raise_unexpected_type(value, ADD_QUOTES(value), "TypedData of type " ADD_QUOTES(type), __FILE__, __LINE__, __func__); }
32
+
30
33
  NORETURN(void raise_unexpected_type(VALUE value, const char *value_name, const char *type_name, const char *file, int line, const char* function_name));
31
34
 
32
35
  // Helper to retrieve Datadog::VERSION::STRING
@@ -38,6 +41,13 @@ static inline ddog_CharSlice char_slice_from_ruby_string(VALUE string) {
38
41
  return char_slice;
39
42
  }
40
43
 
44
+ static inline VALUE log_warning(VALUE warning) {
45
+ VALUE datadog_module = rb_const_get(rb_cObject, rb_intern("Datadog"));
46
+ VALUE logger = rb_funcall(datadog_module, rb_intern("logger"), 0);
47
+
48
+ return rb_funcall(logger, rb_intern("warn"), 1, warning);
49
+ }
50
+
41
51
  __attribute__((warn_unused_result))
42
52
  ddog_Vec_Tag convert_tags(VALUE tags_as_array);
43
53
 
@@ -0,0 +1,15 @@
1
+ #include <ruby.h>
2
+
3
+ #include "datadog_ruby_common.h"
4
+ #include "crashtracker.h"
5
+ #include "process_discovery.h"
6
+ #include "library_config.h"
7
+
8
+ void DDTRACE_EXPORT Init_libdatadog_api(void) {
9
+ VALUE datadog_module = rb_define_module("Datadog");
10
+ VALUE core_module = rb_define_module_under(datadog_module, "Core");
11
+
12
+ crashtracker_init(core_module);
13
+ process_discovery_init(core_module);
14
+ library_config_init(core_module);
15
+ }
@@ -0,0 +1,122 @@
1
+ #include <ruby.h>
2
+ #include <datadog/library-config.h>
3
+
4
+ #include "library_config.h"
5
+ #include "datadog_ruby_common.h"
6
+
7
+ static VALUE _native_configurator_new(VALUE klass);
8
+ static VALUE _native_configurator_get(VALUE self);
9
+
10
+ static VALUE config_vec_class = Qnil;
11
+
12
+ // ddog_Configurator memory management
13
+ static void configurator_free(void *configurator_ptr) {
14
+ ddog_Configurator *configurator = (ddog_Configurator *)configurator_ptr;
15
+
16
+ ddog_library_configurator_drop(configurator);
17
+ }
18
+
19
+ static const rb_data_type_t configurator_typed_data = {
20
+ .wrap_struct_name = "Datadog::Core::Configuration::StableConfig::Configurator",
21
+ .function = {
22
+ .dfree = configurator_free,
23
+ .dsize = NULL,
24
+ },
25
+ .flags = RUBY_TYPED_FREE_IMMEDIATELY
26
+ };
27
+
28
+ // ddog_Vec_LibraryConfig memory management
29
+ static void config_vec_free(void *config_vec_ptr) {
30
+ ddog_Vec_LibraryConfig *config_vec = (ddog_Vec_LibraryConfig *)config_vec_ptr;
31
+
32
+ ddog_library_config_drop(*config_vec);
33
+ ruby_xfree(config_vec_ptr);
34
+ }
35
+
36
+ static const rb_data_type_t config_vec_typed_data = {
37
+ .wrap_struct_name = "Datadog::Core::Configuration::StableConfigVec",
38
+ .function = {
39
+ .dfree = config_vec_free,
40
+ .dsize = NULL,
41
+ },
42
+ .flags = RUBY_TYPED_FREE_IMMEDIATELY
43
+ };
44
+
45
+ void library_config_init(VALUE core_module) {
46
+ rb_global_variable(&config_vec_class);
47
+ VALUE configuration_module = rb_define_module_under(core_module, "Configuration");
48
+ VALUE stable_config_module = rb_define_module_under(configuration_module, "StableConfig");
49
+ VALUE configurator_class = rb_define_class_under(stable_config_module, "Configurator", rb_cObject);
50
+ config_vec_class = rb_define_class_under(configuration_module, "StableConfigVec", rb_cObject);
51
+
52
+ rb_define_alloc_func(configurator_class, _native_configurator_new);
53
+ rb_define_method(configurator_class, "get", _native_configurator_get, 0);
54
+
55
+ rb_undef_alloc_func(config_vec_class); // It cannot be created from Ruby code and only serves as an intermediate object for the Ruby GC
56
+ }
57
+
58
+ // TODO: After libdatadog 17.1 release, delete rb_raise, uncomment code and change `DDTRACE_UNUSED VALUE _klass` by `VALUE klass`
59
+ static VALUE _native_configurator_new(DDTRACE_UNUSED VALUE _klass) {
60
+ /*
61
+ ddog_Configurator *configurator = ddog_library_configurator_new(false, DDOG_CHARSLICE_C("ruby"));
62
+
63
+ ddog_library_configurator_with_detect_process_info(configurator);
64
+
65
+ return TypedData_Wrap_Struct(klass, &configurator_typed_data, configurator);
66
+ */
67
+
68
+ rb_raise(rb_eNotImpError, "TODO: Not in use yet, waiting for libdatadog 17.1");
69
+ }
70
+
71
+ static VALUE _native_configurator_get(VALUE self) {
72
+ ddog_Configurator *configurator;
73
+ TypedData_Get_Struct(self, ddog_Configurator, &configurator_typed_data, configurator);
74
+
75
+ ddog_Result_VecLibraryConfig configurator_result = ddog_library_configurator_get(configurator);
76
+
77
+ if (configurator_result.tag == DDOG_RESULT_VEC_LIBRARY_CONFIG_ERR_VEC_LIBRARY_CONFIG) {
78
+ ddog_Error err = configurator_result.err;
79
+ VALUE message = get_error_details_and_drop(&err);
80
+ if (is_config_loaded()) {
81
+ log_warning(message);
82
+ } else {
83
+ log_warning_without_config(message);
84
+ }
85
+ return rb_hash_new();
86
+ }
87
+
88
+ // Wrapping config_vec into a Ruby object enables the Ruby GC to manage its memory
89
+ // We need to allocate memory for config_vec because once it is out of scope, it will be freed (at the end of this function)
90
+ // So we cannot reference it with &config_vec
91
+ // We are doing this in case one of the ruby API raises an exception before the end of this function,
92
+ // so the allocated memory will still be freed
93
+ ddog_Vec_LibraryConfig *config_vec = ruby_xmalloc(sizeof(ddog_Vec_LibraryConfig));
94
+ *config_vec = configurator_result.ok;
95
+ VALUE config_vec_rb = TypedData_Wrap_Struct(config_vec_class, &config_vec_typed_data, config_vec);
96
+
97
+ VALUE local_config_hash = rb_hash_new();
98
+ VALUE fleet_config_hash = rb_hash_new();
99
+ // TODO: Uncomment next block after libdatadog 17.1 release
100
+ /*
101
+ for (uintptr_t i = 0; i < config_vec->len; i++) {
102
+ ddog_LibraryConfig config = config_vec->ptr[i];
103
+ VALUE selected_hash;
104
+ if (config.source == DDOG_LIBRARY_CONFIG_SOURCE_LOCAL_STABLE_CONFIG) {
105
+ selected_hash = local_config_hash;
106
+ }
107
+ else {
108
+ selected_hash = fleet_config_hash;
109
+ }
110
+
111
+ ddog_CStr name = ddog_library_config_name_to_env(config.name);
112
+ rb_hash_aset(selected_hash, rb_str_new(name.ptr, name.length), rb_str_new(config.value.ptr, config.value.length));
113
+ }
114
+ */
115
+
116
+ VALUE result = rb_hash_new();
117
+ rb_hash_aset(result, ID2SYM(rb_intern("local")), local_config_hash);
118
+ rb_hash_aset(result, ID2SYM(rb_intern("fleet")), fleet_config_hash);
119
+
120
+ RB_GC_GUARD(config_vec_rb);
121
+ return result;
122
+ }
@@ -0,0 +1,19 @@
1
+ #pragma once
2
+
3
+ #include "datadog_ruby_common.h"
4
+
5
+ void library_config_init(VALUE core_module);
6
+
7
+ static inline bool is_config_loaded(void) {
8
+ VALUE datadog_module = rb_const_get(rb_cObject, rb_intern("Datadog"));
9
+ VALUE is_config_loaded = rb_funcall(datadog_module, rb_intern("configuration?"), 0);
10
+
11
+ return is_config_loaded == Qtrue;
12
+ }
13
+
14
+ static inline VALUE log_warning_without_config(VALUE warning) {
15
+ VALUE datadog_module = rb_const_get(rb_cObject, rb_intern("Datadog"));
16
+ VALUE logger = rb_funcall(datadog_module, rb_intern("logger_without_configuration"), 0);
17
+
18
+ return rb_funcall(logger, rb_intern("warn"), 1, warning);
19
+ }
@@ -17,9 +17,9 @@ export DD_RUBY_PLATFORM=`ruby -e 'puts Gem::Platform.local.to_s'`
17
17
  mkdir -p my-libdatadog-build/$DD_RUBY_PLATFORM
18
18
  ```
19
19
 
20
- 5. Build libdatadog into this folder: `./build-profiling-ffi.sh my-libdatadog-build/$DD_RUBY_PLATFORM`
21
- 6. Tell the Ruby where to find libdatadog: `export LIBDATADOG_VENDOR_OVERRIDE=/full/path/to/my-libdatadog-build/` (Notice no platform here)
22
- 7. Run `bundle exec rake clean compile`
20
+ 5. From inside of the libdatadog repo, build libdatadog into this folder: `./build-profiling-ffi.sh my-libdatadog-build/$DD_RUBY_PLATFORM`
21
+ 6. Tell Ruby where to find libdatadog: `export LIBDATADOG_VENDOR_OVERRIDE=/full/path/to/my-libdatadog-build/` (Notice no platform here)
22
+ 7. From dd-trace-rb, run `bundle exec rake clean compile`
23
23
 
24
24
  If you additionally want to run the profiler test suite, also remember to `export DD_PROFILING_MACOS_TESTING=true` and re-run `rake clean compile`.
25
25
 
@@ -0,0 +1,117 @@
1
+ #include <errno.h>
2
+ #include <stdlib.h>
3
+ #include <ruby.h>
4
+ #include <datadog/common.h>
5
+
6
+ #include "datadog_ruby_common.h"
7
+
8
+ static VALUE _native_store_tracer_metadata(int argc, VALUE *argv, DDTRACE_UNUSED VALUE _self);
9
+ static VALUE _native_to_rb_int(DDTRACE_UNUSED VALUE _self, VALUE tracer_memfd);
10
+ static VALUE _native_close_tracer_memfd(DDTRACE_UNUSED VALUE _self, VALUE tracer_memfd, VALUE logger);
11
+
12
+ static void tracer_memfd_free(void *ptr) {
13
+ int *fd = (int *)ptr;
14
+ if (*fd != -1) {
15
+ close(*fd);
16
+ }
17
+ ruby_xfree(ptr);
18
+ }
19
+
20
+ static const rb_data_type_t tracer_memfd_type = {
21
+ .wrap_struct_name = "Datadog::Core::ProcessDiscovery::TracerMemfd",
22
+ .function = {
23
+ .dfree = tracer_memfd_free,
24
+ .dsize = NULL,
25
+ },
26
+ .flags = RUBY_TYPED_FREE_IMMEDIATELY
27
+ };
28
+
29
+ void process_discovery_init(VALUE core_module) {
30
+ VALUE process_discovery_class = rb_define_class_under(core_module, "ProcessDiscovery", rb_cObject);
31
+ VALUE tracer_memfd_class = rb_define_class_under(process_discovery_class, "TracerMemfd", rb_cObject);
32
+ rb_undef_alloc_func(tracer_memfd_class); // Class cannot be instantiated from Ruby
33
+
34
+ rb_define_singleton_method(process_discovery_class, "_native_store_tracer_metadata", _native_store_tracer_metadata, -1);
35
+ rb_define_singleton_method(process_discovery_class, "_native_to_rb_int", _native_to_rb_int, 1);
36
+ rb_define_singleton_method(process_discovery_class, "_native_close_tracer_memfd", _native_close_tracer_memfd, 2);
37
+ }
38
+
39
+ // TODO: Remove DDTRACE_UNUSED and rename _self to self once we have updated libdatadog to 17.1
40
+ static VALUE _native_store_tracer_metadata(int argc, VALUE *argv, DDTRACE_UNUSED VALUE _self) {
41
+ VALUE logger;
42
+ VALUE options;
43
+ rb_scan_args(argc, argv, "1:", &logger, &options);
44
+ if (options == Qnil) options = rb_hash_new();
45
+
46
+ VALUE schema_version = rb_hash_fetch(options, ID2SYM(rb_intern("schema_version")));
47
+ VALUE runtime_id = rb_hash_fetch(options, ID2SYM(rb_intern("runtime_id")));
48
+ VALUE tracer_language = rb_hash_fetch(options, ID2SYM(rb_intern("tracer_language")));
49
+ VALUE tracer_version = rb_hash_fetch(options, ID2SYM(rb_intern("tracer_version")));
50
+ VALUE hostname = rb_hash_fetch(options, ID2SYM(rb_intern("hostname")));
51
+ VALUE service_name = rb_hash_fetch(options, ID2SYM(rb_intern("service_name")));
52
+ VALUE service_env = rb_hash_fetch(options, ID2SYM(rb_intern("service_env")));
53
+ VALUE service_version = rb_hash_fetch(options, ID2SYM(rb_intern("service_version")));
54
+
55
+ ENFORCE_TYPE(schema_version, T_FIXNUM);
56
+ ENFORCE_TYPE(runtime_id, T_STRING);
57
+ ENFORCE_TYPE(tracer_language, T_STRING);
58
+ ENFORCE_TYPE(tracer_version, T_STRING);
59
+ ENFORCE_TYPE(hostname, T_STRING);
60
+ ENFORCE_TYPE(service_name, T_STRING);
61
+ ENFORCE_TYPE(service_env, T_STRING);
62
+ ENFORCE_TYPE(service_version, T_STRING);
63
+
64
+ /*
65
+ ddog_Result_TracerMemfdHandle result = ddog_store_tracer_metadata(
66
+ (uint8_t) NUM2UINT(schema_version),
67
+ char_slice_from_ruby_string(runtime_id),
68
+ char_slice_from_ruby_string(tracer_language),
69
+ char_slice_from_ruby_string(tracer_version),
70
+ char_slice_from_ruby_string(hostname),
71
+ char_slice_from_ruby_string(service_name),
72
+ char_slice_from_ruby_string(service_env),
73
+ char_slice_from_ruby_string(service_version)
74
+ );
75
+
76
+ if (result.tag == DDOG_RESULT_TRACER_MEMFD_HANDLE_ERR_TRACER_MEMFD_HANDLE) {
77
+ rb_funcall(logger, rb_intern("debug"), 1, rb_sprintf("Failed to store the tracer configuration in a memory file descriptor: %"PRIsVALUE, get_error_details_and_drop(&result.err)));
78
+ return Qnil;
79
+ }
80
+
81
+ // &result.ok is a ddog_TracerMemfdHandle, which is a struct only containing int fd, which is a file descriptor
82
+ // We should just return the fd
83
+ int *fd = ruby_xmalloc(sizeof(int));
84
+
85
+ *fd = result.ok.fd;
86
+ VALUE tracer_memfd_class = rb_const_get(self, rb_intern("TracerMemfd"));
87
+ VALUE tracer_memfd = TypedData_Wrap_Struct(tracer_memfd_class, &tracer_memfd_type, fd);
88
+ return tracer_memfd;
89
+ */
90
+
91
+ rb_raise(rb_eNotImpError, "TODO: Not in use yet, waiting for libdatadog 17.1");
92
+ }
93
+
94
+ static VALUE _native_to_rb_int(DDTRACE_UNUSED VALUE _self, VALUE tracer_memfd) {
95
+ int *fd;
96
+ TypedData_Get_Struct(tracer_memfd, int, &tracer_memfd_type, fd);
97
+ return INT2NUM(*fd);
98
+ }
99
+
100
+ static VALUE _native_close_tracer_memfd(DDTRACE_UNUSED VALUE _self, VALUE tracer_memfd, VALUE logger) {
101
+ int *fd;
102
+ TypedData_Get_Struct(tracer_memfd, int, &tracer_memfd_type, fd);
103
+ if (*fd == -1) {
104
+ rb_funcall(logger, rb_intern("debug"), 1, rb_sprintf("The tracer configuration memory file descriptor has already been closed"));
105
+ return Qnil;
106
+ }
107
+
108
+ int close_result = close(*fd);
109
+ *fd = -1;
110
+
111
+ if (close_result == -1) {
112
+ rb_funcall(logger, rb_intern("debug"), 1, rb_sprintf("Failed to close the tracer configuration memory file descriptor: %s", strerror(errno)));
113
+ return Qnil;
114
+ }
115
+
116
+ return Qnil;
117
+ }
@@ -0,0 +1,5 @@
1
+ #pragma once
2
+
3
+ #include "datadog_ruby_common.h"
4
+
5
+ void process_discovery_init(VALUE core_module);
@@ -8,7 +8,7 @@ module Datadog
8
8
  module LibdatadogExtconfHelpers
9
9
  # Used to make sure the correct gem version gets loaded, as extconf.rb does not get run with "bundle exec" and thus
10
10
  # may see multiple libdatadog versions. See https://github.com/DataDog/dd-trace-rb/pull/2531 for the horror story.
11
- LIBDATADOG_VERSION = '~> 14.1.0.1.0'
11
+ LIBDATADOG_VERSION = '~> 18.1.0.1.0'
12
12
 
13
13
  # Used as an workaround for a limitation with how dynamic linking works in environments where the datadog gem and
14
14
  # libdatadog are moved after the extension gets compiled.
@@ -0,0 +1,89 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Datadog
4
+ module AppSec
5
+ module ActionsHandler
6
+ # This module serves encapsulates MessagePack serialization for caller locations.
7
+ #
8
+ # It serializes part of the stack:
9
+ # up to 32 frames (configurable)
10
+ # keeping frames from top and bottom of the stack (75% to 25%, configurable).
11
+ #
12
+ # It represents the stack trace that is added to span metastruct field.
13
+ class SerializableBacktrace
14
+ CLASS_AND_FUNCTION_NAME_REGEX = /\b((?:\w+::)*\w+)?[#.]?\b(\w+)\z/.freeze
15
+
16
+ def initialize(locations:, stack_id:)
17
+ @stack_id = stack_id
18
+ @locations = locations
19
+ end
20
+
21
+ def to_msgpack(packer = nil)
22
+ # JRuby doesn't pass the packer
23
+ packer ||= MessagePack::Packer.new
24
+
25
+ packer.write_map_header(3)
26
+
27
+ packer.write('id')
28
+ packer.write(@stack_id.encode('UTF-8'))
29
+
30
+ packer.write('language')
31
+ packer.write('ruby'.encode('UTF-8'))
32
+
33
+ serializable_locations_map = build_serializable_locations_map
34
+
35
+ packer.write('frames')
36
+ packer.write_array_header(serializable_locations_map.size)
37
+
38
+ serializable_locations_map.each do |frame_id, location|
39
+ packer.write_map_header(6)
40
+
41
+ packer.write('id')
42
+ packer.write(frame_id)
43
+
44
+ packer.write('text')
45
+ packer.write(location.to_s.encode('UTF-8'))
46
+
47
+ packer.write('file')
48
+ packer.write(location.path&.encode('UTF-8'))
49
+
50
+ packer.write('line')
51
+ packer.write(location.lineno)
52
+
53
+ class_name, function_name = location.label&.match(CLASS_AND_FUNCTION_NAME_REGEX)&.captures
54
+
55
+ packer.write('class_name')
56
+ packer.write(class_name&.encode('UTF-8'))
57
+
58
+ packer.write('function')
59
+ packer.write(function_name&.encode('UTF-8'))
60
+ end
61
+
62
+ packer
63
+ end
64
+
65
+ private
66
+
67
+ def build_serializable_locations_map
68
+ max_depth = Datadog.configuration.appsec.stack_trace.max_depth
69
+ top_percent = Datadog.configuration.appsec.stack_trace.top_percentage
70
+
71
+ drop_from_idx = max_depth * top_percent / 100
72
+ drop_until_idx = @locations.size - (max_depth - drop_from_idx)
73
+
74
+ frame_idx = -1
75
+ @locations.each_with_object({}) do |location, map|
76
+ # we are dropping frames from library code without increasing frame index
77
+ next if location.path&.include?('lib/datadog')
78
+
79
+ frame_idx += 1
80
+
81
+ next if max_depth != 0 && frame_idx >= drop_from_idx && frame_idx < drop_until_idx
82
+
83
+ map[frame_idx] = location
84
+ end
85
+ end
86
+ end
87
+ end
88
+ end
89
+ end
@@ -0,0 +1,49 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'actions_handler/serializable_backtrace'
4
+
5
+ module Datadog
6
+ module AppSec
7
+ # this module encapsulates functions for handling actions that libddawf returns
8
+ module ActionsHandler
9
+ module_function
10
+
11
+ def handle(actions_hash)
12
+ # handle actions according their precedence
13
+ # stack and schema generation should be done before we throw an interrupt signal
14
+ generate_stack(actions_hash['generate_stack']) if actions_hash.key?('generate_stack')
15
+ generate_schema(actions_hash['generate_schema']) if actions_hash.key?('generate_schema')
16
+ interrupt_execution(actions_hash['redirect_request']) if actions_hash.key?('redirect_request')
17
+ interrupt_execution(actions_hash['block_request']) if actions_hash.key?('block_request')
18
+ end
19
+
20
+ def interrupt_execution(action_params)
21
+ throw(Datadog::AppSec::Ext::INTERRUPT, action_params)
22
+ end
23
+
24
+ def generate_stack(action_params)
25
+ return unless Datadog.configuration.appsec.stack_trace.enabled
26
+
27
+ stack_id = action_params['stack_id']
28
+ return unless stack_id
29
+
30
+ active_span = AppSec.active_context&.span
31
+ return unless active_span
32
+
33
+ event_category = Ext::EXPLOIT_PREVENTION_EVENT_CATEGORY
34
+ tag_key = Ext::TAG_METASTRUCT_STACK_TRACE
35
+
36
+ existing_stack_data = active_span.get_metastruct_tag(tag_key).dup || {event_category => []}
37
+ max_stack_traces = Datadog.configuration.appsec.stack_trace.max_stack_traces
38
+ return if max_stack_traces != 0 && existing_stack_data[event_category].count >= max_stack_traces
39
+
40
+ backtrace = SerializableBacktrace.new(locations: Array(caller_locations), stack_id: stack_id)
41
+ existing_stack_data[event_category] << backtrace
42
+ active_span.set_metastruct_tag(tag_key, existing_stack_data)
43
+ end
44
+
45
+ def generate_schema(_action_params)
46
+ end
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,16 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'digest/sha2'
4
+
5
+ module Datadog
6
+ module AppSec
7
+ # Manual anonymization of the potential PII data
8
+ module Anonymizer
9
+ def self.anonymize(payload)
10
+ raise ArgumentError, "expected String, received #{payload.class}" unless payload.is_a?(String)
11
+
12
+ "anon_#{Digest::SHA256.hexdigest(payload)[0, 32]}"
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,49 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'forwardable'
4
+
5
+ module Datadog
6
+ module AppSec
7
+ module APISecurity
8
+ # An LRU (Least Recently Used) cache implementation that relies on the
9
+ # Ruby 1.9+ `Hash` implementation that guarantees insertion order.
10
+ #
11
+ # WARNING: This implementation is NOT thread-safe and should be used
12
+ # in a single-threaded context.
13
+ class LRUCache
14
+ extend Forwardable
15
+
16
+ def_delegators :@store, :clear, :empty?
17
+
18
+ def initialize(max_size)
19
+ raise ArgumentError, 'max_size must be an Integer' unless max_size.is_a?(Integer)
20
+ raise ArgumentError, 'max_size must be greater than 0' if max_size <= 0
21
+
22
+ @max_size = max_size
23
+ @store = {}
24
+ end
25
+
26
+ # NOTE: Accessing a key moves it to the end of the list.
27
+ def [](key)
28
+ if (entry = @store.delete(key))
29
+ @store[key] = entry
30
+ end
31
+ end
32
+
33
+ # NOTE: If the key exists, it's moved to the end of the list and
34
+ # if does not, the given block will be executed and the result
35
+ # will be stored (which will add it to the end of the list).
36
+ def fetch_or_store(key)
37
+ if (entry = @store.delete(key))
38
+ return @store[key] = entry
39
+ end
40
+
41
+ # NOTE: evict the oldest entry if store reached the maximum allowed size
42
+ @store.shift if @store.size >= @max_size
43
+
44
+ @store[key] ||= yield
45
+ end
46
+ end
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Datadog
4
+ module AppSec
5
+ # A namespace for API Security features.
6
+ module APISecurity
7
+ end
8
+ end
9
+ end