datadog 2.7.1 → 2.18.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 (441) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +353 -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 +78 -102
  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 +235 -57
  9. data/ext/datadog_profiling_native_extension/collectors_stack.h +21 -5
  10. data/ext/datadog_profiling_native_extension/collectors_thread_context.c +376 -156
  11. data/ext/datadog_profiling_native_extension/collectors_thread_context.h +1 -0
  12. data/ext/datadog_profiling_native_extension/datadog_ruby_common.c +1 -4
  13. data/ext/datadog_profiling_native_extension/datadog_ruby_common.h +10 -0
  14. data/ext/datadog_profiling_native_extension/encoded_profile.c +79 -0
  15. data/ext/datadog_profiling_native_extension/encoded_profile.h +8 -0
  16. data/ext/datadog_profiling_native_extension/extconf.rb +14 -8
  17. data/ext/datadog_profiling_native_extension/gvl_profiling_helper.c +2 -0
  18. data/ext/datadog_profiling_native_extension/gvl_profiling_helper.h +0 -8
  19. data/ext/datadog_profiling_native_extension/heap_recorder.c +295 -532
  20. data/ext/datadog_profiling_native_extension/heap_recorder.h +6 -8
  21. data/ext/datadog_profiling_native_extension/http_transport.c +64 -98
  22. data/ext/datadog_profiling_native_extension/libdatadog_helpers.c +22 -0
  23. data/ext/datadog_profiling_native_extension/libdatadog_helpers.h +8 -5
  24. data/ext/datadog_profiling_native_extension/private_vm_api_access.c +69 -1
  25. data/ext/datadog_profiling_native_extension/private_vm_api_access.h +16 -4
  26. data/ext/datadog_profiling_native_extension/profiling.c +19 -8
  27. data/ext/datadog_profiling_native_extension/ruby_helpers.c +9 -21
  28. data/ext/datadog_profiling_native_extension/ruby_helpers.h +2 -10
  29. data/ext/datadog_profiling_native_extension/stack_recorder.c +231 -181
  30. data/ext/datadog_profiling_native_extension/stack_recorder.h +2 -2
  31. data/ext/datadog_profiling_native_extension/time_helpers.h +1 -1
  32. data/ext/datadog_profiling_native_extension/unsafe_api_calls_check.c +47 -0
  33. data/ext/datadog_profiling_native_extension/unsafe_api_calls_check.h +31 -0
  34. data/ext/libdatadog_api/crashtracker.c +17 -15
  35. data/ext/libdatadog_api/crashtracker.h +5 -0
  36. data/ext/libdatadog_api/datadog_ruby_common.c +1 -4
  37. data/ext/libdatadog_api/datadog_ruby_common.h +10 -0
  38. data/ext/libdatadog_api/extconf.rb +2 -2
  39. data/ext/libdatadog_api/init.c +15 -0
  40. data/ext/libdatadog_api/library_config.c +164 -0
  41. data/ext/libdatadog_api/library_config.h +25 -0
  42. data/ext/libdatadog_api/macos_development.md +3 -3
  43. data/ext/libdatadog_api/process_discovery.c +112 -0
  44. data/ext/libdatadog_api/process_discovery.h +5 -0
  45. data/ext/libdatadog_extconf_helpers.rb +2 -2
  46. data/lib/datadog/appsec/actions_handler/serializable_backtrace.rb +89 -0
  47. data/lib/datadog/appsec/actions_handler.rb +49 -0
  48. data/lib/datadog/appsec/anonymizer.rb +16 -0
  49. data/lib/datadog/appsec/api_security/lru_cache.rb +56 -0
  50. data/lib/datadog/appsec/api_security/route_extractor.rb +65 -0
  51. data/lib/datadog/appsec/api_security/sampler.rb +59 -0
  52. data/lib/datadog/appsec/api_security.rb +23 -0
  53. data/lib/datadog/appsec/assets/waf_rules/README.md +50 -5
  54. data/lib/datadog/appsec/assets/waf_rules/recommended.json +623 -253
  55. data/lib/datadog/appsec/assets/waf_rules/strict.json +69 -107
  56. data/lib/datadog/appsec/autoload.rb +1 -1
  57. data/lib/datadog/appsec/component.rb +49 -65
  58. data/lib/datadog/appsec/compressed_json.rb +40 -0
  59. data/lib/datadog/appsec/configuration/settings.rb +212 -27
  60. data/lib/datadog/appsec/context.rb +74 -0
  61. data/lib/datadog/appsec/contrib/active_record/instrumentation.rb +92 -0
  62. data/lib/datadog/appsec/contrib/active_record/integration.rb +41 -0
  63. data/lib/datadog/appsec/contrib/active_record/patcher.rb +101 -0
  64. data/lib/datadog/appsec/contrib/auto_instrument.rb +1 -1
  65. data/lib/datadog/appsec/contrib/devise/configuration.rb +52 -0
  66. data/lib/datadog/appsec/contrib/devise/data_extractor.rb +78 -0
  67. data/lib/datadog/appsec/contrib/devise/ext.rb +22 -0
  68. data/lib/datadog/appsec/contrib/devise/integration.rb +1 -2
  69. data/lib/datadog/appsec/contrib/devise/patcher.rb +33 -25
  70. data/lib/datadog/appsec/contrib/devise/patches/signin_tracking_patch.rb +102 -0
  71. data/lib/datadog/appsec/contrib/devise/patches/signup_tracking_patch.rb +69 -0
  72. data/lib/datadog/appsec/contrib/devise/{patcher/rememberable_patch.rb → patches/skip_signin_tracking_patch.rb} +3 -3
  73. data/lib/datadog/appsec/contrib/devise/tracking_middleware.rb +106 -0
  74. data/lib/datadog/appsec/contrib/excon/integration.rb +41 -0
  75. data/lib/datadog/appsec/contrib/excon/patcher.rb +28 -0
  76. data/lib/datadog/appsec/contrib/excon/ssrf_detection_middleware.rb +42 -0
  77. data/lib/datadog/appsec/contrib/faraday/connection_patch.rb +22 -0
  78. data/lib/datadog/appsec/contrib/faraday/integration.rb +42 -0
  79. data/lib/datadog/appsec/contrib/faraday/patcher.rb +53 -0
  80. data/lib/datadog/appsec/contrib/faraday/rack_builder_patch.rb +22 -0
  81. data/lib/datadog/appsec/contrib/faraday/ssrf_detection_middleware.rb +41 -0
  82. data/lib/datadog/appsec/contrib/graphql/appsec_trace.rb +1 -7
  83. data/lib/datadog/appsec/contrib/graphql/gateway/watcher.rb +17 -30
  84. data/lib/datadog/appsec/contrib/graphql/integration.rb +1 -1
  85. data/lib/datadog/appsec/contrib/graphql/patcher.rb +0 -3
  86. data/lib/datadog/appsec/contrib/rack/ext.rb +34 -0
  87. data/lib/datadog/appsec/contrib/rack/gateway/response.rb +3 -3
  88. data/lib/datadog/appsec/contrib/rack/gateway/watcher.rb +78 -98
  89. data/lib/datadog/appsec/contrib/rack/integration.rb +1 -1
  90. data/lib/datadog/appsec/contrib/rack/patcher.rb +0 -3
  91. data/lib/datadog/appsec/contrib/rack/request_body_middleware.rb +10 -11
  92. data/lib/datadog/appsec/contrib/rack/request_middleware.rb +73 -78
  93. data/lib/datadog/appsec/contrib/rails/gateway/watcher.rb +16 -33
  94. data/lib/datadog/appsec/contrib/rails/integration.rb +1 -1
  95. data/lib/datadog/appsec/contrib/rails/patcher.rb +25 -38
  96. data/lib/datadog/appsec/contrib/rest_client/integration.rb +45 -0
  97. data/lib/datadog/appsec/contrib/rest_client/patcher.rb +28 -0
  98. data/lib/datadog/appsec/contrib/rest_client/request_ssrf_detection_patch.rb +38 -0
  99. data/lib/datadog/appsec/contrib/sinatra/gateway/watcher.rb +31 -68
  100. data/lib/datadog/appsec/contrib/sinatra/integration.rb +1 -1
  101. data/lib/datadog/appsec/contrib/sinatra/patcher.rb +5 -31
  102. data/lib/datadog/appsec/event.rb +96 -135
  103. data/lib/datadog/appsec/ext.rb +12 -3
  104. data/lib/datadog/appsec/instrumentation/gateway/argument.rb +7 -2
  105. data/lib/datadog/appsec/instrumentation/gateway/middleware.rb +24 -0
  106. data/lib/datadog/appsec/instrumentation/gateway.rb +17 -22
  107. data/lib/datadog/appsec/metrics/collector.rb +38 -0
  108. data/lib/datadog/appsec/metrics/exporter.rb +35 -0
  109. data/lib/datadog/appsec/metrics/telemetry.rb +23 -0
  110. data/lib/datadog/appsec/metrics.rb +13 -0
  111. data/lib/datadog/appsec/monitor/gateway/watcher.rb +52 -32
  112. data/lib/datadog/appsec/processor/rule_loader.rb +30 -36
  113. data/lib/datadog/appsec/remote.rb +31 -57
  114. data/lib/datadog/appsec/response.rb +19 -85
  115. data/lib/datadog/appsec/security_engine/engine.rb +194 -0
  116. data/lib/datadog/appsec/security_engine/result.rb +67 -0
  117. data/lib/datadog/appsec/security_engine/runner.rb +87 -0
  118. data/lib/datadog/appsec/security_engine.rb +9 -0
  119. data/lib/datadog/appsec/security_event.rb +39 -0
  120. data/lib/datadog/appsec/utils.rb +0 -2
  121. data/lib/datadog/appsec.rb +22 -12
  122. data/lib/datadog/auto_instrument.rb +3 -0
  123. data/lib/datadog/core/buffer/random.rb +18 -2
  124. data/lib/datadog/core/configuration/agent_settings.rb +52 -0
  125. data/lib/datadog/core/configuration/agent_settings_resolver.rb +4 -18
  126. data/lib/datadog/core/configuration/agentless_settings_resolver.rb +176 -0
  127. data/lib/datadog/core/configuration/components.rb +74 -32
  128. data/lib/datadog/core/configuration/components_state.rb +23 -0
  129. data/lib/datadog/core/configuration/ext.rb +5 -1
  130. data/lib/datadog/core/configuration/option.rb +81 -45
  131. data/lib/datadog/core/configuration/option_definition.rb +6 -4
  132. data/lib/datadog/core/configuration/options.rb +3 -3
  133. data/lib/datadog/core/configuration/settings.rb +121 -50
  134. data/lib/datadog/core/configuration/stable_config.rb +22 -0
  135. data/lib/datadog/core/configuration.rb +43 -11
  136. data/lib/datadog/{tracing → core}/contrib/rails/utils.rb +1 -3
  137. data/lib/datadog/core/crashtracking/component.rb +4 -13
  138. data/lib/datadog/core/crashtracking/tag_builder.rb +4 -22
  139. data/lib/datadog/core/diagnostics/environment_logger.rb +1 -1
  140. data/lib/datadog/core/encoding.rb +17 -1
  141. data/lib/datadog/core/environment/agent_info.rb +78 -0
  142. data/lib/datadog/core/environment/cgroup.rb +10 -12
  143. data/lib/datadog/core/environment/container.rb +38 -40
  144. data/lib/datadog/core/environment/ext.rb +6 -6
  145. data/lib/datadog/core/environment/git.rb +1 -0
  146. data/lib/datadog/core/environment/identity.rb +3 -3
  147. data/lib/datadog/core/environment/platform.rb +3 -3
  148. data/lib/datadog/core/environment/variable_helpers.rb +1 -1
  149. data/lib/datadog/core/error.rb +11 -9
  150. data/lib/datadog/core/logger.rb +2 -2
  151. data/lib/datadog/core/metrics/client.rb +27 -27
  152. data/lib/datadog/core/metrics/logging.rb +5 -5
  153. data/lib/datadog/core/process_discovery/tracer_memfd.rb +15 -0
  154. data/lib/datadog/core/process_discovery.rb +36 -0
  155. data/lib/datadog/core/rate_limiter.rb +4 -2
  156. data/lib/datadog/core/remote/client/capabilities.rb +6 -0
  157. data/lib/datadog/core/remote/client.rb +107 -92
  158. data/lib/datadog/core/remote/component.rb +18 -19
  159. data/lib/datadog/core/remote/configuration/digest.rb +7 -7
  160. data/lib/datadog/core/remote/configuration/path.rb +1 -1
  161. data/lib/datadog/core/remote/configuration/repository.rb +14 -1
  162. data/lib/datadog/core/remote/negotiation.rb +9 -9
  163. data/lib/datadog/core/remote/transport/config.rb +4 -3
  164. data/lib/datadog/core/remote/transport/http/api.rb +13 -18
  165. data/lib/datadog/core/remote/transport/http/client.rb +5 -4
  166. data/lib/datadog/core/remote/transport/http/config.rb +27 -55
  167. data/lib/datadog/core/remote/transport/http/negotiation.rb +8 -51
  168. data/lib/datadog/core/remote/transport/http.rb +25 -94
  169. data/lib/datadog/core/remote/transport/negotiation.rb +17 -4
  170. data/lib/datadog/core/remote/worker.rb +10 -7
  171. data/lib/datadog/core/runtime/metrics.rb +12 -5
  172. data/lib/datadog/core/tag_builder.rb +56 -0
  173. data/lib/datadog/core/telemetry/component.rb +84 -49
  174. data/lib/datadog/core/telemetry/emitter.rb +23 -11
  175. data/lib/datadog/core/telemetry/event/app_client_configuration_change.rb +66 -0
  176. data/lib/datadog/core/telemetry/event/app_closing.rb +18 -0
  177. data/lib/datadog/core/telemetry/event/app_dependencies_loaded.rb +33 -0
  178. data/lib/datadog/core/telemetry/event/app_heartbeat.rb +18 -0
  179. data/lib/datadog/core/telemetry/event/app_integrations_change.rb +58 -0
  180. data/lib/datadog/core/telemetry/event/app_started.rb +269 -0
  181. data/lib/datadog/core/telemetry/event/base.rb +40 -0
  182. data/lib/datadog/core/telemetry/event/distributions.rb +18 -0
  183. data/lib/datadog/core/telemetry/event/generate_metrics.rb +43 -0
  184. data/lib/datadog/core/telemetry/event/log.rb +76 -0
  185. data/lib/datadog/core/telemetry/event/message_batch.rb +42 -0
  186. data/lib/datadog/core/telemetry/event/synth_app_client_configuration_change.rb +43 -0
  187. data/lib/datadog/core/telemetry/event.rb +17 -383
  188. data/lib/datadog/core/telemetry/ext.rb +1 -0
  189. data/lib/datadog/core/telemetry/http/adapters/net.rb +12 -97
  190. data/lib/datadog/core/telemetry/logger.rb +5 -4
  191. data/lib/datadog/core/telemetry/logging.rb +12 -6
  192. data/lib/datadog/core/telemetry/metric.rb +28 -6
  193. data/lib/datadog/core/telemetry/request.rb +4 -4
  194. data/lib/datadog/core/telemetry/transport/http/api.rb +43 -0
  195. data/lib/datadog/core/telemetry/transport/http/client.rb +49 -0
  196. data/lib/datadog/core/telemetry/transport/http/telemetry.rb +92 -0
  197. data/lib/datadog/core/telemetry/transport/http.rb +63 -0
  198. data/lib/datadog/core/telemetry/transport/telemetry.rb +51 -0
  199. data/lib/datadog/core/telemetry/worker.rb +128 -25
  200. data/lib/datadog/core/transport/http/adapters/net.rb +17 -2
  201. data/lib/datadog/core/transport/http/adapters/test.rb +2 -1
  202. data/lib/datadog/core/transport/http/adapters/unix_socket.rb +1 -1
  203. data/lib/datadog/{tracing → core}/transport/http/api/instance.rb +18 -1
  204. data/lib/datadog/core/transport/http/api/spec.rb +36 -0
  205. data/lib/datadog/{tracing → core}/transport/http/builder.rb +53 -31
  206. data/lib/datadog/core/transport/http/env.rb +8 -0
  207. data/lib/datadog/core/transport/http.rb +75 -0
  208. data/lib/datadog/core/transport/response.rb +4 -0
  209. data/lib/datadog/core/utils/at_fork_monkey_patch.rb +6 -6
  210. data/lib/datadog/core/utils/duration.rb +32 -32
  211. data/lib/datadog/core/utils/forking.rb +2 -2
  212. data/lib/datadog/core/utils/network.rb +6 -6
  213. data/lib/datadog/core/utils/only_once_successful.rb +16 -5
  214. data/lib/datadog/core/utils/time.rb +20 -0
  215. data/lib/datadog/core/utils/truncation.rb +21 -0
  216. data/lib/datadog/core/utils.rb +7 -0
  217. data/lib/datadog/core/vendor/multipart-post/multipart/post/composite_read_io.rb +1 -1
  218. data/lib/datadog/core/vendor/multipart-post/multipart/post/multipartable.rb +8 -8
  219. data/lib/datadog/core/vendor/multipart-post/multipart/post/parts.rb +7 -7
  220. data/lib/datadog/core/worker.rb +1 -1
  221. data/lib/datadog/core/workers/async.rb +29 -12
  222. data/lib/datadog/core/workers/interval_loop.rb +12 -1
  223. data/lib/datadog/core/workers/runtime_metrics.rb +2 -2
  224. data/lib/datadog/core.rb +8 -0
  225. data/lib/datadog/di/base.rb +115 -0
  226. data/lib/datadog/di/boot.rb +34 -0
  227. data/lib/datadog/di/code_tracker.rb +26 -15
  228. data/lib/datadog/di/component.rb +23 -14
  229. data/lib/datadog/di/configuration/settings.rb +25 -1
  230. data/lib/datadog/di/contrib/active_record.rb +1 -0
  231. data/lib/datadog/di/contrib/railtie.rb +15 -0
  232. data/lib/datadog/di/contrib.rb +28 -0
  233. data/lib/datadog/di/error.rb +5 -0
  234. data/lib/datadog/di/instrumenter.rb +162 -21
  235. data/lib/datadog/di/logger.rb +30 -0
  236. data/lib/datadog/di/preload.rb +18 -0
  237. data/lib/datadog/di/probe.rb +14 -7
  238. data/lib/datadog/di/probe_builder.rb +1 -0
  239. data/lib/datadog/di/probe_manager.rb +11 -5
  240. data/lib/datadog/di/probe_notification_builder.rb +54 -38
  241. data/lib/datadog/di/probe_notifier_worker.rb +60 -26
  242. data/lib/datadog/di/redactor.rb +0 -1
  243. data/lib/datadog/di/remote.rb +147 -0
  244. data/lib/datadog/di/serializer.rb +19 -8
  245. data/lib/datadog/di/transport/diagnostics.rb +62 -0
  246. data/lib/datadog/di/transport/http/api.rb +42 -0
  247. data/lib/datadog/di/transport/http/client.rb +47 -0
  248. data/lib/datadog/di/transport/http/diagnostics.rb +65 -0
  249. data/lib/datadog/di/transport/http/input.rb +77 -0
  250. data/lib/datadog/di/transport/http.rb +57 -0
  251. data/lib/datadog/di/transport/input.rb +70 -0
  252. data/lib/datadog/di/utils.rb +103 -0
  253. data/lib/datadog/di.rb +14 -76
  254. data/lib/datadog/error_tracking/collector.rb +87 -0
  255. data/lib/datadog/error_tracking/component.rb +167 -0
  256. data/lib/datadog/error_tracking/configuration/settings.rb +63 -0
  257. data/lib/datadog/error_tracking/configuration.rb +11 -0
  258. data/lib/datadog/error_tracking/ext.rb +18 -0
  259. data/lib/datadog/error_tracking/extensions.rb +16 -0
  260. data/lib/datadog/error_tracking/filters.rb +77 -0
  261. data/lib/datadog/error_tracking.rb +18 -0
  262. data/lib/datadog/kit/appsec/events.rb +15 -3
  263. data/lib/datadog/kit/identity.rb +9 -5
  264. data/lib/datadog/opentelemetry/api/baggage.rb +90 -0
  265. data/lib/datadog/opentelemetry/api/baggage.rbs +26 -0
  266. data/lib/datadog/opentelemetry/api/context.rb +16 -2
  267. data/lib/datadog/opentelemetry/sdk/trace/span.rb +1 -1
  268. data/lib/datadog/opentelemetry.rb +2 -1
  269. data/lib/datadog/profiling/collectors/code_provenance.rb +18 -9
  270. data/lib/datadog/profiling/collectors/cpu_and_wall_time_worker.rb +4 -0
  271. data/lib/datadog/profiling/collectors/idle_sampling_helper.rb +1 -0
  272. data/lib/datadog/profiling/collectors/info.rb +3 -0
  273. data/lib/datadog/profiling/collectors/thread_context.rb +17 -2
  274. data/lib/datadog/profiling/component.rb +64 -82
  275. data/lib/datadog/profiling/encoded_profile.rb +11 -0
  276. data/lib/datadog/profiling/exporter.rb +3 -4
  277. data/lib/datadog/profiling/ext.rb +0 -14
  278. data/lib/datadog/profiling/flush.rb +5 -8
  279. data/lib/datadog/profiling/http_transport.rb +8 -87
  280. data/lib/datadog/profiling/load_native_extension.rb +1 -33
  281. data/lib/datadog/profiling/profiler.rb +2 -0
  282. data/lib/datadog/profiling/scheduler.rb +10 -2
  283. data/lib/datadog/profiling/stack_recorder.rb +9 -9
  284. data/lib/datadog/profiling/tag_builder.rb +5 -41
  285. data/lib/datadog/profiling/tasks/setup.rb +2 -0
  286. data/lib/datadog/profiling.rb +6 -2
  287. data/lib/datadog/tracing/analytics.rb +1 -1
  288. data/lib/datadog/tracing/component.rb +16 -12
  289. data/lib/datadog/tracing/configuration/ext.rb +8 -1
  290. data/lib/datadog/tracing/configuration/settings.rb +22 -10
  291. data/lib/datadog/tracing/context_provider.rb +1 -1
  292. data/lib/datadog/tracing/contrib/action_cable/integration.rb +5 -2
  293. data/lib/datadog/tracing/contrib/action_mailer/integration.rb +6 -2
  294. data/lib/datadog/tracing/contrib/action_pack/action_controller/instrumentation.rb +15 -0
  295. data/lib/datadog/tracing/contrib/action_pack/action_dispatch/instrumentation.rb +19 -12
  296. data/lib/datadog/tracing/contrib/action_pack/ext.rb +2 -0
  297. data/lib/datadog/tracing/contrib/action_pack/integration.rb +5 -2
  298. data/lib/datadog/tracing/contrib/action_view/integration.rb +5 -2
  299. data/lib/datadog/tracing/contrib/active_job/integration.rb +5 -2
  300. data/lib/datadog/tracing/contrib/active_record/integration.rb +7 -3
  301. data/lib/datadog/tracing/contrib/active_support/cache/events/cache.rb +7 -2
  302. data/lib/datadog/tracing/contrib/active_support/cache/instrumentation.rb +36 -1
  303. data/lib/datadog/tracing/contrib/active_support/cache/patcher.rb +4 -0
  304. data/lib/datadog/tracing/contrib/active_support/cache/redis.rb +14 -4
  305. data/lib/datadog/tracing/contrib/active_support/configuration/settings.rb +10 -0
  306. data/lib/datadog/tracing/contrib/active_support/integration.rb +5 -2
  307. data/lib/datadog/tracing/contrib/auto_instrument.rb +2 -2
  308. data/lib/datadog/tracing/contrib/aws/instrumentation.rb +10 -0
  309. data/lib/datadog/tracing/contrib/aws/integration.rb +3 -0
  310. data/lib/datadog/tracing/contrib/aws/parsed_context.rb +5 -1
  311. data/lib/datadog/tracing/contrib/concurrent_ruby/integration.rb +3 -0
  312. data/lib/datadog/tracing/contrib/configuration/settings.rb +1 -1
  313. data/lib/datadog/tracing/contrib/elasticsearch/configuration/settings.rb +4 -0
  314. data/lib/datadog/tracing/contrib/elasticsearch/patcher.rb +6 -1
  315. data/lib/datadog/tracing/contrib/ethon/easy_patch.rb +4 -5
  316. data/lib/datadog/tracing/contrib/excon/middleware.rb +5 -3
  317. data/lib/datadog/tracing/contrib/ext.rb +1 -0
  318. data/lib/datadog/tracing/contrib/extensions.rb +29 -3
  319. data/lib/datadog/tracing/contrib/faraday/middleware.rb +5 -3
  320. data/lib/datadog/tracing/contrib/graphql/configuration/error_extension_env_parser.rb +21 -0
  321. data/lib/datadog/tracing/contrib/graphql/configuration/settings.rb +11 -0
  322. data/lib/datadog/tracing/contrib/graphql/ext.rb +5 -0
  323. data/lib/datadog/tracing/contrib/graphql/unified_trace.rb +102 -11
  324. data/lib/datadog/tracing/contrib/grpc/datadog_interceptor/client.rb +7 -1
  325. data/lib/datadog/tracing/contrib/grpc/distributed/propagation.rb +3 -0
  326. data/lib/datadog/tracing/contrib/http/circuit_breaker.rb +0 -15
  327. data/lib/datadog/tracing/contrib/http/distributed/propagation.rb +4 -1
  328. data/lib/datadog/tracing/contrib/http/instrumentation.rb +6 -10
  329. data/lib/datadog/tracing/contrib/http/integration.rb +3 -0
  330. data/lib/datadog/tracing/contrib/httpclient/instrumentation.rb +6 -16
  331. data/lib/datadog/tracing/contrib/httprb/instrumentation.rb +7 -15
  332. data/lib/datadog/tracing/contrib/httprb/integration.rb +3 -0
  333. data/lib/datadog/tracing/contrib/kafka/integration.rb +3 -0
  334. data/lib/datadog/tracing/contrib/karafka/configuration/settings.rb +27 -0
  335. data/lib/datadog/tracing/contrib/karafka/distributed/propagation.rb +48 -0
  336. data/lib/datadog/tracing/contrib/karafka/ext.rb +27 -0
  337. data/lib/datadog/tracing/contrib/karafka/integration.rb +45 -0
  338. data/lib/datadog/tracing/contrib/karafka/monitor.rb +66 -0
  339. data/lib/datadog/tracing/contrib/karafka/patcher.rb +71 -0
  340. data/lib/datadog/tracing/contrib/karafka.rb +37 -0
  341. data/lib/datadog/tracing/contrib/lograge/patcher.rb +4 -2
  342. data/lib/datadog/tracing/contrib/mongodb/configuration/settings.rb +8 -0
  343. data/lib/datadog/tracing/contrib/mongodb/ext.rb +1 -0
  344. data/lib/datadog/tracing/contrib/mongodb/integration.rb +3 -0
  345. data/lib/datadog/tracing/contrib/mongodb/subscribers.rb +18 -1
  346. data/lib/datadog/tracing/contrib/opensearch/configuration/settings.rb +17 -0
  347. data/lib/datadog/tracing/contrib/opensearch/ext.rb +9 -0
  348. data/lib/datadog/tracing/contrib/opensearch/integration.rb +3 -0
  349. data/lib/datadog/tracing/contrib/opensearch/patcher.rb +5 -1
  350. data/lib/datadog/tracing/contrib/patcher.rb +5 -2
  351. data/lib/datadog/tracing/contrib/presto/integration.rb +3 -0
  352. data/lib/datadog/tracing/contrib/rack/header_collection.rb +11 -1
  353. data/lib/datadog/tracing/contrib/rack/integration.rb +2 -2
  354. data/lib/datadog/tracing/contrib/rack/middlewares.rb +1 -1
  355. data/lib/datadog/tracing/contrib/rack/request_queue.rb +1 -1
  356. data/lib/datadog/tracing/contrib/rails/framework.rb +2 -2
  357. data/lib/datadog/tracing/contrib/rails/patcher.rb +1 -1
  358. data/lib/datadog/tracing/contrib/rest_client/integration.rb +3 -0
  359. data/lib/datadog/tracing/contrib/rest_client/request_patch.rb +5 -3
  360. data/lib/datadog/tracing/contrib/sidekiq/client_tracer.rb +6 -1
  361. data/lib/datadog/tracing/contrib/sidekiq/distributed/propagation.rb +3 -0
  362. data/lib/datadog/tracing/contrib/sidekiq/ext.rb +1 -0
  363. data/lib/datadog/tracing/contrib/sidekiq/server_tracer.rb +5 -2
  364. data/lib/datadog/tracing/contrib/span_attribute_schema.rb +6 -1
  365. data/lib/datadog/tracing/contrib/support.rb +28 -0
  366. data/lib/datadog/tracing/contrib.rb +1 -0
  367. data/lib/datadog/tracing/correlation.rb +9 -2
  368. data/lib/datadog/tracing/distributed/b3_multi.rb +1 -1
  369. data/lib/datadog/tracing/distributed/b3_single.rb +1 -1
  370. data/lib/datadog/tracing/distributed/baggage.rb +131 -0
  371. data/lib/datadog/tracing/distributed/datadog.rb +4 -2
  372. data/lib/datadog/tracing/distributed/propagation.rb +25 -4
  373. data/lib/datadog/tracing/distributed/propagation_policy.rb +42 -0
  374. data/lib/datadog/tracing/metadata/errors.rb +4 -4
  375. data/lib/datadog/tracing/metadata/ext.rb +5 -0
  376. data/lib/datadog/tracing/metadata/metastruct.rb +36 -0
  377. data/lib/datadog/tracing/metadata/metastruct_tagging.rb +42 -0
  378. data/lib/datadog/tracing/metadata.rb +2 -0
  379. data/lib/datadog/tracing/sampling/rate_sampler.rb +2 -1
  380. data/lib/datadog/tracing/sampling/span/rule.rb +0 -1
  381. data/lib/datadog/tracing/span.rb +22 -5
  382. data/lib/datadog/tracing/span_event.rb +124 -4
  383. data/lib/datadog/tracing/span_operation.rb +52 -16
  384. data/lib/datadog/tracing/sync_writer.rb +10 -6
  385. data/lib/datadog/tracing/trace_digest.rb +9 -2
  386. data/lib/datadog/tracing/trace_operation.rb +55 -27
  387. data/lib/datadog/tracing/trace_segment.rb +6 -4
  388. data/lib/datadog/tracing/tracer.rb +66 -14
  389. data/lib/datadog/tracing/transport/http/api.rb +5 -4
  390. data/lib/datadog/tracing/transport/http/client.rb +5 -4
  391. data/lib/datadog/tracing/transport/http/traces.rb +13 -44
  392. data/lib/datadog/tracing/transport/http.rb +13 -70
  393. data/lib/datadog/tracing/transport/serializable_trace.rb +31 -7
  394. data/lib/datadog/tracing/transport/trace_formatter.rb +7 -0
  395. data/lib/datadog/tracing/transport/traces.rb +47 -13
  396. data/lib/datadog/tracing/utils.rb +1 -1
  397. data/lib/datadog/tracing/workers/trace_writer.rb +8 -5
  398. data/lib/datadog/tracing/workers.rb +5 -4
  399. data/lib/datadog/tracing/writer.rb +10 -6
  400. data/lib/datadog/tracing.rb +16 -3
  401. data/lib/datadog/version.rb +2 -2
  402. data/lib/datadog.rb +2 -0
  403. metadata +149 -54
  404. data/ext/datadog_profiling_loader/datadog_profiling_loader.c +0 -142
  405. data/ext/datadog_profiling_loader/extconf.rb +0 -60
  406. data/lib/datadog/appsec/assets/waf_rules/processors.json +0 -92
  407. data/lib/datadog/appsec/assets/waf_rules/scanners.json +0 -114
  408. data/lib/datadog/appsec/contrib/devise/event.rb +0 -57
  409. data/lib/datadog/appsec/contrib/devise/patcher/authenticatable_patch.rb +0 -77
  410. data/lib/datadog/appsec/contrib/devise/patcher/registration_controller_patch.rb +0 -54
  411. data/lib/datadog/appsec/contrib/devise/resource.rb +0 -35
  412. data/lib/datadog/appsec/contrib/devise/tracking.rb +0 -57
  413. data/lib/datadog/appsec/contrib/graphql/reactive/multiplex.rb +0 -46
  414. data/lib/datadog/appsec/contrib/patcher.rb +0 -12
  415. data/lib/datadog/appsec/contrib/rack/reactive/request.rb +0 -69
  416. data/lib/datadog/appsec/contrib/rack/reactive/request_body.rb +0 -47
  417. data/lib/datadog/appsec/contrib/rack/reactive/response.rb +0 -53
  418. data/lib/datadog/appsec/contrib/rails/reactive/action.rb +0 -53
  419. data/lib/datadog/appsec/contrib/sinatra/ext.rb +0 -14
  420. data/lib/datadog/appsec/contrib/sinatra/reactive/routed.rb +0 -48
  421. data/lib/datadog/appsec/monitor/reactive/set_user.rb +0 -45
  422. data/lib/datadog/appsec/processor/actions.rb +0 -49
  423. data/lib/datadog/appsec/processor/context.rb +0 -107
  424. data/lib/datadog/appsec/processor/rule_merger.rb +0 -170
  425. data/lib/datadog/appsec/processor.rb +0 -106
  426. data/lib/datadog/appsec/reactive/address_hash.rb +0 -22
  427. data/lib/datadog/appsec/reactive/engine.rb +0 -47
  428. data/lib/datadog/appsec/reactive/operation.rb +0 -68
  429. data/lib/datadog/appsec/reactive/subscriber.rb +0 -19
  430. data/lib/datadog/appsec/scope.rb +0 -58
  431. data/lib/datadog/appsec/utils/trace_operation.rb +0 -15
  432. data/lib/datadog/core/crashtracking/agent_base_url.rb +0 -21
  433. data/lib/datadog/core/remote/transport/http/api/instance.rb +0 -39
  434. data/lib/datadog/core/remote/transport/http/api/spec.rb +0 -21
  435. data/lib/datadog/core/remote/transport/http/builder.rb +0 -219
  436. data/lib/datadog/core/telemetry/http/env.rb +0 -20
  437. data/lib/datadog/core/telemetry/http/ext.rb +0 -28
  438. data/lib/datadog/core/telemetry/http/response.rb +0 -70
  439. data/lib/datadog/core/telemetry/http/transport.rb +0 -90
  440. data/lib/datadog/di/transport.rb +0 -81
  441. data/lib/datadog/tracing/transport/http/api/spec.rb +0 -19
@@ -10,7 +10,7 @@ module Datadog
10
10
  # The loop inside the worker rescues all exceptions to prevent termination
11
11
  # due to unhandled exceptions raised by any downstream code.
12
12
  # This includes communication and protocol errors when sending the
13
- # payloads to the agent.
13
+ # events to the agent.
14
14
  #
15
15
  # The worker groups the data to send into batches. The goal is to perform
16
16
  # no more than one network operation per event type per second.
@@ -23,12 +23,12 @@ module Datadog
23
23
  #
24
24
  # @api private
25
25
  class ProbeNotifierWorker
26
- def initialize(settings, transport, logger, telemetry: nil)
26
+ def initialize(settings, logger, agent_settings:, telemetry: nil)
27
27
  @settings = settings
28
28
  @telemetry = telemetry
29
29
  @status_queue = []
30
30
  @snapshot_queue = []
31
- @transport = transport
31
+ @agent_settings = agent_settings
32
32
  @logger = logger
33
33
  @lock = Mutex.new
34
34
  @wake = Core::Semaphore.new
@@ -36,15 +36,18 @@ module Datadog
36
36
  @sleep_remaining = nil
37
37
  @wake_scheduled = false
38
38
  @thread = nil
39
+ @pid = nil
39
40
  @flush = 0
40
41
  end
41
42
 
42
43
  attr_reader :settings
43
44
  attr_reader :logger
44
45
  attr_reader :telemetry
46
+ attr_reader :agent_settings
45
47
 
46
48
  def start
47
- return if @thread
49
+ return if @thread && @pid == Process.pid
50
+ logger.trace { "di: starting probe notifier: pid #{$$}" }
48
51
  @thread = Thread.new do
49
52
  loop do
50
53
  # TODO If stop is requested, we stop immediately without
@@ -77,7 +80,7 @@ module Datadog
77
80
  rescue => exc
78
81
  raise if settings.dynamic_instrumentation.internal.propagate_all_exceptions
79
82
 
80
- logger.warn("Error in probe notifier worker: #{exc.class}: #{exc} (at #{exc.backtrace.first})")
83
+ logger.debug { "di: error in probe notifier worker: #{exc.class}: #{exc} (at #{exc.backtrace.first})" }
81
84
  telemetry&.report(exc, description: "Error in probe notifier worker")
82
85
  end
83
86
  @lock.synchronize do
@@ -86,6 +89,7 @@ module Datadog
86
89
  wake.wait(more ? min_send_interval : nil)
87
90
  end
88
91
  end
92
+ @pid = Process.pid
89
93
  end
90
94
 
91
95
  # Stops the background thread.
@@ -94,6 +98,7 @@ module Datadog
94
98
  # to killing the thread using Thread#kill.
95
99
  def stop(timeout = 1)
96
100
  @stop_requested = true
101
+ logger.trace { "di: stopping probe notifier: pid #{$$}" }
97
102
  wake.signal
98
103
  if thread
99
104
  unless thread.join(timeout)
@@ -150,7 +155,6 @@ module Datadog
150
155
 
151
156
  private
152
157
 
153
- attr_reader :transport
154
158
  attr_reader :wake
155
159
  attr_reader :thread
156
160
 
@@ -166,6 +170,30 @@ module Datadog
166
170
 
167
171
  attr_reader :last_sent
168
172
 
173
+ def status_transport
174
+ @status_transport ||= DI::Transport::HTTP.diagnostics(agent_settings: agent_settings, logger: logger)
175
+ end
176
+
177
+ def do_send_status(batch)
178
+ status_transport.send_diagnostics(batch)
179
+ end
180
+
181
+ def snapshot_transport
182
+ @snapshot_transport ||= DI::Transport::HTTP.input(agent_settings: agent_settings, logger: logger)
183
+ end
184
+
185
+ def do_send_snapshot(batch)
186
+ snapshot_transport.send_input(batch, tags)
187
+ end
188
+
189
+ def tags
190
+ # DEV: The tags could be cached but they need to be recreated
191
+ # when process forks (since the child receives new runtime IDs).
192
+ Core::TagBuilder.tags(settings).merge(
193
+ 'debugger_version' => Core::Environment::Identity.gem_datadog_version,
194
+ )
195
+ end
196
+
169
197
  [
170
198
  [:status, 'probe status'],
171
199
  [:snapshot, 'snapshot'],
@@ -183,10 +211,10 @@ module Datadog
183
211
  define_method("add_#{event_type}") do |event|
184
212
  @lock.synchronize do
185
213
  queue = send("#{event_type}_queue")
186
- # TODO determine a suitable limit via testing/benchmarking
187
- if queue.length > 100
188
- logger.warn("#{self.class.name}: dropping #{event_type} because queue is full")
214
+ if queue.length > settings.dynamic_instrumentation.internal.snapshot_queue_capacity
215
+ logger.debug { "di: #{self.class.name}: dropping #{event_type} event because queue is full" }
189
216
  else
217
+ logger.trace { "di: #{self.class.name}: queueing #{event_type} event" }
190
218
  queue << event
191
219
  end
192
220
  end
@@ -201,20 +229,10 @@ module Datadog
201
229
  wake.signal
202
230
  end
203
231
  end
204
- end
205
232
 
206
- # Determine how much longer the worker thread should sleep
207
- # so as not to send in less than min send interval since the last send.
208
- # Important: this method must be called when @lock is held.
209
- #
210
- # Returns the time remaining to sleep.
211
- def set_sleep_remaining
212
- now = Core::Utils::Time.get_time
213
- @sleep_remaining = if last_sent
214
- [last_sent + min_send_interval - now, 0].max
215
- else
216
- 0
217
- end
233
+ # Worker could be not running if the process forked - check and
234
+ # start it again in this case.
235
+ start
218
236
  end
219
237
 
220
238
  public "add_#{event_type}"
@@ -233,16 +251,18 @@ module Datadog
233
251
  instance_variable_set("@#{event_type}_queue", [])
234
252
  @io_in_progress = batch.any? # steep:ignore
235
253
  end
254
+ logger.trace { "di: #{self.class.name}: checking #{event_type} queue - #{batch.length} entries" } # steep:ignore
236
255
  if batch.any? # steep:ignore
237
256
  begin
238
- transport.public_send("send_#{event_type}", batch)
257
+ logger.trace { "di: sending #{batch.length} #{event_type} event(s) to agent" } # steep:ignore
258
+ send("do_send_#{event_type}", batch)
239
259
  time = Core::Utils::Time.get_time
240
260
  @lock.synchronize do
241
261
  @last_sent = time
242
262
  end
243
263
  rescue => exc
244
264
  raise if settings.dynamic_instrumentation.internal.propagate_all_exceptions
245
- logger.warn("failed to send #{event_name}: #{exc.class}: #{exc} (at #{exc.backtrace.first})")
265
+ logger.debug { "di: failed to send #{event_name}: #{exc.class}: #{exc} (at #{exc.backtrace.first})" }
246
266
  # Should we report this error to telemetry? Most likely failure
247
267
  # to send is due to a network issue, and trying to send a
248
268
  # telemetry message would also fail.
@@ -253,7 +273,7 @@ module Datadog
253
273
  # Normally the queue should only be consumed in this method,
254
274
  # however if anyone consumes it elsewhere we don't want to block
255
275
  # while consuming it here. Rescue ThreadError and return.
256
- logger.warn("Unexpected #{event_name} queue underflow - consumed elsewhere?")
276
+ logger.debug { "di: unexpected #{event_name} queue underflow - consumed elsewhere?" }
257
277
  telemetry&.report(exc, description: "Unexpected #{event_name} queue underflow")
258
278
  ensure
259
279
  @lock.synchronize do
@@ -262,9 +282,23 @@ module Datadog
262
282
  end
263
283
  end
264
284
 
285
+ # Determine how much longer the worker thread should sleep
286
+ # so as not to send in less than min send interval since the last send.
287
+ # Important: this method must be called when @lock is held.
288
+ #
289
+ # Returns the time remaining to sleep.
290
+ def set_sleep_remaining
291
+ now = Core::Utils::Time.get_time
292
+ @sleep_remaining = if last_sent
293
+ [last_sent + min_send_interval - now, 0].max
294
+ else
295
+ 0
296
+ end
297
+ end
298
+
265
299
  def maybe_send
266
300
  rv = maybe_send_status
267
- rv || maybe_send_snapshot
301
+ maybe_send_snapshot || rv
268
302
  end
269
303
  end
270
304
  end
@@ -119,7 +119,6 @@ module Datadog
119
119
  "dburl",
120
120
  "encryptionkey",
121
121
  "encryptionkeyid",
122
- "env",
123
122
  "geolocation",
124
123
  "gpgkey",
125
124
  "ipaddress",
@@ -0,0 +1,147 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Datadog
4
+ module DI
5
+ # Provides an interface expected by the core Remote subsystem to
6
+ # receive DI-specific remote configuration.
7
+ #
8
+ # In order to apply (i.e., act on) the configuration, we need the
9
+ # state stored under DI Component. Thus, this module forwards actual
10
+ # configuration application to the ProbeManager associated with the
11
+ # global DI Component.
12
+ #
13
+ # @api private
14
+ module Remote
15
+ class ReadError < StandardError; end
16
+
17
+ class << self
18
+ PRODUCT = 'LIVE_DEBUGGING'
19
+
20
+ def products
21
+ # TODO: do not send our product on unsupported runtimes
22
+ # (Ruby 2.5 / JRuby)
23
+ [PRODUCT]
24
+ end
25
+
26
+ def capabilities
27
+ []
28
+ end
29
+
30
+ def receivers(telemetry)
31
+ receiver do |repository, _changes|
32
+ # DEV: Filter our by product. Given it will be very common
33
+ # DEV: we can filter this out before we receive the data in this method.
34
+ # DEV: Apply this refactor to AppSec as well if implemented.
35
+
36
+ component = DI.component
37
+ # We should always have a non-nil DI component here, because we
38
+ # only add DI product to remote config request if DI is enabled.
39
+ # Ideally, we should be injected with the DI component here
40
+ # rather than having to retrieve it from global state.
41
+ # If the component is nil for some reason, we also don't have a
42
+ # logger instance to report the issue.
43
+ if component
44
+
45
+ probe_manager = component.probe_manager
46
+
47
+ current_probe_ids = {}
48
+ repository.contents.each do |content|
49
+ case content.path.product
50
+ when PRODUCT
51
+ begin
52
+ probe_spec = parse_content(content)
53
+ probe = ProbeBuilder.build_from_remote_config(probe_spec)
54
+ probe_notification_builder = component.probe_notification_builder
55
+ payload = probe_notification_builder.build_received(probe)
56
+ probe_notifier_worker = component.probe_notifier_worker
57
+ probe_notifier_worker.add_status(payload)
58
+ component.logger.debug { "di: received #{probe.type} probe at #{probe.location} (#{probe.id}) via RC" }
59
+
60
+ begin
61
+ # TODO test exception capture
62
+ probe_manager.add_probe(probe)
63
+ content.applied
64
+ rescue DI::Error::DITargetNotInRegistry => exc
65
+ component.telemetry&.report(exc, description: "Line probe is targeting a loaded file that is not in code tracker")
66
+
67
+ payload = probe_notification_builder.build_errored(probe, exc)
68
+ probe_notifier_worker.add_status(payload)
69
+
70
+ # If a probe fails to install, we will mark the content
71
+ # as errored. On subsequent remote configuration application
72
+ # attemps, probe manager will raise the "previously errored"
73
+ # exception and we'll rescue it here, again marking the
74
+ # content as errored but with a somewhat different exception
75
+ # message.
76
+ # TODO assert content state (errored for this example)
77
+ content.errored("Error applying dynamic instrumentation configuration: #{exc.class.name} #{exc.message}")
78
+ rescue => exc
79
+ raise if component.settings.dynamic_instrumentation.internal.propagate_all_exceptions
80
+
81
+ component.logger.debug { "di: unhandled exception adding #{probe.type} probe at #{probe.location} (#{probe.id}) in DI remote receiver: #{exc.class}: #{exc}" }
82
+ component.telemetry&.report(exc, description: "Unhandled exception adding probe in DI remote receiver")
83
+
84
+ # TODO test this path
85
+ payload = probe_notification_builder.build_errored(probe, exc)
86
+ probe_notifier_worker.add_status(payload)
87
+
88
+ # If a probe fails to install, we will mark the content
89
+ # as errored. On subsequent remote configuration application
90
+ # attemps, probe manager will raise the "previously errored"
91
+ # exception and we'll rescue it here, again marking the
92
+ # content as errored but with a somewhat different exception
93
+ # message.
94
+ # TODO assert content state (errored for this example)
95
+ content.errored("Error applying dynamic instrumentation configuration: #{exc.class.name} #{exc.message}")
96
+ end
97
+
98
+ # Important: even if processing fails for this probe config,
99
+ # we need to note it as being current so that we do not
100
+ # try to remove instrumentation that is still supposed to be
101
+ # active.
102
+ current_probe_ids[probe_spec.fetch('id')] = true
103
+ rescue => exc
104
+ raise if component.settings.dynamic_instrumentation.internal.propagate_all_exceptions
105
+
106
+ component.logger.debug { "di: unhandled exception handling a probe in DI remote receiver: #{exc.class}: #{exc}" }
107
+ component.telemetry&.report(exc, description: "Unhandled exception handling probe in DI remote receiver")
108
+
109
+ # TODO assert content state (errored for this example)
110
+ content.errored("Error applying dynamic instrumentation configuration: #{exc.class.name} #{exc.message}")
111
+ end
112
+ end
113
+ end
114
+
115
+ begin
116
+ # TODO test exception capture
117
+ probe_manager.remove_other_probes(current_probe_ids.keys)
118
+ rescue => exc
119
+ raise if component.settings.dynamic_instrumentation.internal.propagate_all_exceptions
120
+
121
+ component.logger.debug { "di: unhandled exception removing probes in DI remote receiver: #{exc.class}: #{exc}" }
122
+ component.telemetry&.report(exc, description: "Unhandled exception removing probes in DI remote receiver")
123
+ end
124
+ end
125
+ end
126
+ end
127
+
128
+ def receiver(products = [PRODUCT], &block)
129
+ matcher = Core::Remote::Dispatcher::Matcher::Product.new(products)
130
+ [Core::Remote::Dispatcher::Receiver.new(matcher, &block)]
131
+ end
132
+
133
+ private
134
+
135
+ def parse_content(content)
136
+ data = content.data.read
137
+
138
+ content.data.rewind
139
+
140
+ raise ReadError, 'EOF reached' if data.nil?
141
+
142
+ JSON.parse(data)
143
+ end
144
+ end
145
+ end
146
+ end
147
+ end
@@ -82,24 +82,32 @@ module Datadog
82
82
  # between positional and keyword arguments. We convert positional
83
83
  # arguments to keyword arguments ("arg1", "arg2", ...) and ensure
84
84
  # the positional arguments are listed first.
85
- def serialize_args(args, kwargs)
85
+ #
86
+ # Instance variables are technically a hash just like kwargs,
87
+ # we take them as a separate parameter to avoid a hash merge
88
+ # in upstream code.
89
+ def serialize_args(args, kwargs, instance_vars,
90
+ depth: settings.dynamic_instrumentation.max_capture_depth,
91
+ attribute_count: settings.dynamic_instrumentation.max_capture_attribute_count)
86
92
  counter = 0
87
93
  combined = args.each_with_object({}) do |value, c|
88
94
  counter += 1
89
95
  # Conversion to symbol is needed here to put args ahead of
90
96
  # kwargs when they are merged below.
91
97
  c[:"arg#{counter}"] = value
92
- end.update(kwargs)
93
- serialize_vars(combined)
98
+ end.update(kwargs).update(instance_vars)
99
+ serialize_vars(combined, depth: depth, attribute_count: attribute_count)
94
100
  end
95
101
 
96
102
  # Serializes variables captured by a line probe.
97
103
  #
98
104
  # These are normally local variables that exist on a particular line
99
105
  # of executed code.
100
- def serialize_vars(vars)
106
+ def serialize_vars(vars,
107
+ depth: settings.dynamic_instrumentation.max_capture_depth,
108
+ attribute_count: settings.dynamic_instrumentation.max_capture_attribute_count)
101
109
  vars.each_with_object({}) do |(k, v), agg|
102
- agg[k] = serialize_value(v, name: k)
110
+ agg[k] = serialize_value(v, name: k, depth: depth, attribute_count: attribute_count)
103
111
  end
104
112
  end
105
113
 
@@ -115,7 +123,11 @@ module Datadog
115
123
  # (integers, strings, arrays, hashes).
116
124
  #
117
125
  # Respects string length, collection size and traversal depth limits.
118
- def serialize_value(value, name: nil, depth: settings.dynamic_instrumentation.max_capture_depth, type: nil)
126
+ def serialize_value(value, name: nil,
127
+ depth: settings.dynamic_instrumentation.max_capture_depth,
128
+ attribute_count: nil,
129
+ type: nil)
130
+ attribute_count ||= settings.dynamic_instrumentation.max_capture_attribute_count
119
131
  cls = type || value.class
120
132
  begin
121
133
  if redactor.redact_type?(value)
@@ -203,7 +215,6 @@ module Datadog
203
215
  serialized.update(notCapturedReason: "depth")
204
216
  else
205
217
  fields = {}
206
- max = settings.dynamic_instrumentation.max_capture_attribute_count
207
218
  cur = 0
208
219
 
209
220
  # MRI and JRuby 9.4.5+ preserve instance variable definition
@@ -229,7 +240,7 @@ module Datadog
229
240
  ivars = value.instance_variables
230
241
 
231
242
  ivars.each do |ivar|
232
- if cur >= max
243
+ if cur >= attribute_count
233
244
  serialized.update(notCapturedReason: "fieldCount", fields: fields)
234
245
  break
235
246
  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 Diagnostics
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::DIAGNOSTICS]
29
+ end
30
+
31
+ def send_diagnostics(payload)
32
+ json = JSON.dump(payload)
33
+ parcel = EncodedParcel.new(json)
34
+ request = Request.new(parcel)
35
+
36
+ response = @client.send_diagnostics_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_diagnostics 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_diagnostics failed: #{exc.class}: #{exc}"
57
+ end
58
+ end
59
+ end
60
+ end
61
+ end
62
+ end
@@ -0,0 +1,42 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative '../../../core/encoding'
4
+ require_relative '../../../core/transport/http/api/map'
5
+ require_relative '../../../core/transport/http/api/instance'
6
+ require_relative '../../../core/transport/http/api/spec'
7
+ require_relative 'diagnostics'
8
+ require_relative 'input'
9
+
10
+ module Datadog
11
+ module DI
12
+ module Transport
13
+ module HTTP
14
+ # Namespace for API components
15
+ module API
16
+ # Default API versions
17
+ DIAGNOSTICS = 'diagnostics'
18
+ INPUT = 'input'
19
+
20
+ module_function
21
+
22
+ def defaults
23
+ Datadog::Core::Transport::HTTP::API::Map[
24
+ DIAGNOSTICS => Diagnostics::API::Spec.new do |s|
25
+ s.diagnostics = Diagnostics::API::Endpoint.new(
26
+ '/debugger/v1/diagnostics',
27
+ Core::Encoding::JSONEncoder,
28
+ )
29
+ end,
30
+ INPUT => Input::API::Spec.new do |s|
31
+ s.input = Input::API::Endpoint.new(
32
+ '/debugger/v1/input',
33
+ Core::Encoding::JSONEncoder,
34
+ )
35
+ end,
36
+ ]
37
+ end
38
+ end
39
+ end
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,47 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative '../../../core/transport/http/env'
4
+ require_relative '../../../core/transport/http/response'
5
+
6
+ # TODO: Decouple transport/http/client
7
+ #
8
+ # The standard one does `include Transport::HTTP::Statistics` and performs
9
+ # stats updates, which may or may not be desirable in general.
10
+
11
+ module Datadog
12
+ module DI
13
+ module Transport
14
+ module HTTP
15
+ # Routes, encodes, and sends DI data to the trace agent via HTTP.
16
+ class Client
17
+ attr_reader :api, :logger
18
+
19
+ def initialize(api, logger:)
20
+ @api = api
21
+ @logger = logger
22
+ end
23
+
24
+ def send_request(request, &block)
25
+ # Build request into env
26
+ env = build_env(request)
27
+
28
+ # Get responses from API
29
+ yield(api, env)
30
+ rescue => e
31
+ message =
32
+ "Internal error during #{self.class.name} request. Cause: #{e.class.name} #{e.message} " \
33
+ "Location: #{Array(e.backtrace).first}"
34
+
35
+ logger.debug(message)
36
+
37
+ Datadog::Core::Transport::InternalErrorResponse.new(e)
38
+ end
39
+
40
+ def build_env(request)
41
+ Datadog::Core::Transport::HTTP::Env.new(request)
42
+ end
43
+ end
44
+ end
45
+ end
46
+ end
47
+ end
@@ -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