datadog 2.12.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 (302) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +154 -2
  3. data/ext/datadog_profiling_native_extension/collectors_thread_context.c +16 -14
  4. data/ext/datadog_profiling_native_extension/datadog_ruby_common.c +1 -4
  5. data/ext/datadog_profiling_native_extension/datadog_ruby_common.h +10 -0
  6. data/ext/datadog_profiling_native_extension/encoded_profile.c +79 -0
  7. data/ext/datadog_profiling_native_extension/encoded_profile.h +8 -0
  8. data/ext/datadog_profiling_native_extension/extconf.rb +3 -0
  9. data/ext/datadog_profiling_native_extension/heap_recorder.c +8 -1
  10. data/ext/datadog_profiling_native_extension/http_transport.c +60 -94
  11. data/ext/datadog_profiling_native_extension/private_vm_api_access.c +8 -0
  12. data/ext/datadog_profiling_native_extension/profiling.c +2 -0
  13. data/ext/datadog_profiling_native_extension/stack_recorder.c +23 -23
  14. data/ext/libdatadog_api/crashtracker.c +11 -12
  15. data/ext/libdatadog_api/crashtracker.h +5 -0
  16. data/ext/libdatadog_api/datadog_ruby_common.c +1 -4
  17. data/ext/libdatadog_api/datadog_ruby_common.h +10 -0
  18. data/ext/libdatadog_api/init.c +15 -0
  19. data/ext/libdatadog_api/library_config.c +122 -0
  20. data/ext/libdatadog_api/library_config.h +19 -0
  21. data/ext/libdatadog_api/macos_development.md +3 -3
  22. data/ext/libdatadog_api/process_discovery.c +117 -0
  23. data/ext/libdatadog_api/process_discovery.h +5 -0
  24. data/ext/libdatadog_extconf_helpers.rb +1 -1
  25. data/lib/datadog/appsec/actions_handler/serializable_backtrace.rb +89 -0
  26. data/lib/datadog/appsec/actions_handler.rb +24 -2
  27. data/lib/datadog/appsec/anonymizer.rb +16 -0
  28. data/lib/datadog/appsec/api_security/lru_cache.rb +49 -0
  29. data/lib/datadog/appsec/api_security.rb +9 -0
  30. data/lib/datadog/appsec/assets/waf_rules/README.md +50 -5
  31. data/lib/datadog/appsec/assets/waf_rules/processors.json +239 -10
  32. data/lib/datadog/appsec/assets/waf_rules/scanners.json +926 -17
  33. data/lib/datadog/appsec/autoload.rb +1 -1
  34. data/lib/datadog/appsec/component.rb +29 -20
  35. data/lib/datadog/appsec/compressed_json.rb +40 -0
  36. data/lib/datadog/appsec/configuration/settings.rb +93 -28
  37. data/lib/datadog/appsec/context.rb +1 -1
  38. data/lib/datadog/appsec/contrib/active_record/instrumentation.rb +10 -12
  39. data/lib/datadog/appsec/contrib/active_record/integration.rb +2 -2
  40. data/lib/datadog/appsec/contrib/active_record/patcher.rb +22 -22
  41. data/lib/datadog/appsec/contrib/auto_instrument.rb +1 -1
  42. data/lib/datadog/appsec/contrib/devise/configuration.rb +7 -31
  43. data/lib/datadog/appsec/contrib/devise/data_extractor.rb +78 -0
  44. data/lib/datadog/appsec/contrib/devise/ext.rb +22 -0
  45. data/lib/datadog/appsec/contrib/devise/integration.rb +1 -2
  46. data/lib/datadog/appsec/contrib/devise/patcher.rb +34 -23
  47. data/lib/datadog/appsec/contrib/devise/patches/signin_tracking_patch.rb +102 -0
  48. data/lib/datadog/appsec/contrib/devise/patches/signup_tracking_patch.rb +69 -0
  49. data/lib/datadog/appsec/contrib/devise/{patcher/rememberable_patch.rb → patches/skip_signin_tracking_patch.rb} +2 -2
  50. data/lib/datadog/appsec/contrib/devise/tracking_middleware.rb +106 -0
  51. data/lib/datadog/appsec/contrib/excon/integration.rb +1 -1
  52. data/lib/datadog/appsec/contrib/excon/ssrf_detection_middleware.rb +9 -10
  53. data/lib/datadog/appsec/contrib/faraday/integration.rb +1 -1
  54. data/lib/datadog/appsec/contrib/faraday/ssrf_detection_middleware.rb +8 -9
  55. data/lib/datadog/appsec/contrib/graphql/gateway/watcher.rb +8 -9
  56. data/lib/datadog/appsec/contrib/graphql/integration.rb +1 -1
  57. data/lib/datadog/appsec/contrib/rack/ext.rb +34 -0
  58. data/lib/datadog/appsec/contrib/rack/gateway/watcher.rb +49 -32
  59. data/lib/datadog/appsec/contrib/rack/integration.rb +1 -1
  60. data/lib/datadog/appsec/contrib/rack/request_middleware.rb +19 -18
  61. data/lib/datadog/appsec/contrib/rails/gateway/watcher.rb +11 -13
  62. data/lib/datadog/appsec/contrib/rails/integration.rb +1 -1
  63. data/lib/datadog/appsec/contrib/rails/patcher.rb +21 -21
  64. data/lib/datadog/appsec/contrib/rest_client/integration.rb +1 -1
  65. data/lib/datadog/appsec/contrib/rest_client/request_ssrf_detection_patch.rb +10 -11
  66. data/lib/datadog/appsec/contrib/sinatra/gateway/watcher.rb +17 -23
  67. data/lib/datadog/appsec/contrib/sinatra/integration.rb +1 -1
  68. data/lib/datadog/appsec/event.rb +96 -135
  69. data/lib/datadog/appsec/ext.rb +4 -2
  70. data/lib/datadog/appsec/instrumentation/gateway/argument.rb +7 -2
  71. data/lib/datadog/appsec/instrumentation/gateway/middleware.rb +24 -0
  72. data/lib/datadog/appsec/instrumentation/gateway.rb +17 -22
  73. data/lib/datadog/appsec/metrics/telemetry.rb +1 -1
  74. data/lib/datadog/appsec/monitor/gateway/watcher.rb +49 -14
  75. data/lib/datadog/appsec/processor/rule_loader.rb +26 -28
  76. data/lib/datadog/appsec/processor/rule_merger.rb +7 -6
  77. data/lib/datadog/appsec/processor.rb +1 -1
  78. data/lib/datadog/appsec/remote.rb +23 -11
  79. data/lib/datadog/appsec/response.rb +6 -6
  80. data/lib/datadog/appsec/security_engine/runner.rb +3 -3
  81. data/lib/datadog/appsec/security_event.rb +39 -0
  82. data/lib/datadog/appsec/utils.rb +0 -2
  83. data/lib/datadog/appsec.rb +1 -1
  84. data/lib/datadog/core/buffer/random.rb +18 -2
  85. data/lib/datadog/core/configuration/agent_settings_resolver.rb +5 -5
  86. data/lib/datadog/core/configuration/agentless_settings_resolver.rb +176 -0
  87. data/lib/datadog/core/configuration/components.rb +50 -31
  88. data/lib/datadog/core/configuration/components_state.rb +23 -0
  89. data/lib/datadog/core/configuration/ext.rb +4 -0
  90. data/lib/datadog/core/configuration/option.rb +79 -43
  91. data/lib/datadog/core/configuration/option_definition.rb +4 -4
  92. data/lib/datadog/core/configuration/options.rb +3 -3
  93. data/lib/datadog/core/configuration/settings.rb +68 -35
  94. data/lib/datadog/core/configuration/stable_config.rb +23 -0
  95. data/lib/datadog/core/configuration.rb +40 -16
  96. data/lib/datadog/core/crashtracking/component.rb +3 -10
  97. data/lib/datadog/core/diagnostics/environment_logger.rb +1 -1
  98. data/lib/datadog/core/encoding.rb +1 -1
  99. data/lib/datadog/core/environment/agent_info.rb +4 -3
  100. data/lib/datadog/core/environment/cgroup.rb +10 -12
  101. data/lib/datadog/core/environment/container.rb +38 -40
  102. data/lib/datadog/core/environment/ext.rb +6 -6
  103. data/lib/datadog/core/environment/git.rb +1 -0
  104. data/lib/datadog/core/environment/identity.rb +3 -3
  105. data/lib/datadog/core/environment/platform.rb +3 -3
  106. data/lib/datadog/core/environment/variable_helpers.rb +1 -1
  107. data/lib/datadog/core/error.rb +11 -9
  108. data/lib/datadog/core/logger.rb +2 -2
  109. data/lib/datadog/core/metrics/client.rb +20 -21
  110. data/lib/datadog/core/metrics/logging.rb +5 -5
  111. data/lib/datadog/core/process_discovery.rb +32 -0
  112. data/lib/datadog/core/rate_limiter.rb +4 -2
  113. data/lib/datadog/core/remote/client.rb +40 -32
  114. data/lib/datadog/core/remote/component.rb +6 -9
  115. data/lib/datadog/core/remote/configuration/digest.rb +7 -7
  116. data/lib/datadog/core/remote/configuration/path.rb +1 -1
  117. data/lib/datadog/core/remote/configuration/repository.rb +2 -1
  118. data/lib/datadog/core/remote/negotiation.rb +9 -9
  119. data/lib/datadog/core/remote/transport/config.rb +4 -3
  120. data/lib/datadog/core/remote/transport/http/client.rb +5 -4
  121. data/lib/datadog/core/remote/transport/http/config.rb +27 -37
  122. data/lib/datadog/core/remote/transport/http/negotiation.rb +7 -33
  123. data/lib/datadog/core/remote/transport/http.rb +22 -57
  124. data/lib/datadog/core/remote/transport/negotiation.rb +4 -3
  125. data/lib/datadog/core/runtime/metrics.rb +12 -5
  126. data/lib/datadog/core/telemetry/component.rb +78 -53
  127. data/lib/datadog/core/telemetry/emitter.rb +23 -11
  128. data/lib/datadog/core/telemetry/event/app_client_configuration_change.rb +65 -0
  129. data/lib/datadog/core/telemetry/event/app_closing.rb +18 -0
  130. data/lib/datadog/core/telemetry/event/app_dependencies_loaded.rb +33 -0
  131. data/lib/datadog/core/telemetry/event/app_heartbeat.rb +18 -0
  132. data/lib/datadog/core/telemetry/event/app_integrations_change.rb +58 -0
  133. data/lib/datadog/core/telemetry/event/app_started.rb +179 -0
  134. data/lib/datadog/core/telemetry/event/base.rb +40 -0
  135. data/lib/datadog/core/telemetry/event/distributions.rb +18 -0
  136. data/lib/datadog/core/telemetry/event/generate_metrics.rb +43 -0
  137. data/lib/datadog/core/telemetry/event/log.rb +76 -0
  138. data/lib/datadog/core/telemetry/event/message_batch.rb +42 -0
  139. data/lib/datadog/core/telemetry/event/synth_app_client_configuration_change.rb +43 -0
  140. data/lib/datadog/core/telemetry/event.rb +17 -472
  141. data/lib/datadog/core/telemetry/http/adapters/net.rb +12 -97
  142. data/lib/datadog/core/telemetry/logger.rb +1 -1
  143. data/lib/datadog/core/telemetry/metric.rb +8 -8
  144. data/lib/datadog/core/telemetry/request.rb +4 -4
  145. data/lib/datadog/core/telemetry/transport/http/api.rb +43 -0
  146. data/lib/datadog/core/telemetry/transport/http/client.rb +49 -0
  147. data/lib/datadog/core/telemetry/transport/http/telemetry.rb +92 -0
  148. data/lib/datadog/core/telemetry/transport/http.rb +63 -0
  149. data/lib/datadog/core/telemetry/transport/telemetry.rb +51 -0
  150. data/lib/datadog/core/telemetry/worker.rb +90 -24
  151. data/lib/datadog/core/transport/http/adapters/test.rb +2 -1
  152. data/lib/datadog/core/transport/http/api/instance.rb +17 -0
  153. data/lib/datadog/core/transport/http/api/spec.rb +17 -0
  154. data/lib/datadog/core/transport/http/builder.rb +18 -16
  155. data/lib/datadog/core/transport/http.rb +39 -2
  156. data/lib/datadog/core/utils/at_fork_monkey_patch.rb +6 -6
  157. data/lib/datadog/core/utils/duration.rb +32 -32
  158. data/lib/datadog/core/utils/forking.rb +2 -2
  159. data/lib/datadog/core/utils/network.rb +6 -6
  160. data/lib/datadog/core/utils/only_once_successful.rb +16 -5
  161. data/lib/datadog/core/utils/time.rb +20 -0
  162. data/lib/datadog/core/utils/truncation.rb +21 -0
  163. data/lib/datadog/core/vendor/multipart-post/multipart/post/composite_read_io.rb +1 -1
  164. data/lib/datadog/core/vendor/multipart-post/multipart/post/multipartable.rb +8 -8
  165. data/lib/datadog/core/vendor/multipart-post/multipart/post/parts.rb +7 -7
  166. data/lib/datadog/core/worker.rb +1 -1
  167. data/lib/datadog/core/workers/async.rb +29 -12
  168. data/lib/datadog/core/workers/interval_loop.rb +12 -1
  169. data/lib/datadog/core/workers/runtime_metrics.rb +2 -2
  170. data/lib/datadog/core.rb +8 -0
  171. data/lib/datadog/di/boot.rb +34 -0
  172. data/lib/datadog/di/component.rb +0 -2
  173. data/lib/datadog/di/probe_notification_builder.rb +1 -1
  174. data/lib/datadog/di/probe_notifier_worker.rb +16 -16
  175. data/lib/datadog/di/remote.rb +2 -0
  176. data/lib/datadog/di/transport/diagnostics.rb +4 -3
  177. data/lib/datadog/di/transport/http/api.rb +2 -12
  178. data/lib/datadog/di/transport/http/client.rb +4 -3
  179. data/lib/datadog/di/transport/http/diagnostics.rb +7 -34
  180. data/lib/datadog/di/transport/http/input.rb +7 -34
  181. data/lib/datadog/di/transport/http.rb +14 -62
  182. data/lib/datadog/di/transport/input.rb +4 -3
  183. data/lib/datadog/di/utils.rb +5 -0
  184. data/lib/datadog/di.rb +5 -32
  185. data/lib/datadog/error_tracking/collector.rb +87 -0
  186. data/lib/datadog/error_tracking/component.rb +167 -0
  187. data/lib/datadog/error_tracking/configuration/settings.rb +63 -0
  188. data/lib/datadog/error_tracking/configuration.rb +11 -0
  189. data/lib/datadog/error_tracking/ext.rb +18 -0
  190. data/lib/datadog/error_tracking/extensions.rb +16 -0
  191. data/lib/datadog/error_tracking/filters.rb +77 -0
  192. data/lib/datadog/error_tracking.rb +18 -0
  193. data/lib/datadog/kit/appsec/events.rb +12 -0
  194. data/lib/datadog/kit/identity.rb +5 -1
  195. data/lib/datadog/opentelemetry/api/baggage.rb +90 -0
  196. data/lib/datadog/opentelemetry/api/baggage.rbs +26 -0
  197. data/lib/datadog/opentelemetry/api/context.rb +16 -2
  198. data/lib/datadog/opentelemetry/sdk/trace/span.rb +1 -1
  199. data/lib/datadog/opentelemetry.rb +2 -1
  200. data/lib/datadog/profiling/collectors/code_provenance.rb +1 -1
  201. data/lib/datadog/profiling/collectors/info.rb +3 -0
  202. data/lib/datadog/profiling/collectors/thread_context.rb +1 -1
  203. data/lib/datadog/profiling/encoded_profile.rb +11 -0
  204. data/lib/datadog/profiling/exporter.rb +3 -4
  205. data/lib/datadog/profiling/ext.rb +0 -2
  206. data/lib/datadog/profiling/flush.rb +5 -8
  207. data/lib/datadog/profiling/http_transport.rb +5 -59
  208. data/lib/datadog/profiling/scheduler.rb +8 -1
  209. data/lib/datadog/profiling/stack_recorder.rb +4 -4
  210. data/lib/datadog/profiling/tag_builder.rb +1 -5
  211. data/lib/datadog/profiling.rb +6 -2
  212. data/lib/datadog/tracing/analytics.rb +1 -1
  213. data/lib/datadog/tracing/component.rb +15 -12
  214. data/lib/datadog/tracing/configuration/ext.rb +7 -1
  215. data/lib/datadog/tracing/configuration/settings.rb +18 -2
  216. data/lib/datadog/tracing/context_provider.rb +1 -1
  217. data/lib/datadog/tracing/contrib/active_record/integration.rb +1 -1
  218. data/lib/datadog/tracing/contrib/active_support/cache/events/cache.rb +4 -1
  219. data/lib/datadog/tracing/contrib/active_support/cache/instrumentation.rb +33 -0
  220. data/lib/datadog/tracing/contrib/active_support/cache/patcher.rb +4 -0
  221. data/lib/datadog/tracing/contrib/active_support/cache/redis.rb +2 -4
  222. data/lib/datadog/tracing/contrib/aws/instrumentation.rb +10 -0
  223. data/lib/datadog/tracing/contrib/aws/parsed_context.rb +5 -1
  224. data/lib/datadog/tracing/contrib/configuration/settings.rb +1 -1
  225. data/lib/datadog/tracing/contrib/ethon/easy_patch.rb +4 -5
  226. data/lib/datadog/tracing/contrib/excon/middleware.rb +5 -3
  227. data/lib/datadog/tracing/contrib/ext.rb +1 -0
  228. data/lib/datadog/tracing/contrib/faraday/middleware.rb +5 -3
  229. data/lib/datadog/tracing/contrib/grpc/datadog_interceptor/client.rb +7 -1
  230. data/lib/datadog/tracing/contrib/grpc/distributed/propagation.rb +3 -0
  231. data/lib/datadog/tracing/contrib/http/circuit_breaker.rb +0 -15
  232. data/lib/datadog/tracing/contrib/http/distributed/propagation.rb +4 -1
  233. data/lib/datadog/tracing/contrib/http/instrumentation.rb +6 -10
  234. data/lib/datadog/tracing/contrib/httpclient/instrumentation.rb +6 -16
  235. data/lib/datadog/tracing/contrib/httprb/instrumentation.rb +7 -15
  236. data/lib/datadog/tracing/contrib/karafka/configuration/settings.rb +27 -0
  237. data/lib/datadog/tracing/contrib/karafka/distributed/propagation.rb +48 -0
  238. data/lib/datadog/tracing/contrib/karafka/ext.rb +27 -0
  239. data/lib/datadog/tracing/contrib/karafka/integration.rb +45 -0
  240. data/lib/datadog/tracing/contrib/karafka/monitor.rb +66 -0
  241. data/lib/datadog/tracing/contrib/karafka/patcher.rb +71 -0
  242. data/lib/datadog/tracing/contrib/karafka.rb +37 -0
  243. data/lib/datadog/tracing/contrib/mongodb/configuration/settings.rb +8 -0
  244. data/lib/datadog/tracing/contrib/mongodb/ext.rb +1 -0
  245. data/lib/datadog/tracing/contrib/mongodb/subscribers.rb +18 -1
  246. data/lib/datadog/tracing/contrib/opensearch/configuration/settings.rb +17 -0
  247. data/lib/datadog/tracing/contrib/opensearch/ext.rb +9 -0
  248. data/lib/datadog/tracing/contrib/opensearch/patcher.rb +5 -1
  249. data/lib/datadog/tracing/contrib/patcher.rb +5 -2
  250. data/lib/datadog/tracing/contrib/rack/request_queue.rb +1 -1
  251. data/lib/datadog/tracing/contrib/rest_client/request_patch.rb +5 -3
  252. data/lib/datadog/tracing/contrib/sidekiq/client_tracer.rb +6 -1
  253. data/lib/datadog/tracing/contrib/sidekiq/distributed/propagation.rb +3 -0
  254. data/lib/datadog/tracing/contrib/sidekiq/server_tracer.rb +1 -1
  255. data/lib/datadog/tracing/contrib/support.rb +28 -0
  256. data/lib/datadog/tracing/contrib.rb +1 -0
  257. data/lib/datadog/tracing/correlation.rb +9 -2
  258. data/lib/datadog/tracing/distributed/b3_multi.rb +1 -1
  259. data/lib/datadog/tracing/distributed/b3_single.rb +1 -1
  260. data/lib/datadog/tracing/distributed/baggage.rb +131 -0
  261. data/lib/datadog/tracing/distributed/datadog.rb +4 -2
  262. data/lib/datadog/tracing/distributed/propagation.rb +25 -4
  263. data/lib/datadog/tracing/distributed/propagation_policy.rb +42 -0
  264. data/lib/datadog/tracing/metadata/errors.rb +4 -4
  265. data/lib/datadog/tracing/metadata/ext.rb +5 -0
  266. data/lib/datadog/tracing/metadata/metastruct.rb +36 -0
  267. data/lib/datadog/tracing/metadata/metastruct_tagging.rb +42 -0
  268. data/lib/datadog/tracing/metadata.rb +2 -0
  269. data/lib/datadog/tracing/sampling/rate_sampler.rb +2 -1
  270. data/lib/datadog/tracing/sampling/span/rule.rb +0 -1
  271. data/lib/datadog/tracing/span.rb +10 -1
  272. data/lib/datadog/tracing/span_event.rb +1 -1
  273. data/lib/datadog/tracing/span_operation.rb +46 -16
  274. data/lib/datadog/tracing/sync_writer.rb +1 -2
  275. data/lib/datadog/tracing/trace_digest.rb +9 -2
  276. data/lib/datadog/tracing/trace_operation.rb +44 -24
  277. data/lib/datadog/tracing/trace_segment.rb +6 -4
  278. data/lib/datadog/tracing/tracer.rb +45 -5
  279. data/lib/datadog/tracing/transport/http/api.rb +2 -10
  280. data/lib/datadog/tracing/transport/http/client.rb +5 -4
  281. data/lib/datadog/tracing/transport/http/traces.rb +13 -41
  282. data/lib/datadog/tracing/transport/http.rb +11 -44
  283. data/lib/datadog/tracing/transport/serializable_trace.rb +3 -1
  284. data/lib/datadog/tracing/transport/trace_formatter.rb +7 -0
  285. data/lib/datadog/tracing/transport/traces.rb +26 -9
  286. data/lib/datadog/tracing/utils.rb +1 -1
  287. data/lib/datadog/tracing/workers/trace_writer.rb +2 -6
  288. data/lib/datadog/tracing/writer.rb +2 -6
  289. data/lib/datadog/tracing.rb +16 -3
  290. data/lib/datadog/version.rb +2 -2
  291. data/lib/datadog.rb +2 -3
  292. metadata +80 -19
  293. data/lib/datadog/appsec/contrib/devise/event.rb +0 -54
  294. data/lib/datadog/appsec/contrib/devise/patcher/authenticatable_patch.rb +0 -72
  295. data/lib/datadog/appsec/contrib/devise/patcher/registration_controller_patch.rb +0 -47
  296. data/lib/datadog/appsec/contrib/devise/resource.rb +0 -35
  297. data/lib/datadog/appsec/contrib/devise/tracking.rb +0 -57
  298. data/lib/datadog/appsec/utils/trace_operation.rb +0 -15
  299. data/lib/datadog/core/telemetry/http/env.rb +0 -20
  300. data/lib/datadog/core/telemetry/http/ext.rb +0 -28
  301. data/lib/datadog/core/telemetry/http/response.rb +0 -70
  302. data/lib/datadog/core/telemetry/http/transport.rb +0 -90
@@ -0,0 +1,71 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative '../patcher'
4
+ require_relative 'ext'
5
+ require_relative 'distributed/propagation'
6
+
7
+ module Datadog
8
+ module Tracing
9
+ module Contrib
10
+ module Karafka
11
+ # Patch to add tracing to Karafka::Messages::Messages
12
+ module MessagesPatch
13
+ def configuration
14
+ Datadog.configuration.tracing[:karafka]
15
+ end
16
+
17
+ def propagation
18
+ @propagation ||= Contrib::Karafka::Distributed::Propagation.new
19
+ end
20
+
21
+ # `each` is the most popular access point to Karafka messages,
22
+ # but not the only one
23
+ # Other access patterns do not have a straightforward tracing avenue
24
+ # (e.g. `my_batch_operation messages.payloads`)
25
+ # @see https://github.com/karafka/karafka/blob/b06d1f7c17818e1605f80c2bb573454a33376b40/README.md?plain=1#L29-L35
26
+ def each(&block)
27
+ @messages_array.each do |message|
28
+ if configuration[:distributed_tracing]
29
+ headers = if message.metadata.respond_to?(:raw_headers)
30
+ message.metadata.raw_headers
31
+ else
32
+ message.metadata.headers
33
+ end
34
+ trace_digest = Karafka.extract(headers)
35
+ Datadog::Tracing.continue_trace!(trace_digest) if trace_digest
36
+ end
37
+
38
+ Tracing.trace(Ext::SPAN_MESSAGE_CONSUME) do |span|
39
+ span.set_tag(Ext::TAG_OFFSET, message.metadata.offset)
40
+ span.set_tag(Contrib::Ext::Messaging::TAG_DESTINATION, message.topic)
41
+ span.set_tag(Contrib::Ext::Messaging::TAG_SYSTEM, Ext::TAG_SYSTEM)
42
+
43
+ span.resource = message.topic
44
+
45
+ yield message
46
+ end
47
+ end
48
+ end
49
+ end
50
+
51
+ # Patcher enables patching of 'karafka' module.
52
+ module Patcher
53
+ include Contrib::Patcher
54
+
55
+ module_function
56
+
57
+ def target_version
58
+ Integration.version
59
+ end
60
+
61
+ def patch
62
+ require_relative 'monitor'
63
+
64
+ ::Karafka::Instrumentation::Monitor.prepend(Monitor)
65
+ ::Karafka::Messages::Messages.prepend(MessagesPatch)
66
+ end
67
+ end
68
+ end
69
+ end
70
+ end
71
+ end
@@ -0,0 +1,37 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'component'
4
+ require_relative 'karafka/integration'
5
+ require_relative 'karafka/distributed/propagation'
6
+
7
+ module Datadog
8
+ module Tracing
9
+ module Contrib
10
+ # `Karafka` integration public API
11
+ module Karafka
12
+ def self.inject(digest, data)
13
+ raise 'Please invoke Datadog.configure at least once before calling this method' unless @propagation
14
+
15
+ @propagation.inject!(digest, data)
16
+ end
17
+
18
+ def self.extract(data)
19
+ raise 'Please invoke Datadog.configure at least once before calling this method' unless @propagation
20
+
21
+ @propagation.extract(data)
22
+ end
23
+
24
+ Contrib::Component.register('karafka') do |config|
25
+ tracing = config.tracing
26
+ tracing.propagation_style
27
+
28
+ @propagation = Karafka::Distributed::Propagation.new(
29
+ propagation_style_inject: tracing.propagation_style_inject,
30
+ propagation_style_extract: tracing.propagation_style_extract,
31
+ propagation_extract_first: tracing.propagation_extract_first
32
+ )
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end
@@ -48,6 +48,14 @@ module Datadog
48
48
  o.type :string, nilable: true
49
49
  o.env Ext::ENV_PEER_SERVICE
50
50
  end
51
+
52
+ # Serializes the command to JSON format, which is the desired format for the agent and Datadog UI.
53
+ # Setting this to false is deprecated and does not have any advantages.
54
+ option :json_command do |o|
55
+ o.type :bool
56
+ o.env Ext::ENV_JSON_COMMAND
57
+ o.default false
58
+ end
51
59
  end
52
60
  end
53
61
  end
@@ -13,6 +13,7 @@ module Datadog
13
13
  # @!visibility private
14
14
  ENV_ANALYTICS_ENABLED = 'DD_TRACE_MONGO_ANALYTICS_ENABLED'
15
15
  ENV_ANALYTICS_SAMPLE_RATE = 'DD_TRACE_MONGO_ANALYTICS_SAMPLE_RATE'
16
+ ENV_JSON_COMMAND = 'DD_TRACE_MONGO_JSON_COMMAND'
16
17
  DEFAULT_PEER_SERVICE_NAME = 'mongodb'
17
18
  SPAN_COMMAND = 'mongo.cmd'
18
19
  SPAN_TYPE_COMMAND = 'mongodb'
@@ -1,5 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require 'json'
4
+
3
5
  require_relative '../analytics'
4
6
  require_relative 'ext'
5
7
  require_relative '../ext'
@@ -30,7 +32,7 @@ module Datadog
30
32
 
31
33
  # build a quantized Query using the Parser module
32
34
  query = MongoDB.query_builder(event.command_name, event.database_name, event.command)
33
- serialized_query = query.to_s
35
+ serialized_query = serialize_query(query)
34
36
 
35
37
  if datadog_configuration[:peer_service]
36
38
  span.set_tag(
@@ -109,6 +111,21 @@ module Datadog
109
111
 
110
112
  private
111
113
 
114
+ def serialize_query(query)
115
+ if datadog_configuration[:json_command]
116
+ query.to_json
117
+ else
118
+ # Incorrect Hash#to_s serialization. The Mongo command should only be encoded as JSON.
119
+ # This code path should be removed, and is only kept to avoid a breaking change.
120
+ Datadog::Core.log_deprecation(key: :mongo_json_command) do
121
+ 'MongoDB integration: `json_command: false` causes invalid command serialization. '\
122
+ 'Use `json_command: true` or `DD_TRACE_MONGO_JSON_COMMAND=1` instead.'
123
+ end
124
+
125
+ query.to_s
126
+ end
127
+ end
128
+
112
129
  def get_span(event)
113
130
  Thread.current[:datadog_mongo_span] \
114
131
  && Thread.current[:datadog_mongo_span][event.request_id]
@@ -46,6 +46,23 @@ module Datadog
46
46
  o.type :string, nilable: true
47
47
  o.env Ext::ENV_PEER_SERVICE
48
48
  end
49
+
50
+ option :resource_pattern do |o|
51
+ o.type :string
52
+ o.env Ext::ENV_RESOURCE_PATTERN
53
+ o.default Ext::DEFAULT_RESOURCE_PATTERN
54
+ o.setter do |value|
55
+ next value if Ext::VALID_RESOURCE_PATTERNS.include?(value)
56
+
57
+ Datadog.logger.warn(
58
+ "Invalid resource pattern: #{value}. " \
59
+ "Supported values are: #{Ext::VALID_RESOURCE_PATTERNS.join(' | ')}. " \
60
+ "Using default value: #{Ext::DEFAULT_RESOURCE_PATTERN}."
61
+ )
62
+
63
+ Ext::DEFAULT_RESOURCE_PATTERN
64
+ end
65
+ end
49
66
  end
50
67
  end
51
68
  end
@@ -13,6 +13,15 @@ module Datadog
13
13
  # @!visibility private
14
14
  ENV_ANALYTICS_ENABLED = 'DD_TRACE_OPENSEARCH_ANALYTICS_ENABLED'
15
15
  ENV_ANALYTICS_SAMPLE_RATE = 'DD_TRACE_OPENSEARCH_ANALYTICS_SAMPLE_RATE'
16
+ ENV_RESOURCE_PATTERN = 'DD_TRACE_OPENSEARCH_RESOURCE_PATTERN'
17
+ ABSOLUTE_RESOURCE_PATTERN = 'absolute'
18
+ RELATIVE_RESOURCE_PATTERN = 'relative'
19
+ VALID_RESOURCE_PATTERNS = [
20
+ ABSOLUTE_RESOURCE_PATTERN,
21
+ RELATIVE_RESOURCE_PATTERN
22
+ ].freeze
23
+ # Default should be changed to RELATIVE in 3.0 to match the Elasticsearch integration
24
+ DEFAULT_RESOURCE_PATTERN = ABSOLUTE_RESOURCE_PATTERN
16
25
  DEFAULT_PEER_SERVICE_NAME = 'opensearch'
17
26
  SPAN_QUERY = 'opensearch.query'
18
27
  SPAN_TYPE_QUERY = 'opensearch'
@@ -77,7 +77,11 @@ module Datadog
77
77
  span.set_tag(Tracing::Metadata::Ext::TAG_PEER_HOSTNAME, host) if host
78
78
 
79
79
  # Define span resource
80
- quantized_url = OpenSearch::Quantize.format_url(url)
80
+ quantized_url = if datadog_configuration[:resource_pattern] == Ext::RELATIVE_RESOURCE_PATTERN
81
+ OpenSearch::Quantize.format_url(url.path)
82
+ else # Default to Ext::ABSOLUTE_RESOURCE_PATTERN
83
+ OpenSearch::Quantize.format_url(url)
84
+ end
81
85
  span.resource = "#{method} #{quantized_url}"
82
86
  Contrib::SpanAttributeSchema.set_peer_service!(span, Ext::PEER_SERVICE_SOURCES)
83
87
  rescue StandardError => e
@@ -20,8 +20,11 @@ module Datadog
20
20
  # @public_api
21
21
  module CommonMethods
22
22
  attr_accessor \
23
- :patch_error_result,
24
- :patch_successful
23
+ :patch_error_result
24
+
25
+ def patch_successful
26
+ !!@patch_successful
27
+ end
25
28
 
26
29
  def patch_name
27
30
  self.class != Class && self.class != Module ? self.class.name : name
@@ -17,7 +17,7 @@ module Datadog
17
17
 
18
18
  module_function
19
19
 
20
- def get_request_start(env, now = Time.now.utc)
20
+ def get_request_start(env, now = Core::Utils::Time.now.utc)
21
21
  header = env[REQUEST_START] || env[QUEUE_START]
22
22
  return unless header
23
23
 
@@ -25,10 +25,12 @@ module Datadog
25
25
  return super(&block) unless Tracing.enabled?
26
26
 
27
27
  datadog_trace_request(uri) do |_span, trace|
28
- if Datadog::AppSec::Utils::TraceOperation.appsec_standalone_reject?(trace)
29
- trace.sampling_priority = Tracing::Sampling::Ext::Priority::AUTO_REJECT
28
+ if Tracing::Distributed::PropagationPolicy.enabled?(
29
+ global_config: datadog_configuration,
30
+ trace: trace
31
+ )
32
+ Contrib::HTTP.inject(trace, processed_headers)
30
33
  end
31
- Contrib::HTTP.inject(trace, processed_headers) if datadog_configuration[:distributed_tracing]
32
34
 
33
35
  super(&block)
34
36
  end
@@ -24,7 +24,12 @@ module Datadog
24
24
  resource = job_resource(job)
25
25
 
26
26
  Datadog::Tracing.trace(Ext::SPAN_PUSH, service: @sidekiq_service) do |span, trace_op|
27
- Sidekiq.inject(trace_op, job) if configuration[:distributed_tracing]
27
+ if Tracing::Distributed::PropagationPolicy.enabled?(
28
+ global_config: configuration,
29
+ trace: trace_op
30
+ )
31
+ Sidekiq.inject(trace_op, job)
32
+ end
28
33
 
29
34
  span.resource = resource
30
35
 
@@ -2,6 +2,7 @@
2
2
 
3
3
  require_relative '../../../distributed/fetcher'
4
4
  require_relative '../../../distributed/propagation'
5
+ require_relative '../../../distributed/propagation_policy'
5
6
  require_relative '../../../distributed/b3_multi'
6
7
  require_relative '../../../distributed/b3_single'
7
8
  require_relative '../../../distributed/datadog'
@@ -31,6 +32,8 @@ module Datadog
31
32
  Tracing::Distributed::Datadog.new(fetcher: Tracing::Distributed::Fetcher),
32
33
  Tracing::Configuration::Ext::Distributed::PROPAGATION_STYLE_TRACE_CONTEXT =>
33
34
  Tracing::Distributed::TraceContext.new(fetcher: Tracing::Distributed::Fetcher),
35
+ Tracing::Configuration::Ext::Distributed::PROPAGATION_STYLE_BAGGAGE =>
36
+ Tracing::Distributed::Baggage.new(fetcher: Tracing::Distributed::Fetcher),
34
37
  Tracing::Configuration::Ext::Distributed::PROPAGATION_STYLE_NONE => Tracing::Distributed::None.new
35
38
  },
36
39
  propagation_style_inject: propagation_style_inject,
@@ -61,7 +61,7 @@ module Datadog
61
61
  span.set_tag(Ext::TAG_JOB_RETRY_COUNT, job['retry_count'])
62
62
  span.set_tag(Ext::TAG_JOB_QUEUE, job['queue'])
63
63
  span.set_tag(Ext::TAG_JOB_WRAPPER, job['class']) if job['wrapped']
64
- span.set_tag(Ext::TAG_JOB_DELAY, 1000.0 * (Time.now.utc.to_f - job['enqueued_at'].to_f))
64
+ span.set_tag(Ext::TAG_JOB_DELAY, 1000.0 * (Core::Utils::Time.now.utc.to_f - job['enqueued_at'].to_f))
65
65
 
66
66
  args = job['args']
67
67
  if args && !args.empty?
@@ -0,0 +1,28 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Datadog
4
+ module Tracing
5
+ module Contrib
6
+ # Miscellaneous support methods to aid in the creation of integrations.
7
+ module Support
8
+ module_function
9
+
10
+ # Checks if a constant is loaded in a module, handling autoloaded constants correctly.
11
+ #
12
+ # This method is particularly useful when you need to check if a constant is fully loaded,
13
+ # not just defined. It handles the special case of autoloaded constants, which return
14
+ # non-nil for `defined?` even when they haven't been loaded yet.
15
+ #
16
+ # @param base_module [Module] the module to check for the constant
17
+ # @param constant [Symbol] the name of the constant to check
18
+ # @return [Boolean] true if the constant has been loaded, false otherwise
19
+ def fully_loaded?(base_module, constant)
20
+ # Autoload constants return `constant` for `defined?`, but that doesn't mean they are loaded...
21
+ base_module.const_defined?(constant) &&
22
+ # ... to check that we need to call `autoload?`. If it returns `nil`, it's loaded.
23
+ base_module.autoload?(constant).nil?
24
+ end
25
+ end
26
+ end
27
+ end
28
+ end
@@ -55,6 +55,7 @@ require_relative 'contrib/httpclient/integration'
55
55
  require_relative 'contrib/httprb/integration'
56
56
  require_relative 'contrib/integration'
57
57
  require_relative 'contrib/kafka/integration'
58
+ require_relative 'contrib/karafka'
58
59
  require_relative 'contrib/lograge/integration'
59
60
  require_relative 'contrib/mongodb/integration'
60
61
  require_relative 'contrib/mysql2/integration'
@@ -94,8 +94,15 @@ module Datadog
94
94
  end
95
95
 
96
96
  def format_trace_id(trace_id)
97
- if Datadog.configuration.tracing.trace_id_128_bit_logging_enabled &&
98
- !Tracing::Utils::TraceId.to_high_order(trace_id).zero?
97
+ if Datadog.configuration.tracing.trace_id_128_bit_logging_enabled
98
+ format_trace_id_128(trace_id)
99
+ else
100
+ Tracing::Utils::TraceId.to_low_order(trace_id).to_s
101
+ end
102
+ end
103
+
104
+ def format_trace_id_128(trace_id)
105
+ if !Tracing::Utils::TraceId.to_high_order(trace_id).zero?
99
106
  Kernel.format('%032x', trace_id)
100
107
  else
101
108
  Tracing::Utils::TraceId.to_low_order(trace_id).to_s
@@ -55,7 +55,7 @@ module Datadog
55
55
  span_id = Helpers.parse_hex_id(fetcher[@span_id_key])
56
56
 
57
57
  # Return early if this propagation is not valid
58
- return if span_id.nil? || span_id <= 0 || span_id >= Tracing::Utils::EXTERNAL_MAX_ID
58
+ return if span_id.nil? || span_id <= 0 || span_id > Tracing::Utils::EXTERNAL_MAX_ID
59
59
 
60
60
  # We don't need to try and convert sampled since B3 supports 0/1 (AUTO_REJECT/AUTO_KEEP)
61
61
  sampling_priority = Helpers.parse_decimal_id(fetcher[@sampled_key])
@@ -54,7 +54,7 @@ module Datadog
54
54
 
55
55
  span_id = Helpers.parse_hex_id(parts[1]) if parts.length > 1
56
56
  # Return early if this propagation is not valid
57
- return if span_id.nil? || span_id <= 0 || span_id >= Tracing::Utils::EXTERNAL_MAX_ID
57
+ return if span_id.nil? || span_id <= 0 || span_id > Tracing::Utils::EXTERNAL_MAX_ID
58
58
 
59
59
  sampling_priority = Helpers.parse_decimal_id(parts[2]) if parts.length > 2
60
60
 
@@ -0,0 +1,131 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative '../metadata/ext'
4
+ require_relative '../trace_digest'
5
+ require_relative 'datadog_tags_codec'
6
+ require_relative '../utils'
7
+ require_relative 'helpers'
8
+ require 'uri'
9
+
10
+ module Datadog
11
+ module Tracing
12
+ module Distributed
13
+ # W3C Baggage propagator implementation.
14
+ # The baggage header is propagated through `baggage`.
15
+ # @see https://www.w3.org/TR/baggage/
16
+ class Baggage
17
+ BAGGAGE_KEY = 'baggage'
18
+ DD_TRACE_BAGGAGE_MAX_ITEMS = 64
19
+ DD_TRACE_BAGGAGE_MAX_BYTES = 8192
20
+ SAFE_CHARACTERS_KEY = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789$!#&'*+-.^_`|~"
21
+ SAFE_CHARACTERS_VALUE = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789$!#&'()*+-./:<>?@[]^_`{|}~"
22
+
23
+ def initialize(
24
+ fetcher:,
25
+ baggage_key: BAGGAGE_KEY
26
+ )
27
+ @baggage_key = baggage_key
28
+ @fetcher = fetcher
29
+ end
30
+
31
+ def inject!(digest, data)
32
+ return if digest.nil? || digest.baggage.nil?
33
+
34
+ baggage_items = digest.baggage.reject { |k, v| k.nil? || v.nil? }
35
+ return if baggage_items.empty?
36
+
37
+ begin
38
+ if baggage_items.size > DD_TRACE_BAGGAGE_MAX_ITEMS
39
+ ::Datadog.logger.warn('Baggage item limit exceeded, dropping excess items')
40
+ baggage_items = baggage_items.first(DD_TRACE_BAGGAGE_MAX_ITEMS)
41
+ end
42
+
43
+ encoded_items = []
44
+ total_size = 0
45
+
46
+ baggage_items.each do |key, value|
47
+ item = "#{encode_item(key, SAFE_CHARACTERS_KEY)}=#{encode_item(value, SAFE_CHARACTERS_VALUE)}"
48
+ item_size = item.bytesize + (encoded_items.empty? ? 0 : 1) # +1 for comma if not first item
49
+ if total_size + item_size > DD_TRACE_BAGGAGE_MAX_BYTES
50
+ ::Datadog.logger.warn('Baggage header size exceeded, dropping excess items')
51
+ break # stop adding items when size limit is reached
52
+ end
53
+ encoded_items << item
54
+ total_size += item_size
55
+ end
56
+
57
+ # edge case where a single item is too large
58
+ return if encoded_items.empty?
59
+
60
+ header_value = encoded_items.join(',')
61
+ data[@baggage_key] = header_value
62
+ rescue => e
63
+ ::Datadog.logger.warn("Failed to encode and inject baggage header: #{e.message}")
64
+ end
65
+ end
66
+
67
+ def extract(data)
68
+ fetcher = @fetcher.new(data)
69
+ data = fetcher[@baggage_key]
70
+ return unless data
71
+
72
+ baggage = parse_baggage_header(fetcher[@baggage_key])
73
+ return unless baggage
74
+
75
+ TraceDigest.new(
76
+ baggage: baggage,
77
+ )
78
+ end
79
+
80
+ private
81
+
82
+ def encode_item(item, safe_characters)
83
+ # Strip whitespace and URL-encode the item
84
+ result = URI.encode_www_form_component(item.strip)
85
+ # Replace '+' with '%20' for space encoding consistency with W3C spec
86
+ result = result.gsub('+', '%20')
87
+ # Selectively decode percent-encoded characters that are considered "safe" in W3C Baggage spec
88
+ result.gsub(/%[0-9A-F]{2}/) do |encoded|
89
+ if encoded.size >= 3 && encoded[1..2] =~ /\A[0-9A-F]{2}\z/
90
+ hex_str = encoded[1..2]
91
+ next encoded unless hex_str && !hex_str.empty?
92
+
93
+ # Convert hex representation back to character
94
+ char = [hex_str.hex].pack('C')
95
+ # Keep the character as-is if it's in the safe character set, otherwise keep it encoded
96
+ safe_characters.include?(char) ? char : encoded
97
+ else
98
+ encoded
99
+ end
100
+ end
101
+ end
102
+
103
+ # Parses a W3C Baggage header string into a hash of key-value pairs
104
+ # The header format follows the W3C Baggage specification:
105
+ # - Multiple baggage items are separated by commas
106
+ # - Each baggage item is a key-value pair separated by '='
107
+ # - Keys and values are URL-encoded
108
+ # - Returns an empty hash if the baggage header is malformed
109
+ #
110
+ # @param baggage_header [String] The W3C Baggage header string to parse
111
+ # @return [Hash<String, String>] A hash of decoded baggage items
112
+ def parse_baggage_header(baggage_header)
113
+ baggage = {}
114
+ baggages = baggage_header.split(',')
115
+ baggages.each do |key_value|
116
+ key, value = key_value.split('=', 2)
117
+ # If baggage is malformed, return an empty hash
118
+ return {} unless key && value
119
+
120
+ key = URI.decode_www_form_component(key.strip)
121
+ value = URI.decode_www_form_component(value.strip)
122
+ return {} if key.empty? || value.empty?
123
+
124
+ baggage[key] = value
125
+ end
126
+ baggage
127
+ end
128
+ end
129
+ end
130
+ end
131
+ end
@@ -89,7 +89,7 @@ module Datadog
89
89
  trace_id = Helpers.parse_decimal_id(fetcher_object[@trace_id_key])
90
90
 
91
91
  return unless trace_id
92
- return if trace_id <= 0 || trace_id >= Tracing::Utils::EXTERNAL_MAX_ID
92
+ return if trace_id <= 0 || trace_id > Tracing::Utils::EXTERNAL_MAX_ID
93
93
 
94
94
  trace_id
95
95
  end
@@ -98,7 +98,7 @@ module Datadog
98
98
  parent_id = Helpers.parse_decimal_id(fetcher_object[@parent_id_key])
99
99
 
100
100
  return unless parent_id
101
- return if parent_id <= 0 || parent_id >= Tracing::Utils::EXTERNAL_MAX_ID
101
+ return if parent_id <= 0 || parent_id > Tracing::Utils::EXTERNAL_MAX_ID
102
102
 
103
103
  parent_id
104
104
  end
@@ -116,6 +116,8 @@ module Datadog
116
116
  def extract_trace_id!(trace_id, tags)
117
117
  return trace_id unless tags
118
118
  return trace_id unless (high_order = tags.delete(Tracing::Metadata::Ext::Distributed::TAG_TID))
119
+ return trace_id unless high_order.size == 16
120
+ return trace_id unless /\A[0-9a-f]+\z/i.match?(high_order)
119
121
 
120
122
  Tracing::Utils::TraceId.concatenate(high_order.to_i(16), trace_id)
121
123
  end
@@ -4,6 +4,7 @@ require_relative '../configuration/ext'
4
4
  require_relative '../trace_digest'
5
5
  require_relative '../trace_operation'
6
6
  require_relative '../../core/telemetry/logger'
7
+ require_relative 'baggage'
7
8
 
8
9
  module Datadog
9
10
  module Tracing
@@ -26,9 +27,13 @@ module Datadog
26
27
  )
27
28
  @propagation_styles = propagation_styles
28
29
  @propagation_extract_first = propagation_extract_first
29
-
30
30
  @propagation_style_inject = propagation_style_inject.map { |style| propagation_styles[style] }
31
31
  @propagation_style_extract = propagation_style_extract.map { |style| propagation_styles[style] }
32
+
33
+ # The baggage propagator is unique in that baggage should always be extracted, if present.
34
+ # Therefore we remove it from the `propagation_style_extract` list.
35
+ @baggage_propagator = @propagation_style_extract.find { |propagator| propagator.is_a?(Baggage) }
36
+ @propagation_style_extract.delete(@baggage_propagator) if @baggage_propagator
32
37
  end
33
38
 
34
39
  # inject! populates the env with span ID, trace ID and sampling priority
@@ -57,9 +62,8 @@ module Datadog
57
62
  end
58
63
 
59
64
  digest = digest.to_digest if digest.respond_to?(:to_digest)
60
-
61
- if digest.trace_id.nil?
62
- ::Datadog.logger.debug('Cannot inject distributed trace data: digest.trace_id is nil.')
65
+ if digest.trace_id.nil? && digest.baggage.nil?
66
+ ::Datadog.logger.debug('Cannot inject distributed trace data: digest.trace_id and digest.baggage are both nil.')
63
67
  return nil
64
68
  end
65
69
 
@@ -138,12 +142,29 @@ module Datadog
138
142
  "Error extracting distributed trace data. Cause: #{e} Location: #{Array(e.backtrace).first}"
139
143
  )
140
144
  end
145
+ # Handle baggage after all other styles if present
146
+ extracted_trace_digest = propagate_baggage(data, extracted_trace_digest) if @baggage_propagator
141
147
 
142
148
  extracted_trace_digest
143
149
  end
144
150
 
145
151
  private
146
152
 
153
+ def propagate_baggage(data, extracted_trace_digest)
154
+ if extracted_trace_digest
155
+ # Merge with baggage if present
156
+ digest = @baggage_propagator.extract(data)
157
+ if digest
158
+ extracted_trace_digest.merge(baggage: digest.baggage)
159
+ else
160
+ extracted_trace_digest
161
+ end
162
+ else
163
+ # Baggage is the only style
164
+ @baggage_propagator.extract(data)
165
+ end
166
+ end
167
+
147
168
  def last_datadog_parent_id(headers, tracecontext_tags)
148
169
  dd_propagator = @propagation_style_extract.find { |propagator| propagator.is_a?(Datadog) }
149
170
  if tracecontext_tags&.fetch(
@@ -0,0 +1,42 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Datadog
4
+ module Tracing
5
+ module Distributed
6
+ # Helper method to decide when to skip distributed tracing
7
+ module PropagationPolicy
8
+ module_function
9
+
10
+ # Skips distributed tracing if disabled for this instrumentation
11
+ # or if APM is disabled unless there is an AppSec event (from upstream distributed trace or local)
12
+ #
13
+ # Both pin_config and global_config are configuration for integrations.
14
+ # pin_config is a Datadog::Core::Pin object, which gives the configuration of a single instance of an integration.
15
+ # global_config is the config for all instances of an integration.
16
+ def enabled?(pin_config: nil, global_config: nil, trace: nil)
17
+ return false unless Tracing.enabled?
18
+
19
+ unless ::Datadog.configuration.apm.tracing.enabled
20
+ return false if trace.nil?
21
+
22
+ trace_source = trace.get_tag(::Datadog::Tracing::Metadata::Ext::Distributed::TAG_TRACE_SOURCE)&.to_i(16)
23
+ return false if trace_source.nil?
24
+
25
+ # If AppSec is enabled and AppSec bit is set in the trace, we should not skip distributed tracing
26
+ # Other products that will use dd.p.ts should implement similar behavior here
27
+ if ::Datadog.configuration.appsec.enabled && (trace_source & ::Datadog::AppSec::Ext::PRODUCT_BIT) != 0
28
+ return true
29
+ end
30
+
31
+ return false
32
+ end
33
+
34
+ return pin_config[:distributed_tracing] if pin_config && pin_config.key?(:distributed_tracing)
35
+ return global_config[:distributed_tracing] if global_config
36
+
37
+ true
38
+ end
39
+ end
40
+ end
41
+ end
42
+ end