datadog 2.12.1 → 2.19.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (346) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +243 -2
  3. data/ext/datadog_profiling_native_extension/collectors_cpu_and_wall_time_worker.c +63 -56
  4. data/ext/datadog_profiling_native_extension/collectors_stack.c +263 -76
  5. data/ext/datadog_profiling_native_extension/collectors_stack.h +20 -3
  6. data/ext/datadog_profiling_native_extension/collectors_thread_context.c +78 -26
  7. data/ext/datadog_profiling_native_extension/collectors_thread_context.h +1 -0
  8. data/ext/datadog_profiling_native_extension/datadog_ruby_common.c +1 -4
  9. data/ext/datadog_profiling_native_extension/datadog_ruby_common.h +10 -0
  10. data/ext/datadog_profiling_native_extension/encoded_profile.c +79 -0
  11. data/ext/datadog_profiling_native_extension/encoded_profile.h +8 -0
  12. data/ext/datadog_profiling_native_extension/extconf.rb +10 -0
  13. data/ext/datadog_profiling_native_extension/heap_recorder.c +247 -364
  14. data/ext/datadog_profiling_native_extension/heap_recorder.h +4 -6
  15. data/ext/datadog_profiling_native_extension/http_transport.c +60 -94
  16. data/ext/datadog_profiling_native_extension/libdatadog_helpers.c +22 -0
  17. data/ext/datadog_profiling_native_extension/libdatadog_helpers.h +8 -5
  18. data/ext/datadog_profiling_native_extension/private_vm_api_access.c +41 -21
  19. data/ext/datadog_profiling_native_extension/private_vm_api_access.h +6 -4
  20. data/ext/datadog_profiling_native_extension/profiling.c +2 -0
  21. data/ext/datadog_profiling_native_extension/ruby_helpers.c +1 -13
  22. data/ext/datadog_profiling_native_extension/ruby_helpers.h +3 -11
  23. data/ext/datadog_profiling_native_extension/stack_recorder.c +173 -76
  24. data/ext/libdatadog_api/crashtracker.c +11 -12
  25. data/ext/libdatadog_api/crashtracker.h +5 -0
  26. data/ext/libdatadog_api/datadog_ruby_common.c +1 -4
  27. data/ext/libdatadog_api/datadog_ruby_common.h +10 -0
  28. data/ext/libdatadog_api/extconf.rb +2 -2
  29. data/ext/libdatadog_api/init.c +15 -0
  30. data/ext/libdatadog_api/library_config.c +164 -0
  31. data/ext/libdatadog_api/library_config.h +25 -0
  32. data/ext/libdatadog_api/macos_development.md +3 -3
  33. data/ext/libdatadog_api/process_discovery.c +112 -0
  34. data/ext/libdatadog_api/process_discovery.h +5 -0
  35. data/ext/libdatadog_extconf_helpers.rb +2 -2
  36. data/lib/datadog/appsec/actions_handler/serializable_backtrace.rb +89 -0
  37. data/lib/datadog/appsec/actions_handler.rb +24 -2
  38. data/lib/datadog/appsec/anonymizer.rb +16 -0
  39. data/lib/datadog/appsec/api_security/lru_cache.rb +56 -0
  40. data/lib/datadog/appsec/api_security/route_extractor.rb +71 -0
  41. data/lib/datadog/appsec/api_security/sampler.rb +59 -0
  42. data/lib/datadog/appsec/api_security.rb +23 -0
  43. data/lib/datadog/appsec/assets/waf_rules/README.md +50 -5
  44. data/lib/datadog/appsec/assets/waf_rules/recommended.json +257 -85
  45. data/lib/datadog/appsec/assets/waf_rules/strict.json +10 -78
  46. data/lib/datadog/appsec/autoload.rb +1 -1
  47. data/lib/datadog/appsec/component.rb +46 -61
  48. data/lib/datadog/appsec/compressed_json.rb +40 -0
  49. data/lib/datadog/appsec/configuration/settings.rb +153 -30
  50. data/lib/datadog/appsec/context.rb +7 -7
  51. data/lib/datadog/appsec/contrib/active_record/instrumentation.rb +10 -12
  52. data/lib/datadog/appsec/contrib/active_record/integration.rb +2 -2
  53. data/lib/datadog/appsec/contrib/active_record/patcher.rb +22 -22
  54. data/lib/datadog/appsec/contrib/auto_instrument.rb +1 -1
  55. data/lib/datadog/appsec/contrib/devise/configuration.rb +7 -31
  56. data/lib/datadog/appsec/contrib/devise/data_extractor.rb +78 -0
  57. data/lib/datadog/appsec/contrib/devise/ext.rb +22 -0
  58. data/lib/datadog/appsec/contrib/devise/integration.rb +1 -2
  59. data/lib/datadog/appsec/contrib/devise/patcher.rb +34 -23
  60. data/lib/datadog/appsec/contrib/devise/patches/signin_tracking_patch.rb +102 -0
  61. data/lib/datadog/appsec/contrib/devise/patches/signup_tracking_patch.rb +69 -0
  62. data/lib/datadog/appsec/contrib/devise/{patcher/rememberable_patch.rb → patches/skip_signin_tracking_patch.rb} +2 -2
  63. data/lib/datadog/appsec/contrib/devise/tracking_middleware.rb +106 -0
  64. data/lib/datadog/appsec/contrib/excon/integration.rb +1 -1
  65. data/lib/datadog/appsec/contrib/excon/ssrf_detection_middleware.rb +9 -10
  66. data/lib/datadog/appsec/contrib/faraday/integration.rb +1 -1
  67. data/lib/datadog/appsec/contrib/faraday/ssrf_detection_middleware.rb +8 -9
  68. data/lib/datadog/appsec/contrib/graphql/gateway/watcher.rb +8 -9
  69. data/lib/datadog/appsec/contrib/graphql/integration.rb +1 -1
  70. data/lib/datadog/appsec/contrib/rack/ext.rb +34 -0
  71. data/lib/datadog/appsec/contrib/rack/gateway/watcher.rb +49 -32
  72. data/lib/datadog/appsec/contrib/rack/integration.rb +1 -1
  73. data/lib/datadog/appsec/contrib/rack/request_middleware.rb +42 -30
  74. data/lib/datadog/appsec/contrib/rails/gateway/watcher.rb +11 -13
  75. data/lib/datadog/appsec/contrib/rails/integration.rb +1 -1
  76. data/lib/datadog/appsec/contrib/rails/patcher.rb +21 -21
  77. data/lib/datadog/appsec/contrib/rest_client/integration.rb +1 -1
  78. data/lib/datadog/appsec/contrib/rest_client/request_ssrf_detection_patch.rb +10 -11
  79. data/lib/datadog/appsec/contrib/sinatra/gateway/watcher.rb +17 -23
  80. data/lib/datadog/appsec/contrib/sinatra/integration.rb +1 -1
  81. data/lib/datadog/appsec/event.rb +96 -135
  82. data/lib/datadog/appsec/ext.rb +4 -2
  83. data/lib/datadog/appsec/instrumentation/gateway/argument.rb +7 -2
  84. data/lib/datadog/appsec/instrumentation/gateway/middleware.rb +24 -0
  85. data/lib/datadog/appsec/instrumentation/gateway.rb +17 -22
  86. data/lib/datadog/appsec/metrics/telemetry.rb +1 -1
  87. data/lib/datadog/appsec/monitor/gateway/watcher.rb +49 -14
  88. data/lib/datadog/appsec/processor/rule_loader.rb +30 -33
  89. data/lib/datadog/appsec/remote.rb +31 -59
  90. data/lib/datadog/appsec/response.rb +6 -6
  91. data/lib/datadog/appsec/security_engine/engine.rb +194 -0
  92. data/lib/datadog/appsec/security_engine/runner.rb +13 -14
  93. data/lib/datadog/appsec/security_event.rb +39 -0
  94. data/lib/datadog/appsec/utils.rb +0 -2
  95. data/lib/datadog/appsec.rb +5 -8
  96. data/lib/datadog/core/buffer/random.rb +18 -2
  97. data/lib/datadog/core/configuration/agent_settings.rb +52 -0
  98. data/lib/datadog/core/configuration/agent_settings_resolver.rb +4 -46
  99. data/lib/datadog/core/configuration/agentless_settings_resolver.rb +176 -0
  100. data/lib/datadog/core/configuration/components.rb +48 -31
  101. data/lib/datadog/core/configuration/components_state.rb +23 -0
  102. data/lib/datadog/core/configuration/ext.rb +4 -0
  103. data/lib/datadog/core/configuration/option.rb +81 -45
  104. data/lib/datadog/core/configuration/option_definition.rb +4 -4
  105. data/lib/datadog/core/configuration/options.rb +3 -3
  106. data/lib/datadog/core/configuration/settings.rb +109 -44
  107. data/lib/datadog/core/configuration/stable_config.rb +22 -0
  108. data/lib/datadog/core/configuration.rb +40 -16
  109. data/lib/datadog/core/crashtracking/component.rb +3 -10
  110. data/lib/datadog/core/crashtracking/tag_builder.rb +4 -22
  111. data/lib/datadog/core/diagnostics/environment_logger.rb +1 -1
  112. data/lib/datadog/core/encoding.rb +1 -1
  113. data/lib/datadog/core/environment/agent_info.rb +4 -3
  114. data/lib/datadog/core/environment/cgroup.rb +10 -12
  115. data/lib/datadog/core/environment/container.rb +38 -40
  116. data/lib/datadog/core/environment/ext.rb +6 -6
  117. data/lib/datadog/core/environment/git.rb +1 -0
  118. data/lib/datadog/core/environment/identity.rb +3 -3
  119. data/lib/datadog/core/environment/platform.rb +3 -3
  120. data/lib/datadog/core/environment/variable_helpers.rb +1 -1
  121. data/lib/datadog/core/error.rb +11 -9
  122. data/lib/datadog/core/logger.rb +2 -2
  123. data/lib/datadog/core/metrics/client.rb +20 -21
  124. data/lib/datadog/core/metrics/logging.rb +5 -5
  125. data/lib/datadog/core/process_discovery/tracer_memfd.rb +15 -0
  126. data/lib/datadog/core/process_discovery.rb +36 -0
  127. data/lib/datadog/core/rate_limiter.rb +4 -2
  128. data/lib/datadog/core/remote/client.rb +40 -32
  129. data/lib/datadog/core/remote/component.rb +6 -9
  130. data/lib/datadog/core/remote/configuration/digest.rb +7 -7
  131. data/lib/datadog/core/remote/configuration/path.rb +1 -1
  132. data/lib/datadog/core/remote/configuration/repository.rb +14 -1
  133. data/lib/datadog/core/remote/negotiation.rb +9 -9
  134. data/lib/datadog/core/remote/transport/config.rb +4 -3
  135. data/lib/datadog/core/remote/transport/http/client.rb +5 -4
  136. data/lib/datadog/core/remote/transport/http/config.rb +27 -37
  137. data/lib/datadog/core/remote/transport/http/negotiation.rb +7 -33
  138. data/lib/datadog/core/remote/transport/http.rb +22 -57
  139. data/lib/datadog/core/remote/transport/negotiation.rb +4 -3
  140. data/lib/datadog/core/runtime/metrics.rb +12 -5
  141. data/lib/datadog/core/tag_builder.rb +56 -0
  142. data/lib/datadog/core/telemetry/component.rb +81 -52
  143. data/lib/datadog/core/telemetry/emitter.rb +23 -11
  144. data/lib/datadog/core/telemetry/event/app_client_configuration_change.rb +66 -0
  145. data/lib/datadog/core/telemetry/event/app_closing.rb +18 -0
  146. data/lib/datadog/core/telemetry/event/app_dependencies_loaded.rb +33 -0
  147. data/lib/datadog/core/telemetry/event/app_heartbeat.rb +18 -0
  148. data/lib/datadog/core/telemetry/event/app_integrations_change.rb +58 -0
  149. data/lib/datadog/core/telemetry/event/app_started.rb +287 -0
  150. data/lib/datadog/core/telemetry/event/base.rb +40 -0
  151. data/lib/datadog/core/telemetry/event/distributions.rb +18 -0
  152. data/lib/datadog/core/telemetry/event/generate_metrics.rb +43 -0
  153. data/lib/datadog/core/telemetry/event/log.rb +76 -0
  154. data/lib/datadog/core/telemetry/event/message_batch.rb +42 -0
  155. data/lib/datadog/core/telemetry/event/synth_app_client_configuration_change.rb +43 -0
  156. data/lib/datadog/core/telemetry/event.rb +17 -472
  157. data/lib/datadog/core/telemetry/http/adapters/net.rb +12 -97
  158. data/lib/datadog/core/telemetry/logger.rb +5 -4
  159. data/lib/datadog/core/telemetry/logging.rb +11 -5
  160. data/lib/datadog/core/telemetry/metric.rb +8 -8
  161. data/lib/datadog/core/telemetry/request.rb +4 -4
  162. data/lib/datadog/core/telemetry/transport/http/api.rb +43 -0
  163. data/lib/datadog/core/telemetry/transport/http/client.rb +49 -0
  164. data/lib/datadog/core/telemetry/transport/http/telemetry.rb +92 -0
  165. data/lib/datadog/core/telemetry/transport/http.rb +63 -0
  166. data/lib/datadog/core/telemetry/transport/telemetry.rb +51 -0
  167. data/lib/datadog/core/telemetry/worker.rb +90 -24
  168. data/lib/datadog/core/transport/http/adapters/net.rb +17 -2
  169. data/lib/datadog/core/transport/http/adapters/test.rb +2 -1
  170. data/lib/datadog/core/transport/http/api/instance.rb +17 -0
  171. data/lib/datadog/core/transport/http/api/spec.rb +17 -0
  172. data/lib/datadog/core/transport/http/builder.rb +19 -17
  173. data/lib/datadog/core/transport/http/env.rb +8 -0
  174. data/lib/datadog/core/transport/http.rb +39 -2
  175. data/lib/datadog/core/utils/at_fork_monkey_patch.rb +6 -6
  176. data/lib/datadog/core/utils/duration.rb +32 -32
  177. data/lib/datadog/core/utils/forking.rb +2 -2
  178. data/lib/datadog/core/utils/network.rb +6 -6
  179. data/lib/datadog/core/utils/only_once_successful.rb +16 -5
  180. data/lib/datadog/core/utils/time.rb +20 -0
  181. data/lib/datadog/core/utils/truncation.rb +21 -0
  182. data/lib/datadog/core/utils.rb +7 -0
  183. data/lib/datadog/core/vendor/multipart-post/multipart/post/composite_read_io.rb +1 -1
  184. data/lib/datadog/core/vendor/multipart-post/multipart/post/multipartable.rb +8 -8
  185. data/lib/datadog/core/vendor/multipart-post/multipart/post/parts.rb +7 -7
  186. data/lib/datadog/core/worker.rb +1 -1
  187. data/lib/datadog/core/workers/async.rb +29 -12
  188. data/lib/datadog/core/workers/interval_loop.rb +12 -1
  189. data/lib/datadog/core/workers/runtime_metrics.rb +2 -2
  190. data/lib/datadog/core.rb +8 -0
  191. data/lib/datadog/di/boot.rb +34 -0
  192. data/lib/datadog/di/component.rb +0 -2
  193. data/lib/datadog/di/instrumenter.rb +48 -5
  194. data/lib/datadog/di/probe_notification_builder.rb +38 -43
  195. data/lib/datadog/di/probe_notifier_worker.rb +25 -17
  196. data/lib/datadog/di/remote.rb +2 -0
  197. data/lib/datadog/di/serializer.rb +10 -2
  198. data/lib/datadog/di/transport/diagnostics.rb +4 -3
  199. data/lib/datadog/di/transport/http/api.rb +2 -12
  200. data/lib/datadog/di/transport/http/client.rb +4 -3
  201. data/lib/datadog/di/transport/http/diagnostics.rb +7 -34
  202. data/lib/datadog/di/transport/http/input.rb +18 -35
  203. data/lib/datadog/di/transport/http.rb +14 -62
  204. data/lib/datadog/di/transport/input.rb +14 -5
  205. data/lib/datadog/di/utils.rb +5 -0
  206. data/lib/datadog/di.rb +0 -33
  207. data/lib/datadog/error_tracking/collector.rb +87 -0
  208. data/lib/datadog/error_tracking/component.rb +167 -0
  209. data/lib/datadog/error_tracking/configuration/settings.rb +63 -0
  210. data/lib/datadog/error_tracking/configuration.rb +11 -0
  211. data/lib/datadog/error_tracking/ext.rb +18 -0
  212. data/lib/datadog/error_tracking/extensions.rb +16 -0
  213. data/lib/datadog/error_tracking/filters.rb +77 -0
  214. data/lib/datadog/error_tracking.rb +18 -0
  215. data/lib/datadog/kit/appsec/events/v2.rb +195 -0
  216. data/lib/datadog/kit/appsec/events.rb +12 -0
  217. data/lib/datadog/kit/identity.rb +5 -1
  218. data/lib/datadog/opentelemetry/api/baggage.rb +90 -0
  219. data/lib/datadog/opentelemetry/api/baggage.rbs +26 -0
  220. data/lib/datadog/opentelemetry/api/context.rb +16 -2
  221. data/lib/datadog/opentelemetry/sdk/trace/span.rb +1 -1
  222. data/lib/datadog/opentelemetry.rb +2 -1
  223. data/lib/datadog/profiling/collectors/code_provenance.rb +18 -9
  224. data/lib/datadog/profiling/collectors/cpu_and_wall_time_worker.rb +6 -0
  225. data/lib/datadog/profiling/collectors/idle_sampling_helper.rb +1 -0
  226. data/lib/datadog/profiling/collectors/info.rb +44 -0
  227. data/lib/datadog/profiling/collectors/thread_context.rb +17 -2
  228. data/lib/datadog/profiling/component.rb +8 -9
  229. data/lib/datadog/profiling/encoded_profile.rb +11 -0
  230. data/lib/datadog/profiling/exporter.rb +12 -7
  231. data/lib/datadog/profiling/ext.rb +0 -14
  232. data/lib/datadog/profiling/flush.rb +5 -8
  233. data/lib/datadog/profiling/http_transport.rb +7 -61
  234. data/lib/datadog/profiling/profiler.rb +2 -0
  235. data/lib/datadog/profiling/scheduler.rb +10 -2
  236. data/lib/datadog/profiling/sequence_tracker.rb +44 -0
  237. data/lib/datadog/profiling/stack_recorder.rb +9 -9
  238. data/lib/datadog/profiling/tag_builder.rb +7 -41
  239. data/lib/datadog/profiling/tasks/setup.rb +2 -0
  240. data/lib/datadog/profiling.rb +7 -2
  241. data/lib/datadog/single_step_instrument.rb +9 -0
  242. data/lib/datadog/tracing/analytics.rb +1 -1
  243. data/lib/datadog/tracing/component.rb +15 -12
  244. data/lib/datadog/tracing/configuration/ext.rb +7 -1
  245. data/lib/datadog/tracing/configuration/settings.rb +18 -2
  246. data/lib/datadog/tracing/context_provider.rb +1 -1
  247. data/lib/datadog/tracing/contrib/action_pack/action_controller/instrumentation.rb +15 -0
  248. data/lib/datadog/tracing/contrib/action_pack/action_dispatch/instrumentation.rb +19 -12
  249. data/lib/datadog/tracing/contrib/action_pack/ext.rb +2 -0
  250. data/lib/datadog/tracing/contrib/active_record/integration.rb +1 -1
  251. data/lib/datadog/tracing/contrib/active_support/cache/events/cache.rb +11 -2
  252. data/lib/datadog/tracing/contrib/active_support/cache/instrumentation.rb +33 -0
  253. data/lib/datadog/tracing/contrib/active_support/cache/patcher.rb +4 -0
  254. data/lib/datadog/tracing/contrib/active_support/cache/redis.rb +2 -4
  255. data/lib/datadog/tracing/contrib/active_support/configuration/settings.rb +13 -0
  256. data/lib/datadog/tracing/contrib/aws/instrumentation.rb +10 -0
  257. data/lib/datadog/tracing/contrib/aws/parsed_context.rb +5 -1
  258. data/lib/datadog/tracing/contrib/configuration/settings.rb +1 -1
  259. data/lib/datadog/tracing/contrib/ethon/easy_patch.rb +4 -5
  260. data/lib/datadog/tracing/contrib/excon/middleware.rb +5 -3
  261. data/lib/datadog/tracing/contrib/ext.rb +1 -0
  262. data/lib/datadog/tracing/contrib/faraday/middleware.rb +5 -3
  263. data/lib/datadog/tracing/contrib/grpc/datadog_interceptor/client.rb +7 -1
  264. data/lib/datadog/tracing/contrib/grpc/distributed/propagation.rb +3 -0
  265. data/lib/datadog/tracing/contrib/http/circuit_breaker.rb +0 -15
  266. data/lib/datadog/tracing/contrib/http/distributed/propagation.rb +4 -1
  267. data/lib/datadog/tracing/contrib/http/instrumentation.rb +6 -10
  268. data/lib/datadog/tracing/contrib/httpclient/instrumentation.rb +6 -16
  269. data/lib/datadog/tracing/contrib/httprb/instrumentation.rb +7 -15
  270. data/lib/datadog/tracing/contrib/karafka/configuration/settings.rb +27 -0
  271. data/lib/datadog/tracing/contrib/karafka/distributed/propagation.rb +48 -0
  272. data/lib/datadog/tracing/contrib/karafka/ext.rb +27 -0
  273. data/lib/datadog/tracing/contrib/karafka/integration.rb +45 -0
  274. data/lib/datadog/tracing/contrib/karafka/monitor.rb +66 -0
  275. data/lib/datadog/tracing/contrib/karafka/patcher.rb +71 -0
  276. data/lib/datadog/tracing/contrib/karafka.rb +37 -0
  277. data/lib/datadog/tracing/contrib/lograge/patcher.rb +4 -2
  278. data/lib/datadog/tracing/contrib/mongodb/configuration/settings.rb +8 -0
  279. data/lib/datadog/tracing/contrib/mongodb/ext.rb +1 -0
  280. data/lib/datadog/tracing/contrib/mongodb/subscribers.rb +18 -1
  281. data/lib/datadog/tracing/contrib/mysql2/instrumentation.rb +16 -6
  282. data/lib/datadog/tracing/contrib/opensearch/configuration/settings.rb +17 -0
  283. data/lib/datadog/tracing/contrib/opensearch/ext.rb +9 -0
  284. data/lib/datadog/tracing/contrib/opensearch/patcher.rb +5 -1
  285. data/lib/datadog/tracing/contrib/patcher.rb +5 -2
  286. data/lib/datadog/tracing/contrib/rack/request_queue.rb +1 -1
  287. data/lib/datadog/tracing/contrib/rails/patcher.rb +4 -1
  288. data/lib/datadog/tracing/contrib/rails/runner.rb +61 -40
  289. data/lib/datadog/tracing/contrib/rest_client/request_patch.rb +5 -3
  290. data/lib/datadog/tracing/contrib/sidekiq/client_tracer.rb +6 -1
  291. data/lib/datadog/tracing/contrib/sidekiq/distributed/propagation.rb +3 -0
  292. data/lib/datadog/tracing/contrib/sidekiq/ext.rb +1 -0
  293. data/lib/datadog/tracing/contrib/sidekiq/server_tracer.rb +5 -2
  294. data/lib/datadog/tracing/contrib/support.rb +28 -0
  295. data/lib/datadog/tracing/contrib.rb +1 -0
  296. data/lib/datadog/tracing/correlation.rb +9 -2
  297. data/lib/datadog/tracing/diagnostics/environment_logger.rb +3 -1
  298. data/lib/datadog/tracing/distributed/b3_multi.rb +1 -1
  299. data/lib/datadog/tracing/distributed/b3_single.rb +1 -1
  300. data/lib/datadog/tracing/distributed/baggage.rb +131 -0
  301. data/lib/datadog/tracing/distributed/datadog.rb +4 -2
  302. data/lib/datadog/tracing/distributed/propagation.rb +25 -4
  303. data/lib/datadog/tracing/distributed/propagation_policy.rb +42 -0
  304. data/lib/datadog/tracing/metadata/errors.rb +4 -4
  305. data/lib/datadog/tracing/metadata/ext.rb +5 -0
  306. data/lib/datadog/tracing/metadata/metastruct.rb +36 -0
  307. data/lib/datadog/tracing/metadata/metastruct_tagging.rb +42 -0
  308. data/lib/datadog/tracing/metadata.rb +2 -0
  309. data/lib/datadog/tracing/sampling/rate_sampler.rb +2 -1
  310. data/lib/datadog/tracing/sampling/span/rule.rb +0 -1
  311. data/lib/datadog/tracing/span.rb +10 -1
  312. data/lib/datadog/tracing/span_event.rb +2 -2
  313. data/lib/datadog/tracing/span_operation.rb +68 -16
  314. data/lib/datadog/tracing/sync_writer.rb +2 -3
  315. data/lib/datadog/tracing/trace_digest.rb +9 -2
  316. data/lib/datadog/tracing/trace_operation.rb +55 -27
  317. data/lib/datadog/tracing/trace_segment.rb +6 -4
  318. data/lib/datadog/tracing/tracer.rb +51 -7
  319. data/lib/datadog/tracing/transport/http/api.rb +2 -10
  320. data/lib/datadog/tracing/transport/http/client.rb +5 -4
  321. data/lib/datadog/tracing/transport/http/traces.rb +13 -41
  322. data/lib/datadog/tracing/transport/http.rb +11 -44
  323. data/lib/datadog/tracing/transport/serializable_trace.rb +3 -1
  324. data/lib/datadog/tracing/transport/trace_formatter.rb +7 -0
  325. data/lib/datadog/tracing/transport/traces.rb +26 -9
  326. data/lib/datadog/tracing/utils.rb +1 -1
  327. data/lib/datadog/tracing/workers/trace_writer.rb +2 -6
  328. data/lib/datadog/tracing/writer.rb +2 -6
  329. data/lib/datadog/tracing.rb +16 -3
  330. data/lib/datadog/version.rb +2 -2
  331. data/lib/datadog.rb +8 -2
  332. metadata +88 -23
  333. data/lib/datadog/appsec/assets/waf_rules/processors.json +0 -92
  334. data/lib/datadog/appsec/assets/waf_rules/scanners.json +0 -114
  335. data/lib/datadog/appsec/contrib/devise/event.rb +0 -54
  336. data/lib/datadog/appsec/contrib/devise/patcher/authenticatable_patch.rb +0 -72
  337. data/lib/datadog/appsec/contrib/devise/patcher/registration_controller_patch.rb +0 -47
  338. data/lib/datadog/appsec/contrib/devise/resource.rb +0 -35
  339. data/lib/datadog/appsec/contrib/devise/tracking.rb +0 -57
  340. data/lib/datadog/appsec/processor/rule_merger.rb +0 -170
  341. data/lib/datadog/appsec/processor.rb +0 -107
  342. data/lib/datadog/appsec/utils/trace_operation.rb +0 -15
  343. data/lib/datadog/core/telemetry/http/env.rb +0 -20
  344. data/lib/datadog/core/telemetry/http/ext.rb +0 -28
  345. data/lib/datadog/core/telemetry/http/response.rb +0 -70
  346. data/lib/datadog/core/telemetry/http/transport.rb +0 -90
@@ -0,0 +1,195 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative '../../identity'
4
+
5
+ module Datadog
6
+ module Kit
7
+ module AppSec
8
+ module Events
9
+ # The second version of Business Logic Events SDK
10
+ module V2
11
+ LOGIN_SUCCESS_EVENT = 'users.login.success'
12
+ LOGIN_FAILURE_EVENT = 'users.login.failure'
13
+ TELEMETRY_METRICS_NAMESPACE = 'appsec'
14
+ TELEMETRY_METRICS_SDK_EVENT = 'sdk.event'
15
+ TELEMETRY_METRICS_SDK_VERSION = 'v2'
16
+ TELEMETRY_METRICS_EVENTS_INTO_TYPES = {
17
+ LOGIN_SUCCESS_EVENT => 'login_success',
18
+ LOGIN_FAILURE_EVENT => 'login_failure'
19
+ }.freeze
20
+
21
+ class << self
22
+ # Attach user login success information to the service entry span
23
+ # and trigger AppSec event processing.
24
+ #
25
+ # @param login [String] The user login (e.g., username or email).
26
+ # @param user_or_id [String, Hash<Symbol, String>] (optional) If a
27
+ # String, considered as a user ID, if a Hash, considered as a user
28
+ # attributes. The Hash must include `:id` as a key.
29
+ # @param metadata [Hash<Symbol, String>] Additional flat free-form
30
+ # metadata to attach to the event.
31
+ #
32
+ # @example Login only
33
+ # Datadog::Kit::AppSec::Events::V2.track_user_login_success('alice@example.com')
34
+ #
35
+ # @example Login and user attributes
36
+ # Datadog::Kit::AppSec::Events::V2.track_user_login_success(
37
+ # 'alice@example.com',
38
+ # { id: 'user-123', email: 'alice@example.com', name: 'Alice' },
39
+ # ip: '192.168.1.1', device: 'mobile', 'usr.country': 'US'
40
+ # )
41
+ #
42
+ # @return [void]
43
+ def track_user_login_success(login, user_or_id = nil, metadata = {})
44
+ trace = service_entry_trace
45
+ span = service_entry_span
46
+
47
+ if trace.nil? || span.nil?
48
+ return Datadog.logger.warn(
49
+ 'Kit::AppSec: Tracing is not enabled. Please enable tracing if you want to track events'
50
+ )
51
+ end
52
+
53
+ raise TypeError, '`login` argument must be a String' unless login.is_a?(String)
54
+ raise TypeError, '`metadata` argument must be a Hash' unless metadata.is_a?(Hash)
55
+
56
+ user_attributes = build_user_attributes(user_or_id, login)
57
+
58
+ set_span_tags(span, metadata, namespace: LOGIN_SUCCESS_EVENT)
59
+ set_span_tags(span, user_attributes, namespace: "#{LOGIN_SUCCESS_EVENT}.usr")
60
+ span.set_tag('appsec.events.users.login.success.track', 'true')
61
+ span.set_tag('_dd.appsec.events.users.login.success.sdk', 'true')
62
+
63
+ trace.keep!
64
+
65
+ record_event_telemetry_metric(LOGIN_SUCCESS_EVENT)
66
+ ::Datadog::AppSec::Instrumentation.gateway.push('appsec.events.user_lifecycle', LOGIN_SUCCESS_EVENT)
67
+
68
+ # NOTE: Guard-clause will not work with Steep typechecking
69
+ return Kit::Identity.set_user(trace, span, **user_attributes) if user_attributes.key?(:id) # steep:ignore
70
+
71
+ # NOTE: This is a fallback for the case when we don't have an ID,
72
+ # but need to trigger WAF.
73
+ user = ::Datadog::AppSec::Instrumentation::Gateway::User.new(nil, login)
74
+ ::Datadog::AppSec::Instrumentation.gateway.push('identity.set_user', user)
75
+ end
76
+
77
+ # Attach user login failure information to the service entry span
78
+ # and trigger AppSec event processing.
79
+ #
80
+ # @param login [String] The user login (e.g., username or email).
81
+ # @param user_exists [Boolean] Whether the user exists in the system.
82
+ # @param metadata [Hash<Symbol, String>] Additional flat free-form
83
+ # metadata to attach to the event.
84
+ #
85
+ # @example Login only
86
+ # Datadog::Kit::AppSec::Events::V2.track_user_login_failure('alice@example.com')
87
+ #
88
+ # @example With user existence and metadata
89
+ # Datadog::Kit::AppSec::Events::V2.track_user_login_failure(
90
+ # 'alice@example.com',
91
+ # true,
92
+ # ip: '192.168.1.1', device: 'mobile', 'usr.country': 'US'
93
+ # )
94
+ #
95
+ # @return [void]
96
+ def track_user_login_failure(login, user_exists = false, metadata = {})
97
+ trace = service_entry_trace
98
+ span = service_entry_span
99
+
100
+ if trace.nil? || span.nil?
101
+ return Datadog.logger.warn(
102
+ 'Kit::AppSec: Tracing is not enabled. Please enable tracing if you want to track events'
103
+ )
104
+ end
105
+
106
+ raise TypeError, '`login` argument must be a String' unless login.is_a?(String)
107
+ raise TypeError, '`metadata` argument must be a Hash' unless metadata.is_a?(Hash)
108
+
109
+ unless user_exists.is_a?(TrueClass) || user_exists.is_a?(FalseClass)
110
+ raise TypeError, '`user_exists` argument must be a boolean'
111
+ end
112
+
113
+ set_span_tags(span, metadata, namespace: LOGIN_FAILURE_EVENT)
114
+ span.set_tag('appsec.events.users.login.failure.track', 'true')
115
+ span.set_tag('_dd.appsec.events.users.login.failure.sdk', 'true')
116
+ span.set_tag('appsec.events.users.login.failure.usr.login', login)
117
+ span.set_tag('appsec.events.users.login.failure.usr.exists', user_exists.to_s)
118
+
119
+ trace.keep!
120
+
121
+ record_event_telemetry_metric(LOGIN_FAILURE_EVENT)
122
+ ::Datadog::AppSec::Instrumentation.gateway.push('appsec.events.user_lifecycle', LOGIN_FAILURE_EVENT)
123
+
124
+ user = ::Datadog::AppSec::Instrumentation::Gateway::User.new(nil, login)
125
+ ::Datadog::AppSec::Instrumentation.gateway.push('identity.set_user', user)
126
+ end
127
+
128
+ private
129
+
130
+ # NOTE: Current tracer implementation does not provide a way to
131
+ # get the service entry span. This is a shortcut we take now.
132
+ def service_entry_trace
133
+ return Datadog::Tracing.active_trace unless Datadog::AppSec.active_context
134
+
135
+ Datadog::AppSec.active_context&.trace
136
+ end
137
+
138
+ # NOTE: Current tracer implementation does not provide a way to
139
+ # get the service entry span. This is a shortcut we take now.
140
+ def service_entry_span
141
+ return Datadog::Tracing.active_span unless Datadog::AppSec.active_context
142
+
143
+ Datadog::AppSec.active_context&.span
144
+ end
145
+
146
+ def build_user_attributes(user_or_id, login)
147
+ raise TypeError, '`login` argument must be a String' unless login.is_a?(String)
148
+
149
+ case user_or_id
150
+ when nil
151
+ { login: login }
152
+ when String
153
+ { login: login, id: user_or_id }
154
+ when Hash
155
+ raise ArgumentError, 'missing required user key `:id`' unless user_or_id.key?(:id)
156
+ raise TypeError, 'user key `:id` must be a String' unless user_or_id[:id].is_a?(String)
157
+
158
+ user_or_id.merge(login: login)
159
+ else
160
+ raise TypeError, '`user_or_id` argument must be either String or Hash'
161
+ end
162
+ end
163
+
164
+ def set_span_tags(span, tags, namespace:)
165
+ tags.each do |name, value|
166
+ next if value.nil?
167
+
168
+ span.set_tag("appsec.events.#{namespace}.#{name}", value)
169
+ end
170
+ end
171
+
172
+ # TODO: In case if we need to introduce telemetry metrics to the SDK v1
173
+ # or highly increase the number of metrics, this method should be
174
+ # extracted into a proper module.
175
+ def record_event_telemetry_metric(event)
176
+ telemetry = ::Datadog.send(:components, allow_initialization: false)&.telemetry
177
+
178
+ if telemetry.nil?
179
+ return Datadog.logger.debug(
180
+ 'Kit::AppSec: Telemetry component is unavailable. Skip recording SDK metrics'
181
+ )
182
+ end
183
+
184
+ tags = {
185
+ event_type: TELEMETRY_METRICS_EVENTS_INTO_TYPES[event],
186
+ sdk_version: TELEMETRY_METRICS_SDK_VERSION
187
+ }
188
+ telemetry.inc(TELEMETRY_METRICS_NAMESPACE, TELEMETRY_METRICS_SDK_EVENT, 1, tags: tags)
189
+ end
190
+ end
191
+ end
192
+ end
193
+ end
194
+ end
195
+ end
@@ -10,6 +10,7 @@ module Datadog
10
10
  LOGIN_SUCCESS_EVENT = 'users.login.success'
11
11
  LOGIN_FAILURE_EVENT = 'users.login.failure'
12
12
  SIGNUP_EVENT = 'users.signup'
13
+ USER_LOGIN_KEYS = ['usr.login', :'usr.login'].freeze
13
14
 
14
15
  class << self
15
16
  # Attach login success event information to the trace
@@ -30,11 +31,15 @@ module Datadog
30
31
  set_trace_and_span_context('track_login_success', trace, span) do |active_trace, active_span|
31
32
  user_options = user.dup
32
33
  user_id = user_options.delete(:id)
34
+ user_login = user_options[:login] || others[:'usr.login'] || others['usr.login'] || user_id
33
35
 
34
36
  raise ArgumentError, 'missing required key: :user => { :id }' if user_id.nil?
35
37
 
38
+ others = others.reject { |key, _| USER_LOGIN_KEYS.include?(key) }
39
+ others[:'usr.login'] = user_login
36
40
  track(LOGIN_SUCCESS_EVENT, active_trace, active_span, **others)
37
41
 
42
+ user_options[:login] = user_login
38
43
  Kit::Identity.set_user(active_trace, active_span, id: user_id, **user_options)
39
44
  end
40
45
  end
@@ -55,6 +60,7 @@ module Datadog
55
60
  # event information to attach to the trace.
56
61
  def track_login_failure(trace = nil, span = nil, user_exists:, user_id: nil, **others)
57
62
  set_trace_and_span_context('track_login_failure', trace, span) do |active_trace, active_span|
63
+ others[:'usr.login'] = user_id if user_id && !others.key?(:'usr.login') && !others.key?('usr.login')
58
64
  track(LOGIN_FAILURE_EVENT, active_trace, active_span, **others)
59
65
 
60
66
  active_span.set_tag('appsec.events.users.login.failure.usr.id', user_id) if user_id
@@ -80,11 +86,15 @@ module Datadog
80
86
  set_trace_and_span_context('track_signup', trace, span) do |active_trace, active_span|
81
87
  user_options = user.dup
82
88
  user_id = user_options.delete(:id)
89
+ user_login = user_options[:login] || others[:'usr.login'] || others['usr.login'] || user_id
83
90
 
84
91
  raise ArgumentError, 'missing required key: :user => { :id }' if user_id.nil?
85
92
 
93
+ others = others.reject { |key, _| USER_LOGIN_KEYS.include?(key) }
94
+ others[:'usr.login'] = user_login
86
95
  track(SIGNUP_EVENT, active_trace, active_span, **others)
87
96
 
97
+ user_options[:login] = user_login
88
98
  Kit::Identity.set_user(trace, id: user_id, **user_options)
89
99
  end
90
100
  end
@@ -131,6 +141,8 @@ module Datadog
131
141
  active_trace.keep!
132
142
  end
133
143
  end
144
+
145
+ ::Datadog::AppSec::Instrumentation.gateway.push('appsec.events.user_lifecycle', event)
134
146
  end
135
147
 
136
148
  private
@@ -33,6 +33,7 @@ module Datadog
33
33
  # @param others [Hash<Symbol, String>] Additional free-form
34
34
  # user information to attach to the trace.
35
35
  #
36
+ # rubocop:disable Metrics/AbcSize
36
37
  # rubocop:disable Metrics/CyclomaticComplexity
37
38
  # rubocop:disable Metrics/PerceivedComplexity
38
39
  def set_user(
@@ -67,11 +68,14 @@ module Datadog
67
68
  end
68
69
 
69
70
  if Datadog::AppSec.active_context
70
- user = ::Datadog::AppSec::Instrumentation::Gateway::User.new(id)
71
+ active_span.set_tag('_dd.appsec.user.collection_mode', 'sdk')
72
+
73
+ user = ::Datadog::AppSec::Instrumentation::Gateway::User.new(id, others[:login], session_id)
71
74
  ::Datadog::AppSec::Instrumentation.gateway.push('identity.set_user', user)
72
75
  end
73
76
  end
74
77
  end
78
+ # rubocop:enable Metrics/AbcSize
75
79
  # rubocop:enable Metrics/PerceivedComplexity
76
80
  # rubocop:enable Metrics/CyclomaticComplexity
77
81
 
@@ -0,0 +1,90 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'trace/span'
4
+ require_relative '../../tracing/trace_operation'
5
+ require_relative '../trace'
6
+
7
+ module Datadog
8
+ module OpenTelemetry
9
+ module API
10
+ # The Baggage module provides an implementation of the OpenTelemetry Baggage API.
11
+ #
12
+ # Baggage is a set of name/value pairs describing user-defined properties that can be
13
+ # propagated through a distributed trace. This implementation follows the W3C Baggage
14
+ # specification and the OpenTelemetry Baggage API.
15
+ #
16
+ # @see https://www.w3.org/TR/baggage/
17
+ # @see https://opentelemetry.io/docs/specs/otel/baggage/api/
18
+ module Baggage
19
+ def initialize(trace: nil)
20
+ @trace = trace
21
+ end
22
+
23
+ # Returns a new context with empty baggage
24
+ #
25
+ # @param [optional Context] context Context to clear baggage from. Defaults
26
+ # to ::OpenTelemetry::Context.current
27
+ # @return [Context]
28
+ def clear(context: ::OpenTelemetry::Context.current)
29
+ context.ensure_trace.baggage.clear
30
+ context
31
+ end
32
+
33
+ # Returns the corresponding value for key
34
+ #
35
+ # @param [String] key The lookup key
36
+ # @param [optional Context] context The context from which to retrieve
37
+ # the key. Defaults to ::OpenTelemetry::Context.current
38
+ # @return [String, nil]
39
+ def value(key, context: ::OpenTelemetry::Context.current)
40
+ trace = context.ensure_trace
41
+ return nil if trace.nil?
42
+
43
+ trace.baggage && trace.baggage[key]
44
+ end
45
+
46
+ # Returns all baggage values
47
+ #
48
+ # @param [optional Context] context The context from which to retrieve
49
+ # the baggage. Defaults to ::OpenTelemetry::Context.current
50
+ # @return [Hash<String, String>]
51
+ def values(context: ::OpenTelemetry::Context.current)
52
+ trace = context.ensure_trace
53
+ return {} if trace.nil?
54
+
55
+ trace.baggage ? trace.baggage.dup : {}
56
+ end
57
+
58
+ # Returns a new context with new key-value pair
59
+ #
60
+ # @param [String] key The key to store this value under
61
+ # @param [String] value String value to be stored under key
62
+ # @param [optional String] metadata This is here to store properties
63
+ # received from other W3C Baggage implementations but is not exposed in
64
+ # OpenTelemetry. This is considered private API and not for use by
65
+ # end-users.
66
+ # @param [optional Context] context The context to update with new
67
+ # value. Defaults to ::OpenTelemetry::Context.current
68
+ # @return [Context]
69
+ def set_value(key, value, metadata: nil, context: ::OpenTelemetry::Context.current)
70
+ # Delegate to the context to set the value because an active trace is not guaranteed
71
+ # set_values handles this logic
72
+ context.set_values({ ::OpenTelemetry::Baggage.const_get(:BAGGAGE_KEY) => { key => value } })
73
+ end
74
+
75
+ # Returns a new context with value at key removed
76
+ #
77
+ # @param [String] key The key to remove
78
+ # @param [optional Context] context The context to remove baggage
79
+ # from. Defaults to ::OpenTelemetry::Context.current
80
+ # @return [Context]
81
+ def remove_value(key, context: ::OpenTelemetry::Context.current)
82
+ # Delegate to the context to remove the value because an active trace is not guaranteed
83
+ # set_values handles this logic
84
+ context.set_values({ Context::BAGGAGE_REMOVE_KEY => key })
85
+ end
86
+ ::OpenTelemetry::Baggage.singleton_class.prepend(self)
87
+ end
88
+ end
89
+ end
90
+ end
@@ -0,0 +1,26 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Datadog
4
+ module OpenTelemetry
5
+ module API
6
+ module Baggage
7
+ def initialize: (?trace: Datadog::Tracing::TraceOperation?) -> void
8
+
9
+ # Returns a new context with empty baggage
10
+ def clear: (?context: OpenTelemetry::Context) -> OpenTelemetry::Context
11
+
12
+ # Returns the corresponding value for key
13
+ def value: (String key, ?context: OpenTelemetry::Context) -> String?
14
+
15
+ # Returns all baggage values
16
+ def values: (?context: OpenTelemetry::Context) -> Hash[String, String]
17
+
18
+ # Returns a new context with key-value pair
19
+ def set_value: (String key, String value, ?metadata: String?, ?context: OpenTelemetry::Context) -> OpenTelemetry::Context
20
+
21
+ # Returns a new context with value at key removed
22
+ def remove_value: (String key, ?context: OpenTelemetry::Context) -> OpenTelemetry::Context
23
+ end
24
+ end
25
+ end
26
+ end
@@ -21,11 +21,13 @@ module Datadog
21
21
  module Context
22
22
  CURRENT_SPAN_KEY = ::OpenTelemetry::Trace.const_get(:CURRENT_SPAN_KEY)
23
23
  private_constant :CURRENT_SPAN_KEY
24
+ BAGGAGE_REMOVE_KEY = Object.new # sentinel object to indicate the deletion of a value in baggage
24
25
 
25
- def initialize(entries, trace: nil)
26
+ def initialize(entries, trace: nil, baggage: nil)
26
27
  @trace = trace || ::Datadog::Tracing.send(:tracer).send(:start_trace)
27
28
  @trace.otel_values.merge!(entries) if entries
28
29
  @trace.otel_context ||= self
30
+ @trace.baggage = baggage if baggage
29
31
  end
30
32
 
31
33
  # Because Context can be reused, we have to make sure we have
@@ -79,8 +81,20 @@ module Datadog
79
81
  end
80
82
 
81
83
  existing_values = @trace && @trace.otel_values || {}
84
+ existing_baggage = @trace && @trace.baggage || {}
82
85
 
83
- ::OpenTelemetry::Context.new(existing_values.merge(values), trace: trace)
86
+ # Retrieve the baggage removal sentinel and remove it from the values hash
87
+ existing_baggage.delete(values[BAGGAGE_REMOVE_KEY]) if values.key?(BAGGAGE_REMOVE_KEY)
88
+
89
+ # If the values hash contains a BAGGAGE_KEY, merge its contents with existing baggage
90
+ # Otherwise, keep the existing baggage unchanged
91
+ new_baggage = if values.key?(::OpenTelemetry::Baggage.const_get(:BAGGAGE_KEY))
92
+ existing_baggage.merge(values[::OpenTelemetry::Baggage.const_get(:BAGGAGE_KEY)])
93
+ else
94
+ existing_baggage
95
+ end
96
+
97
+ ::OpenTelemetry::Context.new(existing_values.merge(values), trace: trace, baggage: new_baggage)
84
98
  end
85
99
 
86
100
  # The Datadog {TraceOperation} associated with this {Context}.
@@ -45,7 +45,7 @@ module Datadog
45
45
  def add_attributes(attributes)
46
46
  res = super
47
47
  # Attributes can get dropped or their values truncated by `super`
48
- attributes.each { |key, _| datadog_set_attribute(key) }
48
+ attributes.each_key { |key| datadog_set_attribute(key) }
49
49
  res
50
50
  end
51
51
 
@@ -13,6 +13,7 @@ require_relative 'tracing'
13
13
  require_relative 'tracing/contrib'
14
14
 
15
15
  require_relative 'opentelemetry/api/context'
16
+ require_relative 'opentelemetry/api/baggage'
16
17
 
17
18
  # DEV: Should this be a Contrib integration, that depends on the `opentelemetry-sdk`
18
19
  # DEV: and checks for compatibility?
@@ -29,7 +30,7 @@ module Datadog
29
30
 
30
31
  # Use `Datadog.logger` as the default logger
31
32
  def logger
32
- @logger ||= ::Datadog.logger
33
+ ::Datadog.logger
33
34
  end
34
35
 
35
36
  ::OpenTelemetry.singleton_class.prepend(self)
@@ -14,7 +14,10 @@ module Datadog
14
14
  #
15
15
  # This class acts both as a collector (collecting data) as well as a recorder (records/serializes it)
16
16
  class CodeProvenance
17
- def initialize(standard_library_path: RbConfig::CONFIG.fetch("rubylibdir"))
17
+ def initialize(
18
+ standard_library_path: RbConfig::CONFIG.fetch("rubylibdir"),
19
+ ruby_native_filename: Datadog::Profiling::Collectors::Stack._native_ruby_native_filename
20
+ )
18
21
  @libraries_by_name = {}
19
22
  @libraries_by_path = {}
20
23
  @seen_files = Set.new
@@ -26,6 +29,7 @@ module Datadog
26
29
  name: "stdlib",
27
30
  version: RUBY_VERSION,
28
31
  path: standard_library_path,
32
+ extra_path: ruby_native_filename,
29
33
  )
30
34
  )
31
35
  end
@@ -37,12 +41,8 @@ module Datadog
37
41
  self
38
42
  end
39
43
 
40
- def generate
41
- seen_libraries
42
- end
43
-
44
44
  def generate_json
45
- JSON.fast_generate(v1: seen_libraries.to_a)
45
+ JSON.generate(v1: seen_libraries.to_a)
46
46
  end
47
47
 
48
48
  private
@@ -79,7 +79,15 @@ module Datadog
79
79
  loaded_specs.each do |spec|
80
80
  next if libraries_by_name.key?(spec.name)
81
81
 
82
- record_library(Library.new(kind: "library", name: spec.name, version: spec.version, path: spec.gem_dir))
82
+ record_library(
83
+ Library.new(
84
+ kind: "library",
85
+ name: spec.name,
86
+ version: spec.version,
87
+ path: spec.gem_dir,
88
+ extra_path: (spec.extension_dir if spec.extensions.any?),
89
+ )
90
+ )
83
91
  recorded_library = true
84
92
  end
85
93
 
@@ -110,11 +118,12 @@ module Datadog
110
118
  class Library
111
119
  attr_reader :kind, :name, :version
112
120
 
113
- def initialize(kind:, name:, version:, path:)
121
+ def initialize(kind:, name:, version:, path:, extra_path: nil)
122
+ extra_path = nil if extra_path&.empty?
114
123
  @kind = kind.freeze
115
124
  @name = name.dup.freeze
116
125
  @version = version.to_s.dup.freeze
117
- @paths = [path.dup.freeze].freeze
126
+ @paths = [path.dup.freeze, extra_path.dup.freeze].compact.freeze
118
127
  freeze
119
128
  end
120
129
 
@@ -23,6 +23,7 @@ module Datadog
23
23
  allocation_profiling_enabled:,
24
24
  allocation_counting_enabled:,
25
25
  gvl_profiling_enabled:,
26
+ sighandler_sampling_enabled:,
26
27
  # **NOTE**: This should only be used for testing; disabling the dynamic sampling rate will increase the
27
28
  # profiler overhead!
28
29
  dynamic_sampling_rate_enabled: true,
@@ -33,6 +34,9 @@ module Datadog
33
34
  Datadog.logger.warn(
34
35
  "Profiling dynamic sampling rate disabled. This should only be used for testing, and will increase overhead!"
35
36
  )
37
+ Datadog::Core::Telemetry::Logger.error(
38
+ "Profiling dynamic sampling rate disabled. This should only be used for testing, and will increase overhead!"
39
+ )
36
40
  end
37
41
 
38
42
  self.class._native_initialize(
@@ -46,6 +50,7 @@ module Datadog
46
50
  allocation_profiling_enabled: allocation_profiling_enabled,
47
51
  allocation_counting_enabled: allocation_counting_enabled,
48
52
  gvl_profiling_enabled: gvl_profiling_enabled,
53
+ sighandler_sampling_enabled: sighandler_sampling_enabled,
49
54
  skip_idle_samples_for_testing: skip_idle_samples_for_testing,
50
55
  )
51
56
  @worker_thread = nil
@@ -77,6 +82,7 @@ module Datadog
77
82
  "Cause: #{e.class.name} #{e.message} Location: #{Array(e.backtrace).first}"
78
83
  )
79
84
  on_failure_proc&.call
85
+ Datadog::Core::Telemetry::Logger.report(e, description: "CpuAndWallTimeWorker thread error", pii_safe: true)
80
86
  end
81
87
  @worker_thread.name = self.class.name # Repeated from above to make sure thread gets named asap
82
88
  @worker_thread.thread_variable_set(:fork_safe, true)
@@ -41,6 +41,7 @@ module Datadog
41
41
  "IdleSamplingHelper thread error. " \
42
42
  "Cause: #{e.class.name} #{e.message} Location: #{Array(e.backtrace).first}"
43
43
  )
44
+ Datadog::Core::Telemetry::Logger.report(e, description: "IdleSamplingHelper thread error", pii_safe: true)
44
45
  end
45
46
  @worker_thread.name = self.class.name # Repeated from above to make sure thread gets named asap
46
47
  @worker_thread.thread_variable_set(:fork_safe, true)
@@ -28,9 +28,43 @@ module Datadog
28
28
 
29
29
  private
30
30
 
31
+ # Ruby GC tuning environment variables
32
+ RUBY_GC_TUNING_ENV_VARS = [
33
+ "RUBY_GC_HEAP_FREE_SLOTS",
34
+ "RUBY_GC_HEAP_GROWTH_FACTOR",
35
+ "RUBY_GC_HEAP_GROWTH_MAX_SLOTS",
36
+ "RUBY_GC_HEAP_FREE_SLOTS_MIN_RATIO",
37
+ "RUBY_GC_HEAP_FREE_SLOTS_MAX_RATIO",
38
+ "RUBY_GC_HEAP_FREE_SLOTS_GOAL_RATIO",
39
+ "RUBY_GC_HEAP_OLDOBJECT_LIMIT_FACTOR",
40
+ "RUBY_GC_HEAP_REMEMBERED_WB_UNPROTECTED_OBJECTS_LIMIT_RATIO",
41
+ "RUBY_GC_MALLOC_LIMIT",
42
+ "RUBY_GC_MALLOC_LIMIT_MAX",
43
+ "RUBY_GC_MALLOC_LIMIT_GROWTH_FACTOR",
44
+ "RUBY_GC_OLDMALLOC_LIMIT",
45
+ "RUBY_GC_OLDMALLOC_LIMIT_MAX",
46
+ "RUBY_GC_OLDMALLOC_LIMIT_GROWTH_FACTOR",
47
+ # INIT_SLOTS changed for Ruby 3.3+:
48
+ # * https://bugs.ruby-lang.org/issues/19785
49
+ # * https://www.ruby-lang.org/en/news/2023/12/25/ruby-3-3-0-released/#:~:text=Removed%20environment%20variables
50
+ "RUBY_GC_HEAP_0_INIT_SLOTS",
51
+ "RUBY_GC_HEAP_1_INIT_SLOTS",
52
+ "RUBY_GC_HEAP_2_INIT_SLOTS",
53
+ "RUBY_GC_HEAP_3_INIT_SLOTS",
54
+ "RUBY_GC_HEAP_4_INIT_SLOTS",
55
+ # There was only one setting for older Rubies:
56
+ "RUBY_GC_HEAP_INIT_SLOTS",
57
+ # Ruby 2.x only, alias for others:
58
+ "RUBY_FREE_MIN",
59
+ "RUBY_HEAP_MIN_SLOTS",
60
+ ].freeze
61
+
31
62
  # Instead of trying to figure out real process start time by checking
32
63
  # /proc or some other complex/non-portable way, approximate start time
33
64
  # by time of requirement of this file.
65
+ #
66
+ # Note: this does not use Core::Utils::Time.now because this constant
67
+ # gets initialized before a user has a chance to configure the library.
34
68
  START_TIME = Time.now.utc.freeze
35
69
 
36
70
  def collect_platform_info
@@ -48,6 +82,7 @@ module Datadog
48
82
  engine: Datadog::Core::Environment::Identity.lang_engine,
49
83
  version: Datadog::Core::Environment::Identity.lang_version,
50
84
  platform: Datadog::Core::Environment::Identity.lang_platform,
85
+ gc_tuning: collect_gc_tuning_info,
51
86
  }.freeze
52
87
  end
53
88
 
@@ -106,6 +141,15 @@ module Datadog
106
141
  v.inspect
107
142
  end
108
143
  end
144
+
145
+ def collect_gc_tuning_info
146
+ return @gc_tuning_info if defined?(@gc_tuning_info)
147
+
148
+ @gc_tuning_info = RUBY_GC_TUNING_ENV_VARS.each_with_object({}) do |var, hash|
149
+ current_value = ENV[var]
150
+ hash[var.to_sym] = current_value if current_value
151
+ end.freeze
152
+ end
109
153
  end
110
154
  end
111
155
  end