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
@@ -0,0 +1,65 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative '../../../core/transport/http/api/instance'
4
+ require_relative '../../../core/transport/http/api/spec'
5
+ require_relative 'client'
6
+
7
+ module Datadog
8
+ module DI
9
+ module Transport
10
+ module HTTP
11
+ module Diagnostics
12
+ module Client
13
+ def send_diagnostics_payload(request)
14
+ send_request(request) do |api, env|
15
+ api.send_diagnostics(env)
16
+ end
17
+ end
18
+ end
19
+
20
+ module API
21
+ class Instance < Core::Transport::HTTP::API::Instance
22
+ def send_diagnostics(env)
23
+ raise Core::Transport::HTTP::API::Instance::EndpointNotSupportedError.new('diagnostics', self) unless spec.is_a?(Diagnostics::API::Spec)
24
+
25
+ spec.send_diagnostics(env) do |request_env|
26
+ call(request_env)
27
+ end
28
+ end
29
+ end
30
+
31
+ class Spec < Core::Transport::HTTP::API::Spec
32
+ attr_accessor :diagnostics
33
+
34
+ def send_diagnostics(env, &block)
35
+ raise Core::Transport::HTTP::API::Spec::EndpointNotDefinedError.new('diagnostics', self) if diagnostics.nil?
36
+
37
+ diagnostics.call(env, &block)
38
+ end
39
+ end
40
+
41
+ class Endpoint < Datadog::Core::Transport::HTTP::API::Endpoint
42
+ attr_reader :encoder
43
+
44
+ def initialize(path, encoder)
45
+ super(:post, path)
46
+ @encoder = encoder
47
+ end
48
+
49
+ def call(env, &block)
50
+ event_payload = Core::Vendor::Multipart::Post::UploadIO.new(
51
+ StringIO.new(env.request.parcel.data), 'application/json', 'event.json'
52
+ )
53
+ env.form = {'event' => event_payload}
54
+
55
+ super
56
+ end
57
+ end
58
+ end
59
+ end
60
+
61
+ HTTP::Client.include(Diagnostics::Client)
62
+ end
63
+ end
64
+ end
65
+ end
@@ -0,0 +1,67 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative '../../../core/transport/http/api/instance'
4
+ require_relative '../../../core/transport/http/api/spec'
5
+ require_relative 'client'
6
+
7
+ module Datadog
8
+ module DI
9
+ module Transport
10
+ module HTTP
11
+ module Input
12
+ module Client
13
+ def send_input_payload(request)
14
+ send_request(request) do |api, env|
15
+ api.send_input(env)
16
+ end
17
+ end
18
+ end
19
+
20
+ module API
21
+ class Instance < Core::Transport::HTTP::API::Instance
22
+ def send_input(env)
23
+ raise Core::Transport::HTTP::API::Instance::EndpointNotSupportedError.new('input', self) unless spec.is_a?(Input::API::Spec)
24
+
25
+ spec.send_input(env) do |request_env|
26
+ call(request_env)
27
+ end
28
+ end
29
+ end
30
+
31
+ class Spec < Core::Transport::HTTP::API::Spec
32
+ attr_accessor :input
33
+
34
+ def send_input(env, &block)
35
+ raise Core::Transport::HTTP::API::Spec::EndpointNotDefinedError.new('input', self) if input.nil?
36
+
37
+ input.call(env, &block)
38
+ end
39
+ end
40
+
41
+ class Endpoint < Datadog::Core::Transport::HTTP::API::Endpoint
42
+ HEADER_CONTENT_TYPE = 'Content-Type'
43
+
44
+ attr_reader \
45
+ :encoder
46
+
47
+ def initialize(path, encoder)
48
+ super(:post, path)
49
+ @encoder = encoder
50
+ end
51
+
52
+ def call(env, &block)
53
+ # Encode body & type
54
+ env.headers[HEADER_CONTENT_TYPE] = encoder.content_type
55
+ env.body = env.request.parcel.data
56
+
57
+ super
58
+ end
59
+ end
60
+ end
61
+ end
62
+
63
+ HTTP::Client.include(Input::Client)
64
+ end
65
+ end
66
+ end
67
+ end
@@ -0,0 +1,57 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'diagnostics'
4
+ require_relative 'input'
5
+ require_relative 'http/api'
6
+ require_relative '../../core/transport/http'
7
+
8
+ module Datadog
9
+ module DI
10
+ module Transport
11
+ # Namespace for HTTP transport components
12
+ module HTTP
13
+ module_function
14
+
15
+ # Builds a new Transport::HTTP::Client with default settings
16
+ # Pass a block to override any settings.
17
+ def diagnostics(
18
+ agent_settings:,
19
+ logger:,
20
+ api_version: nil,
21
+ headers: nil
22
+ )
23
+ Core::Transport::HTTP.build(api_instance_class: Diagnostics::API::Instance,
24
+ logger: logger,
25
+ agent_settings: agent_settings, api_version: api_version, headers: headers) do |transport|
26
+ apis = API.defaults
27
+
28
+ transport.api API::DIAGNOSTICS, apis[API::DIAGNOSTICS]
29
+
30
+ # Call block to apply any customization, if provided
31
+ yield(transport) if block_given?
32
+ end.to_transport(DI::Transport::Diagnostics::Transport)
33
+ end
34
+
35
+ # Builds a new Transport::HTTP::Client with default settings
36
+ # Pass a block to override any settings.
37
+ def input(
38
+ agent_settings:,
39
+ logger:,
40
+ api_version: nil,
41
+ headers: nil
42
+ )
43
+ Core::Transport::HTTP.build(api_instance_class: Input::API::Instance,
44
+ logger: logger,
45
+ agent_settings: agent_settings, api_version: api_version, headers: headers) do |transport|
46
+ apis = API.defaults
47
+
48
+ transport.api API::INPUT, apis[API::INPUT]
49
+
50
+ # Call block to apply any customization, if provided
51
+ yield(transport) if block_given?
52
+ end.to_transport(DI::Transport::Input::Transport)
53
+ end
54
+ end
55
+ end
56
+ end
57
+ end
@@ -0,0 +1,62 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative '../../core/transport/parcel'
4
+ require_relative 'http/client'
5
+
6
+ module Datadog
7
+ module DI
8
+ module Transport
9
+ module Input
10
+ class EncodedParcel
11
+ include Datadog::Core::Transport::Parcel
12
+ end
13
+
14
+ class Request < Datadog::Core::Transport::Request
15
+ end
16
+
17
+ class Transport
18
+ attr_reader :client, :apis, :default_api, :current_api_id, :logger
19
+
20
+ def initialize(apis, default_api, logger:)
21
+ @apis = apis
22
+ @logger = logger
23
+
24
+ @client = HTTP::Client.new(current_api, logger: logger)
25
+ end
26
+
27
+ def current_api
28
+ @apis[HTTP::API::INPUT]
29
+ end
30
+
31
+ def send_input(payload)
32
+ json = JSON.dump(payload)
33
+ parcel = EncodedParcel.new(json)
34
+ request = Request.new(parcel)
35
+
36
+ response = @client.send_input_payload(request)
37
+ unless response.ok?
38
+ # TODO Datadog::Core::Transport::InternalErrorResponse
39
+ # does not have +code+ method, what is the actual API of
40
+ # these response objects?
41
+ raise Error::AgentCommunicationError, "send_input failed: #{begin
42
+ response.code
43
+ rescue
44
+ "???"
45
+ end}: #{response.payload}"
46
+ end
47
+ rescue Error::AgentCommunicationError
48
+ raise
49
+ # Datadog::Core::Transport does not perform any exception mapping,
50
+ # therefore we could have any exception here from failure to parse
51
+ # agent URI for example.
52
+ # If we ever implement retries for network errors, we should distinguish
53
+ # actual network errors from non-network errors that are raised by
54
+ # transport code.
55
+ rescue => exc
56
+ raise Error::AgentCommunicationError, "send_input failed: #{exc.class}: #{exc}"
57
+ end
58
+ end
59
+ end
60
+ end
61
+ end
62
+ end
@@ -1,8 +1,87 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ # standard gets itself into an infinite loop over this
4
+ # rubocop:disable Layout/SpaceAfterNot
5
+
3
6
  module Datadog
4
7
  module DI
5
8
  module Utils
9
+ # General path matching considerations
10
+ # ------------------------------------
11
+ #
12
+ # The following use cases must be supported:
13
+ # 1. The "probe path" is relative path to the file from source code
14
+ # repository root. The project is deployed from the repository root,
15
+ # such that that same relative path exists at runtime from the
16
+ # root of the application.
17
+ # 2. The "probe path" is a relative path to the file in a monorepo
18
+ # where the project being deployed is in a subdirectory.
19
+ # This the "probe path" contains additional directory components
20
+ # in the beginning that do not exist in the runtime environment.
21
+ # 3. The "probe path" is an absolute path to the file on the customer's
22
+ # development system. As specified this path definitely does not
23
+ # exist at runtime, and can start with a prefix that is unknown
24
+ # to any both UI and tracer code.
25
+ # 4. Same as (3), but the customer is using a Windows computer for
26
+ # development and has the path specified in the wrong case
27
+ # (which works fine on their development machine).
28
+ # 5. The "probe path" is the basename or any suffix of the path to
29
+ # the desired file, typed manually by the customer into the UI.
30
+ #
31
+ # A related concern is that if multiple runtime paths match the path
32
+ # specification in the probe, the tracer must return an error to the
33
+ # backend/UI rather than instrumenting any of the matching paths.
34
+ #
35
+ # The logic for path matching should therefore, generally, be as follows:
36
+ # 1. If the "probe path" is absolute, see if it exists at runtime.
37
+ # If so, take it as the desired path and finish.
38
+ # 2. Attempt to identify the application root, by checking if the current
39
+ # working directory contains a file called Gemfile. If yes, assume
40
+ # the current working directory is the application root, otherwise
41
+ # consider the application root to be unknown.
42
+ # 3. If the application root is known and the "probe path" is relative,
43
+ # concatenate the "probe path" to the application root and check
44
+ # if the resulting path exists at runtime. If so, take it as the
45
+ # desired path and finish.
46
+ # 4. If the "probe path" is relative, go through the known file paths,
47
+ # filter these paths down to those whose suffix is the "probe path",
48
+ # and check how many we are left with. If exactly one, assume this
49
+ # is the desired path and finish. If more than one, return an error
50
+ # "multiple matching paths".
51
+ # 5. If the application root is known, for each suffix of the "probe path",
52
+ # see if that relative paths concatenated to the application root
53
+ # results in a known file. If a known file is found, assume this
54
+ # is the wanted file and finish.
55
+ # 6. For each suffix of the "probe path", filter the set of known paths
56
+ # down to those that end in the suffix. If exactly one path remains
57
+ # for a given suffix, assume this is the wanted path and finish.
58
+ # If more than one path remains for a given suffix, return the error
59
+ # "multiple matching paths".
60
+ # 7. Repeat step 5 but perform case-insensitive comparison.
61
+ # 8. Repeat step 6 but perform case-insensitive comparison.
62
+ #
63
+ # Note that we do not look for "probe paths" under the current working
64
+ # directory at runtime if the current working directory does not contain
65
+ # a Gemfile, to avoid finding files from potentially undesired bases.
66
+ #
67
+ # What "known file"/"known path" means also differs based on the
68
+ # operation being performed:
69
+ # - If the operation is "install a probe", "known file/path" can
70
+ # include files on the filesystem that have not been loaded as
71
+ # well as paths from the code tracker.
72
+ # - If the operation is "check if any pending probes match the file
73
+ # that was just loaded", we would only consider the path that was
74
+ # just loaded and not check the filesystem.
75
+ #
76
+ # Filesystem inquiries are obviously quite expensive and should be
77
+ # cached. For the vast majority of applications it should be safe to
78
+ # indefinitely cache whether a particular filesystem paths exists
79
+ # in both positive and negative.
80
+ #
81
+ # As a "quick fix", currently after performing the suffix matching
82
+ # we just strip leading directory components from the "probe path"
83
+ # until we get a match via a "suffix of the suffix".
84
+
6
85
  # Returns whether the provided +path+ matches the user-designated
7
86
  # file suffix (of a line probe).
8
87
  #
@@ -12,6 +91,13 @@ module Datadog
12
91
  # If suffix is not an absolute path, the path matches if its suffix is
13
92
  # the provided suffix, at a path component boundary.
14
93
  module_function def path_matches_suffix?(path, suffix)
94
+ if path.nil?
95
+ raise ArgumentError, "nil path passed"
96
+ end
97
+ if suffix.nil?
98
+ raise ArgumentError, "nil suffix passed"
99
+ end
100
+
15
101
  if suffix.start_with?('/')
16
102
  path == suffix
17
103
  else
@@ -34,6 +120,23 @@ module Datadog
34
120
  # !!(path =~ %r,(/|\A)#{Regexp.quote(suffix)}\z,)
35
121
  end
36
122
  end
123
+
124
+ # Returns whether the provided +path+ matches the "probe path" in
125
+ # +spec+. Attempts all of the fuzzy matches by stripping directories
126
+ # from the front of +spec+. Does not consider othr known paths to
127
+ # identify the case of (potentially) multiple matching paths for +spec+.
128
+ module_function def path_can_match_spec?(path, spec)
129
+ return true if path_matches_suffix?(path, spec)
130
+
131
+ spec = spec.dup
132
+ loop do
133
+ return false unless spec.include?('/')
134
+ spec.sub!(%r{.*/+}, '')
135
+ return true if path_matches_suffix?(path, spec)
136
+ end
137
+ end
37
138
  end
38
139
  end
39
140
  end
141
+
142
+ # rubocop:enable Layout/SpaceAfterNot
data/lib/datadog/di.rb CHANGED
@@ -1,32 +1,8 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative 'di/error'
4
- require_relative 'di/code_tracker'
5
- require_relative 'di/component'
6
3
  require_relative 'di/configuration'
7
4
  require_relative 'di/extensions'
8
- require_relative 'di/instrumenter'
9
- require_relative 'di/probe'
10
- require_relative 'di/probe_builder'
11
- require_relative 'di/probe_manager'
12
- require_relative 'di/probe_notification_builder'
13
- require_relative 'di/probe_notifier_worker'
14
- require_relative 'di/redactor'
15
- require_relative 'di/serializer'
16
- require_relative 'di/transport'
17
- require_relative 'di/utils'
18
-
19
- if defined?(ActiveRecord::Base)
20
- # The third-party library integrations need to be loaded after the
21
- # third-party libraries are loaded. Tracing and appsec use Railtie
22
- # to delay integrations until all of the application's dependencies
23
- # are loaded, when running under Rails. We should do the same here in
24
- # principle, however DI currently only has an ActiveRecord integration
25
- # and AR should be loaded before any application code is loaded, being
26
- # part of Rails, therefore for now we should be OK to just require the
27
- # AR integration from here.
28
- require_relative 'di/contrib/active_record'
29
- end
5
+ require_relative 'di/remote'
30
6
 
31
7
  module Datadog
32
8
  # Namespace for Datadog dynamic instrumentation.
@@ -43,63 +19,25 @@ module Datadog
43
19
  Extensions.activate!
44
20
 
45
21
  class << self
46
- attr_reader :code_tracker
47
22
 
48
- # Activates code tracking. Normally this method should be called
49
- # when the application starts. If instrumenting third-party code,
50
- # code tracking needs to be enabled before the third-party libraries
51
- # are loaded. If you definitely will not be instrumenting
52
- # third-party libraries, activating tracking after third-party libraries
53
- # have been loaded may improve lookup performance.
23
+ # This method is called from DI Remote handler to issue DI operations
24
+ # to the probe manager (add or remove probes).
54
25
  #
55
- # TODO test that activating tracker multiple times preserves
56
- # existing mappings in the registry
57
- def activate_tracking!
58
- (@code_tracker ||= CodeTracker.new).start
59
- end
60
-
61
- # Deactivates code tracking. In normal usage of DI this method should
62
- # never be called, however it is used by DI's test suite to reset
63
- # state for individual tests.
26
+ # When DI Remote is executing, Datadog.components should be initialized
27
+ # and we should be able to reference it to get to the DI component.
64
28
  #
65
- # Note that deactivating tracking clears out the registry, losing
66
- # the ability to look up files that have been loaded into the process
67
- # already.
68
- def deactivate_tracking!
69
- code_tracker&.stop
70
- end
71
-
72
- # Returns whether code tracking is available.
73
- # This method should be used instead of querying #code_tracker
74
- # because the latter one may be nil.
75
- def code_tracking_active?
76
- code_tracker&.active? || false
77
- end
78
-
29
+ # Given that we need the current_component anyway for code tracker,
30
+ # perhaps we should delete the +component+ method and just use
31
+ # +current_component+ in all cases.
79
32
  def component
80
- # TODO uncomment when remote is merged
81
- #Datadog.send(:components).dynamic_instrumentation
33
+ Datadog.send(:components).dynamic_instrumentation
82
34
  end
83
35
  end
84
36
  end
85
37
  end
86
38
 
87
- =begin not yet enabled
88
- # :script_compiled trace point was added in Ruby 2.6.
89
- if RUBY_VERSION >= '2.6'
90
- begin
91
- # Activate code tracking by default because line trace points will not work
92
- # without it.
93
- Datadog::DI.activate_tracking!
94
- rescue => exc
95
- if defined?(Datadog.logger)
96
- Datadog.logger.warn("Failed to activate code tracking for DI: #{exc.class}: #{exc}")
97
- else
98
- # We do not have Datadog logger potentially because DI code tracker is
99
- # being loaded early in application boot process and the rest of datadog
100
- # wasn't loaded yet. Output to standard error.
101
- warn("Failed to activate code tracking for DI: #{exc.class}: #{exc}")
102
- end
103
- end
104
- end
105
- =end
39
+ # Line probes will not work on Ruby < 2.6 because of lack of :script_compiled
40
+ # trace point. Activate DI automatically on supported Ruby versions but
41
+ # always load its settings so that, for example, turning DI off when
42
+ # we are on Ruby 2.5 does not produce exceptions.
43
+ require_relative 'di/boot' if RUBY_VERSION >= '2.6' && RUBY_ENGINE != 'jruby'
@@ -0,0 +1,87 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'ext'
4
+
5
+ module Datadog
6
+ module ErrorTracking
7
+ # The Collector is in charge, for a SpanOperation of storing the span events
8
+ # created when an error is handled. Each SpanOperation has a Collector as soon
9
+ # as a span event is created and the Collector has the same life time as the SpanOp.
10
+ #
11
+ # If an error is handled then rethrown, the SpanEvent corresponding to the error
12
+ # will be deleted. That is why we do not add directly the SpanEvent to the SpanOp.
13
+ #
14
+ # @api private
15
+ class Collector
16
+ SPAN_EVENTS_LIMIT = 100
17
+ LOCK = Mutex.new
18
+ # Proc called when the span_operation :after_stop event is published
19
+ def self.after_stop
20
+ @after_stop ||= proc do |span_op, error|
21
+ # if this proc is called, we are sure that span_op has a collector
22
+ collector = span_op.get_collector_or_initialize
23
+ # if an error exited the scope of the span, we delete the corresponding SpanEvent.
24
+ collector.on_error(span_op, error) if error
25
+
26
+ span_events = collector.span_events
27
+ span_op.span_events.concat(span_events)
28
+ end
29
+ end
30
+
31
+ def initialize
32
+ @span_event_per_error = {}
33
+ end
34
+
35
+ def add_span_event(span_op, span_event, error)
36
+ # When this is the first time we add a span event for a span,
37
+ # we suscribe to the :after_stop event
38
+ if @span_event_per_error.empty?
39
+ events = span_op.send(:events)
40
+ events.after_stop.subscribe(&self.class.after_stop)
41
+
42
+ # This tag is used by the Error Tracking product to report
43
+ # the error in Error Tracking
44
+ span_op.set_tag(Ext::SPAN_EVENTS_HAS_EXCEPTION, true)
45
+ end
46
+ # Set a limit to the number of span event we can store per SpanOp
47
+ # If an error has been handled several times in the same span we can still
48
+ # modify the event (even if the capacity is reached) in order to report
49
+ # the information of the last rescue
50
+ if @span_event_per_error.key?(error) || @span_event_per_error.length < SPAN_EVENTS_LIMIT
51
+ @span_event_per_error[error] = span_event
52
+ end
53
+ end
54
+
55
+ if RUBY_VERSION >= Ext::RUBY_VERSION_WITH_RESCUE_EVENT
56
+ # Starting from ruby3.3, as we are listening to :rescue event,
57
+ # we just want to remove the span event if the error was
58
+ # previously handled
59
+ def on_error(_span_op, error)
60
+ @span_event_per_error.delete(error)
61
+ end
62
+ else
63
+ # Up to ruby3.2, we are listening to :raise event. We need to ensure
64
+ # that an error exiting the scope of a span is not handled in a parent span.
65
+ # This function will propagate the span event to the parent span. If the
66
+ # error is not handled in the parent span, it will be deleted by design.
67
+ def on_error(span_op, error)
68
+ return unless @span_event_per_error.key?(error)
69
+
70
+ unless span_op.root?
71
+ parent = span_op.send(:parent)
72
+ LOCK.synchronize do
73
+ parent_collector = parent.get_collector_or_initialize { Collector.new }
74
+ parent_collector.add_span_event(parent, @span_event_per_error[error], error)
75
+ end
76
+ end
77
+
78
+ @span_event_per_error.delete(error)
79
+ end
80
+ end
81
+
82
+ def span_events
83
+ @span_event_per_error.values
84
+ end
85
+ end
86
+ end
87
+ end