ddtrace 1.12.1 → 1.13.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 (264) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +109 -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 +1 -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 +104 -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/base.rb +5 -5
  56. data/lib/datadog/core/configuration/components.rb +6 -1
  57. data/lib/datadog/core/configuration/ext.rb +7 -5
  58. data/lib/datadog/core/configuration/option.rb +269 -19
  59. data/lib/datadog/core/configuration/option_definition.rb +76 -11
  60. data/lib/datadog/core/configuration/options.rb +22 -10
  61. data/lib/datadog/core/configuration/settings.rb +116 -61
  62. data/lib/datadog/core/environment/ext.rb +13 -11
  63. data/lib/datadog/core/environment/yjit.rb +58 -0
  64. data/lib/datadog/core/git/ext.rb +24 -22
  65. data/lib/datadog/core/logging/ext.rb +3 -1
  66. data/lib/datadog/core/metrics/ext.rb +7 -5
  67. data/lib/datadog/core/remote/client/capabilities.rb +5 -0
  68. data/lib/datadog/core/remote/client.rb +3 -0
  69. data/lib/datadog/core/remote/component.rb +25 -34
  70. data/lib/datadog/core/remote/configuration/content.rb +28 -1
  71. data/lib/datadog/core/remote/configuration/repository.rb +3 -1
  72. data/lib/datadog/core/remote/ext.rb +1 -1
  73. data/lib/datadog/core/remote/negotiation.rb +17 -4
  74. data/lib/datadog/core/runtime/ext.rb +22 -12
  75. data/lib/datadog/core/runtime/metrics.rb +43 -0
  76. data/lib/datadog/core/telemetry/client.rb +12 -2
  77. data/lib/datadog/core/telemetry/emitter.rb +4 -2
  78. data/lib/datadog/core/telemetry/event.rb +19 -4
  79. data/lib/datadog/core/telemetry/ext.rb +4 -1
  80. data/lib/datadog/core/telemetry/heartbeat.rb +2 -4
  81. data/lib/datadog/core/telemetry/http/ext.rb +10 -8
  82. data/lib/datadog/core/telemetry/http/transport.rb +1 -0
  83. data/lib/datadog/core/telemetry/v2/app_client_configuration_change.rb +41 -0
  84. data/lib/datadog/core/telemetry/v2/request.rb +29 -0
  85. data/lib/datadog/core/transport/http/client.rb +1 -1
  86. data/lib/datadog/core/transport/http/config.rb +10 -0
  87. data/lib/datadog/core/utils/duration.rb +52 -0
  88. data/lib/datadog/core/utils/hash.rb +47 -0
  89. data/lib/datadog/core/utils/network.rb +1 -1
  90. data/lib/datadog/core/utils/safe_dup.rb +27 -20
  91. data/lib/datadog/core/utils.rb +1 -1
  92. data/lib/datadog/core/workers/async.rb +2 -2
  93. data/lib/datadog/kit/appsec/events.rb +139 -89
  94. data/lib/datadog/kit/identity.rb +80 -65
  95. data/lib/datadog/profiling/collectors/cpu_and_wall_time_worker.rb +3 -0
  96. data/lib/datadog/profiling/collectors/idle_sampling_helper.rb +1 -0
  97. data/lib/datadog/profiling/collectors/thread_context.rb +9 -2
  98. data/lib/datadog/profiling/component.rb +41 -9
  99. data/lib/datadog/profiling/exporter.rb +5 -1
  100. data/lib/datadog/profiling/flush.rb +9 -2
  101. data/lib/datadog/profiling/http_transport.rb +4 -1
  102. data/lib/datadog/profiling/load_native_extension.rb +7 -1
  103. data/lib/datadog/profiling.rb +11 -1
  104. data/lib/datadog/tracing/component.rb +58 -6
  105. data/lib/datadog/tracing/configuration/dynamic/option.rb +71 -0
  106. data/lib/datadog/tracing/configuration/dynamic.rb +64 -0
  107. data/lib/datadog/tracing/configuration/ext.rb +35 -32
  108. data/lib/datadog/tracing/configuration/http.rb +74 -0
  109. data/lib/datadog/tracing/configuration/settings.rb +106 -92
  110. data/lib/datadog/tracing/contrib/action_cable/configuration/settings.rb +9 -6
  111. data/lib/datadog/tracing/contrib/action_cable/ext.rb +20 -18
  112. data/lib/datadog/tracing/contrib/action_mailer/configuration/settings.rb +9 -6
  113. data/lib/datadog/tracing/contrib/action_mailer/ext.rb +20 -18
  114. data/lib/datadog/tracing/contrib/action_pack/configuration/settings.rb +8 -6
  115. data/lib/datadog/tracing/contrib/action_pack/ext.rb +10 -8
  116. data/lib/datadog/tracing/contrib/action_view/configuration/settings.rb +9 -6
  117. data/lib/datadog/tracing/contrib/action_view/ext.rb +12 -10
  118. data/lib/datadog/tracing/contrib/active_job/configuration/settings.rb +13 -7
  119. data/lib/datadog/tracing/contrib/active_job/ext.rb +25 -23
  120. data/lib/datadog/tracing/contrib/active_job/log_injection.rb +1 -1
  121. data/lib/datadog/tracing/contrib/active_job/patcher.rb +1 -1
  122. data/lib/datadog/tracing/contrib/active_model_serializers/configuration/settings.rb +9 -6
  123. data/lib/datadog/tracing/contrib/active_model_serializers/ext.rb +12 -10
  124. data/lib/datadog/tracing/contrib/active_record/configuration/settings.rb +9 -7
  125. data/lib/datadog/tracing/contrib/active_record/events/sql.rb +0 -8
  126. data/lib/datadog/tracing/contrib/active_record/ext.rb +17 -15
  127. data/lib/datadog/tracing/contrib/active_support/cache/instrumentation.rb +0 -5
  128. data/lib/datadog/tracing/contrib/active_support/configuration/settings.rb +9 -7
  129. data/lib/datadog/tracing/contrib/active_support/ext.rb +18 -16
  130. data/lib/datadog/tracing/contrib/aws/configuration/settings.rb +14 -7
  131. data/lib/datadog/tracing/contrib/aws/ext.rb +37 -24
  132. data/lib/datadog/tracing/contrib/aws/instrumentation.rb +9 -5
  133. data/lib/datadog/tracing/contrib/concurrent_ruby/configuration/settings.rb +3 -2
  134. data/lib/datadog/tracing/contrib/concurrent_ruby/ext.rb +4 -2
  135. data/lib/datadog/tracing/contrib/dalli/configuration/settings.rb +14 -7
  136. data/lib/datadog/tracing/contrib/dalli/ext.rb +19 -11
  137. data/lib/datadog/tracing/contrib/dalli/instrumentation.rb +8 -6
  138. data/lib/datadog/tracing/contrib/delayed_job/configuration/settings.rb +13 -7
  139. data/lib/datadog/tracing/contrib/delayed_job/ext.rb +16 -14
  140. data/lib/datadog/tracing/contrib/elasticsearch/configuration/settings.rb +14 -7
  141. data/lib/datadog/tracing/contrib/elasticsearch/ext.rb +21 -15
  142. data/lib/datadog/tracing/contrib/elasticsearch/patcher.rb +8 -5
  143. data/lib/datadog/tracing/contrib/ethon/configuration/settings.rb +16 -9
  144. data/lib/datadog/tracing/contrib/ethon/easy_patch.rb +43 -3
  145. data/lib/datadog/tracing/contrib/ethon/ext.rb +19 -11
  146. data/lib/datadog/tracing/contrib/ethon/multi_patch.rb +0 -5
  147. data/lib/datadog/tracing/contrib/excon/configuration/settings.rb +19 -10
  148. data/lib/datadog/tracing/contrib/excon/ext.rb +16 -8
  149. data/lib/datadog/tracing/contrib/excon/middleware.rb +20 -5
  150. data/lib/datadog/tracing/contrib/ext.rb +23 -1
  151. data/lib/datadog/tracing/contrib/extensions.rb +32 -0
  152. data/lib/datadog/tracing/contrib/faraday/configuration/settings.rb +20 -10
  153. data/lib/datadog/tracing/contrib/faraday/ext.rb +16 -8
  154. data/lib/datadog/tracing/contrib/faraday/middleware.rb +16 -5
  155. data/lib/datadog/tracing/contrib/grape/configuration/settings.rb +8 -6
  156. data/lib/datadog/tracing/contrib/grape/ext.rb +16 -14
  157. data/lib/datadog/tracing/contrib/graphql/configuration/settings.rb +8 -6
  158. data/lib/datadog/tracing/contrib/graphql/ext.rb +7 -5
  159. data/lib/datadog/tracing/contrib/grpc/configuration/settings.rb +19 -9
  160. data/lib/datadog/tracing/contrib/grpc/datadog_interceptor/client.rb +29 -20
  161. data/lib/datadog/tracing/contrib/grpc/datadog_interceptor/server.rb +21 -20
  162. data/lib/datadog/tracing/contrib/grpc/ext.rb +16 -13
  163. data/lib/datadog/tracing/contrib/grpc/formatting.rb +127 -0
  164. data/lib/datadog/tracing/contrib/hanami/configuration/settings.rb +3 -2
  165. data/lib/datadog/tracing/contrib/hanami/ext.rb +10 -8
  166. data/lib/datadog/tracing/contrib/http/circuit_breaker.rb +4 -7
  167. data/lib/datadog/tracing/contrib/http/configuration/settings.rb +33 -11
  168. data/lib/datadog/tracing/contrib/http/ext.rb +16 -9
  169. data/lib/datadog/tracing/contrib/http/instrumentation.rb +17 -5
  170. data/lib/datadog/tracing/contrib/httpclient/configuration/settings.rb +33 -11
  171. data/lib/datadog/tracing/contrib/httpclient/ext.rb +17 -9
  172. data/lib/datadog/tracing/contrib/httpclient/instrumentation.rb +17 -5
  173. data/lib/datadog/tracing/contrib/httprb/configuration/settings.rb +33 -11
  174. data/lib/datadog/tracing/contrib/httprb/ext.rb +16 -9
  175. data/lib/datadog/tracing/contrib/httprb/instrumentation.rb +17 -5
  176. data/lib/datadog/tracing/contrib/kafka/configuration/settings.rb +9 -6
  177. data/lib/datadog/tracing/contrib/kafka/ext.rb +42 -39
  178. data/lib/datadog/tracing/contrib/lograge/configuration/settings.rb +3 -2
  179. data/lib/datadog/tracing/contrib/lograge/ext.rb +3 -1
  180. data/lib/datadog/tracing/contrib/lograge/instrumentation.rb +1 -0
  181. data/lib/datadog/tracing/contrib/mongodb/configuration/settings.rb +14 -7
  182. data/lib/datadog/tracing/contrib/mongodb/ext.rb +20 -16
  183. data/lib/datadog/tracing/contrib/mongodb/subscribers.rb +9 -5
  184. data/lib/datadog/tracing/contrib/mysql2/configuration/settings.rb +17 -14
  185. data/lib/datadog/tracing/contrib/mysql2/ext.rb +15 -10
  186. data/lib/datadog/tracing/contrib/mysql2/instrumentation.rb +9 -5
  187. data/lib/datadog/tracing/contrib/opensearch/configuration/settings.rb +52 -0
  188. data/lib/datadog/tracing/contrib/opensearch/ext.rb +37 -0
  189. data/lib/datadog/tracing/contrib/opensearch/integration.rb +44 -0
  190. data/lib/datadog/tracing/contrib/opensearch/patcher.rb +128 -0
  191. data/lib/datadog/tracing/contrib/opensearch/quantize.rb +81 -0
  192. data/lib/datadog/tracing/contrib/pg/configuration/settings.rb +17 -14
  193. data/lib/datadog/tracing/contrib/pg/ext.rb +22 -19
  194. data/lib/datadog/tracing/contrib/pg/instrumentation.rb +9 -5
  195. data/lib/datadog/tracing/contrib/presto/configuration/settings.rb +14 -7
  196. data/lib/datadog/tracing/contrib/presto/ext.rb +25 -20
  197. data/lib/datadog/tracing/contrib/presto/instrumentation.rb +9 -5
  198. data/lib/datadog/tracing/contrib/propagation/sql_comment/ext.rb +12 -10
  199. data/lib/datadog/tracing/contrib/qless/configuration/settings.rb +12 -8
  200. data/lib/datadog/tracing/contrib/qless/ext.rb +14 -12
  201. data/lib/datadog/tracing/contrib/que/configuration/settings.rb +21 -12
  202. data/lib/datadog/tracing/contrib/racecar/configuration/settings.rb +9 -7
  203. data/lib/datadog/tracing/contrib/racecar/event.rb +0 -5
  204. data/lib/datadog/tracing/contrib/racecar/ext.rb +20 -18
  205. data/lib/datadog/tracing/contrib/rack/configuration/settings.rb +16 -12
  206. data/lib/datadog/tracing/contrib/rack/ext.rb +18 -16
  207. data/lib/datadog/tracing/contrib/rack/header_collection.rb +3 -0
  208. data/lib/datadog/tracing/contrib/rack/header_tagging.rb +53 -0
  209. data/lib/datadog/tracing/contrib/rack/middlewares.rb +8 -49
  210. data/lib/datadog/tracing/contrib/rails/configuration/settings.rb +15 -11
  211. data/lib/datadog/tracing/contrib/rails/ext.rb +7 -5
  212. data/lib/datadog/tracing/contrib/rails/log_injection.rb +4 -10
  213. data/lib/datadog/tracing/contrib/rails/patcher.rb +10 -41
  214. data/lib/datadog/tracing/contrib/rails/railtie.rb +3 -3
  215. data/lib/datadog/tracing/contrib/rake/configuration/settings.rb +12 -9
  216. data/lib/datadog/tracing/contrib/rake/ext.rb +14 -12
  217. data/lib/datadog/tracing/contrib/redis/configuration/settings.rb +17 -9
  218. data/lib/datadog/tracing/contrib/redis/ext.rb +22 -15
  219. data/lib/datadog/tracing/contrib/redis/tags.rb +9 -5
  220. data/lib/datadog/tracing/contrib/resque/configuration/settings.rb +13 -7
  221. data/lib/datadog/tracing/contrib/resque/ext.rb +9 -7
  222. data/lib/datadog/tracing/contrib/rest_client/configuration/settings.rb +16 -9
  223. data/lib/datadog/tracing/contrib/rest_client/ext.rb +15 -8
  224. data/lib/datadog/tracing/contrib/rest_client/request_patch.rb +20 -5
  225. data/lib/datadog/tracing/contrib/roda/configuration/settings.rb +9 -6
  226. data/lib/datadog/tracing/contrib/semantic_logger/configuration/settings.rb +3 -2
  227. data/lib/datadog/tracing/contrib/semantic_logger/ext.rb +3 -1
  228. data/lib/datadog/tracing/contrib/semantic_logger/instrumentation.rb +1 -0
  229. data/lib/datadog/tracing/contrib/sequel/configuration/settings.rb +9 -6
  230. data/lib/datadog/tracing/contrib/sequel/ext.rb +10 -8
  231. data/lib/datadog/tracing/contrib/sequel/utils.rb +2 -7
  232. data/lib/datadog/tracing/contrib/shoryuken/configuration/settings.rb +14 -8
  233. data/lib/datadog/tracing/contrib/shoryuken/ext.rb +14 -12
  234. data/lib/datadog/tracing/contrib/sidekiq/configuration/settings.rb +18 -11
  235. data/lib/datadog/tracing/contrib/sidekiq/ext.rb +32 -30
  236. data/lib/datadog/tracing/contrib/sinatra/configuration/settings.rb +11 -9
  237. data/lib/datadog/tracing/contrib/sinatra/env.rb +0 -17
  238. data/lib/datadog/tracing/contrib/sinatra/ext.rb +21 -19
  239. data/lib/datadog/tracing/contrib/sinatra/tracer_middleware.rb +3 -14
  240. data/lib/datadog/tracing/contrib/sneakers/configuration/settings.rb +14 -8
  241. data/lib/datadog/tracing/contrib/sneakers/ext.rb +1 -0
  242. data/lib/datadog/tracing/contrib/sneakers/tracer.rb +1 -1
  243. data/lib/datadog/tracing/contrib/span_attribute_schema.rb +74 -10
  244. data/lib/datadog/tracing/contrib/stripe/configuration/settings.rb +9 -6
  245. data/lib/datadog/tracing/contrib/sucker_punch/configuration/settings.rb +9 -6
  246. data/lib/datadog/tracing/contrib/sucker_punch/ext.rb +15 -13
  247. data/lib/datadog/tracing/contrib/utils/database.rb +5 -3
  248. data/lib/datadog/tracing/correlation.rb +9 -12
  249. data/lib/datadog/tracing/diagnostics/ext.rb +21 -19
  250. data/lib/datadog/tracing/distributed/b3_multi.rb +2 -2
  251. data/lib/datadog/tracing/distributed/b3_single.rb +1 -1
  252. data/lib/datadog/tracing/distributed/trace_context.rb +52 -17
  253. data/lib/datadog/tracing/metadata/ext.rb +9 -6
  254. data/lib/datadog/tracing/remote.rb +78 -0
  255. data/lib/datadog/tracing/sampling/rule_sampler.rb +29 -0
  256. data/lib/datadog/tracing/span_operation.rb +3 -15
  257. data/lib/datadog/tracing/trace_operation.rb +16 -3
  258. data/lib/datadog/tracing/trace_segment.rb +5 -2
  259. data/lib/datadog/tracing/tracer.rb +10 -1
  260. data/lib/ddtrace/transport/ext.rb +15 -9
  261. data/lib/ddtrace/transport/trace_formatter.rb +9 -0
  262. data/lib/ddtrace/version.rb +9 -12
  263. metadata +38 -10
  264. data/lib/datadog/tracing/contrib/sinatra/headers.rb +0 -35
@@ -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,
@@ -40,7 +40,9 @@ module Datadog
40
40
  :active_span,
41
41
  :id,
42
42
  :max_length,
43
- :parent_span_id
43
+ :parent_span_id,
44
+ :trace_state,
45
+ :trace_state_unknown_fields
44
46
 
45
47
  attr_writer \
46
48
  :name,
@@ -64,8 +66,11 @@ module Datadog
64
66
  sampled: nil,
65
67
  sampling_priority: nil,
66
68
  service: nil,
69
+ profiling_enabled: nil,
67
70
  tags: nil,
68
- metrics: nil
71
+ metrics: nil,
72
+ trace_state: nil,
73
+ trace_state_unknown_fields: nil
69
74
  )
70
75
  # Attributes
71
76
  @id = id || Tracing::Utils::TraceId.next_id
@@ -84,6 +89,9 @@ module Datadog
84
89
  @sample_rate = sample_rate
85
90
  @sampling_priority = sampling_priority
86
91
  @service = service
92
+ @profiling_enabled = profiling_enabled
93
+ @trace_state = trace_state
94
+ @trace_state_unknown_fields = trace_state_unknown_fields
87
95
 
88
96
  # Generic tags
89
97
  set_tags(tags) if tags
@@ -288,6 +296,8 @@ module Datadog
288
296
  trace_runtime_id: Core::Environment::Identity.id,
289
297
  trace_sampling_priority: @sampling_priority,
290
298
  trace_service: service,
299
+ trace_state: @trace_state,
300
+ trace_state_unknown_fields: @trace_state_unknown_fields,
291
301
  ).freeze
292
302
  end
293
303
 
@@ -310,6 +320,8 @@ module Datadog
310
320
  sampled: @sampled,
311
321
  sampling_priority: @sampling_priority,
312
322
  service: (service && service.dup),
323
+ trace_state: (@trace_state && @trace_state.dup),
324
+ trace_state_unknown_fields: (@trace_state_unknown_fields && @trace_state_unknown_fields.dup),
313
325
  tags: meta.dup,
314
326
  metrics: metrics.dup
315
327
  )
@@ -450,7 +462,8 @@ module Datadog
450
462
  service: service,
451
463
  tags: meta,
452
464
  metrics: metrics,
453
- root_span_id: !partial ? root_span && root_span.id : nil
465
+ root_span_id: !partial ? root_span && root_span.id : nil,
466
+ profiling_enabled: @profiling_enabled,
454
467
  )
455
468
  end
456
469
 
@@ -31,7 +31,8 @@ module Datadog
31
31
  :sample_rate,
32
32
  :sampling_decision_maker,
33
33
  :sampling_priority,
34
- :service
34
+ :service,
35
+ :profiling_enabled
35
36
 
36
37
  # rubocop:disable Metrics/CyclomaticComplexity
37
38
  # rubocop:disable Metrics/PerceivedComplexity
@@ -54,7 +55,8 @@ module Datadog
54
55
  sampling_priority: nil,
55
56
  service: nil,
56
57
  tags: nil,
57
- metrics: nil
58
+ metrics: nil,
59
+ profiling_enabled: nil
58
60
  )
59
61
  @id = id
60
62
  @root_span_id = root_span_id
@@ -80,6 +82,7 @@ module Datadog
80
82
  @sampling_decision_maker = sampling_decision_maker_tag
81
83
  @sampling_priority = sampling_priority || sampling_priority_tag
82
84
  @service = Core::Utils::SafeDup.frozen_or_dup(service || service_tag)
85
+ @profiling_enabled = profiling_enabled
83
86
  end
84
87
  # rubocop:enable Metrics/PerceivedComplexity
85
88
  # rubocop:enable Metrics/CyclomaticComplexity
@@ -320,16 +320,20 @@ module Datadog
320
320
  if digest
321
321
  TraceOperation.new(
322
322
  hostname: hostname,
323
+ profiling_enabled: profiling_enabled,
323
324
  id: digest.trace_id,
324
325
  origin: digest.trace_origin,
325
326
  parent_span_id: digest.span_id,
326
327
  sampling_priority: digest.trace_sampling_priority,
327
328
  # Distributed tags are just regular trace tags with special meaning to Datadog
328
329
  tags: digest.trace_distributed_tags,
330
+ trace_state: digest.trace_state,
331
+ trace_state_unknown_fields: digest.trace_state_unknown_fields,
329
332
  )
330
333
  else
331
334
  TraceOperation.new(
332
- hostname: hostname
335
+ hostname: hostname,
336
+ profiling_enabled: profiling_enabled,
333
337
  )
334
338
  end
335
339
  end
@@ -525,6 +529,11 @@ module Datadog
525
529
  span
526
530
  end
527
531
  end
532
+
533
+ def profiling_enabled
534
+ @profiling_enabled ||=
535
+ !!(defined?(Datadog::Profiling) && Datadog::Profiling.respond_to?(:enabled?) && Datadog::Profiling.enabled?)
536
+ end
528
537
  end
529
538
  end
530
539
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Datadog
2
4
  module Transport
3
5
  # @public_api
@@ -5,22 +7,26 @@ module Datadog
5
7
  # @public_api
6
8
  module HTTP
7
9
  ADAPTER = :net_http # DEV: Rename to simply `:http`, as Net::HTTP is an implementation detail.
8
- DEFAULT_HOST = '127.0.0.1'.freeze
10
+ DEFAULT_HOST = '127.0.0.1'
9
11
  DEFAULT_PORT = 8126
10
12
 
11
- HEADER_CONTAINER_ID = 'Datadog-Container-ID'.freeze
12
- HEADER_DD_API_KEY = 'DD-API-KEY'.freeze
13
+ HEADER_CONTAINER_ID = 'Datadog-Container-ID'
14
+ HEADER_DD_API_KEY = 'DD-API-KEY'
13
15
  # Tells agent that `_dd.top_level` metrics have been set by the tracer.
14
16
  # The agent will not calculate top-level spans but instead trust the tracer tagging.
15
17
  #
16
18
  # This prevents partially flushed traces being mistakenly marked as top-level.
17
19
  #
18
20
  # Setting this header to any non-empty value enables this feature.
19
- HEADER_CLIENT_COMPUTED_TOP_LEVEL = 'Datadog-Client-Computed-Top-Level'.freeze
20
- HEADER_META_LANG = 'Datadog-Meta-Lang'.freeze
21
- HEADER_META_LANG_VERSION = 'Datadog-Meta-Lang-Version'.freeze
22
- HEADER_META_LANG_INTERPRETER = 'Datadog-Meta-Lang-Interpreter'.freeze
23
- HEADER_META_TRACER_VERSION = 'Datadog-Meta-Tracer-Version'.freeze
21
+ HEADER_CLIENT_COMPUTED_TOP_LEVEL = 'Datadog-Client-Computed-Top-Level'
22
+ HEADER_META_LANG = 'Datadog-Meta-Lang'
23
+ HEADER_META_LANG_VERSION = 'Datadog-Meta-Lang-Version'
24
+ HEADER_META_LANG_INTERPRETER = 'Datadog-Meta-Lang-Interpreter'
25
+ HEADER_META_TRACER_VERSION = 'Datadog-Meta-Tracer-Version'
26
+
27
+ # Header that prevents the Net::HTTP integration from tracing internal trace requests.
28
+ # Set it to any value to skip tracing.
29
+ HEADER_DD_INTERNAL_UNTRACED_REQUEST = 'DD-Internal-Untraced-Request'
24
30
  end
25
31
 
26
32
  # @public_api
@@ -31,7 +37,7 @@ module Datadog
31
37
  # @public_api
32
38
  module UnixSocket
33
39
  ADAPTER = :unix
34
- DEFAULT_PATH = '/var/run/datadog/apm.socket'.freeze
40
+ DEFAULT_PATH = '/var/run/datadog/apm.socket'
35
41
  DEFAULT_TIMEOUT_SECONDS = 1
36
42
  end
37
43
  end
@@ -51,6 +51,7 @@ module Datadog
51
51
  tag_sampling_decision_maker!
52
52
  tag_high_order_trace_id!
53
53
  tag_sampling_priority!
54
+ tag_profiling_enabled!
54
55
 
55
56
  trace
56
57
  end
@@ -175,6 +176,14 @@ module Datadog
175
176
  root_span.set_tag(Tracing::Metadata::Ext::Distributed::TAG_TID, high_order_tid)
176
177
  end
177
178
 
179
+ def tag_profiling_enabled!
180
+ return if trace.profiling_enabled.nil?
181
+
182
+ root_span.set_tag(
183
+ Tracing::Metadata::Ext::TAG_PROFILING_ENABLED, trace.profiling_enabled ? 1 : 0
184
+ )
185
+ end
186
+
178
187
  private
179
188
 
180
189
  def partial?
@@ -3,8 +3,8 @@
3
3
  module DDTrace
4
4
  module VERSION
5
5
  MAJOR = 1
6
- MINOR = 12
7
- PATCH = 1
6
+ MINOR = 13
7
+ PATCH = 0
8
8
  PRE = nil
9
9
  BUILD = nil
10
10
  # PRE and BUILD above are modified for dev gems during gem build GHA workflow
@@ -13,17 +13,14 @@ module DDTrace
13
13
 
14
14
  MINIMUM_RUBY_VERSION = '2.1.0'
15
15
 
16
- # A maximum version was initially added in https://github.com/DataDog/dd-trace-rb/pull/1495 because we expected
17
- # the `ruby2_keywords` method to be removed (see the PR for the discussion).
18
- # That is because Ruby 3.x support as implemented using `*args` needs `ruby2_keywords` to continue working,
19
- # but if `ruby2_keywords` gets removed we would need to change the code to use `*args, **kwargs`.
16
+ # Restrict the installation of this gem with untested future versions of Ruby.
20
17
  #
21
- # Now Ruby 3.2.0-preview1 is out and `ruby2_keywords` are still there, and there's even a recent change for it
22
- # in https://github.com/ruby/ruby/pull/5684 that is documented as "ruby2_keywords needed in 3.2+".
18
+ # This prevents crashes in the native extension code and sends a clear signal to the
19
+ # user that this version of the gem is untested for the host Ruby version.
23
20
  #
24
- # So for now let's bump the maximum version to < 3.3 to allow the Ruby 3.2 series to be supported and we can keep
25
- # an eye on the Ruby 3.2 test releases to see if anything changes. (Otherwise, once Ruby 3.2.0 stable is out, we
26
- # should probably bump this to 3.4, and so on...)
27
- MAXIMUM_RUBY_VERSION = '3.3'
21
+ # To allow testing with the next unreleased version of Ruby, the version check is performed
22
+ # as `< #{MAXIMUM_RUBY_VERSION}`, meaning prereleases of MAXIMUM_RUBY_VERSION are allowed
23
+ # but not stable MAXIMUM_RUBY_VERSION releases.
24
+ MAXIMUM_RUBY_VERSION = '3.4'
28
25
  end
29
26
  end