ddtrace 1.12.1 → 1.14.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (275) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +158 -9
  3. data/ext/ddtrace_profiling_native_extension/collectors_thread_context.c +97 -14
  4. data/ext/ddtrace_profiling_native_extension/extconf.rb +6 -0
  5. data/ext/ddtrace_profiling_native_extension/http_transport.c +19 -6
  6. data/ext/ddtrace_profiling_native_extension/native_extension_helpers.rb +16 -1
  7. data/ext/ddtrace_profiling_native_extension/private_vm_api_access.c +41 -2
  8. data/ext/ddtrace_profiling_native_extension/private_vm_api_access.h +6 -0
  9. data/ext/ddtrace_profiling_native_extension/stack_recorder.c +6 -10
  10. data/ext/ddtrace_profiling_native_extension/time_helpers.c +40 -4
  11. data/ext/ddtrace_profiling_native_extension/time_helpers.h +14 -0
  12. data/lib/datadog/appsec/component.rb +9 -0
  13. data/lib/datadog/appsec/configuration/settings.rb +110 -195
  14. data/lib/datadog/appsec/configuration.rb +0 -79
  15. data/lib/datadog/appsec/contrib/auto_instrument.rb +2 -4
  16. data/lib/datadog/appsec/contrib/devise/event.rb +57 -0
  17. data/lib/datadog/appsec/contrib/devise/ext.rb +13 -0
  18. data/lib/datadog/appsec/contrib/devise/integration.rb +42 -0
  19. data/lib/datadog/appsec/contrib/devise/patcher/authenticatable_patch.rb +76 -0
  20. data/lib/datadog/appsec/contrib/devise/patcher/registration_controller_patch.rb +52 -0
  21. data/lib/datadog/appsec/contrib/devise/patcher.rb +45 -0
  22. data/lib/datadog/appsec/contrib/devise/resource.rb +35 -0
  23. data/lib/datadog/appsec/contrib/devise/tracking.rb +49 -0
  24. data/lib/datadog/appsec/contrib/rack/ext.rb +2 -1
  25. data/lib/datadog/appsec/contrib/rack/reactive/request.rb +1 -1
  26. data/lib/datadog/appsec/contrib/rack/reactive/request_body.rb +1 -1
  27. data/lib/datadog/appsec/contrib/rack/reactive/response.rb +1 -1
  28. data/lib/datadog/appsec/contrib/rack/request_middleware.rb +12 -7
  29. data/lib/datadog/appsec/contrib/rails/ext.rb +3 -2
  30. data/lib/datadog/appsec/contrib/rails/framework.rb +1 -3
  31. data/lib/datadog/appsec/contrib/rails/patcher.rb +8 -8
  32. data/lib/datadog/appsec/contrib/rails/reactive/action.rb +1 -1
  33. data/lib/datadog/appsec/contrib/sinatra/ext.rb +2 -1
  34. data/lib/datadog/appsec/contrib/sinatra/framework.rb +1 -3
  35. data/lib/datadog/appsec/contrib/sinatra/reactive/routed.rb +1 -1
  36. data/lib/datadog/appsec/event.rb +1 -1
  37. data/lib/datadog/appsec/extensions.rb +1 -130
  38. data/lib/datadog/appsec/monitor/reactive/set_user.rb +1 -1
  39. data/lib/datadog/appsec/processor.rb +1 -1
  40. data/lib/datadog/appsec/rate_limiter.rb +1 -1
  41. data/lib/datadog/appsec/remote.rb +1 -1
  42. data/lib/datadog/appsec.rb +1 -2
  43. data/lib/datadog/ci/configuration/settings.rb +6 -8
  44. data/lib/datadog/ci/contrib/cucumber/configuration/settings.rb +7 -5
  45. data/lib/datadog/ci/contrib/cucumber/ext.rb +10 -8
  46. data/lib/datadog/ci/contrib/minitest/configuration/settings.rb +35 -0
  47. data/lib/datadog/ci/contrib/minitest/ext.rb +21 -0
  48. data/lib/datadog/ci/contrib/minitest/integration.rb +49 -0
  49. data/lib/datadog/ci/contrib/minitest/patcher.rb +27 -0
  50. data/lib/datadog/ci/contrib/minitest/test_helper.rb +68 -0
  51. data/lib/datadog/ci/contrib/rspec/configuration/settings.rb +7 -5
  52. data/lib/datadog/ci/contrib/rspec/ext.rb +9 -7
  53. data/lib/datadog/ci.rb +1 -0
  54. data/lib/datadog/core/backport.rb +51 -0
  55. data/lib/datadog/core/configuration/agent_settings_resolver.rb +9 -5
  56. data/lib/datadog/core/configuration/base.rb +5 -5
  57. data/lib/datadog/core/configuration/components.rb +8 -1
  58. data/lib/datadog/core/configuration/ext.rb +7 -5
  59. data/lib/datadog/core/configuration/option.rb +269 -19
  60. data/lib/datadog/core/configuration/option_definition.rb +76 -11
  61. data/lib/datadog/core/configuration/options.rb +22 -10
  62. data/lib/datadog/core/configuration/settings.rb +139 -61
  63. data/lib/datadog/core/diagnostics/environment_logger.rb +130 -234
  64. data/lib/datadog/core/environment/execution.rb +65 -0
  65. data/lib/datadog/core/environment/ext.rb +13 -11
  66. data/lib/datadog/core/environment/yjit.rb +58 -0
  67. data/lib/datadog/core/git/ext.rb +24 -22
  68. data/lib/datadog/core/logging/ext.rb +3 -1
  69. data/lib/datadog/core/metrics/ext.rb +7 -5
  70. data/lib/datadog/core/remote/client/capabilities.rb +5 -0
  71. data/lib/datadog/core/remote/client.rb +3 -0
  72. data/lib/datadog/core/remote/component.rb +25 -34
  73. data/lib/datadog/core/remote/configuration/content.rb +28 -1
  74. data/lib/datadog/core/remote/configuration/repository.rb +3 -1
  75. data/lib/datadog/core/remote/ext.rb +1 -1
  76. data/lib/datadog/core/remote/negotiation.rb +17 -4
  77. data/lib/datadog/core/runtime/ext.rb +22 -12
  78. data/lib/datadog/core/runtime/metrics.rb +43 -0
  79. data/lib/datadog/core/telemetry/client.rb +12 -2
  80. data/lib/datadog/core/telemetry/collector.rb +10 -2
  81. data/lib/datadog/core/telemetry/emitter.rb +4 -2
  82. data/lib/datadog/core/telemetry/event.rb +19 -4
  83. data/lib/datadog/core/telemetry/ext.rb +4 -1
  84. data/lib/datadog/core/telemetry/heartbeat.rb +2 -4
  85. data/lib/datadog/core/telemetry/http/ext.rb +10 -8
  86. data/lib/datadog/core/telemetry/http/transport.rb +1 -0
  87. data/lib/datadog/core/telemetry/v2/app_client_configuration_change.rb +41 -0
  88. data/lib/datadog/core/telemetry/v2/request.rb +29 -0
  89. data/lib/datadog/core/transport/http/client.rb +1 -1
  90. data/lib/datadog/core/transport/http/config.rb +10 -0
  91. data/lib/datadog/core/utils/duration.rb +52 -0
  92. data/lib/datadog/core/utils/hash.rb +47 -0
  93. data/lib/datadog/core/utils/network.rb +1 -1
  94. data/lib/datadog/core/utils/safe_dup.rb +27 -20
  95. data/lib/datadog/core/utils.rb +1 -1
  96. data/lib/datadog/core/workers/async.rb +2 -2
  97. data/lib/datadog/kit/appsec/events.rb +139 -89
  98. data/lib/datadog/kit/identity.rb +80 -65
  99. data/lib/datadog/profiling/collectors/cpu_and_wall_time_worker.rb +3 -0
  100. data/lib/datadog/profiling/collectors/idle_sampling_helper.rb +1 -0
  101. data/lib/datadog/profiling/collectors/thread_context.rb +9 -2
  102. data/lib/datadog/profiling/component.rb +51 -9
  103. data/lib/datadog/profiling/diagnostics/environment_logger.rb +39 -0
  104. data/lib/datadog/profiling/exporter.rb +5 -1
  105. data/lib/datadog/profiling/flush.rb +7 -2
  106. data/lib/datadog/profiling/http_transport.rb +13 -3
  107. data/lib/datadog/profiling/load_native_extension.rb +7 -1
  108. data/lib/datadog/profiling.rb +12 -1
  109. data/lib/datadog/tracing/component.rb +60 -7
  110. data/lib/datadog/tracing/configuration/dynamic/option.rb +71 -0
  111. data/lib/datadog/tracing/configuration/dynamic.rb +64 -0
  112. data/lib/datadog/tracing/configuration/ext.rb +35 -32
  113. data/lib/datadog/tracing/configuration/http.rb +74 -0
  114. data/lib/datadog/tracing/configuration/settings.rb +106 -92
  115. data/lib/datadog/tracing/contrib/action_cable/configuration/settings.rb +9 -6
  116. data/lib/datadog/tracing/contrib/action_cable/ext.rb +20 -18
  117. data/lib/datadog/tracing/contrib/action_mailer/configuration/settings.rb +9 -6
  118. data/lib/datadog/tracing/contrib/action_mailer/ext.rb +20 -18
  119. data/lib/datadog/tracing/contrib/action_pack/configuration/settings.rb +8 -6
  120. data/lib/datadog/tracing/contrib/action_pack/ext.rb +10 -8
  121. data/lib/datadog/tracing/contrib/action_view/configuration/settings.rb +9 -6
  122. data/lib/datadog/tracing/contrib/action_view/ext.rb +12 -10
  123. data/lib/datadog/tracing/contrib/active_job/configuration/settings.rb +13 -7
  124. data/lib/datadog/tracing/contrib/active_job/ext.rb +25 -23
  125. data/lib/datadog/tracing/contrib/active_job/log_injection.rb +1 -1
  126. data/lib/datadog/tracing/contrib/active_job/patcher.rb +1 -1
  127. data/lib/datadog/tracing/contrib/active_model_serializers/configuration/settings.rb +9 -6
  128. data/lib/datadog/tracing/contrib/active_model_serializers/ext.rb +12 -10
  129. data/lib/datadog/tracing/contrib/active_record/configuration/resolver.rb +18 -11
  130. data/lib/datadog/tracing/contrib/active_record/configuration/settings.rb +9 -7
  131. data/lib/datadog/tracing/contrib/active_record/events/sql.rb +0 -8
  132. data/lib/datadog/tracing/contrib/active_record/ext.rb +17 -15
  133. data/lib/datadog/tracing/contrib/active_record/utils.rb +1 -1
  134. data/lib/datadog/tracing/contrib/active_support/cache/instrumentation.rb +0 -5
  135. data/lib/datadog/tracing/contrib/active_support/configuration/settings.rb +9 -7
  136. data/lib/datadog/tracing/contrib/active_support/ext.rb +18 -16
  137. data/lib/datadog/tracing/contrib/aws/configuration/settings.rb +14 -7
  138. data/lib/datadog/tracing/contrib/aws/ext.rb +37 -24
  139. data/lib/datadog/tracing/contrib/aws/instrumentation.rb +9 -5
  140. data/lib/datadog/tracing/contrib/concurrent_ruby/configuration/settings.rb +3 -2
  141. data/lib/datadog/tracing/contrib/concurrent_ruby/ext.rb +4 -2
  142. data/lib/datadog/tracing/contrib/dalli/configuration/settings.rb +14 -7
  143. data/lib/datadog/tracing/contrib/dalli/ext.rb +19 -11
  144. data/lib/datadog/tracing/contrib/dalli/instrumentation.rb +8 -6
  145. data/lib/datadog/tracing/contrib/delayed_job/configuration/settings.rb +13 -7
  146. data/lib/datadog/tracing/contrib/delayed_job/ext.rb +16 -14
  147. data/lib/datadog/tracing/contrib/elasticsearch/configuration/settings.rb +14 -7
  148. data/lib/datadog/tracing/contrib/elasticsearch/ext.rb +21 -15
  149. data/lib/datadog/tracing/contrib/elasticsearch/patcher.rb +99 -99
  150. data/lib/datadog/tracing/contrib/ethon/configuration/settings.rb +16 -9
  151. data/lib/datadog/tracing/contrib/ethon/easy_patch.rb +43 -3
  152. data/lib/datadog/tracing/contrib/ethon/ext.rb +19 -11
  153. data/lib/datadog/tracing/contrib/ethon/multi_patch.rb +0 -5
  154. data/lib/datadog/tracing/contrib/excon/configuration/settings.rb +19 -10
  155. data/lib/datadog/tracing/contrib/excon/ext.rb +16 -8
  156. data/lib/datadog/tracing/contrib/excon/middleware.rb +20 -5
  157. data/lib/datadog/tracing/contrib/ext.rb +23 -1
  158. data/lib/datadog/tracing/contrib/extensions.rb +32 -0
  159. data/lib/datadog/tracing/contrib/faraday/configuration/settings.rb +20 -10
  160. data/lib/datadog/tracing/contrib/faraday/ext.rb +16 -8
  161. data/lib/datadog/tracing/contrib/faraday/middleware.rb +16 -5
  162. data/lib/datadog/tracing/contrib/grape/configuration/settings.rb +8 -6
  163. data/lib/datadog/tracing/contrib/grape/ext.rb +16 -14
  164. data/lib/datadog/tracing/contrib/graphql/configuration/settings.rb +8 -6
  165. data/lib/datadog/tracing/contrib/graphql/ext.rb +7 -5
  166. data/lib/datadog/tracing/contrib/grpc/configuration/settings.rb +19 -9
  167. data/lib/datadog/tracing/contrib/grpc/datadog_interceptor/client.rb +29 -20
  168. data/lib/datadog/tracing/contrib/grpc/datadog_interceptor/server.rb +21 -20
  169. data/lib/datadog/tracing/contrib/grpc/ext.rb +16 -13
  170. data/lib/datadog/tracing/contrib/grpc/formatting.rb +127 -0
  171. data/lib/datadog/tracing/contrib/hanami/configuration/settings.rb +3 -2
  172. data/lib/datadog/tracing/contrib/hanami/ext.rb +10 -8
  173. data/lib/datadog/tracing/contrib/http/circuit_breaker.rb +4 -7
  174. data/lib/datadog/tracing/contrib/http/configuration/settings.rb +33 -11
  175. data/lib/datadog/tracing/contrib/http/ext.rb +16 -9
  176. data/lib/datadog/tracing/contrib/http/instrumentation.rb +22 -7
  177. data/lib/datadog/tracing/contrib/httpclient/configuration/settings.rb +33 -11
  178. data/lib/datadog/tracing/contrib/httpclient/ext.rb +17 -9
  179. data/lib/datadog/tracing/contrib/httpclient/instrumentation.rb +17 -5
  180. data/lib/datadog/tracing/contrib/httprb/configuration/settings.rb +33 -11
  181. data/lib/datadog/tracing/contrib/httprb/ext.rb +16 -9
  182. data/lib/datadog/tracing/contrib/httprb/instrumentation.rb +17 -5
  183. data/lib/datadog/tracing/contrib/kafka/configuration/settings.rb +9 -6
  184. data/lib/datadog/tracing/contrib/kafka/ext.rb +42 -39
  185. data/lib/datadog/tracing/contrib/lograge/configuration/settings.rb +3 -2
  186. data/lib/datadog/tracing/contrib/lograge/ext.rb +3 -1
  187. data/lib/datadog/tracing/contrib/lograge/instrumentation.rb +2 -17
  188. data/lib/datadog/tracing/contrib/mongodb/configuration/settings.rb +14 -7
  189. data/lib/datadog/tracing/contrib/mongodb/ext.rb +20 -16
  190. data/lib/datadog/tracing/contrib/mongodb/subscribers.rb +9 -5
  191. data/lib/datadog/tracing/contrib/mysql2/configuration/settings.rb +17 -14
  192. data/lib/datadog/tracing/contrib/mysql2/ext.rb +15 -10
  193. data/lib/datadog/tracing/contrib/mysql2/instrumentation.rb +9 -5
  194. data/lib/datadog/tracing/contrib/opensearch/configuration/settings.rb +52 -0
  195. data/lib/datadog/tracing/contrib/opensearch/ext.rb +37 -0
  196. data/lib/datadog/tracing/contrib/opensearch/integration.rb +44 -0
  197. data/lib/datadog/tracing/contrib/opensearch/patcher.rb +128 -0
  198. data/lib/datadog/tracing/contrib/opensearch/quantize.rb +81 -0
  199. data/lib/datadog/tracing/contrib/pg/configuration/settings.rb +17 -14
  200. data/lib/datadog/tracing/contrib/pg/ext.rb +22 -19
  201. data/lib/datadog/tracing/contrib/pg/instrumentation.rb +9 -5
  202. data/lib/datadog/tracing/contrib/presto/configuration/settings.rb +14 -7
  203. data/lib/datadog/tracing/contrib/presto/ext.rb +25 -20
  204. data/lib/datadog/tracing/contrib/presto/instrumentation.rb +9 -5
  205. data/lib/datadog/tracing/contrib/propagation/sql_comment/ext.rb +12 -10
  206. data/lib/datadog/tracing/contrib/qless/configuration/settings.rb +12 -8
  207. data/lib/datadog/tracing/contrib/qless/ext.rb +14 -12
  208. data/lib/datadog/tracing/contrib/que/configuration/settings.rb +21 -12
  209. data/lib/datadog/tracing/contrib/racecar/configuration/settings.rb +9 -7
  210. data/lib/datadog/tracing/contrib/racecar/event.rb +0 -5
  211. data/lib/datadog/tracing/contrib/racecar/ext.rb +20 -18
  212. data/lib/datadog/tracing/contrib/rack/configuration/settings.rb +16 -12
  213. data/lib/datadog/tracing/contrib/rack/ext.rb +18 -16
  214. data/lib/datadog/tracing/contrib/rack/header_collection.rb +3 -0
  215. data/lib/datadog/tracing/contrib/rack/header_tagging.rb +53 -0
  216. data/lib/datadog/tracing/contrib/rack/middlewares.rb +8 -49
  217. data/lib/datadog/tracing/contrib/rails/configuration/settings.rb +15 -11
  218. data/lib/datadog/tracing/contrib/rails/ext.rb +7 -5
  219. data/lib/datadog/tracing/contrib/rails/log_injection.rb +7 -10
  220. data/lib/datadog/tracing/contrib/rails/patcher.rb +10 -41
  221. data/lib/datadog/tracing/contrib/rails/railtie.rb +3 -3
  222. data/lib/datadog/tracing/contrib/rake/configuration/settings.rb +12 -9
  223. data/lib/datadog/tracing/contrib/rake/ext.rb +14 -12
  224. data/lib/datadog/tracing/contrib/redis/configuration/settings.rb +17 -9
  225. data/lib/datadog/tracing/contrib/redis/ext.rb +22 -15
  226. data/lib/datadog/tracing/contrib/redis/tags.rb +9 -5
  227. data/lib/datadog/tracing/contrib/resque/configuration/settings.rb +13 -7
  228. data/lib/datadog/tracing/contrib/resque/ext.rb +9 -7
  229. data/lib/datadog/tracing/contrib/rest_client/configuration/settings.rb +16 -9
  230. data/lib/datadog/tracing/contrib/rest_client/ext.rb +15 -8
  231. data/lib/datadog/tracing/contrib/rest_client/request_patch.rb +20 -5
  232. data/lib/datadog/tracing/contrib/roda/configuration/settings.rb +9 -6
  233. data/lib/datadog/tracing/contrib/semantic_logger/configuration/settings.rb +3 -2
  234. data/lib/datadog/tracing/contrib/semantic_logger/ext.rb +3 -1
  235. data/lib/datadog/tracing/contrib/semantic_logger/instrumentation.rb +4 -20
  236. data/lib/datadog/tracing/contrib/sequel/configuration/settings.rb +9 -6
  237. data/lib/datadog/tracing/contrib/sequel/ext.rb +10 -8
  238. data/lib/datadog/tracing/contrib/sequel/utils.rb +2 -7
  239. data/lib/datadog/tracing/contrib/shoryuken/configuration/settings.rb +14 -8
  240. data/lib/datadog/tracing/contrib/shoryuken/ext.rb +14 -12
  241. data/lib/datadog/tracing/contrib/sidekiq/configuration/settings.rb +18 -11
  242. data/lib/datadog/tracing/contrib/sidekiq/ext.rb +32 -30
  243. data/lib/datadog/tracing/contrib/sinatra/configuration/settings.rb +11 -9
  244. data/lib/datadog/tracing/contrib/sinatra/env.rb +0 -17
  245. data/lib/datadog/tracing/contrib/sinatra/ext.rb +21 -19
  246. data/lib/datadog/tracing/contrib/sinatra/tracer_middleware.rb +3 -14
  247. data/lib/datadog/tracing/contrib/sneakers/configuration/settings.rb +14 -8
  248. data/lib/datadog/tracing/contrib/sneakers/ext.rb +1 -0
  249. data/lib/datadog/tracing/contrib/sneakers/tracer.rb +1 -1
  250. data/lib/datadog/tracing/contrib/span_attribute_schema.rb +74 -10
  251. data/lib/datadog/tracing/contrib/stripe/configuration/settings.rb +9 -6
  252. data/lib/datadog/tracing/contrib/sucker_punch/configuration/settings.rb +9 -6
  253. data/lib/datadog/tracing/contrib/sucker_punch/ext.rb +15 -13
  254. data/lib/datadog/tracing/contrib/utils/database.rb +5 -3
  255. data/lib/datadog/tracing/contrib/utils/quantization/http.rb +9 -9
  256. data/lib/datadog/tracing/contrib.rb +1 -0
  257. data/lib/datadog/tracing/correlation.rb +29 -12
  258. data/lib/datadog/tracing/diagnostics/environment_logger.rb +159 -0
  259. data/lib/datadog/tracing/diagnostics/ext.rb +21 -19
  260. data/lib/datadog/tracing/distributed/b3_multi.rb +2 -2
  261. data/lib/datadog/tracing/distributed/b3_single.rb +1 -1
  262. data/lib/datadog/tracing/distributed/trace_context.rb +52 -17
  263. data/lib/datadog/tracing/metadata/ext.rb +9 -6
  264. data/lib/datadog/tracing/remote.rb +78 -0
  265. data/lib/datadog/tracing/sampling/rule_sampler.rb +29 -0
  266. data/lib/datadog/tracing/span_operation.rb +3 -15
  267. data/lib/datadog/tracing/trace_operation.rb +16 -3
  268. data/lib/datadog/tracing/trace_segment.rb +5 -2
  269. data/lib/datadog/tracing/tracer.rb +10 -1
  270. data/lib/datadog/tracing/workers/trace_writer.rb +1 -1
  271. data/lib/ddtrace/transport/ext.rb +15 -9
  272. data/lib/ddtrace/transport/trace_formatter.rb +9 -0
  273. data/lib/ddtrace/version.rb +9 -12
  274. metadata +37 -6
  275. data/lib/datadog/tracing/contrib/sinatra/headers.rb +0 -35
@@ -1,5 +1,6 @@
1
1
  require_relative 'utils'
2
2
  require_relative 'metadata/ext'
3
+ require_relative '../core/logging/ext'
3
4
 
4
5
  module Datadog
5
6
  module Tracing
@@ -14,6 +15,7 @@ module Datadog
14
15
  LOG_ATTR_SPAN_ID = 'dd.span_id'.freeze
15
16
  LOG_ATTR_TRACE_ID = 'dd.trace_id'.freeze
16
17
  LOG_ATTR_VERSION = 'dd.version'.freeze
18
+ LOG_ATTR_SOURCE = 'ddsource'.freeze
17
19
 
18
20
  attr_reader \
19
21
  :env,
@@ -23,7 +25,6 @@ module Datadog
23
25
  :span_resource,
24
26
  :span_service,
25
27
  :span_type,
26
- :trace_id,
27
28
  :trace_name,
28
29
  :trace_resource,
29
30
  :trace_service,
@@ -59,28 +60,44 @@ module Datadog
59
60
  @version = Core::Utils::SafeDup.frozen_dup(version || Datadog.configuration.version)
60
61
  end
61
62
 
63
+ def to_h
64
+ @to_h ||= {
65
+ # Adds IDs as tags to log output
66
+ dd: {
67
+ # To preserve precision during JSON serialization, use strings for large numbers
68
+ env: env.to_s,
69
+ service: service.to_s,
70
+ version: version.to_s,
71
+ trace_id: trace_id.to_s,
72
+ span_id: span_id.to_s
73
+ },
74
+ ddsource: Core::Logging::Ext::DD_SOURCE
75
+ }
76
+ end
77
+
78
+ # This method (#to_log_format) implements an algorithm by prefixing keys for nested values
79
+ # but the algorithm makes the constants implicit. Hence, we use it for validation during test.
62
80
  def to_log_format
63
81
  @log_format ||= begin
64
82
  attributes = []
65
83
  attributes << "#{LOG_ATTR_ENV}=#{env}" unless env.nil?
66
84
  attributes << "#{LOG_ATTR_SERVICE}=#{service}"
67
85
  attributes << "#{LOG_ATTR_VERSION}=#{version}" unless version.nil?
68
- attributes << "#{LOG_ATTR_TRACE_ID}=#{logging_trace_id}"
86
+ attributes << "#{LOG_ATTR_TRACE_ID}=#{trace_id}"
69
87
  attributes << "#{LOG_ATTR_SPAN_ID}=#{span_id}"
88
+ attributes << "#{LOG_ATTR_SOURCE}=#{Core::Logging::Ext::DD_SOURCE}"
70
89
  attributes.join(' ')
71
90
  end
72
91
  end
73
92
 
74
- private
75
-
76
- def logging_trace_id
77
- @logging_trace_id ||=
78
- if Datadog.configuration.tracing.trace_id_128_bit_logging_enabled &&
79
- !Tracing::Utils::TraceId.to_high_order(@trace_id).zero?
80
- Kernel.format('%032x', trace_id)
81
- else
82
- Tracing::Utils::TraceId.to_low_order(@trace_id)
83
- end
93
+ # DEV-2.0: This public method was returning an Integer, but with 128 bit trace id it would return a String.
94
+ def trace_id
95
+ if Datadog.configuration.tracing.trace_id_128_bit_logging_enabled &&
96
+ !Tracing::Utils::TraceId.to_high_order(@trace_id).zero?
97
+ Kernel.format('%032x', @trace_id)
98
+ else
99
+ Tracing::Utils::TraceId.to_low_order(@trace_id)
100
+ end
84
101
  end
85
102
  end
86
103
 
@@ -0,0 +1,159 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'date'
4
+ require 'json'
5
+ require 'rbconfig'
6
+ require_relative '../../core/diagnostics/environment_logger'
7
+
8
+ module Datadog
9
+ module Tracing
10
+ module Diagnostics
11
+ # Collects and logs Tracing diagnostic and error information
12
+ module EnvironmentLogger
13
+ extend Core::Diagnostics::EnvironmentLogging
14
+
15
+ def self.collect_and_log!(responses: nil)
16
+ log_once! do
17
+ env_data = EnvironmentCollector.collect_config!
18
+ log_configuration!('TRACING', env_data.to_json)
19
+
20
+ if responses
21
+ err_data = EnvironmentCollector.collect_errors!(responses)
22
+ err_data.reject! { |_, v| v.nil? } # Remove empty values from hash output
23
+ log_error!('TRACING', 'Agent Error', err_data.to_json) unless err_data.empty?
24
+ end
25
+ end
26
+ rescue => e
27
+ logger.warn("Failed to collect tracing environment information: #{e} Location: #{Array(e.backtrace).first}")
28
+ end
29
+ end
30
+
31
+ # Collects environment information for Tracing diagnostic logging
32
+ module EnvironmentCollector
33
+ class << self
34
+ def collect_config!
35
+ {
36
+ enabled: enabled,
37
+ agent_url: agent_url,
38
+ analytics_enabled: analytics_enabled,
39
+ sample_rate: sample_rate,
40
+ sampling_rules: sampling_rules,
41
+ integrations_loaded: integrations_loaded,
42
+ partial_flushing_enabled: partial_flushing_enabled,
43
+ priority_sampling_enabled: priority_sampling_enabled,
44
+ **instrumented_integrations_settings
45
+ }
46
+ end
47
+
48
+ def collect_errors!(responses)
49
+ {
50
+ agent_error: agent_error(responses)
51
+ }
52
+ end
53
+
54
+ # @return [Boolean, nil]
55
+ def enabled
56
+ !!Datadog.configuration.tracing.enabled
57
+ end
58
+
59
+ # @return [String, nil] target agent URL for trace flushing
60
+ def agent_url
61
+ # Retrieve the effect agent URL, regardless of how it was configured
62
+ transport = Tracing.send(:tracer).writer.transport
63
+
64
+ # return `nil` with IO transport
65
+ return unless transport.respond_to?(:client)
66
+
67
+ adapter = transport.client.api.adapter
68
+ adapter.url
69
+ end
70
+
71
+ # Error returned by Datadog agent during a tracer flush attempt
72
+ # @return [String] concatenated list of transport errors
73
+ def agent_error(responses)
74
+ error_responses = responses.reject(&:ok?)
75
+
76
+ return nil if error_responses.empty?
77
+
78
+ error_responses.map(&:inspect).join(',')
79
+ end
80
+
81
+ # @return [Boolean, nil] analytics enabled in configuration
82
+ def analytics_enabled
83
+ !!Datadog.configuration.tracing.analytics.enabled
84
+ end
85
+
86
+ # @return [Numeric, nil] tracer sample rate configured
87
+ def sample_rate
88
+ sampler = Datadog.configuration.tracing.sampler
89
+ return nil unless sampler
90
+
91
+ sampler.sample_rate(nil) rescue nil
92
+ end
93
+
94
+ # DEV: We currently only support SimpleRule instances.
95
+ # DEV: These are the most commonly used rules.
96
+ # DEV: We should expand support for other rules in the future,
97
+ # DEV: although it is tricky to serialize arbitrary rules.
98
+ #
99
+ # @return [Hash, nil] sample rules configured
100
+ def sampling_rules
101
+ sampler = Datadog.configuration.tracing.sampler
102
+ return nil unless sampler.is_a?(Tracing::Sampling::PrioritySampler) &&
103
+ sampler.priority_sampler.is_a?(Tracing::Sampling::RuleSampler)
104
+
105
+ sampler.priority_sampler.rules.map do |rule|
106
+ next unless rule.is_a?(Tracing::Sampling::SimpleRule)
107
+
108
+ {
109
+ name: rule.matcher.name,
110
+ service: rule.matcher.service,
111
+ sample_rate: rule.sampler.sample_rate(nil)
112
+ }
113
+ end.compact
114
+ end
115
+
116
+ # Concatenated list of integrations activated, with their gem version.
117
+ # Example: "rails@6.0.3,rack@2.2.3"
118
+ #
119
+ # @return [String, nil]
120
+ def integrations_loaded
121
+ integrations = instrumented_integrations
122
+ return if integrations.empty?
123
+
124
+ integrations.map { |name, integration| "#{name}@#{integration.class.version}" }.join(',')
125
+ end
126
+
127
+ # @return [Boolean, nil] partial flushing enabled in configuration
128
+ def partial_flushing_enabled
129
+ !!Datadog.configuration.tracing.partial_flush.enabled
130
+ end
131
+
132
+ # @return [Boolean, nil] priority sampling enabled in configuration
133
+ def priority_sampling_enabled
134
+ !!Datadog.configuration.tracing.priority_sampling
135
+ end
136
+
137
+ private
138
+
139
+ def instrumented_integrations
140
+ Datadog.configuration.tracing.instrumented_integrations
141
+ end
142
+
143
+ # Capture all active integration settings into "integrationName_settingName: value" entries.
144
+ def instrumented_integrations_settings
145
+ instrumented_integrations.flat_map do |name, integration|
146
+ integration.configuration.to_h.flat_map do |setting, value|
147
+ next [] if setting == :tracer # Skip internal Ruby objects
148
+
149
+ # Convert value to a string to avoid custom #to_json
150
+ # handlers possibly causing errors.
151
+ [[:"integration_#{name}_#{setting}", value.to_s]]
152
+ end
153
+ end.to_h
154
+ end
155
+ end
156
+ end
157
+ end
158
+ end
159
+ end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Datadog
2
4
  module Tracing
3
5
  module Diagnostics
@@ -7,25 +9,25 @@ module Datadog
7
9
  module Health
8
10
  # Metrics
9
11
  module Metrics
10
- METRIC_API_ERRORS = 'datadog.tracer.api.errors'.freeze
11
- METRIC_API_REQUESTS = 'datadog.tracer.api.requests'.freeze
12
- METRIC_API_RESPONSES = 'datadog.tracer.api.responses'.freeze
13
- METRIC_ERROR_CONTEXT_OVERFLOW = 'datadog.tracer.error.context_overflow'.freeze
14
- METRIC_ERROR_INSTRUMENTATION_PATCH = 'datadog.tracer.error.instrumentation_patch'.freeze
15
- METRIC_ERROR_SPAN_FINISH = 'datadog.tracer.error.span_finish'.freeze
16
- METRIC_ERROR_UNFINISHED_SPANS = 'datadog.tracer.error.unfinished_spans'.freeze
17
- METRIC_INSTRUMENTATION_PATCHED = 'datadog.tracer.instrumentation_patched'.freeze
18
- METRIC_QUEUE_ACCEPTED = 'datadog.tracer.queue.accepted'.freeze
19
- METRIC_QUEUE_ACCEPTED_LENGTHS = 'datadog.tracer.queue.accepted_lengths'.freeze
20
- METRIC_QUEUE_DROPPED = 'datadog.tracer.queue.dropped'.freeze
21
- METRIC_QUEUE_LENGTH = 'datadog.tracer.queue.length'.freeze
22
- METRIC_QUEUE_MAX_LENGTH = 'datadog.tracer.queue.max_length'.freeze
23
- METRIC_QUEUE_SPANS = 'datadog.tracer.queue.spans'.freeze
24
- METRIC_SAMPLING_SERVICE_CACHE_LENGTH = 'datadog.tracer.sampling.service_cache_length'.freeze
25
- METRIC_TRACES_FILTERED = 'datadog.tracer.traces.filtered'.freeze
26
- METRIC_TRANSPORT_CHUNKED = 'datadog.tracer.transport.chunked'.freeze
27
- METRIC_TRANSPORT_TRACE_TOO_LARGE = 'datadog.tracer.transport.trace_too_large'.freeze
28
- METRIC_WRITER_CPU_TIME = 'datadog.tracer.writer.cpu_time'.freeze
12
+ METRIC_API_ERRORS = 'datadog.tracer.api.errors'
13
+ METRIC_API_REQUESTS = 'datadog.tracer.api.requests'
14
+ METRIC_API_RESPONSES = 'datadog.tracer.api.responses'
15
+ METRIC_ERROR_CONTEXT_OVERFLOW = 'datadog.tracer.error.context_overflow'
16
+ METRIC_ERROR_INSTRUMENTATION_PATCH = 'datadog.tracer.error.instrumentation_patch'
17
+ METRIC_ERROR_SPAN_FINISH = 'datadog.tracer.error.span_finish'
18
+ METRIC_ERROR_UNFINISHED_SPANS = 'datadog.tracer.error.unfinished_spans'
19
+ METRIC_INSTRUMENTATION_PATCHED = 'datadog.tracer.instrumentation_patched'
20
+ METRIC_QUEUE_ACCEPTED = 'datadog.tracer.queue.accepted'
21
+ METRIC_QUEUE_ACCEPTED_LENGTHS = 'datadog.tracer.queue.accepted_lengths'
22
+ METRIC_QUEUE_DROPPED = 'datadog.tracer.queue.dropped'
23
+ METRIC_QUEUE_LENGTH = 'datadog.tracer.queue.length'
24
+ METRIC_QUEUE_MAX_LENGTH = 'datadog.tracer.queue.max_length'
25
+ METRIC_QUEUE_SPANS = 'datadog.tracer.queue.spans'
26
+ METRIC_SAMPLING_SERVICE_CACHE_LENGTH = 'datadog.tracer.sampling.service_cache_length'
27
+ METRIC_TRACES_FILTERED = 'datadog.tracer.traces.filtered'
28
+ METRIC_TRANSPORT_CHUNKED = 'datadog.tracer.transport.chunked'
29
+ METRIC_TRANSPORT_TRACE_TOO_LARGE = 'datadog.tracer.transport.trace_too_large'
30
+ METRIC_WRITER_CPU_TIME = 'datadog.tracer.writer.cpu_time'
29
31
  end
30
32
  end
31
33
  end
@@ -30,8 +30,8 @@ module Datadog
30
30
  return if digest.nil?
31
31
 
32
32
  # DEV: We need these to be hex encoded
33
- data[@trace_id_key] = digest.trace_id.to_s(16)
34
- data[@span_id_key] = digest.span_id.to_s(16)
33
+ data[@trace_id_key] = format('%032x', digest.trace_id)
34
+ data[@span_id_key] = format('%016x', digest.span_id)
35
35
 
36
36
  if digest.trace_sampling_priority
37
37
  sampling_priority = Helpers.clamp_sampling_priority(
@@ -26,7 +26,7 @@ module Datadog
26
26
  return if digest.nil?
27
27
 
28
28
  # DEV: We need these to be hex encoded
29
- value = "#{digest.trace_id.to_s(16)}-#{digest.span_id.to_s(16)}"
29
+ value = "#{format('%032x', digest.trace_id)}-#{format('%016x', digest.span_id)}"
30
30
 
31
31
  if digest.trace_sampling_priority
32
32
  sampling_priority = Helpers.clamp_sampling_priority(
@@ -44,7 +44,15 @@ module Datadog
44
44
 
45
45
  tracestate, sampling_priority, origin, tags, unknown_fields = extract_tracestate(fetcher[@tracestate_key])
46
46
 
47
- sampling_priority = parse_priority_sampling(sampled, sampling_priority)
47
+ sampling_priority = parse_priority_sampling(sampled, sampling_priority) do |decision|
48
+ case decision
49
+ when String
50
+ tags ||= {}
51
+ tags[Tracing::Metadata::Ext::Distributed::TAG_DECISION_MAKER] = decision
52
+ when :drop
53
+ tags.delete(Tracing::Metadata::Ext::Distributed::TAG_DECISION_MAKER) if tags
54
+ end
55
+ end
48
56
 
49
57
  TraceDigest.new(
50
58
  span_id: parent_id,
@@ -160,8 +168,10 @@ module Datadog
160
168
  tracestate.chop! # Removes trailing `;` from Datadog trace state string.
161
169
 
162
170
  if digest.trace_state
171
+ trace_state = digest.trace_state.strip
172
+
163
173
  # Delete existing `dd=` tracestate fields, if present.
164
- vendors = split_tracestate(digest.trace_state)
174
+ vendors = split_tracestate(trace_state)
165
175
  vendors.reject! { |v| v.start_with?('dd=') }
166
176
  end
167
177
 
@@ -179,13 +189,21 @@ module Datadog
179
189
  end
180
190
 
181
191
  # If any characters in <origin_value> are invalid, replace each invalid character with 0x5F (underscore).
182
- # Invalid characters are: characters outside the ASCII range 0x20 to 0x7E, 0x2C (comma), and 0x3D (equals).
192
+ # Invalid characters are: characters outside the ASCII range 0x20 to 0x7E,
193
+ # 0x2C (comma), 0x3B (semi-colon), and 0x7E (tilde).
194
+ # Then, remap 0x3D (equals) to 0x7E (tilde)
183
195
  def serialize_origin(value)
184
196
  # DEV: It's unlikely that characters will be out of range, as they mostly
185
197
  # DEV: come from Datadog-controlled sources.
186
198
  # DEV: Trying to `match?` is measurably faster than a `gsub` that does not match.
187
- if INVALID_ORIGIN_CHARS.match?(value)
188
- value.gsub(INVALID_ORIGIN_CHARS, '_')
199
+ value = if INVALID_ORIGIN_CHARS.match?(value)
200
+ value.gsub(INVALID_ORIGIN_CHARS, '_')
201
+ else
202
+ value
203
+ end
204
+
205
+ if REMAP_ORIGIN_CHARS.match?(value)
206
+ value.gsub(REMAP_ORIGIN_CHARS, '~')
189
207
  else
190
208
  value
191
209
  end
@@ -245,13 +263,15 @@ module Datadog
245
263
 
246
264
  version, trace_id, parent_id, trace_flags, extra = traceparent.strip.split('-')
247
265
 
266
+ return if version.size != 2 || version[0] < '0' || version[0] > 'f' || version[1] < '0' || version[1] > 'f'
267
+
248
268
  return if version == INVALID_VERSION
249
269
 
250
270
  # Extra fields are not allowed in version 00, but we have to be lenient for future versions.
251
271
  return if version == SPEC_VERSION && extra
252
272
 
253
273
  # Invalid field sizes
254
- return if version.size != 2 || trace_id.size != 32 || parent_id.size != 16 || trace_flags.size != 2
274
+ return if trace_id.size != 32 || parent_id.size != 16 || trace_flags.size != 2
255
275
 
256
276
  [Integer(trace_id, 16), Integer(parent_id, 16), Integer(trace_flags, 16)]
257
277
  rescue ArgumentError # Conversion to integer failed
@@ -324,20 +344,31 @@ module Datadog
324
344
 
325
345
  # If `sampled` and `sampling_priority` disagree, `sampled` overrides the decision.
326
346
  # @return [Integer] one of the {Datadog::Tracing::Sampling::Ext::Priority} values
347
+ # @yieldparam the new decision maker (either :drop or a new decision maker String value).
327
348
  def parse_priority_sampling(sampled, sampling_priority)
328
- # If both fields agree
329
- if sampling_priority &&
330
- (!Tracing::Sampling::PrioritySampler.sampled?(sampling_priority) && sampled == 0 || # Both drop
331
- Tracing::Sampling::PrioritySampler.sampled?(sampling_priority) && sampled == 1) # Both keep
332
-
333
- return sampling_priority # Return the richer `sampling_priority`
349
+ if sampled == 1
350
+ if sampling_priority && Tracing::Sampling::PrioritySampler.sampled?(sampling_priority)
351
+ # Both sampling fields agree.
352
+ sampling_priority
353
+ else
354
+ # Sampling fields disagree.
355
+ # Let's force the trace to be kept, while also updating the decision maker to ourselves.
356
+ yield Tracing::Sampling::Ext::Decision::DEFAULT
357
+ sampled
358
+ end
359
+ elsif sampling_priority && !Tracing::Sampling::PrioritySampler.sampled?(sampling_priority)
360
+ sampling_priority
361
+ # Both sampling fields agree.
362
+ else
363
+ # Sampling fields disagree.
364
+ # Let's drop the trace and remove the sampling decision tag, as dropped spans don't carry sampling decision.
365
+ yield :drop
366
+ sampled
334
367
  end
335
-
336
- sampled # Sampled flag trumps `sampling_priority` on conflict
337
368
  end
338
369
 
339
370
  def split_tracestate(tracestate)
340
- tracestate.split(/[ \t]*,[ \t]*/)[0..31]
371
+ tracestate.split(/[ \t]*+,[ \t]*+/)[0..31]
341
372
  end
342
373
 
343
374
  # Version 0xFF is invalid as per spec
@@ -361,10 +392,14 @@ module Datadog
361
392
  private_constant :TRACESTATE_VALUE_SIZE_LIMIT
362
393
 
363
394
  # Replace all characters with `_`, except ASCII characters 0x20-0x7E.
364
- # Additionally, `,`, ';', and `=` must also be replaced by `_`.
365
- INVALID_ORIGIN_CHARS = /[\u0000-\u0019,;=\u007F-\u{10FFFF}]/.freeze
395
+ # Additionally, `,`, ';', and `~` must also be replaced by `_`.
396
+ INVALID_ORIGIN_CHARS = /[\u0000-\u0019,;~\u007F-\u{10FFFF}]/.freeze
366
397
  private_constant :INVALID_ORIGIN_CHARS
367
398
 
399
+ # Additionally, remap `=` to `~`
400
+ REMAP_ORIGIN_CHARS = /=/.freeze
401
+ private_constant :REMAP_ORIGIN_CHARS
402
+
368
403
  # Replace all characters with `_`, except ASCII characters 0x21-0x7E.
369
404
  # Additionally, `,` and `=` must also be replaced by `_`.
370
405
  INVALID_TAG_KEY_CHARS = /[\u0000-\u0020,=\u007F-\u{10FFFF}]/.freeze
@@ -23,6 +23,10 @@ module Datadog
23
23
  # Set this tag to `1.0` if the span is a Service Entry span.
24
24
  TAG_TOP_LEVEL = '_dd.top_level'
25
25
 
26
+ # Set to `1.0` if profiling is enabled together with tracing, and `0.0` otherwise
27
+ # See Datadog-internal "RFC: Identifying which spans have profiling enabled " for details
28
+ TAG_PROFILING_ENABLED = '_dd.profiling.enabled'
29
+
26
30
  # Defines constants for trace analytics
27
31
  # @public_api
28
32
  module Analytics
@@ -90,7 +94,10 @@ module Datadog
90
94
  INVALID_TAG_CHARACTERS = %r{[^a-z0-9_\-:./]}.freeze
91
95
 
92
96
  # Normalizes an HTTP header string into a valid tag string.
93
- def to_tag(name)
97
+ #
98
+ # By default, tags cannot create nested span tag levels:
99
+ # `allow_nested` allows you to override this behavior.
100
+ def to_tag(name, allow_nested: false)
94
101
  # Tag normalization based on: https://docs.datadoghq.com/getting_started/tagging/#defining-tags.
95
102
  #
96
103
  # Only the following characters are accepted.
@@ -109,7 +116,7 @@ module Datadog
109
116
  # Additional HTTP header normalization.
110
117
  #
111
118
  # Periods are replaced with an underscore.
112
- tag.tr!('.', '_')
119
+ tag.tr!('.', '_') unless allow_nested
113
120
  tag
114
121
  end
115
122
  end
@@ -178,10 +185,6 @@ module Datadog
178
185
  end
179
186
 
180
187
  # @public_api
181
- module SpanAttributeSchema
182
- # current span attribute schema version
183
- TAG_SCHEMA_VERSION = '_dd.trace_span_attribute_schema'
184
- end
185
188
  end
186
189
  end
187
190
  end
@@ -0,0 +1,78 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative '../core/remote/dispatcher'
4
+ require_relative 'configuration/dynamic'
5
+
6
+ module Datadog
7
+ module Tracing
8
+ # Remote configuration declaration
9
+ module Remote
10
+ class ReadError < StandardError; end
11
+
12
+ class << self
13
+ PRODUCT = 'APM_TRACING'
14
+
15
+ def products
16
+ [PRODUCT]
17
+ end
18
+
19
+ def capabilities
20
+ [] # No capabilities advertised
21
+ end
22
+
23
+ def process_config(config, content)
24
+ lib_config = config['lib_config']
25
+
26
+ env_vars = Datadog::Tracing::Configuration::Dynamic::OPTIONS.map do |name, env_var, option|
27
+ value = lib_config[name]
28
+
29
+ # Guard for RBS/Steep
30
+ raise "option is a #{option.class}, expected Option" unless option.is_a?(Configuration::Dynamic::Option)
31
+
32
+ option.call(value)
33
+
34
+ [env_var, value]
35
+ end
36
+
37
+ content.applied
38
+
39
+ Datadog.send(:components).telemetry.client_configuration_change!(env_vars)
40
+ rescue => e
41
+ content.errored("#{e.class.name} #{e.message}: #{Array(e.backtrace).join("\n")}")
42
+ end
43
+
44
+ def receivers
45
+ receiver do |repository, _changes|
46
+ # DEV: Filter our by product. Given it will be very common
47
+ # DEV: we can filter this out before we receive the data in this method.
48
+ # DEV: Apply this refactor to AppSec as well if implemented.
49
+ repository.contents.map do |content|
50
+ case content.path.product
51
+ when PRODUCT
52
+ config = parse_content(content)
53
+ process_config(config, content)
54
+ end
55
+ end
56
+ end
57
+ end
58
+
59
+ def receiver(products = [PRODUCT], &block)
60
+ matcher = Core::Remote::Dispatcher::Matcher::Product.new(products)
61
+ [Core::Remote::Dispatcher::Receiver.new(matcher, &block)]
62
+ end
63
+
64
+ private
65
+
66
+ def parse_content(content)
67
+ data = content.data.read
68
+
69
+ content.data.rewind
70
+
71
+ raise ReadError, 'EOF reached' if data.nil?
72
+
73
+ JSON.parse(data)
74
+ end
75
+ end
76
+ end
77
+ end
78
+ end
@@ -48,6 +48,35 @@ module Datadog
48
48
  end
49
49
  end
50
50
 
51
+ def self.parse(rules, rate_limit, default_sample_rate)
52
+ parsed_rules = JSON.parse(rules).map do |rule|
53
+ sample_rate = rule['sample_rate']
54
+
55
+ begin
56
+ sample_rate = Float(sample_rate)
57
+ rescue
58
+ raise "Rule '#{rule.inspect}' does not contain a float property `sample_rate`"
59
+ end
60
+
61
+ kwargs = {
62
+ name: rule['name'],
63
+ service: rule['service'],
64
+ sample_rate: sample_rate,
65
+ }
66
+
67
+ Core::BackportFrom24.hash_compact!(kwargs)
68
+
69
+ SimpleRule.new(**kwargs)
70
+ end
71
+
72
+ new(parsed_rules, rate_limit: rate_limit, default_sample_rate: default_sample_rate)
73
+ rescue => e
74
+ Datadog.logger.error do
75
+ "Could not parse trace sampling rules '#{rules}': #{e.class.name} #{e.message} at #{Array(e.backtrace).first}"
76
+ end
77
+ nil
78
+ end
79
+
51
80
  # /RuleSampler's components (it's rate limiter, for example) are
52
81
  # not be guaranteed to be size-effect free.
53
82
  # It is not possible to guarantee that a call to {#sample?} will
@@ -3,6 +3,7 @@ require 'time'
3
3
  require_relative '../core/environment/identity'
4
4
  require_relative '../core/utils'
5
5
  require_relative '../core/utils/time'
6
+ require_relative '../core/utils/safe_dup'
6
7
 
7
8
  require_relative 'event'
8
9
  require_relative 'metadata'
@@ -434,19 +435,6 @@ module Datadog
434
435
  :parent,
435
436
  :span
436
437
 
437
- if RUBY_VERSION < '2.2' # nil.dup only fails in Ruby 2.1
438
- # Ensures #initialize can call nil.dup safely
439
- module RefineNil
440
- refine NilClass do
441
- def dup
442
- self
443
- end
444
- end
445
- end
446
-
447
- using RefineNil
448
- end
449
-
450
438
  # Create a Span from the operation which represents
451
439
  # the finalized measurement. We #dup here to prevent
452
440
  # mutation by reference; when this span is returned,
@@ -457,8 +445,8 @@ module Datadog
457
445
  duration: duration,
458
446
  end_time: @end_time,
459
447
  id: @id,
460
- meta: meta.dup,
461
- metrics: metrics.dup,
448
+ meta: Core::Utils::SafeDup.frozen_or_dup(meta),
449
+ metrics: Core::Utils::SafeDup.frozen_or_dup(metrics),
462
450
  parent_id: @parent_id,
463
451
  resource: @resource,
464
452
  service: @service,