datadog 2.12.1 → 2.19.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 (346) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +243 -2
  3. data/ext/datadog_profiling_native_extension/collectors_cpu_and_wall_time_worker.c +63 -56
  4. data/ext/datadog_profiling_native_extension/collectors_stack.c +263 -76
  5. data/ext/datadog_profiling_native_extension/collectors_stack.h +20 -3
  6. data/ext/datadog_profiling_native_extension/collectors_thread_context.c +78 -26
  7. data/ext/datadog_profiling_native_extension/collectors_thread_context.h +1 -0
  8. data/ext/datadog_profiling_native_extension/datadog_ruby_common.c +1 -4
  9. data/ext/datadog_profiling_native_extension/datadog_ruby_common.h +10 -0
  10. data/ext/datadog_profiling_native_extension/encoded_profile.c +79 -0
  11. data/ext/datadog_profiling_native_extension/encoded_profile.h +8 -0
  12. data/ext/datadog_profiling_native_extension/extconf.rb +10 -0
  13. data/ext/datadog_profiling_native_extension/heap_recorder.c +247 -364
  14. data/ext/datadog_profiling_native_extension/heap_recorder.h +4 -6
  15. data/ext/datadog_profiling_native_extension/http_transport.c +60 -94
  16. data/ext/datadog_profiling_native_extension/libdatadog_helpers.c +22 -0
  17. data/ext/datadog_profiling_native_extension/libdatadog_helpers.h +8 -5
  18. data/ext/datadog_profiling_native_extension/private_vm_api_access.c +41 -21
  19. data/ext/datadog_profiling_native_extension/private_vm_api_access.h +6 -4
  20. data/ext/datadog_profiling_native_extension/profiling.c +2 -0
  21. data/ext/datadog_profiling_native_extension/ruby_helpers.c +1 -13
  22. data/ext/datadog_profiling_native_extension/ruby_helpers.h +3 -11
  23. data/ext/datadog_profiling_native_extension/stack_recorder.c +173 -76
  24. data/ext/libdatadog_api/crashtracker.c +11 -12
  25. data/ext/libdatadog_api/crashtracker.h +5 -0
  26. data/ext/libdatadog_api/datadog_ruby_common.c +1 -4
  27. data/ext/libdatadog_api/datadog_ruby_common.h +10 -0
  28. data/ext/libdatadog_api/extconf.rb +2 -2
  29. data/ext/libdatadog_api/init.c +15 -0
  30. data/ext/libdatadog_api/library_config.c +164 -0
  31. data/ext/libdatadog_api/library_config.h +25 -0
  32. data/ext/libdatadog_api/macos_development.md +3 -3
  33. data/ext/libdatadog_api/process_discovery.c +112 -0
  34. data/ext/libdatadog_api/process_discovery.h +5 -0
  35. data/ext/libdatadog_extconf_helpers.rb +2 -2
  36. data/lib/datadog/appsec/actions_handler/serializable_backtrace.rb +89 -0
  37. data/lib/datadog/appsec/actions_handler.rb +24 -2
  38. data/lib/datadog/appsec/anonymizer.rb +16 -0
  39. data/lib/datadog/appsec/api_security/lru_cache.rb +56 -0
  40. data/lib/datadog/appsec/api_security/route_extractor.rb +71 -0
  41. data/lib/datadog/appsec/api_security/sampler.rb +59 -0
  42. data/lib/datadog/appsec/api_security.rb +23 -0
  43. data/lib/datadog/appsec/assets/waf_rules/README.md +50 -5
  44. data/lib/datadog/appsec/assets/waf_rules/recommended.json +257 -85
  45. data/lib/datadog/appsec/assets/waf_rules/strict.json +10 -78
  46. data/lib/datadog/appsec/autoload.rb +1 -1
  47. data/lib/datadog/appsec/component.rb +46 -61
  48. data/lib/datadog/appsec/compressed_json.rb +40 -0
  49. data/lib/datadog/appsec/configuration/settings.rb +153 -30
  50. data/lib/datadog/appsec/context.rb +7 -7
  51. data/lib/datadog/appsec/contrib/active_record/instrumentation.rb +10 -12
  52. data/lib/datadog/appsec/contrib/active_record/integration.rb +2 -2
  53. data/lib/datadog/appsec/contrib/active_record/patcher.rb +22 -22
  54. data/lib/datadog/appsec/contrib/auto_instrument.rb +1 -1
  55. data/lib/datadog/appsec/contrib/devise/configuration.rb +7 -31
  56. data/lib/datadog/appsec/contrib/devise/data_extractor.rb +78 -0
  57. data/lib/datadog/appsec/contrib/devise/ext.rb +22 -0
  58. data/lib/datadog/appsec/contrib/devise/integration.rb +1 -2
  59. data/lib/datadog/appsec/contrib/devise/patcher.rb +34 -23
  60. data/lib/datadog/appsec/contrib/devise/patches/signin_tracking_patch.rb +102 -0
  61. data/lib/datadog/appsec/contrib/devise/patches/signup_tracking_patch.rb +69 -0
  62. data/lib/datadog/appsec/contrib/devise/{patcher/rememberable_patch.rb → patches/skip_signin_tracking_patch.rb} +2 -2
  63. data/lib/datadog/appsec/contrib/devise/tracking_middleware.rb +106 -0
  64. data/lib/datadog/appsec/contrib/excon/integration.rb +1 -1
  65. data/lib/datadog/appsec/contrib/excon/ssrf_detection_middleware.rb +9 -10
  66. data/lib/datadog/appsec/contrib/faraday/integration.rb +1 -1
  67. data/lib/datadog/appsec/contrib/faraday/ssrf_detection_middleware.rb +8 -9
  68. data/lib/datadog/appsec/contrib/graphql/gateway/watcher.rb +8 -9
  69. data/lib/datadog/appsec/contrib/graphql/integration.rb +1 -1
  70. data/lib/datadog/appsec/contrib/rack/ext.rb +34 -0
  71. data/lib/datadog/appsec/contrib/rack/gateway/watcher.rb +49 -32
  72. data/lib/datadog/appsec/contrib/rack/integration.rb +1 -1
  73. data/lib/datadog/appsec/contrib/rack/request_middleware.rb +42 -30
  74. data/lib/datadog/appsec/contrib/rails/gateway/watcher.rb +11 -13
  75. data/lib/datadog/appsec/contrib/rails/integration.rb +1 -1
  76. data/lib/datadog/appsec/contrib/rails/patcher.rb +21 -21
  77. data/lib/datadog/appsec/contrib/rest_client/integration.rb +1 -1
  78. data/lib/datadog/appsec/contrib/rest_client/request_ssrf_detection_patch.rb +10 -11
  79. data/lib/datadog/appsec/contrib/sinatra/gateway/watcher.rb +17 -23
  80. data/lib/datadog/appsec/contrib/sinatra/integration.rb +1 -1
  81. data/lib/datadog/appsec/event.rb +96 -135
  82. data/lib/datadog/appsec/ext.rb +4 -2
  83. data/lib/datadog/appsec/instrumentation/gateway/argument.rb +7 -2
  84. data/lib/datadog/appsec/instrumentation/gateway/middleware.rb +24 -0
  85. data/lib/datadog/appsec/instrumentation/gateway.rb +17 -22
  86. data/lib/datadog/appsec/metrics/telemetry.rb +1 -1
  87. data/lib/datadog/appsec/monitor/gateway/watcher.rb +49 -14
  88. data/lib/datadog/appsec/processor/rule_loader.rb +30 -33
  89. data/lib/datadog/appsec/remote.rb +31 -59
  90. data/lib/datadog/appsec/response.rb +6 -6
  91. data/lib/datadog/appsec/security_engine/engine.rb +194 -0
  92. data/lib/datadog/appsec/security_engine/runner.rb +13 -14
  93. data/lib/datadog/appsec/security_event.rb +39 -0
  94. data/lib/datadog/appsec/utils.rb +0 -2
  95. data/lib/datadog/appsec.rb +5 -8
  96. data/lib/datadog/core/buffer/random.rb +18 -2
  97. data/lib/datadog/core/configuration/agent_settings.rb +52 -0
  98. data/lib/datadog/core/configuration/agent_settings_resolver.rb +4 -46
  99. data/lib/datadog/core/configuration/agentless_settings_resolver.rb +176 -0
  100. data/lib/datadog/core/configuration/components.rb +48 -31
  101. data/lib/datadog/core/configuration/components_state.rb +23 -0
  102. data/lib/datadog/core/configuration/ext.rb +4 -0
  103. data/lib/datadog/core/configuration/option.rb +81 -45
  104. data/lib/datadog/core/configuration/option_definition.rb +4 -4
  105. data/lib/datadog/core/configuration/options.rb +3 -3
  106. data/lib/datadog/core/configuration/settings.rb +109 -44
  107. data/lib/datadog/core/configuration/stable_config.rb +22 -0
  108. data/lib/datadog/core/configuration.rb +40 -16
  109. data/lib/datadog/core/crashtracking/component.rb +3 -10
  110. data/lib/datadog/core/crashtracking/tag_builder.rb +4 -22
  111. data/lib/datadog/core/diagnostics/environment_logger.rb +1 -1
  112. data/lib/datadog/core/encoding.rb +1 -1
  113. data/lib/datadog/core/environment/agent_info.rb +4 -3
  114. data/lib/datadog/core/environment/cgroup.rb +10 -12
  115. data/lib/datadog/core/environment/container.rb +38 -40
  116. data/lib/datadog/core/environment/ext.rb +6 -6
  117. data/lib/datadog/core/environment/git.rb +1 -0
  118. data/lib/datadog/core/environment/identity.rb +3 -3
  119. data/lib/datadog/core/environment/platform.rb +3 -3
  120. data/lib/datadog/core/environment/variable_helpers.rb +1 -1
  121. data/lib/datadog/core/error.rb +11 -9
  122. data/lib/datadog/core/logger.rb +2 -2
  123. data/lib/datadog/core/metrics/client.rb +20 -21
  124. data/lib/datadog/core/metrics/logging.rb +5 -5
  125. data/lib/datadog/core/process_discovery/tracer_memfd.rb +15 -0
  126. data/lib/datadog/core/process_discovery.rb +36 -0
  127. data/lib/datadog/core/rate_limiter.rb +4 -2
  128. data/lib/datadog/core/remote/client.rb +40 -32
  129. data/lib/datadog/core/remote/component.rb +6 -9
  130. data/lib/datadog/core/remote/configuration/digest.rb +7 -7
  131. data/lib/datadog/core/remote/configuration/path.rb +1 -1
  132. data/lib/datadog/core/remote/configuration/repository.rb +14 -1
  133. data/lib/datadog/core/remote/negotiation.rb +9 -9
  134. data/lib/datadog/core/remote/transport/config.rb +4 -3
  135. data/lib/datadog/core/remote/transport/http/client.rb +5 -4
  136. data/lib/datadog/core/remote/transport/http/config.rb +27 -37
  137. data/lib/datadog/core/remote/transport/http/negotiation.rb +7 -33
  138. data/lib/datadog/core/remote/transport/http.rb +22 -57
  139. data/lib/datadog/core/remote/transport/negotiation.rb +4 -3
  140. data/lib/datadog/core/runtime/metrics.rb +12 -5
  141. data/lib/datadog/core/tag_builder.rb +56 -0
  142. data/lib/datadog/core/telemetry/component.rb +81 -52
  143. data/lib/datadog/core/telemetry/emitter.rb +23 -11
  144. data/lib/datadog/core/telemetry/event/app_client_configuration_change.rb +66 -0
  145. data/lib/datadog/core/telemetry/event/app_closing.rb +18 -0
  146. data/lib/datadog/core/telemetry/event/app_dependencies_loaded.rb +33 -0
  147. data/lib/datadog/core/telemetry/event/app_heartbeat.rb +18 -0
  148. data/lib/datadog/core/telemetry/event/app_integrations_change.rb +58 -0
  149. data/lib/datadog/core/telemetry/event/app_started.rb +287 -0
  150. data/lib/datadog/core/telemetry/event/base.rb +40 -0
  151. data/lib/datadog/core/telemetry/event/distributions.rb +18 -0
  152. data/lib/datadog/core/telemetry/event/generate_metrics.rb +43 -0
  153. data/lib/datadog/core/telemetry/event/log.rb +76 -0
  154. data/lib/datadog/core/telemetry/event/message_batch.rb +42 -0
  155. data/lib/datadog/core/telemetry/event/synth_app_client_configuration_change.rb +43 -0
  156. data/lib/datadog/core/telemetry/event.rb +17 -472
  157. data/lib/datadog/core/telemetry/http/adapters/net.rb +12 -97
  158. data/lib/datadog/core/telemetry/logger.rb +5 -4
  159. data/lib/datadog/core/telemetry/logging.rb +11 -5
  160. data/lib/datadog/core/telemetry/metric.rb +8 -8
  161. data/lib/datadog/core/telemetry/request.rb +4 -4
  162. data/lib/datadog/core/telemetry/transport/http/api.rb +43 -0
  163. data/lib/datadog/core/telemetry/transport/http/client.rb +49 -0
  164. data/lib/datadog/core/telemetry/transport/http/telemetry.rb +92 -0
  165. data/lib/datadog/core/telemetry/transport/http.rb +63 -0
  166. data/lib/datadog/core/telemetry/transport/telemetry.rb +51 -0
  167. data/lib/datadog/core/telemetry/worker.rb +90 -24
  168. data/lib/datadog/core/transport/http/adapters/net.rb +17 -2
  169. data/lib/datadog/core/transport/http/adapters/test.rb +2 -1
  170. data/lib/datadog/core/transport/http/api/instance.rb +17 -0
  171. data/lib/datadog/core/transport/http/api/spec.rb +17 -0
  172. data/lib/datadog/core/transport/http/builder.rb +19 -17
  173. data/lib/datadog/core/transport/http/env.rb +8 -0
  174. data/lib/datadog/core/transport/http.rb +39 -2
  175. data/lib/datadog/core/utils/at_fork_monkey_patch.rb +6 -6
  176. data/lib/datadog/core/utils/duration.rb +32 -32
  177. data/lib/datadog/core/utils/forking.rb +2 -2
  178. data/lib/datadog/core/utils/network.rb +6 -6
  179. data/lib/datadog/core/utils/only_once_successful.rb +16 -5
  180. data/lib/datadog/core/utils/time.rb +20 -0
  181. data/lib/datadog/core/utils/truncation.rb +21 -0
  182. data/lib/datadog/core/utils.rb +7 -0
  183. data/lib/datadog/core/vendor/multipart-post/multipart/post/composite_read_io.rb +1 -1
  184. data/lib/datadog/core/vendor/multipart-post/multipart/post/multipartable.rb +8 -8
  185. data/lib/datadog/core/vendor/multipart-post/multipart/post/parts.rb +7 -7
  186. data/lib/datadog/core/worker.rb +1 -1
  187. data/lib/datadog/core/workers/async.rb +29 -12
  188. data/lib/datadog/core/workers/interval_loop.rb +12 -1
  189. data/lib/datadog/core/workers/runtime_metrics.rb +2 -2
  190. data/lib/datadog/core.rb +8 -0
  191. data/lib/datadog/di/boot.rb +34 -0
  192. data/lib/datadog/di/component.rb +0 -2
  193. data/lib/datadog/di/instrumenter.rb +48 -5
  194. data/lib/datadog/di/probe_notification_builder.rb +38 -43
  195. data/lib/datadog/di/probe_notifier_worker.rb +25 -17
  196. data/lib/datadog/di/remote.rb +2 -0
  197. data/lib/datadog/di/serializer.rb +10 -2
  198. data/lib/datadog/di/transport/diagnostics.rb +4 -3
  199. data/lib/datadog/di/transport/http/api.rb +2 -12
  200. data/lib/datadog/di/transport/http/client.rb +4 -3
  201. data/lib/datadog/di/transport/http/diagnostics.rb +7 -34
  202. data/lib/datadog/di/transport/http/input.rb +18 -35
  203. data/lib/datadog/di/transport/http.rb +14 -62
  204. data/lib/datadog/di/transport/input.rb +14 -5
  205. data/lib/datadog/di/utils.rb +5 -0
  206. data/lib/datadog/di.rb +0 -33
  207. data/lib/datadog/error_tracking/collector.rb +87 -0
  208. data/lib/datadog/error_tracking/component.rb +167 -0
  209. data/lib/datadog/error_tracking/configuration/settings.rb +63 -0
  210. data/lib/datadog/error_tracking/configuration.rb +11 -0
  211. data/lib/datadog/error_tracking/ext.rb +18 -0
  212. data/lib/datadog/error_tracking/extensions.rb +16 -0
  213. data/lib/datadog/error_tracking/filters.rb +77 -0
  214. data/lib/datadog/error_tracking.rb +18 -0
  215. data/lib/datadog/kit/appsec/events/v2.rb +195 -0
  216. data/lib/datadog/kit/appsec/events.rb +12 -0
  217. data/lib/datadog/kit/identity.rb +5 -1
  218. data/lib/datadog/opentelemetry/api/baggage.rb +90 -0
  219. data/lib/datadog/opentelemetry/api/baggage.rbs +26 -0
  220. data/lib/datadog/opentelemetry/api/context.rb +16 -2
  221. data/lib/datadog/opentelemetry/sdk/trace/span.rb +1 -1
  222. data/lib/datadog/opentelemetry.rb +2 -1
  223. data/lib/datadog/profiling/collectors/code_provenance.rb +18 -9
  224. data/lib/datadog/profiling/collectors/cpu_and_wall_time_worker.rb +6 -0
  225. data/lib/datadog/profiling/collectors/idle_sampling_helper.rb +1 -0
  226. data/lib/datadog/profiling/collectors/info.rb +44 -0
  227. data/lib/datadog/profiling/collectors/thread_context.rb +17 -2
  228. data/lib/datadog/profiling/component.rb +8 -9
  229. data/lib/datadog/profiling/encoded_profile.rb +11 -0
  230. data/lib/datadog/profiling/exporter.rb +12 -7
  231. data/lib/datadog/profiling/ext.rb +0 -14
  232. data/lib/datadog/profiling/flush.rb +5 -8
  233. data/lib/datadog/profiling/http_transport.rb +7 -61
  234. data/lib/datadog/profiling/profiler.rb +2 -0
  235. data/lib/datadog/profiling/scheduler.rb +10 -2
  236. data/lib/datadog/profiling/sequence_tracker.rb +44 -0
  237. data/lib/datadog/profiling/stack_recorder.rb +9 -9
  238. data/lib/datadog/profiling/tag_builder.rb +7 -41
  239. data/lib/datadog/profiling/tasks/setup.rb +2 -0
  240. data/lib/datadog/profiling.rb +7 -2
  241. data/lib/datadog/single_step_instrument.rb +9 -0
  242. data/lib/datadog/tracing/analytics.rb +1 -1
  243. data/lib/datadog/tracing/component.rb +15 -12
  244. data/lib/datadog/tracing/configuration/ext.rb +7 -1
  245. data/lib/datadog/tracing/configuration/settings.rb +18 -2
  246. data/lib/datadog/tracing/context_provider.rb +1 -1
  247. data/lib/datadog/tracing/contrib/action_pack/action_controller/instrumentation.rb +15 -0
  248. data/lib/datadog/tracing/contrib/action_pack/action_dispatch/instrumentation.rb +19 -12
  249. data/lib/datadog/tracing/contrib/action_pack/ext.rb +2 -0
  250. data/lib/datadog/tracing/contrib/active_record/integration.rb +1 -1
  251. data/lib/datadog/tracing/contrib/active_support/cache/events/cache.rb +11 -2
  252. data/lib/datadog/tracing/contrib/active_support/cache/instrumentation.rb +33 -0
  253. data/lib/datadog/tracing/contrib/active_support/cache/patcher.rb +4 -0
  254. data/lib/datadog/tracing/contrib/active_support/cache/redis.rb +2 -4
  255. data/lib/datadog/tracing/contrib/active_support/configuration/settings.rb +13 -0
  256. data/lib/datadog/tracing/contrib/aws/instrumentation.rb +10 -0
  257. data/lib/datadog/tracing/contrib/aws/parsed_context.rb +5 -1
  258. data/lib/datadog/tracing/contrib/configuration/settings.rb +1 -1
  259. data/lib/datadog/tracing/contrib/ethon/easy_patch.rb +4 -5
  260. data/lib/datadog/tracing/contrib/excon/middleware.rb +5 -3
  261. data/lib/datadog/tracing/contrib/ext.rb +1 -0
  262. data/lib/datadog/tracing/contrib/faraday/middleware.rb +5 -3
  263. data/lib/datadog/tracing/contrib/grpc/datadog_interceptor/client.rb +7 -1
  264. data/lib/datadog/tracing/contrib/grpc/distributed/propagation.rb +3 -0
  265. data/lib/datadog/tracing/contrib/http/circuit_breaker.rb +0 -15
  266. data/lib/datadog/tracing/contrib/http/distributed/propagation.rb +4 -1
  267. data/lib/datadog/tracing/contrib/http/instrumentation.rb +6 -10
  268. data/lib/datadog/tracing/contrib/httpclient/instrumentation.rb +6 -16
  269. data/lib/datadog/tracing/contrib/httprb/instrumentation.rb +7 -15
  270. data/lib/datadog/tracing/contrib/karafka/configuration/settings.rb +27 -0
  271. data/lib/datadog/tracing/contrib/karafka/distributed/propagation.rb +48 -0
  272. data/lib/datadog/tracing/contrib/karafka/ext.rb +27 -0
  273. data/lib/datadog/tracing/contrib/karafka/integration.rb +45 -0
  274. data/lib/datadog/tracing/contrib/karafka/monitor.rb +66 -0
  275. data/lib/datadog/tracing/contrib/karafka/patcher.rb +71 -0
  276. data/lib/datadog/tracing/contrib/karafka.rb +37 -0
  277. data/lib/datadog/tracing/contrib/lograge/patcher.rb +4 -2
  278. data/lib/datadog/tracing/contrib/mongodb/configuration/settings.rb +8 -0
  279. data/lib/datadog/tracing/contrib/mongodb/ext.rb +1 -0
  280. data/lib/datadog/tracing/contrib/mongodb/subscribers.rb +18 -1
  281. data/lib/datadog/tracing/contrib/mysql2/instrumentation.rb +16 -6
  282. data/lib/datadog/tracing/contrib/opensearch/configuration/settings.rb +17 -0
  283. data/lib/datadog/tracing/contrib/opensearch/ext.rb +9 -0
  284. data/lib/datadog/tracing/contrib/opensearch/patcher.rb +5 -1
  285. data/lib/datadog/tracing/contrib/patcher.rb +5 -2
  286. data/lib/datadog/tracing/contrib/rack/request_queue.rb +1 -1
  287. data/lib/datadog/tracing/contrib/rails/patcher.rb +4 -1
  288. data/lib/datadog/tracing/contrib/rails/runner.rb +61 -40
  289. data/lib/datadog/tracing/contrib/rest_client/request_patch.rb +5 -3
  290. data/lib/datadog/tracing/contrib/sidekiq/client_tracer.rb +6 -1
  291. data/lib/datadog/tracing/contrib/sidekiq/distributed/propagation.rb +3 -0
  292. data/lib/datadog/tracing/contrib/sidekiq/ext.rb +1 -0
  293. data/lib/datadog/tracing/contrib/sidekiq/server_tracer.rb +5 -2
  294. data/lib/datadog/tracing/contrib/support.rb +28 -0
  295. data/lib/datadog/tracing/contrib.rb +1 -0
  296. data/lib/datadog/tracing/correlation.rb +9 -2
  297. data/lib/datadog/tracing/diagnostics/environment_logger.rb +3 -1
  298. data/lib/datadog/tracing/distributed/b3_multi.rb +1 -1
  299. data/lib/datadog/tracing/distributed/b3_single.rb +1 -1
  300. data/lib/datadog/tracing/distributed/baggage.rb +131 -0
  301. data/lib/datadog/tracing/distributed/datadog.rb +4 -2
  302. data/lib/datadog/tracing/distributed/propagation.rb +25 -4
  303. data/lib/datadog/tracing/distributed/propagation_policy.rb +42 -0
  304. data/lib/datadog/tracing/metadata/errors.rb +4 -4
  305. data/lib/datadog/tracing/metadata/ext.rb +5 -0
  306. data/lib/datadog/tracing/metadata/metastruct.rb +36 -0
  307. data/lib/datadog/tracing/metadata/metastruct_tagging.rb +42 -0
  308. data/lib/datadog/tracing/metadata.rb +2 -0
  309. data/lib/datadog/tracing/sampling/rate_sampler.rb +2 -1
  310. data/lib/datadog/tracing/sampling/span/rule.rb +0 -1
  311. data/lib/datadog/tracing/span.rb +10 -1
  312. data/lib/datadog/tracing/span_event.rb +2 -2
  313. data/lib/datadog/tracing/span_operation.rb +68 -16
  314. data/lib/datadog/tracing/sync_writer.rb +2 -3
  315. data/lib/datadog/tracing/trace_digest.rb +9 -2
  316. data/lib/datadog/tracing/trace_operation.rb +55 -27
  317. data/lib/datadog/tracing/trace_segment.rb +6 -4
  318. data/lib/datadog/tracing/tracer.rb +51 -7
  319. data/lib/datadog/tracing/transport/http/api.rb +2 -10
  320. data/lib/datadog/tracing/transport/http/client.rb +5 -4
  321. data/lib/datadog/tracing/transport/http/traces.rb +13 -41
  322. data/lib/datadog/tracing/transport/http.rb +11 -44
  323. data/lib/datadog/tracing/transport/serializable_trace.rb +3 -1
  324. data/lib/datadog/tracing/transport/trace_formatter.rb +7 -0
  325. data/lib/datadog/tracing/transport/traces.rb +26 -9
  326. data/lib/datadog/tracing/utils.rb +1 -1
  327. data/lib/datadog/tracing/workers/trace_writer.rb +2 -6
  328. data/lib/datadog/tracing/writer.rb +2 -6
  329. data/lib/datadog/tracing.rb +16 -3
  330. data/lib/datadog/version.rb +2 -2
  331. data/lib/datadog.rb +8 -2
  332. metadata +88 -23
  333. data/lib/datadog/appsec/assets/waf_rules/processors.json +0 -92
  334. data/lib/datadog/appsec/assets/waf_rules/scanners.json +0 -114
  335. data/lib/datadog/appsec/contrib/devise/event.rb +0 -54
  336. data/lib/datadog/appsec/contrib/devise/patcher/authenticatable_patch.rb +0 -72
  337. data/lib/datadog/appsec/contrib/devise/patcher/registration_controller_patch.rb +0 -47
  338. data/lib/datadog/appsec/contrib/devise/resource.rb +0 -35
  339. data/lib/datadog/appsec/contrib/devise/tracking.rb +0 -57
  340. data/lib/datadog/appsec/processor/rule_merger.rb +0 -170
  341. data/lib/datadog/appsec/processor.rb +0 -107
  342. data/lib/datadog/appsec/utils/trace_operation.rb +0 -15
  343. data/lib/datadog/core/telemetry/http/env.rb +0 -20
  344. data/lib/datadog/core/telemetry/http/ext.rb +0 -28
  345. data/lib/datadog/core/telemetry/http/response.rb +0 -70
  346. data/lib/datadog/core/telemetry/http/transport.rb +0 -90
@@ -10,34 +10,48 @@ module Datadog
10
10
  # * `-`: for code provided through the STDIN.
11
11
  # * File path: for code provided through a local file.
12
12
  # * `inline code`: for code provided directly as a command line argument.
13
+ #
14
+ # The difficulty in instrumenting the Rails Runner is that
15
+ # the Rails application (and as a consequence the Datadog tracing library)
16
+ # is loaded very late in the runner execution.
17
+ # The Rails application is loaded inside the same method the method
18
+ # that directly executes the code the user wants the runner to execute:
19
+ #
20
+ # ```ruby
21
+ # def perform(code_or_file = nil, *command_argv)
22
+ # boot_application! # Loads the Rails and Datadog
23
+ #
24
+ # if code_or_file == "-"
25
+ # eval($stdin.read, TOPLEVEL_BINDING, "stdin") # Calls the user code for this Runner
26
+ # # ...
27
+ # ```
28
+ #
29
+ # This means that there's no time to instrument the calling method, `perform`, which
30
+ # would be ideal. Instead, we resort to instrumenting `eval` and `load`, but
31
+ # only for calls from the `Rails::Command::RunnerCommand` class.
32
+ #
13
33
  # @see https://guides.rubyonrails.org/v6.1/command_line.html#bin-rails-runner
14
34
  module Runner
15
35
  # Limit the maximum size of the source code captured in the source tag.
16
36
  MAX_TAG_VALUE_SIZE = 4096
17
37
  private_constant :MAX_TAG_VALUE_SIZE
18
38
 
19
- def runner(code_or_file = nil, *_command_argv)
20
- if code_or_file == '-'
39
+ # Instruments the `Kernel.eval` method, but only for the
40
+ # `Rails::Command::RunnerCommand` class.
41
+ def eval(*args)
42
+ source = args[0]
43
+
44
+ if args[2] == 'stdin'
21
45
  name = Ext::SPAN_RUNNER_STDIN
22
- resource = nil
23
46
  operation = Ext::TAG_OPERATION_STDIN
24
- # The source is not yet available for STDIN, but it will be captured in `eval`.
25
- elsif File.exist?(code_or_file)
26
- name = Ext::SPAN_RUNNER_FILE
27
- resource = code_or_file
28
- operation = Ext::TAG_OPERATION_FILE
29
- source = File.read(code_or_file)
30
47
  else
31
48
  name = Ext::SPAN_RUNNER_INLINE
32
- resource = nil
33
49
  operation = Ext::TAG_OPERATION_INLINE
34
- source = code_or_file
35
50
  end
36
51
 
37
52
  Tracing.trace(
38
53
  name,
39
54
  service: Datadog.configuration.tracing[:rails][:service_name],
40
- resource: resource,
41
55
  tags: {
42
56
  Tracing::Metadata::Ext::TAG_COMPONENT => Ext::TAG_COMPONENT,
43
57
  Tracing::Metadata::Ext::TAG_OPERATION => operation,
@@ -55,39 +69,46 @@ module Datadog
55
69
  end
56
70
  end
57
71
 
58
- # Capture the executed source code when provided from STDIN.
59
- def eval(*args)
60
- span = Datadog::Tracing.active_span
61
- if span&.name == Ext::SPAN_RUNNER_STDIN
62
- source = args[0]
63
- span.set_tag(
64
- Ext::TAG_RUNNER_SOURCE,
65
- Core::Utils.truncate(source, MAX_TAG_VALUE_SIZE)
66
- )
67
- end
68
-
69
- super
72
+ def self.prepend(base)
73
+ base.const_set(:Kernel, Kernel)
70
74
  end
71
75
 
72
- ruby2_keywords :eval if respond_to?(:ruby2_keywords, true)
73
- end
76
+ # Instruments the `Kernel.load` method, but only for the
77
+ # `Rails::Command::RunnerCommand` class.
78
+ module Kernel
79
+ def self.load(file, wrap = true)
80
+ name = Ext::SPAN_RUNNER_FILE
81
+ resource = file
82
+ operation = Ext::TAG_OPERATION_FILE
83
+
84
+ begin
85
+ # Reads one more byte than the limit to allow us to check if the source exceeds the limit.
86
+ source = File.read(file, MAX_TAG_VALUE_SIZE + 1)
87
+ rescue => e
88
+ Datadog.logger.debug("Failed to read file '#{file}' for Rails runner: #{e.message}")
89
+ end
74
90
 
75
- # The instrumentation target, {Rails::Command::RunnerCommand} is only loaded
76
- # right before `bin/rails runner` is executed. This means there's not much
77
- # opportunity to patch it ahead of time.
78
- # To ensure we can patch it successfully, we patch it's caller, {Rails::Command}
79
- # and promptly patch {Rails::Command::RunnerCommand} when it is loaded.
80
- module Command
81
- def find_by_namespace(*args)
82
- ret = super
83
- # Patch RunnerCommand if it is loaded and not already patched.
84
- if defined?(::Rails::Command::RunnerCommand) && !(::Rails::Command::RunnerCommand < Runner)
85
- ::Rails::Command::RunnerCommand.prepend(Runner)
91
+ Tracing.trace(
92
+ name,
93
+ service: Datadog.configuration.tracing[:rails][:service_name],
94
+ resource: resource,
95
+ tags: {
96
+ Tracing::Metadata::Ext::TAG_COMPONENT => Ext::TAG_COMPONENT,
97
+ Tracing::Metadata::Ext::TAG_OPERATION => operation,
98
+ }
99
+ ) do |span|
100
+ if source
101
+ span.set_tag(
102
+ Ext::TAG_RUNNER_SOURCE,
103
+ Core::Utils.truncate(source, MAX_TAG_VALUE_SIZE)
104
+ )
105
+ end
106
+ Contrib::Analytics.set_rate!(span, Datadog.configuration.tracing[:rails])
107
+
108
+ super
109
+ end
86
110
  end
87
- ret
88
111
  end
89
-
90
- ruby2_keywords :find_by_namespace if respond_to?(:ruby2_keywords, true)
91
112
  end
92
113
  end
93
114
  end
@@ -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,
@@ -13,6 +13,7 @@ module Datadog
13
13
  ENV_ANALYTICS_ENABLED = 'DD_TRACE_SIDEKIQ_ANALYTICS_ENABLED'
14
14
  ENV_ANALYTICS_SAMPLE_RATE = 'DD_TRACE_SIDEKIQ_ANALYTICS_SAMPLE_RATE'
15
15
  SERVICE_NAME = 'sidekiq'
16
+ SIDEKIQ_8_SECONDS_PER_INTEGER = 0.001 # Sidekiq 8 uses integer epoch milliseconds, rather than epoch floats
16
17
  SPAN_PUSH = 'sidekiq.push'
17
18
  SPAN_JOB = 'sidekiq.job'
18
19
  SPAN_JOB_FETCH = 'sidekiq.job_fetch'
@@ -22,7 +22,7 @@ module Datadog
22
22
  @quantize = options[:quantize] || configuration[:quantize]
23
23
  end
24
24
 
25
- def call(worker, job, queue)
25
+ def call(worker, job, queue) # rubocop:disable Metrics/MethodLength
26
26
  resource = job_resource(job)
27
27
 
28
28
  if @distributed_tracing
@@ -61,7 +61,10 @@ 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
+
65
+ enqueued_at = job['enqueued_at']
66
+ enqueued_at *= Ext::SIDEKIQ_8_SECONDS_PER_INTEGER if enqueued_at.is_a?(Integer)
67
+ span.set_tag(Ext::TAG_JOB_DELAY, 1000.0 * (Core::Utils::Time.now.utc.to_f - enqueued_at.to_f))
65
68
 
66
69
  args = job['args']
67
70
  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
@@ -84,7 +84,7 @@ module Datadog
84
84
  # @return [Numeric, nil] tracer sample rate configured
85
85
  def sample_rate
86
86
  sampler = Datadog.configuration.tracing.sampler
87
- return nil unless sampler
87
+ return Datadog.configuration.tracing.sampling.default_rate unless sampler
88
88
 
89
89
  sampler.sample_rate(nil) rescue nil
90
90
  end
@@ -97,6 +97,8 @@ module Datadog
97
97
  # @return [Hash, nil] sample rules configured
98
98
  def sampling_rules
99
99
  sampler = Datadog.configuration.tracing.sampler
100
+ return Datadog.configuration.tracing.sampling.rules unless sampler
101
+
100
102
  return nil unless sampler.is_a?(Tracing::Sampling::PrioritySampler) &&
101
103
  sampler.priority_sampler.is_a?(Tracing::Sampling::RuleSampler)
102
104
 
@@ -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
@@ -10,17 +10,17 @@ module Datadog
10
10
  # Adds error tagging behavior
11
11
  # @public_api
12
12
  module Errors
13
- def set_error(e)
13
+ def set_error(error)
14
14
  Datadog::Core.log_deprecation do
15
15
  'Errors.set_error(..) is deprecated. ' \
16
16
  'Use Errors.set_error_tags(..) instead.'
17
17
  end
18
- set_error_tags(e)
18
+ set_error_tags(error)
19
19
  end
20
20
 
21
21
  # Mark the span with the given error.
22
- def set_error_tags(e)
23
- e = Core::Error.build_from(e)
22
+ def set_error_tags(error)
23
+ e = Core::Error.build_from(error)
24
24
 
25
25
  set_tag(Ext::Errors::TAG_TYPE, e.type) unless e.type.empty?
26
26
  set_tag(Ext::Errors::TAG_MSG, e.message) unless e.message.empty?
@@ -31,6 +31,8 @@ module Datadog
31
31
  # See Datadog-internal "RFC: Identifying which spans have profiling enabled " for details
32
32
  TAG_PROFILING_ENABLED = '_dd.profiling.enabled'
33
33
 
34
+ TAG_APM_ENABLED = '_dd.apm.enabled'
35
+
34
36
  # Defines constants for trace analytics
35
37
  # @public_api
36
38
  module Analytics
@@ -55,6 +57,9 @@ module Datadog
55
57
  # @see Datadog::Tracing::Sampling::Ext::Mechanism
56
58
  TAG_DECISION_MAKER = '_dd.p.dm'
57
59
 
60
+ # Bitmask for which product generated an event. E.g.: 2 for an AppSec event.
61
+ TAG_TRACE_SOURCE = '_dd.p.ts'
62
+
58
63
  TAG_ORIGIN = '_dd.origin'
59
64
  TAG_SAMPLING_PRIORITY = '_sampling_priority_v1'
60
65
 
@@ -0,0 +1,36 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'forwardable'
4
+
5
+ module Datadog
6
+ module Tracing
7
+ module Metadata
8
+ # This class is a data structure that is used to store
9
+ # complex metadata, such as an array of objects.
10
+ #
11
+ # It is serialized to MessagePack format when sent to the agent.
12
+ class Metastruct
13
+ extend Forwardable
14
+
15
+ def_delegators :@metastruct, :[], :[]=, :to_h
16
+
17
+ def initialize
18
+ @metastruct = {}
19
+ end
20
+
21
+ def to_msgpack(packer = nil)
22
+ # JRuby doesn't pass the packer
23
+ packer ||= MessagePack::Packer.new
24
+
25
+ packer.write(@metastruct.transform_values(&:to_msgpack))
26
+ end
27
+
28
+ def pretty_print(q)
29
+ q.seplist @metastruct.each do |key, value|
30
+ q.text "#{key} => #{value}"
31
+ end
32
+ end
33
+ end
34
+ end
35
+ end
36
+ end