datadog 2.18.0 → 2.20.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 (297) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +73 -1
  3. data/ext/datadog_profiling_native_extension/collectors_cpu_and_wall_time_worker.c +51 -10
  4. data/ext/datadog_profiling_native_extension/collectors_stack.c +58 -49
  5. data/ext/datadog_profiling_native_extension/collectors_stack.h +2 -1
  6. data/ext/datadog_profiling_native_extension/collectors_thread_context.c +5 -6
  7. data/ext/datadog_profiling_native_extension/collectors_thread_context.h +1 -1
  8. data/ext/datadog_profiling_native_extension/private_vm_api_access.c +37 -26
  9. data/ext/datadog_profiling_native_extension/private_vm_api_access.h +0 -1
  10. data/ext/datadog_profiling_native_extension/ruby_helpers.h +1 -1
  11. data/ext/libdatadog_api/extconf.rb +3 -1
  12. data/ext/libdatadog_extconf_helpers.rb +13 -3
  13. data/lib/datadog/appsec/api_security/route_extractor.rb +7 -1
  14. data/lib/datadog/appsec/component.rb +3 -13
  15. data/lib/datadog/appsec/context.rb +23 -0
  16. data/lib/datadog/appsec/contrib/devise/patches/signin_tracking_patch.rb +2 -1
  17. data/lib/datadog/appsec/contrib/devise/patches/signup_tracking_patch.rb +2 -1
  18. data/lib/datadog/appsec/contrib/excon/ssrf_detection_middleware.rb +0 -1
  19. data/lib/datadog/appsec/contrib/faraday/ssrf_detection_middleware.rb +0 -1
  20. data/lib/datadog/appsec/contrib/rack/request_middleware.rb +14 -22
  21. data/lib/datadog/appsec/contrib/rails/gateway/watcher.rb +23 -2
  22. data/lib/datadog/appsec/contrib/rails/patcher.rb +14 -26
  23. data/lib/datadog/appsec/contrib/rails/patches/process_action_patch.rb +27 -0
  24. data/lib/datadog/appsec/contrib/rails/patches/render_to_body_patch.rb +33 -0
  25. data/lib/datadog/appsec/contrib/rest_client/request_ssrf_detection_patch.rb +0 -1
  26. data/lib/datadog/appsec/contrib/sinatra/gateway/watcher.rb +23 -0
  27. data/lib/datadog/appsec/contrib/sinatra/patcher.rb +8 -18
  28. data/lib/datadog/appsec/contrib/sinatra/patches/json_patch.rb +31 -0
  29. data/lib/datadog/appsec/event.rb +3 -18
  30. data/lib/datadog/appsec/instrumentation/gateway/argument.rb +17 -1
  31. data/lib/datadog/appsec/metrics/collector.rb +7 -3
  32. data/lib/datadog/appsec/metrics/telemetry.rb +1 -1
  33. data/lib/datadog/appsec/metrics/telemetry_exporter.rb +28 -0
  34. data/lib/datadog/appsec/metrics.rb +1 -0
  35. data/lib/datadog/appsec/security_engine/engine.rb +14 -32
  36. data/lib/datadog/appsec/security_engine/result.rb +16 -0
  37. data/lib/datadog/appsec/security_engine/runner.rb +18 -4
  38. data/lib/datadog/appsec/thread_safe_ref.rb +61 -0
  39. data/lib/datadog/appsec/trace_keeper.rb +24 -0
  40. data/lib/datadog/appsec/utils/hash_coercion.rb +23 -0
  41. data/lib/datadog/appsec.rb +0 -7
  42. data/lib/datadog/auto_instrument_base.rb +2 -1
  43. data/lib/datadog/core/configuration/option.rb +29 -20
  44. data/lib/datadog/core/configuration/option_definition.rb +2 -2
  45. data/lib/datadog/core/configuration/options.rb +13 -7
  46. data/lib/datadog/core/configuration/settings.rb +20 -0
  47. data/lib/datadog/core/telemetry/component.rb +8 -4
  48. data/lib/datadog/core/telemetry/event/app_started.rb +21 -3
  49. data/lib/datadog/di/boot.rb +7 -0
  50. data/lib/datadog/di/component.rb +7 -0
  51. data/lib/datadog/di/instrumenter.rb +11 -18
  52. data/lib/datadog/di/probe_file_loader/railtie.rb +15 -0
  53. data/lib/datadog/di/probe_file_loader.rb +82 -0
  54. data/lib/datadog/di/probe_notification_builder.rb +21 -16
  55. data/lib/datadog/di/remote.rb +3 -5
  56. data/lib/datadog/di/serializer.rb +6 -2
  57. data/lib/datadog/di.rb +0 -7
  58. data/lib/datadog/kit/appsec/events/v2.rb +196 -0
  59. data/lib/datadog/kit/appsec/events.rb +11 -10
  60. data/lib/datadog/kit/identity.rb +17 -11
  61. data/lib/datadog/opentelemetry/api/baggage.rb +2 -2
  62. data/lib/datadog/opentelemetry/api/context.rb +10 -9
  63. data/lib/datadog/opentelemetry/sdk/propagator.rb +4 -4
  64. data/lib/datadog/opentelemetry/sdk/span_processor.rb +8 -8
  65. data/lib/datadog/opentelemetry/sdk/trace/span.rb +14 -10
  66. data/lib/datadog/opentelemetry/trace.rb +4 -4
  67. data/lib/datadog/profiling/collectors/cpu_and_wall_time_worker.rb +2 -0
  68. data/lib/datadog/profiling/collectors/info.rb +41 -0
  69. data/lib/datadog/profiling/component.rb +1 -0
  70. data/lib/datadog/profiling/exporter.rb +9 -3
  71. data/lib/datadog/profiling/sequence_tracker.rb +44 -0
  72. data/lib/datadog/profiling/tag_builder.rb +2 -0
  73. data/lib/datadog/profiling.rb +7 -8
  74. data/lib/datadog/single_step_instrument.rb +9 -0
  75. data/lib/datadog/tracing/analytics.rb +1 -1
  76. data/lib/datadog/tracing/buffer.rb +7 -7
  77. data/lib/datadog/tracing/configuration/dynamic.rb +4 -6
  78. data/lib/datadog/tracing/configuration/ext.rb +3 -2
  79. data/lib/datadog/tracing/configuration/settings.rb +17 -0
  80. data/lib/datadog/tracing/context.rb +2 -2
  81. data/lib/datadog/tracing/contrib/action_cable/event.rb +1 -1
  82. data/lib/datadog/tracing/contrib/action_cable/integration.rb +1 -1
  83. data/lib/datadog/tracing/contrib/action_mailer/integration.rb +1 -1
  84. data/lib/datadog/tracing/contrib/action_pack/action_controller/instrumentation.rb +4 -4
  85. data/lib/datadog/tracing/contrib/action_pack/integration.rb +1 -1
  86. data/lib/datadog/tracing/contrib/action_view/events/render_template.rb +1 -1
  87. data/lib/datadog/tracing/contrib/active_job/event.rb +8 -8
  88. data/lib/datadog/tracing/contrib/active_job/events/discard.rb +1 -1
  89. data/lib/datadog/tracing/contrib/active_job/events/enqueue.rb +1 -1
  90. data/lib/datadog/tracing/contrib/active_job/events/enqueue_at.rb +1 -1
  91. data/lib/datadog/tracing/contrib/active_job/events/enqueue_retry.rb +1 -1
  92. data/lib/datadog/tracing/contrib/active_job/events/perform.rb +1 -1
  93. data/lib/datadog/tracing/contrib/active_job/events/retry_stopped.rb +1 -1
  94. data/lib/datadog/tracing/contrib/active_job/integration.rb +1 -1
  95. data/lib/datadog/tracing/contrib/active_model_serializers/events/render.rb +1 -1
  96. data/lib/datadog/tracing/contrib/active_model_serializers/events/serialize.rb +3 -3
  97. data/lib/datadog/tracing/contrib/active_model_serializers/integration.rb +1 -2
  98. data/lib/datadog/tracing/contrib/active_record/configuration/resolver.rb +1 -1
  99. data/lib/datadog/tracing/contrib/active_record/events/instantiation.rb +1 -1
  100. data/lib/datadog/tracing/contrib/active_record/events/sql.rb +5 -5
  101. data/lib/datadog/tracing/contrib/active_record/integration.rb +1 -1
  102. data/lib/datadog/tracing/contrib/active_record/utils.rb +15 -15
  103. data/lib/datadog/tracing/contrib/active_support/cache/events/cache.rb +13 -7
  104. data/lib/datadog/tracing/contrib/active_support/configuration/settings.rb +13 -0
  105. data/lib/datadog/tracing/contrib/active_support/integration.rb +1 -1
  106. data/lib/datadog/tracing/contrib/active_support/notifications/event.rb +2 -1
  107. data/lib/datadog/tracing/contrib/active_support/notifications/subscription.rb +7 -9
  108. data/lib/datadog/tracing/contrib/aws/ext.rb +1 -1
  109. data/lib/datadog/tracing/contrib/aws/instrumentation.rb +2 -2
  110. data/lib/datadog/tracing/contrib/aws/parsed_context.rb +3 -1
  111. data/lib/datadog/tracing/contrib/aws/patcher.rb +5 -1
  112. data/lib/datadog/tracing/contrib/aws/service/base.rb +2 -1
  113. data/lib/datadog/tracing/contrib/aws/service/dynamodb.rb +1 -1
  114. data/lib/datadog/tracing/contrib/aws/service/eventbridge.rb +1 -1
  115. data/lib/datadog/tracing/contrib/aws/service/kinesis.rb +1 -1
  116. data/lib/datadog/tracing/contrib/aws/service/s3.rb +1 -1
  117. data/lib/datadog/tracing/contrib/aws/service/sns.rb +1 -1
  118. data/lib/datadog/tracing/contrib/aws/service/sqs.rb +1 -1
  119. data/lib/datadog/tracing/contrib/aws/service/states.rb +1 -1
  120. data/lib/datadog/tracing/contrib/aws/services.rb +7 -7
  121. data/lib/datadog/tracing/contrib/concurrent_ruby/async_patch.rb +1 -1
  122. data/lib/datadog/tracing/contrib/concurrent_ruby/context_composite_executor_service.rb +1 -1
  123. data/lib/datadog/tracing/contrib/concurrent_ruby/future_patch.rb +1 -1
  124. data/lib/datadog/tracing/contrib/concurrent_ruby/integration.rb +1 -1
  125. data/lib/datadog/tracing/contrib/concurrent_ruby/promises_future_patch.rb +1 -1
  126. data/lib/datadog/tracing/contrib/configurable.rb +6 -6
  127. data/lib/datadog/tracing/contrib/configuration/resolvers/pattern_resolver.rb +4 -4
  128. data/lib/datadog/tracing/contrib/dalli/ext.rb +3 -2
  129. data/lib/datadog/tracing/contrib/dalli/integration.rb +1 -1
  130. data/lib/datadog/tracing/contrib/delayed_job/integration.rb +1 -1
  131. data/lib/datadog/tracing/contrib/elasticsearch/ext.rb +3 -2
  132. data/lib/datadog/tracing/contrib/elasticsearch/integration.rb +4 -4
  133. data/lib/datadog/tracing/contrib/elasticsearch/patcher.rb +51 -53
  134. data/lib/datadog/tracing/contrib/elasticsearch/quantize.rb +5 -5
  135. data/lib/datadog/tracing/contrib/ethon/easy_patch.rb +2 -2
  136. data/lib/datadog/tracing/contrib/ethon/ext.rb +3 -2
  137. data/lib/datadog/tracing/contrib/ethon/integration.rb +1 -1
  138. data/lib/datadog/tracing/contrib/excon/ext.rb +3 -2
  139. data/lib/datadog/tracing/contrib/excon/integration.rb +1 -1
  140. data/lib/datadog/tracing/contrib/excon/middleware.rb +2 -2
  141. data/lib/datadog/tracing/contrib/ext.rb +3 -3
  142. data/lib/datadog/tracing/contrib/extensions.rb +9 -9
  143. data/lib/datadog/tracing/contrib/faraday/ext.rb +3 -2
  144. data/lib/datadog/tracing/contrib/faraday/integration.rb +1 -1
  145. data/lib/datadog/tracing/contrib/faraday/middleware.rb +4 -2
  146. data/lib/datadog/tracing/contrib/grape/endpoint.rb +8 -8
  147. data/lib/datadog/tracing/contrib/grape/integration.rb +1 -1
  148. data/lib/datadog/tracing/contrib/graphql/integration.rb +1 -1
  149. data/lib/datadog/tracing/contrib/graphql/patcher.rb +2 -2
  150. data/lib/datadog/tracing/contrib/graphql/unified_trace.rb +24 -24
  151. data/lib/datadog/tracing/contrib/grpc/datadog_interceptor/client.rb +8 -8
  152. data/lib/datadog/tracing/contrib/grpc/datadog_interceptor/server.rb +3 -3
  153. data/lib/datadog/tracing/contrib/grpc/distributed/fetcher.rb +1 -1
  154. data/lib/datadog/tracing/contrib/grpc/integration.rb +1 -1
  155. data/lib/datadog/tracing/contrib/hanami/ext.rb +2 -2
  156. data/lib/datadog/tracing/contrib/hanami/integration.rb +1 -1
  157. data/lib/datadog/tracing/contrib/hanami/renderer_policy_tracing.rb +1 -1
  158. data/lib/datadog/tracing/contrib/hanami/router_tracing.rb +9 -11
  159. data/lib/datadog/tracing/contrib/http/distributed/fetcher.rb +4 -4
  160. data/lib/datadog/tracing/contrib/http/ext.rb +3 -2
  161. data/lib/datadog/tracing/contrib/http/instrumentation.rb +5 -5
  162. data/lib/datadog/tracing/contrib/httpclient/ext.rb +3 -2
  163. data/lib/datadog/tracing/contrib/httpclient/instrumentation.rb +3 -3
  164. data/lib/datadog/tracing/contrib/httpclient/integration.rb +1 -1
  165. data/lib/datadog/tracing/contrib/httprb/ext.rb +3 -2
  166. data/lib/datadog/tracing/contrib/httprb/instrumentation.rb +4 -4
  167. data/lib/datadog/tracing/contrib/httprb/integration.rb +1 -1
  168. data/lib/datadog/tracing/contrib/kafka/event.rb +1 -1
  169. data/lib/datadog/tracing/contrib/kafka/events/connection/request.rb +1 -1
  170. data/lib/datadog/tracing/contrib/kafka/events/consumer/process_batch.rb +1 -1
  171. data/lib/datadog/tracing/contrib/kafka/events/consumer/process_message.rb +1 -1
  172. data/lib/datadog/tracing/contrib/kafka/events/consumer_group/heartbeat.rb +1 -1
  173. data/lib/datadog/tracing/contrib/kafka/events/consumer_group/join_group.rb +1 -1
  174. data/lib/datadog/tracing/contrib/kafka/events/consumer_group/leave_group.rb +1 -1
  175. data/lib/datadog/tracing/contrib/kafka/events/consumer_group/sync_group.rb +1 -1
  176. data/lib/datadog/tracing/contrib/kafka/events/produce_operation/send_messages.rb +1 -1
  177. data/lib/datadog/tracing/contrib/kafka/events/producer/deliver_messages.rb +1 -1
  178. data/lib/datadog/tracing/contrib/kafka/integration.rb +1 -1
  179. data/lib/datadog/tracing/contrib/karafka/monitor.rb +13 -13
  180. data/lib/datadog/tracing/contrib/karafka/patcher.rb +4 -4
  181. data/lib/datadog/tracing/contrib/lograge/instrumentation.rb +1 -1
  182. data/lib/datadog/tracing/contrib/lograge/integration.rb +1 -1
  183. data/lib/datadog/tracing/contrib/mongodb/configuration/settings.rb +1 -1
  184. data/lib/datadog/tracing/contrib/mongodb/ext.rb +1 -1
  185. data/lib/datadog/tracing/contrib/mongodb/integration.rb +1 -1
  186. data/lib/datadog/tracing/contrib/mongodb/parsers.rb +1 -1
  187. data/lib/datadog/tracing/contrib/mongodb/subscribers.rb +6 -6
  188. data/lib/datadog/tracing/contrib/mysql2/ext.rb +1 -1
  189. data/lib/datadog/tracing/contrib/mysql2/instrumentation.rb +16 -6
  190. data/lib/datadog/tracing/contrib/mysql2/integration.rb +1 -1
  191. data/lib/datadog/tracing/contrib/opensearch/configuration/settings.rb +1 -1
  192. data/lib/datadog/tracing/contrib/opensearch/ext.rb +3 -2
  193. data/lib/datadog/tracing/contrib/opensearch/integration.rb +1 -2
  194. data/lib/datadog/tracing/contrib/opensearch/patcher.rb +68 -70
  195. data/lib/datadog/tracing/contrib/opensearch/quantize.rb +5 -5
  196. data/lib/datadog/tracing/contrib/patcher.rb +7 -9
  197. data/lib/datadog/tracing/contrib/pg/integration.rb +1 -1
  198. data/lib/datadog/tracing/contrib/presto/ext.rb +1 -1
  199. data/lib/datadog/tracing/contrib/presto/instrumentation.rb +3 -3
  200. data/lib/datadog/tracing/contrib/presto/integration.rb +1 -1
  201. data/lib/datadog/tracing/contrib/propagation/sql_comment/comment.rb +1 -1
  202. data/lib/datadog/tracing/contrib/propagation/sql_comment.rb +1 -1
  203. data/lib/datadog/tracing/contrib/que/integration.rb +1 -1
  204. data/lib/datadog/tracing/contrib/racecar/event.rb +1 -1
  205. data/lib/datadog/tracing/contrib/racecar/events/batch.rb +2 -2
  206. data/lib/datadog/tracing/contrib/racecar/events/consume.rb +1 -1
  207. data/lib/datadog/tracing/contrib/racecar/events/message.rb +2 -2
  208. data/lib/datadog/tracing/contrib/racecar/integration.rb +1 -1
  209. data/lib/datadog/tracing/contrib/rack/header_collection.rb +1 -1
  210. data/lib/datadog/tracing/contrib/rack/header_tagging.rb +32 -32
  211. data/lib/datadog/tracing/contrib/rack/integration.rb +1 -1
  212. data/lib/datadog/tracing/contrib/rack/middlewares.rb +21 -17
  213. data/lib/datadog/tracing/contrib/rack/patcher.rb +1 -1
  214. data/lib/datadog/tracing/contrib/rack/request_queue.rb +2 -2
  215. data/lib/datadog/tracing/contrib/rails/configuration/settings.rb +1 -1
  216. data/lib/datadog/tracing/contrib/rails/integration.rb +1 -1
  217. data/lib/datadog/tracing/contrib/rails/log_injection.rb +1 -1
  218. data/lib/datadog/tracing/contrib/rails/middlewares.rb +1 -1
  219. data/lib/datadog/tracing/contrib/rails/patcher.rb +4 -1
  220. data/lib/datadog/tracing/contrib/rails/runner.rb +62 -40
  221. data/lib/datadog/tracing/contrib/rake/instrumentation.rb +4 -4
  222. data/lib/datadog/tracing/contrib/rake/integration.rb +1 -1
  223. data/lib/datadog/tracing/contrib/redis/configuration/resolver.rb +2 -2
  224. data/lib/datadog/tracing/contrib/redis/ext.rb +3 -2
  225. data/lib/datadog/tracing/contrib/redis/integration.rb +2 -2
  226. data/lib/datadog/tracing/contrib/redis/patcher.rb +4 -4
  227. data/lib/datadog/tracing/contrib/redis/quantize.rb +1 -1
  228. data/lib/datadog/tracing/contrib/redis/tags.rb +1 -1
  229. data/lib/datadog/tracing/contrib/redis/trace_middleware.rb +4 -4
  230. data/lib/datadog/tracing/contrib/registry.rb +1 -1
  231. data/lib/datadog/tracing/contrib/resque/integration.rb +1 -1
  232. data/lib/datadog/tracing/contrib/resque/resque_job.rb +1 -1
  233. data/lib/datadog/tracing/contrib/rest_client/ext.rb +3 -2
  234. data/lib/datadog/tracing/contrib/rest_client/integration.rb +1 -1
  235. data/lib/datadog/tracing/contrib/rest_client/request_patch.rb +3 -3
  236. data/lib/datadog/tracing/contrib/roda/instrumentation.rb +1 -1
  237. data/lib/datadog/tracing/contrib/roda/integration.rb +1 -1
  238. data/lib/datadog/tracing/contrib/semantic_logger/instrumentation.rb +1 -1
  239. data/lib/datadog/tracing/contrib/semantic_logger/integration.rb +1 -1
  240. data/lib/datadog/tracing/contrib/sequel/database.rb +5 -5
  241. data/lib/datadog/tracing/contrib/sequel/dataset.rb +1 -1
  242. data/lib/datadog/tracing/contrib/sequel/integration.rb +1 -1
  243. data/lib/datadog/tracing/contrib/sequel/utils.rb +1 -1
  244. data/lib/datadog/tracing/contrib/shoryuken/integration.rb +1 -1
  245. data/lib/datadog/tracing/contrib/sidekiq/integration.rb +1 -1
  246. data/lib/datadog/tracing/contrib/sidekiq/utils.rb +1 -1
  247. data/lib/datadog/tracing/contrib/sinatra/integration.rb +1 -1
  248. data/lib/datadog/tracing/contrib/sinatra/tracer_middleware.rb +38 -40
  249. data/lib/datadog/tracing/contrib/sneakers/integration.rb +1 -1
  250. data/lib/datadog/tracing/contrib/stripe/integration.rb +1 -1
  251. data/lib/datadog/tracing/contrib/stripe/request.rb +1 -1
  252. data/lib/datadog/tracing/contrib/sucker_punch/integration.rb +1 -1
  253. data/lib/datadog/tracing/contrib/trilogy/ext.rb +1 -1
  254. data/lib/datadog/tracing/contrib/trilogy/integration.rb +1 -1
  255. data/lib/datadog/tracing/contrib/utils/quantization/hash.rb +11 -11
  256. data/lib/datadog/tracing/contrib/utils/quantization/http.rb +6 -6
  257. data/lib/datadog/tracing/diagnostics/environment_logger.rb +8 -2
  258. data/lib/datadog/tracing/distributed/b3_single.rb +1 -1
  259. data/lib/datadog/tracing/distributed/baggage.rb +73 -8
  260. data/lib/datadog/tracing/distributed/datadog.rb +4 -5
  261. data/lib/datadog/tracing/distributed/datadog_tags_codec.rb +11 -13
  262. data/lib/datadog/tracing/distributed/helpers.rb +1 -1
  263. data/lib/datadog/tracing/distributed/none.rb +4 -2
  264. data/lib/datadog/tracing/distributed/propagation.rb +4 -1
  265. data/lib/datadog/tracing/distributed/propagation_policy.rb +1 -1
  266. data/lib/datadog/tracing/distributed/trace_context.rb +22 -16
  267. data/lib/datadog/tracing/event.rb +5 -7
  268. data/lib/datadog/tracing/flush.rb +1 -1
  269. data/lib/datadog/tracing/metadata/analytics.rb +1 -1
  270. data/lib/datadog/tracing/metadata/tagging.rb +4 -4
  271. data/lib/datadog/tracing/pipeline/span_filter.rb +3 -1
  272. data/lib/datadog/tracing/pipeline/span_processor.rb +3 -1
  273. data/lib/datadog/tracing/pipeline.rb +1 -1
  274. data/lib/datadog/tracing/sampling/ext.rb +0 -2
  275. data/lib/datadog/tracing/sampling/rule_sampler.rb +30 -30
  276. data/lib/datadog/tracing/sampling/span/rule_parser.rb +1 -1
  277. data/lib/datadog/tracing/sampling/span/sampler.rb +0 -7
  278. data/lib/datadog/tracing/span.rb +1 -1
  279. data/lib/datadog/tracing/span_event.rb +10 -10
  280. data/lib/datadog/tracing/span_link.rb +12 -12
  281. data/lib/datadog/tracing/span_operation.rb +31 -11
  282. data/lib/datadog/tracing/trace_digest.rb +21 -23
  283. data/lib/datadog/tracing/trace_operation.rb +84 -88
  284. data/lib/datadog/tracing/trace_segment.rb +2 -2
  285. data/lib/datadog/tracing/tracer.rb +36 -38
  286. data/lib/datadog/tracing/transport/http/client.rb +1 -1
  287. data/lib/datadog/tracing/transport/http/traces.rb +2 -2
  288. data/lib/datadog/tracing/transport/io/client.rb +5 -5
  289. data/lib/datadog/tracing/transport/io/traces.rb +4 -4
  290. data/lib/datadog/tracing/transport/statistics.rb +1 -1
  291. data/lib/datadog/tracing/transport/traces.rb +5 -5
  292. data/lib/datadog/tracing/workers/trace_writer.rb +12 -12
  293. data/lib/datadog/tracing/workers.rb +2 -2
  294. data/lib/datadog/tracing.rb +2 -2
  295. data/lib/datadog/version.rb +1 -1
  296. data/lib/datadog.rb +7 -0
  297. metadata +17 -6
@@ -0,0 +1,196 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative '../../identity'
4
+ require_relative '../../../appsec/trace_keeper'
5
+
6
+ module Datadog
7
+ module Kit
8
+ module AppSec
9
+ module Events
10
+ # The second version of Business Logic Events SDK
11
+ module V2
12
+ LOGIN_SUCCESS_EVENT = 'users.login.success'
13
+ LOGIN_FAILURE_EVENT = 'users.login.failure'
14
+ TELEMETRY_METRICS_NAMESPACE = 'appsec'
15
+ TELEMETRY_METRICS_SDK_EVENT = 'sdk.event'
16
+ TELEMETRY_METRICS_SDK_VERSION = 'v2'
17
+ TELEMETRY_METRICS_EVENTS_INTO_TYPES = {
18
+ LOGIN_SUCCESS_EVENT => 'login_success',
19
+ LOGIN_FAILURE_EVENT => 'login_failure'
20
+ }.freeze
21
+
22
+ class << self
23
+ # Attach user login success information to the service entry span
24
+ # and trigger AppSec event processing.
25
+ #
26
+ # @param login [String] The user login (e.g., username or email).
27
+ # @param user_or_id [String, Hash<Symbol, String>] (optional) If a
28
+ # String, considered as a user ID, if a Hash, considered as a user
29
+ # attributes. The Hash must include `:id` as a key.
30
+ # @param metadata [Hash<Symbol, String>] Additional flat free-form
31
+ # metadata to attach to the event.
32
+ #
33
+ # @example Login only
34
+ # Datadog::Kit::AppSec::Events::V2.track_user_login_success('alice@example.com')
35
+ #
36
+ # @example Login and user attributes
37
+ # Datadog::Kit::AppSec::Events::V2.track_user_login_success(
38
+ # 'alice@example.com',
39
+ # { id: 'user-123', email: 'alice@example.com', name: 'Alice' },
40
+ # ip: '192.168.1.1', device: 'mobile', 'usr.country': 'US'
41
+ # )
42
+ #
43
+ # @return [void]
44
+ def track_user_login_success(login, user_or_id = nil, metadata = {})
45
+ trace = service_entry_trace
46
+ span = service_entry_span
47
+
48
+ if trace.nil? || span.nil?
49
+ return Datadog.logger.warn(
50
+ 'Kit::AppSec: Tracing is not enabled. Please enable tracing if you want to track events'
51
+ )
52
+ end
53
+
54
+ raise TypeError, '`login` argument must be a String' unless login.is_a?(String)
55
+ raise TypeError, '`metadata` argument must be a Hash' unless metadata.is_a?(Hash)
56
+
57
+ user_attributes = build_user_attributes(user_or_id, login)
58
+
59
+ set_span_tags(span, metadata, namespace: LOGIN_SUCCESS_EVENT)
60
+ set_span_tags(span, user_attributes, namespace: "#{LOGIN_SUCCESS_EVENT}.usr")
61
+ span.set_tag('appsec.events.users.login.success.track', 'true')
62
+ span.set_tag('_dd.appsec.events.users.login.success.sdk', 'true')
63
+
64
+ ::Datadog::AppSec::TraceKeeper.keep!(trace)
65
+
66
+ record_event_telemetry_metric(LOGIN_SUCCESS_EVENT)
67
+ ::Datadog::AppSec::Instrumentation.gateway.push('appsec.events.user_lifecycle', LOGIN_SUCCESS_EVENT)
68
+
69
+ # NOTE: Guard-clause will not work with Steep typechecking
70
+ return Kit::Identity.set_user(trace, span, **user_attributes) if user_attributes.key?(:id) # steep:ignore
71
+
72
+ # NOTE: This is a fallback for the case when we don't have an ID,
73
+ # but need to trigger WAF.
74
+ user = ::Datadog::AppSec::Instrumentation::Gateway::User.new(nil, login)
75
+ ::Datadog::AppSec::Instrumentation.gateway.push('identity.set_user', user)
76
+ end
77
+
78
+ # Attach user login failure information to the service entry span
79
+ # and trigger AppSec event processing.
80
+ #
81
+ # @param login [String] The user login (e.g., username or email).
82
+ # @param user_exists [Boolean] Whether the user exists in the system.
83
+ # @param metadata [Hash<Symbol, String>] Additional flat free-form
84
+ # metadata to attach to the event.
85
+ #
86
+ # @example Login only
87
+ # Datadog::Kit::AppSec::Events::V2.track_user_login_failure('alice@example.com')
88
+ #
89
+ # @example With user existence and metadata
90
+ # Datadog::Kit::AppSec::Events::V2.track_user_login_failure(
91
+ # 'alice@example.com',
92
+ # true,
93
+ # ip: '192.168.1.1', device: 'mobile', 'usr.country': 'US'
94
+ # )
95
+ #
96
+ # @return [void]
97
+ def track_user_login_failure(login, user_exists = false, metadata = {})
98
+ trace = service_entry_trace
99
+ span = service_entry_span
100
+
101
+ if trace.nil? || span.nil?
102
+ return Datadog.logger.warn(
103
+ 'Kit::AppSec: Tracing is not enabled. Please enable tracing if you want to track events'
104
+ )
105
+ end
106
+
107
+ raise TypeError, '`login` argument must be a String' unless login.is_a?(String)
108
+ raise TypeError, '`metadata` argument must be a Hash' unless metadata.is_a?(Hash)
109
+
110
+ unless user_exists.is_a?(TrueClass) || user_exists.is_a?(FalseClass)
111
+ raise TypeError, '`user_exists` argument must be a boolean'
112
+ end
113
+
114
+ set_span_tags(span, metadata, namespace: LOGIN_FAILURE_EVENT)
115
+ span.set_tag('appsec.events.users.login.failure.track', 'true')
116
+ span.set_tag('_dd.appsec.events.users.login.failure.sdk', 'true')
117
+ span.set_tag('appsec.events.users.login.failure.usr.login', login)
118
+ span.set_tag('appsec.events.users.login.failure.usr.exists', user_exists.to_s)
119
+
120
+ ::Datadog::AppSec::TraceKeeper.keep!(trace)
121
+
122
+ record_event_telemetry_metric(LOGIN_FAILURE_EVENT)
123
+ ::Datadog::AppSec::Instrumentation.gateway.push('appsec.events.user_lifecycle', LOGIN_FAILURE_EVENT)
124
+
125
+ user = ::Datadog::AppSec::Instrumentation::Gateway::User.new(nil, login)
126
+ ::Datadog::AppSec::Instrumentation.gateway.push('identity.set_user', user)
127
+ end
128
+
129
+ private
130
+
131
+ # NOTE: Current tracer implementation does not provide a way to
132
+ # get the service entry span. This is a shortcut we take now.
133
+ def service_entry_trace
134
+ return Datadog::Tracing.active_trace unless Datadog::AppSec.active_context
135
+
136
+ Datadog::AppSec.active_context&.trace
137
+ end
138
+
139
+ # NOTE: Current tracer implementation does not provide a way to
140
+ # get the service entry span. This is a shortcut we take now.
141
+ def service_entry_span
142
+ return Datadog::Tracing.active_span unless Datadog::AppSec.active_context
143
+
144
+ Datadog::AppSec.active_context&.span
145
+ end
146
+
147
+ def build_user_attributes(user_or_id, login)
148
+ raise TypeError, '`login` argument must be a String' unless login.is_a?(String)
149
+
150
+ case user_or_id
151
+ when nil
152
+ {login: login}
153
+ when String
154
+ {login: login, id: user_or_id}
155
+ when Hash
156
+ raise ArgumentError, 'missing required user key `:id`' unless user_or_id.key?(:id)
157
+ raise TypeError, 'user key `:id` must be a String' unless user_or_id[:id].is_a?(String)
158
+
159
+ user_or_id.merge(login: login)
160
+ else
161
+ raise TypeError, '`user_or_id` argument must be either String or Hash'
162
+ end
163
+ end
164
+
165
+ def set_span_tags(span, tags, namespace:)
166
+ tags.each do |name, value|
167
+ next if value.nil?
168
+
169
+ span.set_tag("appsec.events.#{namespace}.#{name}", value)
170
+ end
171
+ end
172
+
173
+ # TODO: In case if we need to introduce telemetry metrics to the SDK v1
174
+ # or highly increase the number of metrics, this method should be
175
+ # extracted into a proper module.
176
+ def record_event_telemetry_metric(event)
177
+ telemetry = ::Datadog.send(:components, allow_initialization: false)&.telemetry
178
+
179
+ if telemetry.nil?
180
+ return Datadog.logger.debug(
181
+ 'Kit::AppSec: Telemetry component is unavailable. Skip recording SDK metrics'
182
+ )
183
+ end
184
+
185
+ tags = {
186
+ event_type: TELEMETRY_METRICS_EVENTS_INTO_TYPES[event],
187
+ sdk_version: TELEMETRY_METRICS_SDK_VERSION
188
+ }
189
+ telemetry.inc(TELEMETRY_METRICS_NAMESPACE, TELEMETRY_METRICS_SDK_EVENT, 1, tags: tags)
190
+ end
191
+ end
192
+ end
193
+ end
194
+ end
195
+ end
196
+ end
@@ -1,6 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require_relative '../identity'
4
+ require_relative '../../appsec/trace_keeper'
4
5
 
5
6
  module Datadog
6
7
  module Kit
@@ -10,7 +11,7 @@ module Datadog
10
11
  LOGIN_SUCCESS_EVENT = 'users.login.success'
11
12
  LOGIN_FAILURE_EVENT = 'users.login.failure'
12
13
  SIGNUP_EVENT = 'users.signup'
13
- USER_LOGIN_KEYS = ['usr.login', :'usr.login'].freeze
14
+ USER_LOGIN_KEYS = ['usr.login', :"usr.login"].freeze
14
15
 
15
16
  class << self
16
17
  # Attach login success event information to the trace
@@ -31,12 +32,12 @@ module Datadog
31
32
  set_trace_and_span_context('track_login_success', trace, span) do |active_trace, active_span|
32
33
  user_options = user.dup
33
34
  user_id = user_options.delete(:id)
34
- user_login = user_options[:login] || others[:'usr.login'] || others['usr.login'] || user_id
35
+ user_login = user_options[:login] || others[:"usr.login"] || others['usr.login'] || user_id
35
36
 
36
37
  raise ArgumentError, 'missing required key: :user => { :id }' if user_id.nil?
37
38
 
38
39
  others = others.reject { |key, _| USER_LOGIN_KEYS.include?(key) }
39
- others[:'usr.login'] = user_login
40
+ others[:"usr.login"] = user_login
40
41
  track(LOGIN_SUCCESS_EVENT, active_trace, active_span, **others)
41
42
 
42
43
  user_options[:login] = user_login
@@ -60,7 +61,7 @@ module Datadog
60
61
  # event information to attach to the trace.
61
62
  def track_login_failure(trace = nil, span = nil, user_exists:, user_id: nil, **others)
62
63
  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')
64
+ others[:"usr.login"] = user_id if user_id && !others.key?(:"usr.login") && !others.key?('usr.login')
64
65
  track(LOGIN_FAILURE_EVENT, active_trace, active_span, **others)
65
66
 
66
67
  active_span.set_tag('appsec.events.users.login.failure.usr.id', user_id) if user_id
@@ -86,12 +87,12 @@ module Datadog
86
87
  set_trace_and_span_context('track_signup', trace, span) do |active_trace, active_span|
87
88
  user_options = user.dup
88
89
  user_id = user_options.delete(:id)
89
- user_login = user_options[:login] || others[:'usr.login'] || others['usr.login'] || user_id
90
+ user_login = user_options[:login] || others[:"usr.login"] || others['usr.login'] || user_id
90
91
 
91
92
  raise ArgumentError, 'missing required key: :user => { :id }' if user_id.nil?
92
93
 
93
94
  others = others.reject { |key, _| USER_LOGIN_KEYS.include?(key) }
94
- others[:'usr.login'] = user_login
95
+ others[:"usr.login"] = user_login
95
96
  track(SIGNUP_EVENT, active_trace, active_span, **others)
96
97
 
97
98
  user_options[:login] = user_login
@@ -126,7 +127,7 @@ module Datadog
126
127
  span.set_tag("appsec.events.#{event}.#{k}", v) unless v.nil?
127
128
  end
128
129
 
129
- trace.keep!
130
+ ::Datadog::AppSec::TraceKeeper.keep!(trace)
130
131
  else
131
132
  set_trace_and_span_context('track', trace, span) do |active_trace, active_span|
132
133
  active_span.set_tag("appsec.events.#{event}.track", 'true')
@@ -138,7 +139,7 @@ module Datadog
138
139
  active_span.set_tag("appsec.events.#{event}.#{k}", v) unless v.nil?
139
140
  end
140
141
 
141
- active_trace.keep!
142
+ ::Datadog::AppSec::TraceKeeper.keep!(active_trace)
142
143
  end
143
144
  end
144
145
 
@@ -154,11 +155,11 @@ module Datadog
154
155
  end
155
156
 
156
157
  trace ||= Datadog::Tracing.active_trace
157
- span ||= trace && trace.active_span || Datadog::Tracing.active_span
158
+ span ||= trace&.active_span || Datadog::Tracing.active_span
158
159
 
159
160
  unless trace && span
160
161
  Datadog.logger.debug(
161
- "Tracing not enabled. Method ##{method} is a no-op. Please enable tracing if you want ##{method}"\
162
+ "Tracing not enabled. Method ##{method} is a no-op. Please enable tracing if you want ##{method}" \
162
163
  ' to track this events'
163
164
  )
164
165
  return
@@ -43,12 +43,12 @@ module Datadog
43
43
 
44
44
  # enforce types
45
45
 
46
- raise TypeError, ':id must be a String' unless id.is_a?(String)
47
- raise TypeError, ':email must be a String' unless email.nil? || email.is_a?(String)
48
- raise TypeError, ':name must be a String' unless name.nil? || name.is_a?(String)
46
+ raise TypeError, ':id must be a String' unless id.is_a?(String)
47
+ raise TypeError, ':email must be a String' unless email.nil? || email.is_a?(String)
48
+ raise TypeError, ':name must be a String' unless name.nil? || name.is_a?(String)
49
49
  raise TypeError, ':session_id must be a String' unless session_id.nil? || session_id.is_a?(String)
50
- raise TypeError, ':role must be a String' unless role.nil? || role.is_a?(String)
51
- raise TypeError, ':scope must be a String' unless scope.nil? || scope.is_a?(String)
50
+ raise TypeError, ':role must be a String' unless role.nil? || role.is_a?(String)
51
+ raise TypeError, ':scope must be a String' unless scope.nil? || scope.is_a?(String)
52
52
 
53
53
  others.each do |k, v|
54
54
  raise TypeError, "#{k.inspect} must be a String" unless v.nil? || v.is_a?(String)
@@ -57,11 +57,11 @@ module Datadog
57
57
  set_trace_and_span_context('set_user', trace, span) do |_active_trace, active_span|
58
58
  # set tags once data is known consistent
59
59
  active_span.set_tag('usr.id', id)
60
- active_span.set_tag('usr.email', email) unless email.nil?
61
- active_span.set_tag('usr.name', name) unless name.nil?
60
+ active_span.set_tag('usr.email', email) unless email.nil?
61
+ active_span.set_tag('usr.name', name) unless name.nil?
62
62
  active_span.set_tag('usr.session_id', session_id) unless session_id.nil?
63
- active_span.set_tag('usr.role', role) unless role.nil?
64
- active_span.set_tag('usr.scope', scope) unless scope.nil?
63
+ active_span.set_tag('usr.role', role) unless role.nil?
64
+ active_span.set_tag('usr.scope', scope) unless scope.nil?
65
65
 
66
66
  others.each do |k, v|
67
67
  active_span.set_tag("usr.#{k}", v) unless v.nil?
@@ -81,6 +81,9 @@ module Datadog
81
81
 
82
82
  private
83
83
 
84
+ # rubocop:disable Metrics/AbcSize
85
+ # rubocop:disable Metrics/CyclomaticComplexity
86
+ # rubocop:disable Metrics/PerceivedComplexity
84
87
  def set_trace_and_span_context(method, trace = nil, span = nil)
85
88
  if (appsec_context = Datadog::AppSec.active_context)
86
89
  trace = appsec_context.trace
@@ -88,11 +91,11 @@ module Datadog
88
91
  end
89
92
 
90
93
  trace ||= Datadog::Tracing.active_trace
91
- span ||= trace && trace.active_span || Datadog::Tracing.active_span
94
+ span ||= trace&.active_span || Datadog::Tracing.active_span
92
95
 
93
96
  unless trace && span
94
97
  Datadog.logger.debug(
95
- "Tracing not enabled. Method ##{method} is a no-op. Please enable tracing if you want ##{method}"\
98
+ "Tracing not enabled. Method ##{method} is a no-op. Please enable tracing if you want ##{method}" \
96
99
  ' to track this events'
97
100
  )
98
101
  return
@@ -102,6 +105,9 @@ module Datadog
102
105
 
103
106
  yield(trace, span)
104
107
  end
108
+ # rubocop:enable Metrics/AbcSize
109
+ # rubocop:enable Metrics/PerceivedComplexity
110
+ # rubocop:enable Metrics/CyclomaticComplexity
105
111
  end
106
112
  end
107
113
  end
@@ -69,7 +69,7 @@ module Datadog
69
69
  def set_value(key, value, metadata: nil, context: ::OpenTelemetry::Context.current)
70
70
  # Delegate to the context to set the value because an active trace is not guaranteed
71
71
  # set_values handles this logic
72
- context.set_values({ ::OpenTelemetry::Baggage.const_get(:BAGGAGE_KEY) => { key => value } })
72
+ context.set_values({::OpenTelemetry::Baggage.const_get(:BAGGAGE_KEY) => {key => value}})
73
73
  end
74
74
 
75
75
  # Returns a new context with value at key removed
@@ -81,7 +81,7 @@ module Datadog
81
81
  def remove_value(key, context: ::OpenTelemetry::Context.current)
82
82
  # Delegate to the context to remove the value because an active trace is not guaranteed
83
83
  # set_values handles this logic
84
- context.set_values({ Context::BAGGAGE_REMOVE_KEY => key })
84
+ context.set_values({Context::BAGGAGE_REMOVE_KEY => key})
85
85
  end
86
86
  ::OpenTelemetry::Baggage.singleton_class.prepend(self)
87
87
  end
@@ -50,7 +50,8 @@ module Datadog
50
50
  @trace.otel_value(key)
51
51
  end
52
52
 
53
- alias [] value
53
+ # `alias` performed to match {::OpenTelemetry::Context} aliasing upstream
54
+ alias [] value # rubocop:disable Style/Alias
54
55
 
55
56
  # Returns a new Context where entries contains the newly added key and value
56
57
  #
@@ -80,8 +81,8 @@ module Datadog
80
81
  )
81
82
  end
82
83
 
83
- existing_values = @trace && @trace.otel_values || {}
84
- existing_baggage = @trace && @trace.baggage || {}
84
+ existing_values = @trace&.otel_values || {}
85
+ existing_baggage = @trace&.baggage || {}
85
86
 
86
87
  # Retrieve the baggage removal sentinel and remove it from the values hash
87
88
  existing_baggage.delete(values[BAGGAGE_REMOVE_KEY]) if values.key?(BAGGAGE_REMOVE_KEY)
@@ -89,10 +90,10 @@ module Datadog
89
90
  # If the values hash contains a BAGGAGE_KEY, merge its contents with existing baggage
90
91
  # Otherwise, keep the existing baggage unchanged
91
92
  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
93
+ existing_baggage.merge(values[::OpenTelemetry::Baggage.const_get(:BAGGAGE_KEY)])
94
+ else
95
+ existing_baggage
96
+ end
96
97
 
97
98
  ::OpenTelemetry::Context.new(existing_values.merge(values), trace: trace, baggage: new_baggage)
98
99
  end
@@ -125,7 +126,7 @@ module Datadog
125
126
  previous_trace = Tracing.active_trace
126
127
  continue_trace!(context)
127
128
 
128
- stack.push(previous_trace && previous_trace.otel_context || ::OpenTelemetry::Context::ROOT)
129
+ stack.push(previous_trace&.otel_context || ::OpenTelemetry::Context::ROOT)
129
130
  stack.size
130
131
  end
131
132
 
@@ -168,7 +169,7 @@ module Datadog
168
169
 
169
170
  def continue_trace!(context, &block)
170
171
  call_context = Tracing.send(:tracer).send(:call_context)
171
- if context && context.trace
172
+ if context&.trace
172
173
  call_context.activate!(context.ensure_trace, &block)
173
174
  else
174
175
  call_context.activate!(nil)
@@ -54,10 +54,10 @@ module Datadog
54
54
  tracestate = Tracing::Distributed::TraceContext.new(fetcher: nil).send(:build_tracestate, digest)
55
55
  else
56
56
  trace_flags = if Tracing::Sampling::PrioritySampler.sampled?(digest.trace_sampling_priority)
57
- ::OpenTelemetry::Trace::TraceFlags::SAMPLED
58
- else
59
- ::OpenTelemetry::Trace::TraceFlags::DEFAULT
60
- end
57
+ ::OpenTelemetry::Trace::TraceFlags::SAMPLED
58
+ else
59
+ ::OpenTelemetry::Trace::TraceFlags::DEFAULT
60
+ end
61
61
  tracestate = ::OpenTelemetry::Trace::Tracestate::DEFAULT
62
62
  end
63
63
 
@@ -120,7 +120,7 @@ module Datadog
120
120
  # Some special attributes can override Datadog Span fields
121
121
  def span_arguments(span, attributes)
122
122
  if attributes.key?('analytics.event') && (analytics_event = attributes['analytics.event']).respond_to?(:casecmp)
123
- attributes[Tracing::Metadata::Ext::Analytics::TAG_SAMPLE_RATE] = analytics_event.casecmp('true') == 0 ? 1 : 0
123
+ attributes[Tracing::Metadata::Ext::Analytics::TAG_SAMPLE_RATE] = (analytics_event.casecmp('true') == 0) ? 1 : 0
124
124
  end
125
125
 
126
126
  if attributes.key?('http.response.status_code')
@@ -129,15 +129,15 @@ module Datadog
129
129
 
130
130
  attributes[Tracing::Metadata::Ext::TAG_KIND] = span.kind || 'internal'
131
131
 
132
- kwargs = { start_time: ns_to_time(span.start_timestamp) }
132
+ kwargs = {start_time: ns_to_time(span.start_timestamp)}
133
133
 
134
134
  name = if attributes.key?('operation.name')
135
- attributes['operation.name']
136
- elsif (rich_name = Datadog::OpenTelemetry::Trace::Span.enrich_name(span.kind, attributes))
137
- rich_name.downcase
138
- else
139
- span.kind
140
- end
135
+ attributes['operation.name']
136
+ elsif (rich_name = Datadog::OpenTelemetry::Trace::Span.enrich_name(span.kind, attributes))
137
+ rich_name.downcase
138
+ else
139
+ span.kind
140
+ end
141
141
 
142
142
  kwargs[:resource] = attributes.key?('resource.name') ? attributes['resource.name'] : span.name
143
143
  kwargs[:service] = attributes['service.name'] if attributes.key?('service.name')
@@ -38,8 +38,8 @@ module Datadog
38
38
  res
39
39
  end
40
40
 
41
- # `alias` performed to match {OpenTelemetry::SDK::Trace::Span} aliasing upstream
42
- alias []= set_attribute
41
+ # `alias` performed to match {::OpenTelemetry::SDK::Trace::Span} aliasing upstream
42
+ alias []= set_attribute # rubocop:disable Style/Alias
43
43
 
44
44
  # Attributes are equivalent to span tags and metrics.
45
45
  def add_attributes(attributes)
@@ -72,24 +72,24 @@ module Datadog
72
72
  return 'http.client.request' if kind == :client
73
73
  end
74
74
 
75
- return "#{attrs['db.system']}.query" if attrs.key?('db.system') && kind == :client
75
+ return "#{attrs["db.system"]}.query" if attrs.key?('db.system') && kind == :client
76
76
 
77
77
  if (attrs.key?('messaging.system') || attrs.key?('messaging.operation')) &&
78
78
  [:consumer, :producer, :server, :client].include?(kind)
79
79
 
80
- return "#{attrs['messaging.system']}.#{attrs['messaging.operation']}"
80
+ return "#{attrs["messaging.system"]}.#{attrs["messaging.operation"]}"
81
81
  end
82
82
 
83
83
  if attrs.key?('rpc.system')
84
84
  if attrs['rpc.system'] == 'aws-api' && kind == :client
85
85
  service = attrs['rpc.service']
86
- return "aws.#{service || 'client'}.request"
86
+ return "aws.#{service || "client"}.request"
87
87
  end
88
88
 
89
89
  if kind == :client
90
- return "#{attrs['rpc.system']}.client.request"
90
+ return "#{attrs["rpc.system"]}.client.request"
91
91
  elsif kind == :server
92
- return "#{attrs['rpc.system']}.server.request"
92
+ return "#{attrs["rpc.system"]}.server.request"
93
93
  end
94
94
  end
95
95
 
@@ -99,7 +99,7 @@ module Datadog
99
99
  return "#{provider}.#{name}.invoke"
100
100
  end
101
101
 
102
- return "#{attrs['faas.trigger']}.invoke" if attrs.key?('faas.trigger') && kind == :server
102
+ return "#{attrs["faas.trigger"]}.invoke" if attrs.key?('faas.trigger') && kind == :server
103
103
 
104
104
  return 'graphql.server.request' if attrs.key?('graphql.operation.type')
105
105
 
@@ -119,6 +119,7 @@ module Datadog
119
119
 
120
120
  private
121
121
 
122
+ # rubocop:disable Metrics/CyclomaticComplexity,Metrics/PerceivedComplexity
122
123
  def datadog_set_attribute(key)
123
124
  # Return if attributes are currently disabled by OpenTelemetry.
124
125
  return unless defined?(@attributes) && @attributes
@@ -149,9 +150,11 @@ module Datadog
149
150
  end
150
151
  end
151
152
  end
153
+ # rubocop:enable Metrics/CyclomaticComplexity,Metrics/PerceivedComplexity
152
154
 
153
155
  # Some special attributes can override Datadog Span fields beyond tags and metrics.
154
156
  # @return [Boolean] true if the key is a Datadog Span override attribute, false otherwise
157
+ # rubocop:disable Metrics/CyclomaticComplexity,Metrics/PerceivedComplexity
155
158
  def override_datadog_values(span, key, value)
156
159
  span.name = value if key == 'operation.name'
157
160
  span.resource = value if key == 'resource.name'
@@ -161,15 +164,16 @@ module Datadog
161
164
  if key == 'analytics.event' && value.respond_to?(:casecmp)
162
165
  Datadog::Tracing::Analytics.set_sample_rate(
163
166
  span,
164
- value.casecmp('true') == 0 ? 1 : 0
167
+ (value.casecmp('true') == 0) ? 1 : 0
165
168
  )
166
169
  end
167
170
 
168
171
  span.set_tag('http.status_code', value) if key == 'http.response.status_code'
169
172
  end
173
+ # rubocop:enable Metrics/CyclomaticComplexity,Metrics/PerceivedComplexity
170
174
 
171
175
  DATADOG_SPAN_ATTRIBUTE_OVERRIDES = ['analytics.event', 'operation.name', 'resource.name', 'service.name',
172
- 'span.type', 'http.response.status_code'].freeze
176
+ 'span.type', 'http.response.status_code'].freeze
173
177
 
174
178
  ::OpenTelemetry::SDK::Trace::Span.prepend(self)
175
179
  end
@@ -15,10 +15,10 @@ module Datadog
15
15
  # @return [TraceOperation]
16
16
  def start_trace_copy(trace, parent_span: nil)
17
17
  digest = if parent_span
18
- digest_with_parent_span(trace, parent_span)
19
- else
20
- trace.to_digest
21
- end
18
+ digest_with_parent_span(trace, parent_span)
19
+ else
20
+ trace.to_digest
21
+ end
22
22
 
23
23
  # Create a new TraceOperation, attached to the current Datadog Tracer.
24
24
  Datadog::Tracing.continue_trace!(digest)
@@ -23,6 +23,7 @@ module Datadog
23
23
  allocation_profiling_enabled:,
24
24
  allocation_counting_enabled:,
25
25
  gvl_profiling_enabled:,
26
+ sighandler_sampling_enabled:,
26
27
  # **NOTE**: This should only be used for testing; disabling the dynamic sampling rate will increase the
27
28
  # profiler overhead!
28
29
  dynamic_sampling_rate_enabled: true,
@@ -49,6 +50,7 @@ module Datadog
49
50
  allocation_profiling_enabled: allocation_profiling_enabled,
50
51
  allocation_counting_enabled: allocation_counting_enabled,
51
52
  gvl_profiling_enabled: gvl_profiling_enabled,
53
+ sighandler_sampling_enabled: sighandler_sampling_enabled,
52
54
  skip_idle_samples_for_testing: skip_idle_samples_for_testing,
53
55
  )
54
56
  @worker_thread = nil
@@ -28,6 +28,37 @@ module Datadog
28
28
 
29
29
  private
30
30
 
31
+ # Ruby GC tuning environment variables
32
+ RUBY_GC_TUNING_ENV_VARS = [
33
+ "RUBY_GC_HEAP_FREE_SLOTS",
34
+ "RUBY_GC_HEAP_GROWTH_FACTOR",
35
+ "RUBY_GC_HEAP_GROWTH_MAX_SLOTS",
36
+ "RUBY_GC_HEAP_FREE_SLOTS_MIN_RATIO",
37
+ "RUBY_GC_HEAP_FREE_SLOTS_MAX_RATIO",
38
+ "RUBY_GC_HEAP_FREE_SLOTS_GOAL_RATIO",
39
+ "RUBY_GC_HEAP_OLDOBJECT_LIMIT_FACTOR",
40
+ "RUBY_GC_HEAP_REMEMBERED_WB_UNPROTECTED_OBJECTS_LIMIT_RATIO",
41
+ "RUBY_GC_MALLOC_LIMIT",
42
+ "RUBY_GC_MALLOC_LIMIT_MAX",
43
+ "RUBY_GC_MALLOC_LIMIT_GROWTH_FACTOR",
44
+ "RUBY_GC_OLDMALLOC_LIMIT",
45
+ "RUBY_GC_OLDMALLOC_LIMIT_MAX",
46
+ "RUBY_GC_OLDMALLOC_LIMIT_GROWTH_FACTOR",
47
+ # INIT_SLOTS changed for Ruby 3.3+:
48
+ # * https://bugs.ruby-lang.org/issues/19785
49
+ # * https://www.ruby-lang.org/en/news/2023/12/25/ruby-3-3-0-released/#:~:text=Removed%20environment%20variables
50
+ "RUBY_GC_HEAP_0_INIT_SLOTS",
51
+ "RUBY_GC_HEAP_1_INIT_SLOTS",
52
+ "RUBY_GC_HEAP_2_INIT_SLOTS",
53
+ "RUBY_GC_HEAP_3_INIT_SLOTS",
54
+ "RUBY_GC_HEAP_4_INIT_SLOTS",
55
+ # There was only one setting for older Rubies:
56
+ "RUBY_GC_HEAP_INIT_SLOTS",
57
+ # Ruby 2.x only, alias for others:
58
+ "RUBY_FREE_MIN",
59
+ "RUBY_HEAP_MIN_SLOTS",
60
+ ].freeze
61
+
31
62
  # Instead of trying to figure out real process start time by checking
32
63
  # /proc or some other complex/non-portable way, approximate start time
33
64
  # by time of requirement of this file.
@@ -51,6 +82,7 @@ module Datadog
51
82
  engine: Datadog::Core::Environment::Identity.lang_engine,
52
83
  version: Datadog::Core::Environment::Identity.lang_version,
53
84
  platform: Datadog::Core::Environment::Identity.lang_platform,
85
+ gc_tuning: collect_gc_tuning_info,
54
86
  }.freeze
55
87
  end
56
88
 
@@ -109,6 +141,15 @@ module Datadog
109
141
  v.inspect
110
142
  end
111
143
  end
144
+
145
+ def collect_gc_tuning_info
146
+ return @gc_tuning_info if defined?(@gc_tuning_info)
147
+
148
+ @gc_tuning_info = RUBY_GC_TUNING_ENV_VARS.each_with_object({}) do |var, hash|
149
+ current_value = ENV[var]
150
+ hash[var.to_sym] = current_value if current_value
151
+ end.freeze
152
+ end
112
153
  end
113
154
  end
114
155
  end
@@ -67,6 +67,7 @@ module Datadog
67
67
  allocation_profiling_enabled: allocation_profiling_enabled,
68
68
  allocation_counting_enabled: settings.profiling.advanced.allocation_counting_enabled,
69
69
  gvl_profiling_enabled: enable_gvl_profiling?(settings, logger),
70
+ sighandler_sampling_enabled: settings.profiling.advanced.sighandler_sampling_enabled,
70
71
  )
71
72
 
72
73
  internal_metadata = {