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
@@ -32,6 +32,12 @@ module Datadog
32
32
  status: 'EMITTING',)
33
33
  end
34
34
 
35
+ def build_errored(probe, exc)
36
+ build_status(probe,
37
+ message: "Instrumentation for probe #{probe.id} failed: #{exc}",
38
+ status: 'ERROR',)
39
+ end
40
+
35
41
  # Duration is in seconds.
36
42
  def build_executed(probe,
37
43
  trace_point: nil, rv: nil, duration: nil, caller_locations: nil,
@@ -65,14 +71,18 @@ module Datadog
65
71
  arguments: if serialized_entry_args
66
72
  serialized_entry_args
67
73
  else
68
- (args || kwargs) && serializer.serialize_args(args, kwargs)
74
+ (args || kwargs) && serializer.serialize_args(args, kwargs,
75
+ depth: probe.max_capture_depth || settings.dynamic_instrumentation.max_capture_depth,
76
+ attribute_count: probe.max_capture_attribute_count || settings.dynamic_instrumentation.max_capture_attribute_count)
69
77
  end,
70
78
  throwable: nil,
71
79
  # standard:enable all
72
80
  },
73
81
  return: {
74
82
  arguments: {
75
- "@return": serializer.serialize_value(rv),
83
+ "@return": serializer.serialize_value(rv,
84
+ depth: probe.max_capture_depth || settings.dynamic_instrumentation.max_capture_depth,
85
+ attribute_count: probe.max_capture_attribute_count || settings.dynamic_instrumentation.max_capture_attribute_count),
76
86
  },
77
87
  throwable: nil,
78
88
  },
@@ -80,7 +90,9 @@ module Datadog
80
90
  elsif probe.line?
81
91
  {
82
92
  lines: snapshot && {
83
- probe.line_no => {locals: serializer.serialize_vars(snapshot)},
93
+ probe.line_no => {locals: serializer.serialize_vars(snapshot,
94
+ depth: probe.max_capture_depth || settings.dynamic_instrumentation.max_capture_depth,
95
+ attribute_count: probe.max_capture_attribute_count || settings.dynamic_instrumentation.max_capture_attribute_count,)},
84
96
  },
85
97
  }
86
98
  end
@@ -121,7 +133,7 @@ module Datadog
121
133
  },
122
134
  # In python tracer duration is under debugger.snapshot,
123
135
  # but UI appears to expect it here at top level.
124
- duration: duration ? (duration * 10**9).to_i : nil,
136
+ duration: duration ? (duration * 10**9).to_i : 0,
125
137
  host: nil,
126
138
  logger: {
127
139
  name: probe.file,
@@ -135,15 +147,17 @@ module Datadog
135
147
  version: 2,
136
148
  },
137
149
  # TODO add tests that the trace/span id is correctly propagated
138
- "dd.trace_id": Datadog::Tracing.active_trace&.id,
139
- "dd.span_id": Datadog::Tracing.active_span&.id,
150
+ "dd.trace_id": active_trace&.id&.to_s,
151
+ "dd.span_id": active_span&.id&.to_s,
140
152
  ddsource: 'dd_debugger',
141
153
  message: probe.template && evaluate_template(probe.template,
142
- duration: duration ? duration * 1000 : nil),
154
+ duration: duration ? duration * 1000 : 0),
143
155
  timestamp: timestamp,
144
156
  }
145
157
  end
146
158
 
159
+ private
160
+
147
161
  def build_status(probe, message:, status:)
148
162
  {
149
163
  service: settings.service,
@@ -177,7 +191,7 @@ module Datadog
177
191
  end
178
192
 
179
193
  def timestamp_now
180
- (Time.now.to_f * 1000).to_i
194
+ (Core::Utils::Time.now.to_f * 1000).to_i
181
195
  end
182
196
 
183
197
  def get_local_variables(trace_point)
@@ -194,6 +208,18 @@ module Datadog
194
208
  map[name] = value
195
209
  end
196
210
  end
211
+
212
+ def active_trace
213
+ if defined?(Datadog::Tracing)
214
+ Datadog::Tracing.active_trace
215
+ end
216
+ end
217
+
218
+ def active_span
219
+ if defined?(Datadog::Tracing)
220
+ Datadog::Tracing.active_span
221
+ end
222
+ end
197
223
  end
198
224
  end
199
225
  end
@@ -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,22 @@ 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)
187
+ end
188
+
169
189
  [
170
190
  [:status, 'probe status'],
171
191
  [:snapshot, 'snapshot'],
@@ -183,10 +203,10 @@ module Datadog
183
203
  define_method("add_#{event_type}") do |event|
184
204
  @lock.synchronize do
185
205
  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")
206
+ if queue.length > settings.dynamic_instrumentation.internal.snapshot_queue_capacity
207
+ logger.debug { "di: #{self.class.name}: dropping #{event_type} event because queue is full" }
189
208
  else
209
+ logger.trace { "di: #{self.class.name}: queueing #{event_type} event" }
190
210
  queue << event
191
211
  end
192
212
  end
@@ -201,20 +221,10 @@ module Datadog
201
221
  wake.signal
202
222
  end
203
223
  end
204
- end
205
224
 
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
225
+ # Worker could be not running if the process forked - check and
226
+ # start it again in this case.
227
+ start
218
228
  end
219
229
 
220
230
  public "add_#{event_type}"
@@ -233,16 +243,18 @@ module Datadog
233
243
  instance_variable_set("@#{event_type}_queue", [])
234
244
  @io_in_progress = batch.any? # steep:ignore
235
245
  end
246
+ logger.trace { "di: #{self.class.name}: checking #{event_type} queue - #{batch.length} entries" } # steep:ignore
236
247
  if batch.any? # steep:ignore
237
248
  begin
238
- transport.public_send("send_#{event_type}", batch)
249
+ logger.trace { "di: sending #{batch.length} #{event_type} event(s) to agent" } # steep:ignore
250
+ send("do_send_#{event_type}", batch)
239
251
  time = Core::Utils::Time.get_time
240
252
  @lock.synchronize do
241
253
  @last_sent = time
242
254
  end
243
255
  rescue => exc
244
256
  raise if settings.dynamic_instrumentation.internal.propagate_all_exceptions
245
- logger.warn("failed to send #{event_name}: #{exc.class}: #{exc} (at #{exc.backtrace.first})")
257
+ logger.debug { "di: failed to send #{event_name}: #{exc.class}: #{exc} (at #{exc.backtrace.first})" }
246
258
  # Should we report this error to telemetry? Most likely failure
247
259
  # to send is due to a network issue, and trying to send a
248
260
  # telemetry message would also fail.
@@ -253,7 +265,7 @@ module Datadog
253
265
  # Normally the queue should only be consumed in this method,
254
266
  # however if anyone consumes it elsewhere we don't want to block
255
267
  # while consuming it here. Rescue ThreadError and return.
256
- logger.warn("Unexpected #{event_name} queue underflow - consumed elsewhere?")
268
+ logger.debug { "di: unexpected #{event_name} queue underflow - consumed elsewhere?" }
257
269
  telemetry&.report(exc, description: "Unexpected #{event_name} queue underflow")
258
270
  ensure
259
271
  @lock.synchronize do
@@ -262,9 +274,23 @@ module Datadog
262
274
  end
263
275
  end
264
276
 
277
+ # Determine how much longer the worker thread should sleep
278
+ # so as not to send in less than min send interval since the last send.
279
+ # Important: this method must be called when @lock is held.
280
+ #
281
+ # Returns the time remaining to sleep.
282
+ def set_sleep_remaining
283
+ now = Core::Utils::Time.get_time
284
+ @sleep_remaining = if last_sent
285
+ [last_sent + min_send_interval - now, 0].max
286
+ else
287
+ 0
288
+ end
289
+ end
290
+
265
291
  def maybe_send
266
292
  rv = maybe_send_status
267
- rv || maybe_send_snapshot
293
+ maybe_send_snapshot || rv
268
294
  end
269
295
  end
270
296
  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,7 +82,9 @@ 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
+ def serialize_args(args, kwargs,
86
+ depth: settings.dynamic_instrumentation.max_capture_depth,
87
+ attribute_count: settings.dynamic_instrumentation.max_capture_attribute_count)
86
88
  counter = 0
87
89
  combined = args.each_with_object({}) do |value, c|
88
90
  counter += 1
@@ -90,16 +92,18 @@ module Datadog
90
92
  # kwargs when they are merged below.
91
93
  c[:"arg#{counter}"] = value
92
94
  end.update(kwargs)
93
- serialize_vars(combined)
95
+ serialize_vars(combined, depth: depth, attribute_count: attribute_count)
94
96
  end
95
97
 
96
98
  # Serializes variables captured by a line probe.
97
99
  #
98
100
  # These are normally local variables that exist on a particular line
99
101
  # of executed code.
100
- def serialize_vars(vars)
102
+ def serialize_vars(vars,
103
+ depth: settings.dynamic_instrumentation.max_capture_depth,
104
+ attribute_count: settings.dynamic_instrumentation.max_capture_attribute_count)
101
105
  vars.each_with_object({}) do |(k, v), agg|
102
- agg[k] = serialize_value(v, name: k)
106
+ agg[k] = serialize_value(v, name: k, depth: depth, attribute_count: attribute_count)
103
107
  end
104
108
  end
105
109
 
@@ -115,7 +119,11 @@ module Datadog
115
119
  # (integers, strings, arrays, hashes).
116
120
  #
117
121
  # 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)
122
+ def serialize_value(value, name: nil,
123
+ depth: settings.dynamic_instrumentation.max_capture_depth,
124
+ attribute_count: nil,
125
+ type: nil)
126
+ attribute_count ||= settings.dynamic_instrumentation.max_capture_attribute_count
119
127
  cls = type || value.class
120
128
  begin
121
129
  if redactor.redact_type?(value)
@@ -203,7 +211,6 @@ module Datadog
203
211
  serialized.update(notCapturedReason: "depth")
204
212
  else
205
213
  fields = {}
206
- max = settings.dynamic_instrumentation.max_capture_attribute_count
207
214
  cur = 0
208
215
 
209
216
  # MRI and JRuby 9.4.5+ preserve instance variable definition
@@ -229,7 +236,7 @@ module Datadog
229
236
  ivars = value.instance_variables
230
237
 
231
238
  ivars.each do |ivar|
232
- if cur >= max
239
+ if cur >= attribute_count
233
240
  serialized.update(notCapturedReason: "fieldCount", fields: fields)
234
241
  break
235
242
  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