datadog 2.7.1 → 2.17.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (417) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +310 -1
  3. data/ext/datadog_profiling_native_extension/clock_id.h +2 -2
  4. data/ext/datadog_profiling_native_extension/collectors_cpu_and_wall_time_worker.c +66 -56
  5. data/ext/datadog_profiling_native_extension/collectors_discrete_dynamic_sampler.c +1 -1
  6. data/ext/datadog_profiling_native_extension/collectors_discrete_dynamic_sampler.h +1 -1
  7. data/ext/datadog_profiling_native_extension/collectors_idle_sampling_helper.c +16 -16
  8. data/ext/datadog_profiling_native_extension/collectors_stack.c +10 -10
  9. data/ext/datadog_profiling_native_extension/collectors_stack.h +2 -2
  10. data/ext/datadog_profiling_native_extension/collectors_thread_context.c +314 -145
  11. data/ext/datadog_profiling_native_extension/datadog_ruby_common.c +1 -4
  12. data/ext/datadog_profiling_native_extension/datadog_ruby_common.h +10 -0
  13. data/ext/datadog_profiling_native_extension/encoded_profile.c +79 -0
  14. data/ext/datadog_profiling_native_extension/encoded_profile.h +8 -0
  15. data/ext/datadog_profiling_native_extension/extconf.rb +7 -8
  16. data/ext/datadog_profiling_native_extension/gvl_profiling_helper.c +2 -0
  17. data/ext/datadog_profiling_native_extension/gvl_profiling_helper.h +0 -8
  18. data/ext/datadog_profiling_native_extension/heap_recorder.c +61 -174
  19. data/ext/datadog_profiling_native_extension/heap_recorder.h +2 -2
  20. data/ext/datadog_profiling_native_extension/http_transport.c +64 -98
  21. data/ext/datadog_profiling_native_extension/private_vm_api_access.c +68 -1
  22. data/ext/datadog_profiling_native_extension/private_vm_api_access.h +10 -1
  23. data/ext/datadog_profiling_native_extension/profiling.c +19 -8
  24. data/ext/datadog_profiling_native_extension/ruby_helpers.c +8 -8
  25. data/ext/datadog_profiling_native_extension/stack_recorder.c +84 -131
  26. data/ext/datadog_profiling_native_extension/stack_recorder.h +2 -2
  27. data/ext/datadog_profiling_native_extension/time_helpers.h +1 -1
  28. data/ext/datadog_profiling_native_extension/unsafe_api_calls_check.c +47 -0
  29. data/ext/datadog_profiling_native_extension/unsafe_api_calls_check.h +31 -0
  30. data/ext/libdatadog_api/crashtracker.c +17 -15
  31. data/ext/libdatadog_api/crashtracker.h +5 -0
  32. data/ext/libdatadog_api/datadog_ruby_common.c +1 -4
  33. data/ext/libdatadog_api/datadog_ruby_common.h +10 -0
  34. data/ext/libdatadog_api/init.c +15 -0
  35. data/ext/libdatadog_api/library_config.c +122 -0
  36. data/ext/libdatadog_api/library_config.h +19 -0
  37. data/ext/libdatadog_api/macos_development.md +3 -3
  38. data/ext/libdatadog_api/process_discovery.c +117 -0
  39. data/ext/libdatadog_api/process_discovery.h +5 -0
  40. data/ext/libdatadog_extconf_helpers.rb +1 -1
  41. data/lib/datadog/appsec/actions_handler/serializable_backtrace.rb +89 -0
  42. data/lib/datadog/appsec/actions_handler.rb +49 -0
  43. data/lib/datadog/appsec/anonymizer.rb +16 -0
  44. data/lib/datadog/appsec/api_security/lru_cache.rb +49 -0
  45. data/lib/datadog/appsec/api_security.rb +9 -0
  46. data/lib/datadog/appsec/assets/waf_rules/README.md +50 -5
  47. data/lib/datadog/appsec/assets/waf_rules/processors.json +239 -10
  48. data/lib/datadog/appsec/assets/waf_rules/recommended.json +355 -157
  49. data/lib/datadog/appsec/assets/waf_rules/scanners.json +926 -17
  50. data/lib/datadog/appsec/assets/waf_rules/strict.json +62 -32
  51. data/lib/datadog/appsec/autoload.rb +1 -1
  52. data/lib/datadog/appsec/component.rb +41 -33
  53. data/lib/datadog/appsec/compressed_json.rb +40 -0
  54. data/lib/datadog/appsec/configuration/settings.rb +152 -25
  55. data/lib/datadog/appsec/context.rb +74 -0
  56. data/lib/datadog/appsec/contrib/active_record/instrumentation.rb +92 -0
  57. data/lib/datadog/appsec/contrib/active_record/integration.rb +41 -0
  58. data/lib/datadog/appsec/contrib/active_record/patcher.rb +101 -0
  59. data/lib/datadog/appsec/contrib/auto_instrument.rb +1 -1
  60. data/lib/datadog/appsec/contrib/devise/configuration.rb +52 -0
  61. data/lib/datadog/appsec/contrib/devise/data_extractor.rb +78 -0
  62. data/lib/datadog/appsec/contrib/devise/ext.rb +22 -0
  63. data/lib/datadog/appsec/contrib/devise/integration.rb +1 -2
  64. data/lib/datadog/appsec/contrib/devise/patcher.rb +33 -25
  65. data/lib/datadog/appsec/contrib/devise/patches/signin_tracking_patch.rb +102 -0
  66. data/lib/datadog/appsec/contrib/devise/patches/signup_tracking_patch.rb +69 -0
  67. data/lib/datadog/appsec/contrib/devise/{patcher/rememberable_patch.rb → patches/skip_signin_tracking_patch.rb} +3 -3
  68. data/lib/datadog/appsec/contrib/devise/tracking_middleware.rb +106 -0
  69. data/lib/datadog/appsec/contrib/excon/integration.rb +41 -0
  70. data/lib/datadog/appsec/contrib/excon/patcher.rb +28 -0
  71. data/lib/datadog/appsec/contrib/excon/ssrf_detection_middleware.rb +42 -0
  72. data/lib/datadog/appsec/contrib/faraday/connection_patch.rb +22 -0
  73. data/lib/datadog/appsec/contrib/faraday/integration.rb +42 -0
  74. data/lib/datadog/appsec/contrib/faraday/patcher.rb +53 -0
  75. data/lib/datadog/appsec/contrib/faraday/rack_builder_patch.rb +22 -0
  76. data/lib/datadog/appsec/contrib/faraday/ssrf_detection_middleware.rb +41 -0
  77. data/lib/datadog/appsec/contrib/graphql/appsec_trace.rb +1 -7
  78. data/lib/datadog/appsec/contrib/graphql/gateway/watcher.rb +17 -30
  79. data/lib/datadog/appsec/contrib/graphql/integration.rb +1 -1
  80. data/lib/datadog/appsec/contrib/graphql/patcher.rb +0 -3
  81. data/lib/datadog/appsec/contrib/rack/ext.rb +34 -0
  82. data/lib/datadog/appsec/contrib/rack/gateway/response.rb +3 -3
  83. data/lib/datadog/appsec/contrib/rack/gateway/watcher.rb +78 -98
  84. data/lib/datadog/appsec/contrib/rack/integration.rb +1 -1
  85. data/lib/datadog/appsec/contrib/rack/patcher.rb +0 -3
  86. data/lib/datadog/appsec/contrib/rack/request_body_middleware.rb +10 -11
  87. data/lib/datadog/appsec/contrib/rack/request_middleware.rb +52 -68
  88. data/lib/datadog/appsec/contrib/rails/gateway/watcher.rb +16 -33
  89. data/lib/datadog/appsec/contrib/rails/integration.rb +1 -1
  90. data/lib/datadog/appsec/contrib/rails/patcher.rb +25 -38
  91. data/lib/datadog/appsec/contrib/rest_client/integration.rb +45 -0
  92. data/lib/datadog/appsec/contrib/rest_client/patcher.rb +28 -0
  93. data/lib/datadog/appsec/contrib/rest_client/request_ssrf_detection_patch.rb +38 -0
  94. data/lib/datadog/appsec/contrib/sinatra/gateway/watcher.rb +31 -68
  95. data/lib/datadog/appsec/contrib/sinatra/integration.rb +1 -1
  96. data/lib/datadog/appsec/contrib/sinatra/patcher.rb +5 -31
  97. data/lib/datadog/appsec/event.rb +96 -135
  98. data/lib/datadog/appsec/ext.rb +12 -3
  99. data/lib/datadog/appsec/instrumentation/gateway/argument.rb +7 -2
  100. data/lib/datadog/appsec/instrumentation/gateway/middleware.rb +24 -0
  101. data/lib/datadog/appsec/instrumentation/gateway.rb +17 -22
  102. data/lib/datadog/appsec/metrics/collector.rb +38 -0
  103. data/lib/datadog/appsec/metrics/exporter.rb +35 -0
  104. data/lib/datadog/appsec/metrics/telemetry.rb +23 -0
  105. data/lib/datadog/appsec/metrics.rb +13 -0
  106. data/lib/datadog/appsec/monitor/gateway/watcher.rb +52 -32
  107. data/lib/datadog/appsec/processor/rule_loader.rb +26 -31
  108. data/lib/datadog/appsec/processor/rule_merger.rb +7 -6
  109. data/lib/datadog/appsec/processor.rb +5 -4
  110. data/lib/datadog/appsec/remote.rb +26 -12
  111. data/lib/datadog/appsec/response.rb +19 -85
  112. data/lib/datadog/appsec/security_engine/result.rb +67 -0
  113. data/lib/datadog/appsec/security_engine/runner.rb +88 -0
  114. data/lib/datadog/appsec/security_engine.rb +9 -0
  115. data/lib/datadog/appsec/security_event.rb +39 -0
  116. data/lib/datadog/appsec/utils.rb +0 -2
  117. data/lib/datadog/appsec.rb +23 -10
  118. data/lib/datadog/auto_instrument.rb +3 -0
  119. data/lib/datadog/core/buffer/random.rb +18 -2
  120. data/lib/datadog/core/configuration/agent_settings_resolver.rb +42 -14
  121. data/lib/datadog/core/configuration/agentless_settings_resolver.rb +176 -0
  122. data/lib/datadog/core/configuration/components.rb +76 -32
  123. data/lib/datadog/core/configuration/components_state.rb +23 -0
  124. data/lib/datadog/core/configuration/ext.rb +5 -1
  125. data/lib/datadog/core/configuration/option.rb +79 -43
  126. data/lib/datadog/core/configuration/option_definition.rb +6 -4
  127. data/lib/datadog/core/configuration/options.rb +3 -3
  128. data/lib/datadog/core/configuration/settings.rb +100 -41
  129. data/lib/datadog/core/configuration/stable_config.rb +23 -0
  130. data/lib/datadog/core/configuration.rb +43 -11
  131. data/lib/datadog/{tracing → core}/contrib/rails/utils.rb +1 -3
  132. data/lib/datadog/core/crashtracking/component.rb +4 -13
  133. data/lib/datadog/core/diagnostics/environment_logger.rb +1 -1
  134. data/lib/datadog/core/encoding.rb +17 -1
  135. data/lib/datadog/core/environment/agent_info.rb +78 -0
  136. data/lib/datadog/core/environment/cgroup.rb +10 -12
  137. data/lib/datadog/core/environment/container.rb +38 -40
  138. data/lib/datadog/core/environment/ext.rb +6 -6
  139. data/lib/datadog/core/environment/git.rb +1 -0
  140. data/lib/datadog/core/environment/identity.rb +3 -3
  141. data/lib/datadog/core/environment/platform.rb +3 -3
  142. data/lib/datadog/core/environment/variable_helpers.rb +1 -1
  143. data/lib/datadog/core/error.rb +11 -9
  144. data/lib/datadog/core/logger.rb +2 -2
  145. data/lib/datadog/core/metrics/client.rb +27 -27
  146. data/lib/datadog/core/metrics/logging.rb +5 -5
  147. data/lib/datadog/core/process_discovery.rb +32 -0
  148. data/lib/datadog/core/rate_limiter.rb +4 -2
  149. data/lib/datadog/core/remote/client/capabilities.rb +6 -0
  150. data/lib/datadog/core/remote/client.rb +107 -92
  151. data/lib/datadog/core/remote/component.rb +18 -19
  152. data/lib/datadog/core/remote/configuration/digest.rb +7 -7
  153. data/lib/datadog/core/remote/configuration/path.rb +1 -1
  154. data/lib/datadog/core/remote/configuration/repository.rb +2 -1
  155. data/lib/datadog/core/remote/negotiation.rb +9 -9
  156. data/lib/datadog/core/remote/transport/config.rb +4 -3
  157. data/lib/datadog/core/remote/transport/http/api.rb +13 -18
  158. data/lib/datadog/core/remote/transport/http/client.rb +5 -4
  159. data/lib/datadog/core/remote/transport/http/config.rb +27 -55
  160. data/lib/datadog/core/remote/transport/http/negotiation.rb +8 -51
  161. data/lib/datadog/core/remote/transport/http.rb +25 -94
  162. data/lib/datadog/core/remote/transport/negotiation.rb +17 -4
  163. data/lib/datadog/core/remote/worker.rb +10 -7
  164. data/lib/datadog/core/runtime/metrics.rb +12 -5
  165. data/lib/datadog/core/telemetry/component.rb +84 -49
  166. data/lib/datadog/core/telemetry/emitter.rb +23 -11
  167. data/lib/datadog/core/telemetry/event/app_client_configuration_change.rb +65 -0
  168. data/lib/datadog/core/telemetry/event/app_closing.rb +18 -0
  169. data/lib/datadog/core/telemetry/event/app_dependencies_loaded.rb +33 -0
  170. data/lib/datadog/core/telemetry/event/app_heartbeat.rb +18 -0
  171. data/lib/datadog/core/telemetry/event/app_integrations_change.rb +58 -0
  172. data/lib/datadog/core/telemetry/event/app_started.rb +179 -0
  173. data/lib/datadog/core/telemetry/event/base.rb +40 -0
  174. data/lib/datadog/core/telemetry/event/distributions.rb +18 -0
  175. data/lib/datadog/core/telemetry/event/generate_metrics.rb +43 -0
  176. data/lib/datadog/core/telemetry/event/log.rb +76 -0
  177. data/lib/datadog/core/telemetry/event/message_batch.rb +42 -0
  178. data/lib/datadog/core/telemetry/event/synth_app_client_configuration_change.rb +43 -0
  179. data/lib/datadog/core/telemetry/event.rb +17 -383
  180. data/lib/datadog/core/telemetry/ext.rb +1 -0
  181. data/lib/datadog/core/telemetry/http/adapters/net.rb +12 -97
  182. data/lib/datadog/core/telemetry/logger.rb +1 -1
  183. data/lib/datadog/core/telemetry/logging.rb +2 -2
  184. data/lib/datadog/core/telemetry/metric.rb +28 -6
  185. data/lib/datadog/core/telemetry/request.rb +4 -4
  186. data/lib/datadog/core/telemetry/transport/http/api.rb +43 -0
  187. data/lib/datadog/core/telemetry/transport/http/client.rb +49 -0
  188. data/lib/datadog/core/telemetry/transport/http/telemetry.rb +92 -0
  189. data/lib/datadog/core/telemetry/transport/http.rb +63 -0
  190. data/lib/datadog/core/telemetry/transport/telemetry.rb +51 -0
  191. data/lib/datadog/core/telemetry/worker.rb +128 -25
  192. data/lib/datadog/core/transport/http/adapters/test.rb +2 -1
  193. data/lib/datadog/core/transport/http/adapters/unix_socket.rb +1 -1
  194. data/lib/datadog/{tracing → core}/transport/http/api/instance.rb +18 -1
  195. data/lib/datadog/core/transport/http/api/spec.rb +36 -0
  196. data/lib/datadog/{tracing → core}/transport/http/builder.rb +53 -31
  197. data/lib/datadog/core/transport/http.rb +75 -0
  198. data/lib/datadog/core/transport/response.rb +4 -0
  199. data/lib/datadog/core/utils/at_fork_monkey_patch.rb +6 -6
  200. data/lib/datadog/core/utils/duration.rb +32 -32
  201. data/lib/datadog/core/utils/forking.rb +2 -2
  202. data/lib/datadog/core/utils/network.rb +6 -6
  203. data/lib/datadog/core/utils/only_once_successful.rb +16 -5
  204. data/lib/datadog/core/utils/time.rb +20 -0
  205. data/lib/datadog/core/utils/truncation.rb +21 -0
  206. data/lib/datadog/core/vendor/multipart-post/multipart/post/composite_read_io.rb +1 -1
  207. data/lib/datadog/core/vendor/multipart-post/multipart/post/multipartable.rb +8 -8
  208. data/lib/datadog/core/vendor/multipart-post/multipart/post/parts.rb +7 -7
  209. data/lib/datadog/core/worker.rb +1 -1
  210. data/lib/datadog/core/workers/async.rb +29 -12
  211. data/lib/datadog/core/workers/interval_loop.rb +12 -1
  212. data/lib/datadog/core/workers/runtime_metrics.rb +2 -2
  213. data/lib/datadog/core.rb +8 -0
  214. data/lib/datadog/di/base.rb +115 -0
  215. data/lib/datadog/di/boot.rb +34 -0
  216. data/lib/datadog/di/code_tracker.rb +26 -15
  217. data/lib/datadog/di/component.rb +23 -14
  218. data/lib/datadog/di/configuration/settings.rb +25 -1
  219. data/lib/datadog/di/contrib/active_record.rb +1 -0
  220. data/lib/datadog/di/contrib/railtie.rb +15 -0
  221. data/lib/datadog/di/contrib.rb +28 -0
  222. data/lib/datadog/di/error.rb +5 -0
  223. data/lib/datadog/di/instrumenter.rb +111 -20
  224. data/lib/datadog/di/logger.rb +30 -0
  225. data/lib/datadog/di/preload.rb +18 -0
  226. data/lib/datadog/di/probe.rb +14 -7
  227. data/lib/datadog/di/probe_builder.rb +1 -0
  228. data/lib/datadog/di/probe_manager.rb +11 -5
  229. data/lib/datadog/di/probe_notification_builder.rb +34 -8
  230. data/lib/datadog/di/probe_notifier_worker.rb +52 -26
  231. data/lib/datadog/di/redactor.rb +0 -1
  232. data/lib/datadog/di/remote.rb +147 -0
  233. data/lib/datadog/di/serializer.rb +14 -7
  234. data/lib/datadog/di/transport/diagnostics.rb +62 -0
  235. data/lib/datadog/di/transport/http/api.rb +42 -0
  236. data/lib/datadog/di/transport/http/client.rb +47 -0
  237. data/lib/datadog/di/transport/http/diagnostics.rb +65 -0
  238. data/lib/datadog/di/transport/http/input.rb +67 -0
  239. data/lib/datadog/di/transport/http.rb +57 -0
  240. data/lib/datadog/di/transport/input.rb +62 -0
  241. data/lib/datadog/di/utils.rb +103 -0
  242. data/lib/datadog/di.rb +14 -76
  243. data/lib/datadog/error_tracking/collector.rb +87 -0
  244. data/lib/datadog/error_tracking/component.rb +167 -0
  245. data/lib/datadog/error_tracking/configuration/settings.rb +63 -0
  246. data/lib/datadog/error_tracking/configuration.rb +11 -0
  247. data/lib/datadog/error_tracking/ext.rb +18 -0
  248. data/lib/datadog/error_tracking/extensions.rb +16 -0
  249. data/lib/datadog/error_tracking/filters.rb +77 -0
  250. data/lib/datadog/error_tracking.rb +18 -0
  251. data/lib/datadog/kit/appsec/events.rb +15 -3
  252. data/lib/datadog/kit/identity.rb +9 -5
  253. data/lib/datadog/opentelemetry/api/baggage.rb +90 -0
  254. data/lib/datadog/opentelemetry/api/baggage.rbs +26 -0
  255. data/lib/datadog/opentelemetry/api/context.rb +16 -2
  256. data/lib/datadog/opentelemetry/sdk/trace/span.rb +1 -1
  257. data/lib/datadog/opentelemetry.rb +2 -1
  258. data/lib/datadog/profiling/collectors/code_provenance.rb +1 -1
  259. data/lib/datadog/profiling/collectors/info.rb +3 -0
  260. data/lib/datadog/profiling/collectors/thread_context.rb +1 -1
  261. data/lib/datadog/profiling/component.rb +60 -76
  262. data/lib/datadog/profiling/encoded_profile.rb +11 -0
  263. data/lib/datadog/profiling/exporter.rb +3 -4
  264. data/lib/datadog/profiling/ext.rb +0 -2
  265. data/lib/datadog/profiling/flush.rb +5 -8
  266. data/lib/datadog/profiling/http_transport.rb +6 -85
  267. data/lib/datadog/profiling/load_native_extension.rb +1 -33
  268. data/lib/datadog/profiling/scheduler.rb +8 -1
  269. data/lib/datadog/profiling/stack_recorder.rb +4 -4
  270. data/lib/datadog/profiling/tag_builder.rb +1 -5
  271. data/lib/datadog/profiling.rb +6 -2
  272. data/lib/datadog/tracing/analytics.rb +1 -1
  273. data/lib/datadog/tracing/component.rb +16 -12
  274. data/lib/datadog/tracing/configuration/ext.rb +8 -1
  275. data/lib/datadog/tracing/configuration/settings.rb +22 -10
  276. data/lib/datadog/tracing/context_provider.rb +1 -1
  277. data/lib/datadog/tracing/contrib/action_cable/integration.rb +5 -2
  278. data/lib/datadog/tracing/contrib/action_mailer/integration.rb +6 -2
  279. data/lib/datadog/tracing/contrib/action_pack/integration.rb +5 -2
  280. data/lib/datadog/tracing/contrib/action_view/integration.rb +5 -2
  281. data/lib/datadog/tracing/contrib/active_job/integration.rb +5 -2
  282. data/lib/datadog/tracing/contrib/active_record/integration.rb +7 -3
  283. data/lib/datadog/tracing/contrib/active_support/cache/events/cache.rb +7 -2
  284. data/lib/datadog/tracing/contrib/active_support/cache/instrumentation.rb +36 -1
  285. data/lib/datadog/tracing/contrib/active_support/cache/patcher.rb +4 -0
  286. data/lib/datadog/tracing/contrib/active_support/cache/redis.rb +14 -4
  287. data/lib/datadog/tracing/contrib/active_support/configuration/settings.rb +10 -0
  288. data/lib/datadog/tracing/contrib/active_support/integration.rb +5 -2
  289. data/lib/datadog/tracing/contrib/auto_instrument.rb +2 -2
  290. data/lib/datadog/tracing/contrib/aws/instrumentation.rb +10 -0
  291. data/lib/datadog/tracing/contrib/aws/integration.rb +3 -0
  292. data/lib/datadog/tracing/contrib/aws/parsed_context.rb +5 -1
  293. data/lib/datadog/tracing/contrib/concurrent_ruby/integration.rb +3 -0
  294. data/lib/datadog/tracing/contrib/configuration/settings.rb +1 -1
  295. data/lib/datadog/tracing/contrib/elasticsearch/configuration/settings.rb +4 -0
  296. data/lib/datadog/tracing/contrib/elasticsearch/patcher.rb +6 -1
  297. data/lib/datadog/tracing/contrib/ethon/easy_patch.rb +4 -5
  298. data/lib/datadog/tracing/contrib/excon/middleware.rb +5 -3
  299. data/lib/datadog/tracing/contrib/ext.rb +1 -0
  300. data/lib/datadog/tracing/contrib/extensions.rb +29 -3
  301. data/lib/datadog/tracing/contrib/faraday/middleware.rb +5 -3
  302. data/lib/datadog/tracing/contrib/graphql/configuration/error_extension_env_parser.rb +21 -0
  303. data/lib/datadog/tracing/contrib/graphql/configuration/settings.rb +11 -0
  304. data/lib/datadog/tracing/contrib/graphql/ext.rb +5 -0
  305. data/lib/datadog/tracing/contrib/graphql/unified_trace.rb +102 -11
  306. data/lib/datadog/tracing/contrib/grpc/datadog_interceptor/client.rb +7 -1
  307. data/lib/datadog/tracing/contrib/grpc/distributed/propagation.rb +3 -0
  308. data/lib/datadog/tracing/contrib/http/circuit_breaker.rb +0 -15
  309. data/lib/datadog/tracing/contrib/http/distributed/propagation.rb +4 -1
  310. data/lib/datadog/tracing/contrib/http/instrumentation.rb +6 -10
  311. data/lib/datadog/tracing/contrib/http/integration.rb +3 -0
  312. data/lib/datadog/tracing/contrib/httpclient/instrumentation.rb +6 -16
  313. data/lib/datadog/tracing/contrib/httprb/instrumentation.rb +7 -15
  314. data/lib/datadog/tracing/contrib/httprb/integration.rb +3 -0
  315. data/lib/datadog/tracing/contrib/kafka/integration.rb +3 -0
  316. data/lib/datadog/tracing/contrib/karafka/configuration/settings.rb +27 -0
  317. data/lib/datadog/tracing/contrib/karafka/distributed/propagation.rb +48 -0
  318. data/lib/datadog/tracing/contrib/karafka/ext.rb +27 -0
  319. data/lib/datadog/tracing/contrib/karafka/integration.rb +45 -0
  320. data/lib/datadog/tracing/contrib/karafka/monitor.rb +66 -0
  321. data/lib/datadog/tracing/contrib/karafka/patcher.rb +71 -0
  322. data/lib/datadog/tracing/contrib/karafka.rb +37 -0
  323. data/lib/datadog/tracing/contrib/mongodb/configuration/settings.rb +8 -0
  324. data/lib/datadog/tracing/contrib/mongodb/ext.rb +1 -0
  325. data/lib/datadog/tracing/contrib/mongodb/integration.rb +3 -0
  326. data/lib/datadog/tracing/contrib/mongodb/subscribers.rb +18 -1
  327. data/lib/datadog/tracing/contrib/opensearch/configuration/settings.rb +17 -0
  328. data/lib/datadog/tracing/contrib/opensearch/ext.rb +9 -0
  329. data/lib/datadog/tracing/contrib/opensearch/integration.rb +3 -0
  330. data/lib/datadog/tracing/contrib/opensearch/patcher.rb +5 -1
  331. data/lib/datadog/tracing/contrib/patcher.rb +5 -2
  332. data/lib/datadog/tracing/contrib/presto/integration.rb +3 -0
  333. data/lib/datadog/tracing/contrib/rack/header_collection.rb +11 -1
  334. data/lib/datadog/tracing/contrib/rack/integration.rb +2 -2
  335. data/lib/datadog/tracing/contrib/rack/middlewares.rb +1 -1
  336. data/lib/datadog/tracing/contrib/rack/request_queue.rb +1 -1
  337. data/lib/datadog/tracing/contrib/rails/framework.rb +2 -2
  338. data/lib/datadog/tracing/contrib/rails/patcher.rb +1 -1
  339. data/lib/datadog/tracing/contrib/rest_client/integration.rb +3 -0
  340. data/lib/datadog/tracing/contrib/rest_client/request_patch.rb +5 -3
  341. data/lib/datadog/tracing/contrib/sidekiq/client_tracer.rb +6 -1
  342. data/lib/datadog/tracing/contrib/sidekiq/distributed/propagation.rb +3 -0
  343. data/lib/datadog/tracing/contrib/sidekiq/server_tracer.rb +1 -1
  344. data/lib/datadog/tracing/contrib/span_attribute_schema.rb +6 -1
  345. data/lib/datadog/tracing/contrib/support.rb +28 -0
  346. data/lib/datadog/tracing/contrib.rb +1 -0
  347. data/lib/datadog/tracing/correlation.rb +9 -2
  348. data/lib/datadog/tracing/distributed/b3_multi.rb +1 -1
  349. data/lib/datadog/tracing/distributed/b3_single.rb +1 -1
  350. data/lib/datadog/tracing/distributed/baggage.rb +131 -0
  351. data/lib/datadog/tracing/distributed/datadog.rb +4 -2
  352. data/lib/datadog/tracing/distributed/propagation.rb +25 -4
  353. data/lib/datadog/tracing/distributed/propagation_policy.rb +42 -0
  354. data/lib/datadog/tracing/metadata/errors.rb +4 -4
  355. data/lib/datadog/tracing/metadata/ext.rb +5 -0
  356. data/lib/datadog/tracing/metadata/metastruct.rb +36 -0
  357. data/lib/datadog/tracing/metadata/metastruct_tagging.rb +42 -0
  358. data/lib/datadog/tracing/metadata.rb +2 -0
  359. data/lib/datadog/tracing/sampling/rate_sampler.rb +2 -1
  360. data/lib/datadog/tracing/sampling/span/rule.rb +0 -1
  361. data/lib/datadog/tracing/span.rb +22 -5
  362. data/lib/datadog/tracing/span_event.rb +124 -4
  363. data/lib/datadog/tracing/span_operation.rb +52 -16
  364. data/lib/datadog/tracing/sync_writer.rb +9 -5
  365. data/lib/datadog/tracing/trace_digest.rb +9 -2
  366. data/lib/datadog/tracing/trace_operation.rb +44 -24
  367. data/lib/datadog/tracing/trace_segment.rb +6 -4
  368. data/lib/datadog/tracing/tracer.rb +60 -12
  369. data/lib/datadog/tracing/transport/http/api.rb +5 -4
  370. data/lib/datadog/tracing/transport/http/client.rb +5 -4
  371. data/lib/datadog/tracing/transport/http/traces.rb +13 -44
  372. data/lib/datadog/tracing/transport/http.rb +13 -70
  373. data/lib/datadog/tracing/transport/serializable_trace.rb +31 -7
  374. data/lib/datadog/tracing/transport/trace_formatter.rb +7 -0
  375. data/lib/datadog/tracing/transport/traces.rb +47 -13
  376. data/lib/datadog/tracing/utils.rb +1 -1
  377. data/lib/datadog/tracing/workers/trace_writer.rb +8 -5
  378. data/lib/datadog/tracing/workers.rb +5 -4
  379. data/lib/datadog/tracing/writer.rb +10 -6
  380. data/lib/datadog/tracing.rb +16 -3
  381. data/lib/datadog/version.rb +2 -2
  382. data/lib/datadog.rb +2 -0
  383. metadata +143 -50
  384. data/ext/datadog_profiling_loader/datadog_profiling_loader.c +0 -142
  385. data/ext/datadog_profiling_loader/extconf.rb +0 -60
  386. data/lib/datadog/appsec/contrib/devise/event.rb +0 -57
  387. data/lib/datadog/appsec/contrib/devise/patcher/authenticatable_patch.rb +0 -77
  388. data/lib/datadog/appsec/contrib/devise/patcher/registration_controller_patch.rb +0 -54
  389. data/lib/datadog/appsec/contrib/devise/resource.rb +0 -35
  390. data/lib/datadog/appsec/contrib/devise/tracking.rb +0 -57
  391. data/lib/datadog/appsec/contrib/graphql/reactive/multiplex.rb +0 -46
  392. data/lib/datadog/appsec/contrib/patcher.rb +0 -12
  393. data/lib/datadog/appsec/contrib/rack/reactive/request.rb +0 -69
  394. data/lib/datadog/appsec/contrib/rack/reactive/request_body.rb +0 -47
  395. data/lib/datadog/appsec/contrib/rack/reactive/response.rb +0 -53
  396. data/lib/datadog/appsec/contrib/rails/reactive/action.rb +0 -53
  397. data/lib/datadog/appsec/contrib/sinatra/ext.rb +0 -14
  398. data/lib/datadog/appsec/contrib/sinatra/reactive/routed.rb +0 -48
  399. data/lib/datadog/appsec/monitor/reactive/set_user.rb +0 -45
  400. data/lib/datadog/appsec/processor/actions.rb +0 -49
  401. data/lib/datadog/appsec/processor/context.rb +0 -107
  402. data/lib/datadog/appsec/reactive/address_hash.rb +0 -22
  403. data/lib/datadog/appsec/reactive/engine.rb +0 -47
  404. data/lib/datadog/appsec/reactive/operation.rb +0 -68
  405. data/lib/datadog/appsec/reactive/subscriber.rb +0 -19
  406. data/lib/datadog/appsec/scope.rb +0 -58
  407. data/lib/datadog/appsec/utils/trace_operation.rb +0 -15
  408. data/lib/datadog/core/crashtracking/agent_base_url.rb +0 -21
  409. data/lib/datadog/core/remote/transport/http/api/instance.rb +0 -39
  410. data/lib/datadog/core/remote/transport/http/api/spec.rb +0 -21
  411. data/lib/datadog/core/remote/transport/http/builder.rb +0 -219
  412. data/lib/datadog/core/telemetry/http/env.rb +0 -20
  413. data/lib/datadog/core/telemetry/http/ext.rb +0 -28
  414. data/lib/datadog/core/telemetry/http/response.rb +0 -70
  415. data/lib/datadog/core/telemetry/http/transport.rb +0 -90
  416. data/lib/datadog/di/transport.rb +0 -81
  417. data/lib/datadog/tracing/transport/http/api/spec.rb +0 -19
@@ -0,0 +1,167 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'set'
4
+ require_relative 'collector'
5
+ require_relative 'filters'
6
+
7
+ module Datadog
8
+ module ErrorTracking
9
+ # Component for Error Tracking.
10
+ #
11
+ # Only one instance of the Component should ever be active.
12
+ #
13
+ # The component instance records every handled exceptions from the configured scopes
14
+ # (user, third_party packages, specified files or everything).
15
+ class Component
16
+ LOCK = Mutex.new
17
+
18
+ class << self
19
+ def build(settings, tracer, logger)
20
+ return if !settings.respond_to?(:error_tracking) || (settings.error_tracking.handled_errors.nil? &&
21
+ settings.error_tracking.handled_errors_include.empty?)
22
+
23
+ return unless environment_supported?(logger)
24
+
25
+ new(
26
+ tracer: tracer,
27
+ handled_errors: settings.error_tracking.handled_errors,
28
+ handled_errors_include: settings.error_tracking.handled_errors_include,
29
+ ).tap(&:start)
30
+ end
31
+
32
+ def environment_supported?(logger)
33
+ if RUBY_ENGINE != 'ruby'
34
+ logger.warn("error tracking: cannot enable error tracking: MRI is required, but running on #{RUBY_ENGINE}")
35
+ false
36
+ elsif RUBY_VERSION < '2.7'
37
+ logger.warn(
38
+ "error tracking: cannot enable error tracking: Ruby 2.7+ is required, but running
39
+ on #{RUBY_VERSION}"
40
+ )
41
+ false
42
+ else
43
+ true
44
+ end
45
+ end
46
+ end
47
+
48
+ def initialize(tracer:, handled_errors:, handled_errors_include:)
49
+ @tracer = tracer
50
+
51
+ # Hash containing the paths to the instrumented files
52
+ @instrumented_files = Set.new unless handled_errors_include.empty?
53
+ # Array containing file paths, file names and gems names to instrument.
54
+ # This is coming from the DD_ERROR_TRACKING_HANDLED_ERRORS_INCLUDE env variable
55
+ @handled_errors_include = handled_errors_include
56
+
57
+ # Filter function is used to filter out the exception
58
+ # we do not want to report. For instance exception from gems.
59
+ @filter_function = Filters.generate_filter(handled_errors, @instrumented_files)
60
+
61
+ # :rescue event was added in Ruby 3.3
62
+ #
63
+ # Before Ruby3.3 the TracePoint listen for :raise events.
64
+ # If an error is not handled, we will delete the according
65
+ # span event in the collector.
66
+ event = (RUBY_VERSION >= '3.3') ? :rescue : :raise
67
+
68
+ # This TracePoint is in charge of capturing the handled exceptions
69
+ # and of adding the corresponding span events to the collector
70
+ @handled_exc_tracker = create_exc_tracker_trace_point(event)
71
+
72
+ if @instrumented_files
73
+ # The only thing we know about the handled errors is the path of the file
74
+ # in which the error was rescued. Therefore, we need to retrieve the path
75
+ # of the files the user want to instrument. This TracePoint is used for that
76
+ # purpose
77
+ @include_path_getter = create_script_compiled_trace_point
78
+ end
79
+ end
80
+
81
+ def create_exc_tracker_trace_point(event)
82
+ TracePoint.new(event) do |tp|
83
+ active_span = @tracer.active_span
84
+ if active_span
85
+ raised_exception = tp.raised_exception
86
+ # Note that in 3.2, this will give the path of where the error was raised
87
+ # which may cause the handled_error_include env variable to malfunction.
88
+ rescue_file_path = tp.path
89
+ if @filter_function.call(rescue_file_path)
90
+ span_event = generate_span_event(raised_exception)
91
+ LOCK.synchronize do
92
+ collector = active_span.get_collector_or_initialize { Collector.new }
93
+ collector.add_span_event(active_span, span_event, raised_exception)
94
+ end
95
+ end
96
+ end
97
+ end
98
+ end
99
+
100
+ def create_script_compiled_trace_point
101
+ TracePoint.new(:script_compiled) do |tp|
102
+ next if tp.eval_script
103
+
104
+ path = tp.instruction_sequence.path
105
+ next if path.nil?
106
+
107
+ @handled_errors_include.each do |file_to_instr|
108
+ # The user can provide either
109
+ # - absolute_path starting with '/'. In that case the path of the file
110
+ # should begin with file_to_instr
111
+ # - a relative_path starting with './'. In that case, we extend the path
112
+ # and it is the same as above
113
+ # - otherwise we just check if the name provided is in the path and is
114
+ # either the name of a folder or of a ruby file.
115
+ regex =
116
+ if file_to_instr.start_with?('/')
117
+ %r{\A#{Regexp.escape(file_to_instr)}(?:/|\.rb\z|\z)}
118
+ elsif file_to_instr.start_with?('./')
119
+ abs_path = File.expand_path(file_to_instr)
120
+ %r{\A#{Regexp.escape(abs_path)}(?:/|\.rb\z|\z)}
121
+ else
122
+ %r{/#{Regexp.escape(file_to_instr)}(?:/|\.rb\z|\z)}
123
+ end
124
+
125
+ add_instrumented_file(path) if path.match?(regex)
126
+ end
127
+ end
128
+ end
129
+
130
+ # Starts the TracePoints.
131
+ #
132
+ # Enables the script_compiled TracePoint if handled_errors_include is not empty.
133
+ def start
134
+ @handled_exc_tracker.enable
135
+ @include_path_getter&.enable
136
+ end
137
+
138
+ # Shuts down error tracker.
139
+ #
140
+ # Disables the TracePoints.
141
+ def shutdown!
142
+ @handled_exc_tracker.disable
143
+ @include_path_getter&.disable
144
+ end
145
+
146
+ private
147
+
148
+ # Generates a span event from the exception info.
149
+ #
150
+ # The event follows the otel semantics.
151
+ # https://opentelemetry.io/docs/specs/otel/trace/exceptions/
152
+ def generate_span_event(exception)
153
+ formatted_exception = Datadog::Core::Error.build_from(exception)
154
+ attributes = {
155
+ 'exception.type' => formatted_exception.type,
156
+ 'exception.message' => formatted_exception.message,
157
+ 'exception.stacktrace' => formatted_exception.backtrace
158
+ }
159
+ Datadog::Tracing::SpanEvent.new('exception', attributes: attributes)
160
+ end
161
+
162
+ def add_instrumented_file(file_path)
163
+ @instrumented_files&.add(file_path)
164
+ end
165
+ end
166
+ end
167
+ end
@@ -0,0 +1,63 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative '../ext'
4
+
5
+ module Datadog
6
+ module ErrorTracking
7
+ module Configuration
8
+ # Settings
9
+ module Settings
10
+ def self.extended(base)
11
+ base = base.singleton_class unless base.is_a?(Class)
12
+ add_settings!(base)
13
+ end
14
+
15
+ def self.add_settings!(base)
16
+ base.class_eval do
17
+ # Error Tracking specific configurations.
18
+ # @public_api
19
+ settings :error_tracking do
20
+ # Enable automatic reporting of handled errors and defines the scope
21
+ # for which to report errors: user code, gems, or both. Possible
22
+ # values are: all | user | third_party.
23
+ #
24
+ # @default 'DD_ERROR_TRACKING_HANDLED_ERRORS' environment variable, otherwise `nil`
25
+ # @return [String, nil]
26
+ option :handled_errors do |o|
27
+ o.type :string, nilable: true
28
+ o.default Ext::DEFAULT_HANDLED_ERRORS
29
+ o.env Ext::ENV_HANDLED_ERRORS
30
+ o.setter do |value|
31
+ next value if Ext::VALID_HANDLED_ERRORS.include?(value)
32
+
33
+ unless value.nil?
34
+ Datadog.logger.warn(
35
+ "Invalid handled errors scope: #{value}. " \
36
+ "Supported values are: #{Ext::VALID_HANDLED_ERRORS.join(" | ")}. " \
37
+ 'Deactivating the feature.'
38
+ )
39
+ end
40
+
41
+ Ext::DEFAULT_HANDLED_ERRORS
42
+ end
43
+ end
44
+
45
+ # Enable automatic reporting of handled errors and specify what files should be
46
+ # instrumented. The value is a list of comma separated paths, filenames or gem names.
47
+ # The paths can be absolute, starting with '/' or relative to directory in which the program
48
+ # is launched, starting with './'.
49
+ #
50
+ # @default 'DD_ERROR_TRACKING_HANDLED_ERRORS_MODULES' environment variable, otherwise `nil`
51
+ # @return [String, nil]
52
+ option :handled_errors_include do |o|
53
+ o.type :array
54
+ o.default []
55
+ o.env Ext::ENV_HANDLED_ERRORS_INCLUDE
56
+ end
57
+ end
58
+ end
59
+ end
60
+ end
61
+ end
62
+ end
63
+ end
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Datadog
4
+ module ErrorTracking
5
+ # Configuration for ErrorTracking
6
+ module Configuration
7
+ end
8
+ end
9
+ end
10
+
11
+ require_relative 'configuration/settings'
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Datadog
4
+ module ErrorTracking
5
+ # Error Tracking constants
6
+ module Ext
7
+ ENV_HANDLED_ERRORS = 'DD_ERROR_TRACKING_HANDLED_ERRORS'
8
+ ENV_HANDLED_ERRORS_INCLUDE = 'DD_ERROR_TRACKING_HANDLED_ERRORS_INCLUDE'
9
+ HANDLED_ERRORS_ALL = 'all'
10
+ HANDLED_ERRORS_USER = 'user'
11
+ HANDLED_ERRORS_THIRD_PARTY = 'third_party'
12
+ DEFAULT_HANDLED_ERRORS = nil
13
+ VALID_HANDLED_ERRORS = [HANDLED_ERRORS_ALL, HANDLED_ERRORS_USER, HANDLED_ERRORS_THIRD_PARTY].freeze
14
+ SPAN_EVENTS_HAS_EXCEPTION = '_dd.span_events.has_exception'
15
+ RUBY_VERSION_WITH_RESCUE_EVENT = '3.3'
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,16 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'configuration'
4
+ require_relative '../core/configuration'
5
+
6
+ module Datadog
7
+ module ErrorTracking
8
+ # Extends Datadog tracing with ErrorTracking features
9
+ module Extensions
10
+ # Inject Error Tracking into global objects.
11
+ def self.activate!
12
+ Core::Configuration::Settings.extend(Configuration::Settings)
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,77 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Datadog
4
+ module ErrorTracking
5
+ # Based on configuration, the TracePoint listening to :rescue or :raise
6
+ # may report more handled errors than we want to report. Therefore we need
7
+ # a function to filter the events. As the filter function both depends
8
+ # on configuration and is called numerous time, we generate it during
9
+ # during the initialization of the feature to have the best performance
10
+ # possible.
11
+ #
12
+ # @api private
13
+ module Filters
14
+ module_function
15
+
16
+ def get_gem_name(file_path)
17
+ regex = %r{gems/([^/]+)-\d}
18
+ regex_match = regex.match(file_path)
19
+ return unless regex_match
20
+
21
+ gem_name = regex_match[1]
22
+
23
+ begin
24
+ Gem::Specification.find_by_name(gem_name) # steep:ignore
25
+ rescue Gem::MissingSpecError
26
+ nil
27
+ end
28
+ end
29
+
30
+ def user_code?(file_path)
31
+ !get_gem_name(file_path)
32
+ end
33
+
34
+ def datadog_code?(file_path)
35
+ file_path.include?('lib/datadog/')
36
+ end
37
+
38
+ def third_party_code?(file_path)
39
+ gem_name = get_gem_name(file_path)
40
+ gem_name && gem_name != "datadog"
41
+ end
42
+
43
+ def file_included?(file_path, instrumented_files)
44
+ instrumented_files.include?(file_path)
45
+ end
46
+
47
+ # Generate the proc used in the TracePoint
48
+ def generate_filter(to_instrument_scope, handled_errors_include = nil)
49
+ case to_instrument_scope
50
+ # If DD_ERROR_TRACKING_HANDLED_ERRORS is set
51
+ when 'all'
52
+ proc { |file_path| !datadog_code?(file_path) }
53
+ when 'user'
54
+ # If DD_ERROR_TRACKING_HANDLED_ERRORS_INCLUDE is set
55
+ if handled_errors_include
56
+ proc { |file_path|
57
+ user_code?(file_path) || file_included?(file_path, handled_errors_include)
58
+ }
59
+ else
60
+ proc { |file_path| user_code?(file_path) }
61
+ end
62
+ when 'third_party'
63
+ if handled_errors_include
64
+ proc { |file_path|
65
+ third_party_code?(file_path) || file_included?(file_path, handled_errors_include)
66
+ }
67
+ else
68
+ proc { |file_path| third_party_code?(file_path) }
69
+ end
70
+ else
71
+ # If only DD_ERROR_TRACKING_HANDLED_ERRORS_INCLUDE is set
72
+ proc { |file_path| file_included?(file_path, handled_errors_include) }
73
+ end
74
+ end
75
+ end
76
+ end
77
+ end
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'error_tracking/collector'
4
+ require_relative 'error_tracking/component'
5
+ require_relative 'error_tracking/configuration'
6
+ require_relative 'error_tracking/ext'
7
+ require_relative 'error_tracking/extensions'
8
+ require_relative 'error_tracking/filters'
9
+
10
+ module Datadog
11
+ # Namespace for Datadog ErrorTracking.
12
+ #
13
+ # @api private
14
+ module ErrorTracking
15
+ # Expose ErrorTracking to global shared objects
16
+ Extensions.activate!
17
+ end
18
+ end
@@ -10,6 +10,7 @@ module Datadog
10
10
  LOGIN_SUCCESS_EVENT = 'users.login.success'
11
11
  LOGIN_FAILURE_EVENT = 'users.login.failure'
12
12
  SIGNUP_EVENT = 'users.signup'
13
+ USER_LOGIN_KEYS = ['usr.login', :'usr.login'].freeze
13
14
 
14
15
  class << self
15
16
  # Attach login success event information to the trace
@@ -30,11 +31,15 @@ module Datadog
30
31
  set_trace_and_span_context('track_login_success', trace, span) do |active_trace, active_span|
31
32
  user_options = user.dup
32
33
  user_id = user_options.delete(:id)
34
+ user_login = user_options[:login] || others[:'usr.login'] || others['usr.login'] || user_id
33
35
 
34
36
  raise ArgumentError, 'missing required key: :user => { :id }' if user_id.nil?
35
37
 
38
+ others = others.reject { |key, _| USER_LOGIN_KEYS.include?(key) }
39
+ others[:'usr.login'] = user_login
36
40
  track(LOGIN_SUCCESS_EVENT, active_trace, active_span, **others)
37
41
 
42
+ user_options[:login] = user_login
38
43
  Kit::Identity.set_user(active_trace, active_span, id: user_id, **user_options)
39
44
  end
40
45
  end
@@ -55,6 +60,7 @@ module Datadog
55
60
  # event information to attach to the trace.
56
61
  def track_login_failure(trace = nil, span = nil, user_exists:, user_id: nil, **others)
57
62
  set_trace_and_span_context('track_login_failure', trace, span) do |active_trace, active_span|
63
+ others[:'usr.login'] = user_id if user_id && !others.key?(:'usr.login') && !others.key?('usr.login')
58
64
  track(LOGIN_FAILURE_EVENT, active_trace, active_span, **others)
59
65
 
60
66
  active_span.set_tag('appsec.events.users.login.failure.usr.id', user_id) if user_id
@@ -80,11 +86,15 @@ module Datadog
80
86
  set_trace_and_span_context('track_signup', trace, span) do |active_trace, active_span|
81
87
  user_options = user.dup
82
88
  user_id = user_options.delete(:id)
89
+ user_login = user_options[:login] || others[:'usr.login'] || others['usr.login'] || user_id
83
90
 
84
91
  raise ArgumentError, 'missing required key: :user => { :id }' if user_id.nil?
85
92
 
93
+ others = others.reject { |key, _| USER_LOGIN_KEYS.include?(key) }
94
+ others[:'usr.login'] = user_login
86
95
  track(SIGNUP_EVENT, active_trace, active_span, **others)
87
96
 
97
+ user_options[:login] = user_login
88
98
  Kit::Identity.set_user(trace, id: user_id, **user_options)
89
99
  end
90
100
  end
@@ -131,14 +141,16 @@ module Datadog
131
141
  active_trace.keep!
132
142
  end
133
143
  end
144
+
145
+ ::Datadog::AppSec::Instrumentation.gateway.push('appsec.events.user_lifecycle', event)
134
146
  end
135
147
 
136
148
  private
137
149
 
138
150
  def set_trace_and_span_context(method, trace = nil, span = nil)
139
- if (appsec_scope = Datadog::AppSec.active_scope)
140
- trace = appsec_scope.trace
141
- span = appsec_scope.service_entry_span
151
+ if (appsec_context = Datadog::AppSec.active_context)
152
+ trace = appsec_context.trace
153
+ span = appsec_context.span
142
154
  end
143
155
 
144
156
  trace ||= Datadog::Tracing.active_trace
@@ -33,6 +33,7 @@ module Datadog
33
33
  # @param others [Hash<Symbol, String>] Additional free-form
34
34
  # user information to attach to the trace.
35
35
  #
36
+ # rubocop:disable Metrics/AbcSize
36
37
  # rubocop:disable Metrics/CyclomaticComplexity
37
38
  # rubocop:disable Metrics/PerceivedComplexity
38
39
  def set_user(
@@ -66,21 +67,24 @@ module Datadog
66
67
  active_span.set_tag("usr.#{k}", v) unless v.nil?
67
68
  end
68
69
 
69
- if Datadog::AppSec.active_scope
70
- user = ::Datadog::AppSec::Instrumentation::Gateway::User.new(id)
70
+ if Datadog::AppSec.active_context
71
+ active_span.set_tag('_dd.appsec.user.collection_mode', 'sdk')
72
+
73
+ user = ::Datadog::AppSec::Instrumentation::Gateway::User.new(id, others[:login], session_id)
71
74
  ::Datadog::AppSec::Instrumentation.gateway.push('identity.set_user', user)
72
75
  end
73
76
  end
74
77
  end
78
+ # rubocop:enable Metrics/AbcSize
75
79
  # rubocop:enable Metrics/PerceivedComplexity
76
80
  # rubocop:enable Metrics/CyclomaticComplexity
77
81
 
78
82
  private
79
83
 
80
84
  def set_trace_and_span_context(method, trace = nil, span = nil)
81
- if (appsec_scope = Datadog::AppSec.active_scope)
82
- trace = appsec_scope.trace
83
- span = appsec_scope.service_entry_span
85
+ if (appsec_context = Datadog::AppSec.active_context)
86
+ trace = appsec_context.trace
87
+ span = appsec_context.span
84
88
  end
85
89
 
86
90
  trace ||= Datadog::Tracing.active_trace
@@ -0,0 +1,90 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'trace/span'
4
+ require_relative '../../tracing/trace_operation'
5
+ require_relative '../trace'
6
+
7
+ module Datadog
8
+ module OpenTelemetry
9
+ module API
10
+ # The Baggage module provides an implementation of the OpenTelemetry Baggage API.
11
+ #
12
+ # Baggage is a set of name/value pairs describing user-defined properties that can be
13
+ # propagated through a distributed trace. This implementation follows the W3C Baggage
14
+ # specification and the OpenTelemetry Baggage API.
15
+ #
16
+ # @see https://www.w3.org/TR/baggage/
17
+ # @see https://opentelemetry.io/docs/specs/otel/baggage/api/
18
+ module Baggage
19
+ def initialize(trace: nil)
20
+ @trace = trace
21
+ end
22
+
23
+ # Returns a new context with empty baggage
24
+ #
25
+ # @param [optional Context] context Context to clear baggage from. Defaults
26
+ # to ::OpenTelemetry::Context.current
27
+ # @return [Context]
28
+ def clear(context: ::OpenTelemetry::Context.current)
29
+ context.ensure_trace.baggage.clear
30
+ context
31
+ end
32
+
33
+ # Returns the corresponding value for key
34
+ #
35
+ # @param [String] key The lookup key
36
+ # @param [optional Context] context The context from which to retrieve
37
+ # the key. Defaults to ::OpenTelemetry::Context.current
38
+ # @return [String, nil]
39
+ def value(key, context: ::OpenTelemetry::Context.current)
40
+ trace = context.ensure_trace
41
+ return nil if trace.nil?
42
+
43
+ trace.baggage && trace.baggage[key]
44
+ end
45
+
46
+ # Returns all baggage values
47
+ #
48
+ # @param [optional Context] context The context from which to retrieve
49
+ # the baggage. Defaults to ::OpenTelemetry::Context.current
50
+ # @return [Hash<String, String>]
51
+ def values(context: ::OpenTelemetry::Context.current)
52
+ trace = context.ensure_trace
53
+ return {} if trace.nil?
54
+
55
+ trace.baggage ? trace.baggage.dup : {}
56
+ end
57
+
58
+ # Returns a new context with new key-value pair
59
+ #
60
+ # @param [String] key The key to store this value under
61
+ # @param [String] value String value to be stored under key
62
+ # @param [optional String] metadata This is here to store properties
63
+ # received from other W3C Baggage implementations but is not exposed in
64
+ # OpenTelemetry. This is considered private API and not for use by
65
+ # end-users.
66
+ # @param [optional Context] context The context to update with new
67
+ # value. Defaults to ::OpenTelemetry::Context.current
68
+ # @return [Context]
69
+ def set_value(key, value, metadata: nil, context: ::OpenTelemetry::Context.current)
70
+ # Delegate to the context to set the value because an active trace is not guaranteed
71
+ # set_values handles this logic
72
+ context.set_values({ ::OpenTelemetry::Baggage.const_get(:BAGGAGE_KEY) => { key => value } })
73
+ end
74
+
75
+ # Returns a new context with value at key removed
76
+ #
77
+ # @param [String] key The key to remove
78
+ # @param [optional Context] context The context to remove baggage
79
+ # from. Defaults to ::OpenTelemetry::Context.current
80
+ # @return [Context]
81
+ def remove_value(key, context: ::OpenTelemetry::Context.current)
82
+ # Delegate to the context to remove the value because an active trace is not guaranteed
83
+ # set_values handles this logic
84
+ context.set_values({ Context::BAGGAGE_REMOVE_KEY => key })
85
+ end
86
+ ::OpenTelemetry::Baggage.singleton_class.prepend(self)
87
+ end
88
+ end
89
+ end
90
+ end
@@ -0,0 +1,26 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Datadog
4
+ module OpenTelemetry
5
+ module API
6
+ module Baggage
7
+ def initialize: (?trace: Datadog::Tracing::TraceOperation?) -> void
8
+
9
+ # Returns a new context with empty baggage
10
+ def clear: (?context: OpenTelemetry::Context) -> OpenTelemetry::Context
11
+
12
+ # Returns the corresponding value for key
13
+ def value: (String key, ?context: OpenTelemetry::Context) -> String?
14
+
15
+ # Returns all baggage values
16
+ def values: (?context: OpenTelemetry::Context) -> Hash[String, String]
17
+
18
+ # Returns a new context with key-value pair
19
+ def set_value: (String key, String value, ?metadata: String?, ?context: OpenTelemetry::Context) -> OpenTelemetry::Context
20
+
21
+ # Returns a new context with value at key removed
22
+ def remove_value: (String key, ?context: OpenTelemetry::Context) -> OpenTelemetry::Context
23
+ end
24
+ end
25
+ end
26
+ end
@@ -21,11 +21,13 @@ module Datadog
21
21
  module Context
22
22
  CURRENT_SPAN_KEY = ::OpenTelemetry::Trace.const_get(:CURRENT_SPAN_KEY)
23
23
  private_constant :CURRENT_SPAN_KEY
24
+ BAGGAGE_REMOVE_KEY = Object.new # sentinel object to indicate the deletion of a value in baggage
24
25
 
25
- def initialize(entries, trace: nil)
26
+ def initialize(entries, trace: nil, baggage: nil)
26
27
  @trace = trace || ::Datadog::Tracing.send(:tracer).send(:start_trace)
27
28
  @trace.otel_values.merge!(entries) if entries
28
29
  @trace.otel_context ||= self
30
+ @trace.baggage = baggage if baggage
29
31
  end
30
32
 
31
33
  # Because Context can be reused, we have to make sure we have
@@ -79,8 +81,20 @@ module Datadog
79
81
  end
80
82
 
81
83
  existing_values = @trace && @trace.otel_values || {}
84
+ existing_baggage = @trace && @trace.baggage || {}
82
85
 
83
- ::OpenTelemetry::Context.new(existing_values.merge(values), trace: trace)
86
+ # Retrieve the baggage removal sentinel and remove it from the values hash
87
+ existing_baggage.delete(values[BAGGAGE_REMOVE_KEY]) if values.key?(BAGGAGE_REMOVE_KEY)
88
+
89
+ # If the values hash contains a BAGGAGE_KEY, merge its contents with existing baggage
90
+ # Otherwise, keep the existing baggage unchanged
91
+ new_baggage = if values.key?(::OpenTelemetry::Baggage.const_get(:BAGGAGE_KEY))
92
+ existing_baggage.merge(values[::OpenTelemetry::Baggage.const_get(:BAGGAGE_KEY)])
93
+ else
94
+ existing_baggage
95
+ end
96
+
97
+ ::OpenTelemetry::Context.new(existing_values.merge(values), trace: trace, baggage: new_baggage)
84
98
  end
85
99
 
86
100
  # The Datadog {TraceOperation} associated with this {Context}.
@@ -45,7 +45,7 @@ module Datadog
45
45
  def add_attributes(attributes)
46
46
  res = super
47
47
  # Attributes can get dropped or their values truncated by `super`
48
- attributes.each { |key, _| datadog_set_attribute(key) }
48
+ attributes.each_key { |key| datadog_set_attribute(key) }
49
49
  res
50
50
  end
51
51
 
@@ -13,6 +13,7 @@ require_relative 'tracing'
13
13
  require_relative 'tracing/contrib'
14
14
 
15
15
  require_relative 'opentelemetry/api/context'
16
+ require_relative 'opentelemetry/api/baggage'
16
17
 
17
18
  # DEV: Should this be a Contrib integration, that depends on the `opentelemetry-sdk`
18
19
  # DEV: and checks for compatibility?
@@ -29,7 +30,7 @@ module Datadog
29
30
 
30
31
  # Use `Datadog.logger` as the default logger
31
32
  def logger
32
- @logger ||= ::Datadog.logger
33
+ ::Datadog.logger
33
34
  end
34
35
 
35
36
  ::OpenTelemetry.singleton_class.prepend(self)
@@ -42,7 +42,7 @@ module Datadog
42
42
  end
43
43
 
44
44
  def generate_json
45
- JSON.fast_generate(v1: seen_libraries.to_a)
45
+ JSON.generate(v1: seen_libraries.to_a)
46
46
  end
47
47
 
48
48
  private