field.rs 37 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199
  1. //! `Span` and `Event` key-value data.
  2. //!
  3. //! Spans and events may be annotated with key-value data, referred to as known
  4. //! as _fields_. These fields consist of a mapping from a key (corresponding to
  5. //! a `&str` but represented internally as an array index) to a [`Value`].
  6. //!
  7. //! # `Value`s and `Subscriber`s
  8. //!
  9. //! `Subscriber`s consume `Value`s as fields attached to [span]s or [`Event`]s.
  10. //! The set of field keys on a given span or is defined on its [`Metadata`].
  11. //! When a span is created, it provides [`Attributes`] to the `Subscriber`'s
  12. //! [`new_span`] method, containing any fields whose values were provided when
  13. //! the span was created; and may call the `Subscriber`'s [`record`] method
  14. //! with additional [`Record`]s if values are added for more of its fields.
  15. //! Similarly, the [`Event`] type passed to the subscriber's [`event`] method
  16. //! will contain any fields attached to each event.
  17. //!
  18. //! `tracing` represents values as either one of a set of Rust primitives
  19. //! (`i64`, `u64`, `f64`, `bool`, and `&str`) or using a `fmt::Display` or
  20. //! `fmt::Debug` implementation. `Subscriber`s are provided these primitive
  21. //! value types as `dyn Value` trait objects.
  22. //!
  23. //! These trait objects can be formatted using `fmt::Debug`, but may also be
  24. //! recorded as typed data by calling the [`Value::record`] method on these
  25. //! trait objects with a _visitor_ implementing the [`Visit`] trait. This trait
  26. //! represents the behavior used to record values of various types. For example,
  27. //! an implementation of `Visit` might record integers by incrementing counters
  28. //! for their field names rather than printing them.
  29. //!
  30. //!
  31. //! # Using `valuable`
  32. //!
  33. //! `tracing`'s [`Value`] trait is intentionally minimalist: it supports only a small
  34. //! number of Rust primitives as typed values, and only permits recording
  35. //! user-defined types with their [`fmt::Debug`] or [`fmt::Display`]
  36. //! implementations. However, there are some cases where it may be useful to record
  37. //! nested values (such as arrays, `Vec`s, or `HashMap`s containing values), or
  38. //! user-defined `struct` and `enum` types without having to format them as
  39. //! unstructured text.
  40. //!
  41. //! To address `Value`'s limitations, `tracing` offers experimental support for
  42. //! the [`valuable`] crate, which provides object-safe inspection of structured
  43. //! values. User-defined types can implement the [`valuable::Valuable`] trait,
  44. //! and be recorded as a `tracing` field by calling their [`as_value`] method.
  45. //! If the [`Subscriber`] also supports the `valuable` crate, it can
  46. //! then visit those types fields as structured values using `valuable`.
  47. //!
  48. //! <pre class="ignore" style="white-space:normal;font:inherit;">
  49. //! <strong>Note</strong>: <code>valuable</code> support is an
  50. //! <a href = "../index.html#unstable-features">unstable feature</a>. See
  51. //! the documentation on unstable features for details on how to enable it.
  52. //! </pre>
  53. //!
  54. //! For example:
  55. //! ```ignore
  56. //! // Derive `Valuable` for our types:
  57. //! use valuable::Valuable;
  58. //!
  59. //! #[derive(Clone, Debug, Valuable)]
  60. //! struct User {
  61. //! name: String,
  62. //! age: u32,
  63. //! address: Address,
  64. //! }
  65. //!
  66. //! #[derive(Clone, Debug, Valuable)]
  67. //! struct Address {
  68. //! country: String,
  69. //! city: String,
  70. //! street: String,
  71. //! }
  72. //!
  73. //! let user = User {
  74. //! name: "Arwen Undomiel".to_string(),
  75. //! age: 3000,
  76. //! address: Address {
  77. //! country: "Middle Earth".to_string(),
  78. //! city: "Rivendell".to_string(),
  79. //! street: "leafy lane".to_string(),
  80. //! },
  81. //! };
  82. //!
  83. //! // Recording `user` as a `valuable::Value` will allow the `tracing` subscriber
  84. //! // to traverse its fields as a nested, typed structure:
  85. //! tracing::info!(current_user = user.as_value());
  86. //! ```
  87. //!
  88. //! Alternatively, the [`valuable()`] function may be used to convert a type
  89. //! implementing [`Valuable`] into a `tracing` field value.
  90. //!
  91. //! When the `valuable` feature is enabled, the [`Visit`] trait will include an
  92. //! optional [`record_value`] method. `Visit` implementations that wish to
  93. //! record `valuable` values can implement this method with custom behavior.
  94. //! If a visitor does not implement `record_value`, the [`valuable::Value`] will
  95. //! be forwarded to the visitor's [`record_debug`] method.
  96. //!
  97. //! [`valuable`]: https://crates.io/crates/valuable
  98. //! [`as_value`]: valuable::Valuable::as_value
  99. //! [`Subscriber`]: crate::Subscriber
  100. //! [`record_value`]: Visit::record_value
  101. //! [`record_debug`]: Visit::record_debug
  102. //!
  103. //! [span]: super::span
  104. //! [`Event`]: super::event::Event
  105. //! [`Metadata`]: super::metadata::Metadata
  106. //! [`Attributes`]: super::span::Attributes
  107. //! [`Record`]: super::span::Record
  108. //! [`new_span`]: super::subscriber::Subscriber::new_span
  109. //! [`record`]: super::subscriber::Subscriber::record
  110. //! [`event`]: super::subscriber::Subscriber::event
  111. //! [`Value::record`]: Value::record
  112. use crate::callsite;
  113. use crate::stdlib::{
  114. borrow::Borrow,
  115. fmt,
  116. hash::{Hash, Hasher},
  117. num,
  118. ops::Range,
  119. };
  120. use self::private::ValidLen;
  121. /// An opaque key allowing _O_(1) access to a field in a `Span`'s key-value
  122. /// data.
  123. ///
  124. /// As keys are defined by the _metadata_ of a span, rather than by an
  125. /// individual instance of a span, a key may be used to access the same field
  126. /// across all instances of a given span with the same metadata. Thus, when a
  127. /// subscriber observes a new span, it need only access a field by name _once_,
  128. /// and use the key for that name for all other accesses.
  129. #[derive(Debug)]
  130. pub struct Field {
  131. i: usize,
  132. fields: FieldSet,
  133. }
  134. /// An empty field.
  135. ///
  136. /// This can be used to indicate that the value of a field is not currently
  137. /// present but will be recorded later.
  138. ///
  139. /// When a field's value is `Empty`. it will not be recorded.
  140. #[derive(Debug, Eq, PartialEq)]
  141. pub struct Empty;
  142. /// Describes the fields present on a span.
  143. pub struct FieldSet {
  144. /// The names of each field on the described span.
  145. names: &'static [&'static str],
  146. /// The callsite where the described span originates.
  147. callsite: callsite::Identifier,
  148. }
  149. /// A set of fields and values for a span.
  150. pub struct ValueSet<'a> {
  151. values: &'a [(&'a Field, Option<&'a (dyn Value + 'a)>)],
  152. fields: &'a FieldSet,
  153. }
  154. /// An iterator over a set of fields.
  155. #[derive(Debug)]
  156. pub struct Iter {
  157. idxs: Range<usize>,
  158. fields: FieldSet,
  159. }
  160. /// Visits typed values.
  161. ///
  162. /// An instance of `Visit` ("a visitor") represents the logic necessary to
  163. /// record field values of various types. When an implementor of [`Value`] is
  164. /// [recorded], it calls the appropriate method on the provided visitor to
  165. /// indicate the type that value should be recorded as.
  166. ///
  167. /// When a [`Subscriber`] implementation [records an `Event`] or a
  168. /// [set of `Value`s added to a `Span`], it can pass an `&mut Visit` to the
  169. /// `record` method on the provided [`ValueSet`] or [`Event`]. This visitor
  170. /// will then be used to record all the field-value pairs present on that
  171. /// `Event` or `ValueSet`.
  172. ///
  173. /// # Examples
  174. ///
  175. /// A simple visitor that writes to a string might be implemented like so:
  176. /// ```
  177. /// # extern crate tracing_core as tracing;
  178. /// use std::fmt::{self, Write};
  179. /// use tracing::field::{Value, Visit, Field};
  180. /// pub struct StringVisitor<'a> {
  181. /// string: &'a mut String,
  182. /// }
  183. ///
  184. /// impl<'a> Visit for StringVisitor<'a> {
  185. /// fn record_debug(&mut self, field: &Field, value: &dyn fmt::Debug) {
  186. /// write!(self.string, "{} = {:?}; ", field.name(), value).unwrap();
  187. /// }
  188. /// }
  189. /// ```
  190. /// This visitor will format each recorded value using `fmt::Debug`, and
  191. /// append the field name and formatted value to the provided string,
  192. /// regardless of the type of the recorded value. When all the values have
  193. /// been recorded, the `StringVisitor` may be dropped, allowing the string
  194. /// to be printed or stored in some other data structure.
  195. ///
  196. /// The `Visit` trait provides default implementations for `record_i64`,
  197. /// `record_u64`, `record_bool`, `record_str`, and `record_error`, which simply
  198. /// forward the recorded value to `record_debug`. Thus, `record_debug` is the
  199. /// only method which a `Visit` implementation *must* implement. However,
  200. /// visitors may override the default implementations of these functions in
  201. /// order to implement type-specific behavior.
  202. ///
  203. /// Additionally, when a visitor receives a value of a type it does not care
  204. /// about, it is free to ignore those values completely. For example, a
  205. /// visitor which only records numeric data might look like this:
  206. ///
  207. /// ```
  208. /// # extern crate tracing_core as tracing;
  209. /// # use std::fmt::{self, Write};
  210. /// # use tracing::field::{Value, Visit, Field};
  211. /// pub struct SumVisitor {
  212. /// sum: i64,
  213. /// }
  214. ///
  215. /// impl Visit for SumVisitor {
  216. /// fn record_i64(&mut self, _field: &Field, value: i64) {
  217. /// self.sum += value;
  218. /// }
  219. ///
  220. /// fn record_u64(&mut self, _field: &Field, value: u64) {
  221. /// self.sum += value as i64;
  222. /// }
  223. ///
  224. /// fn record_debug(&mut self, _field: &Field, _value: &fmt::Debug) {
  225. /// // Do nothing
  226. /// }
  227. /// }
  228. /// ```
  229. ///
  230. /// This visitor (which is probably not particularly useful) keeps a running
  231. /// sum of all the numeric values it records, and ignores all other values. A
  232. /// more practical example of recording typed values is presented in
  233. /// `examples/counters.rs`, which demonstrates a very simple metrics system
  234. /// implemented using `tracing`.
  235. ///
  236. /// <div class="example-wrap" style="display:inline-block">
  237. /// <pre class="ignore" style="white-space:normal;font:inherit;">
  238. /// <strong>Note</strong>: The <code>record_error</code> trait method is only
  239. /// available when the Rust standard library is present, as it requires the
  240. /// <code>std::error::Error</code> trait.
  241. /// </pre></div>
  242. ///
  243. /// [recorded]: Value::record
  244. /// [`Subscriber`]: super::subscriber::Subscriber
  245. /// [records an `Event`]: super::subscriber::Subscriber::event
  246. /// [set of `Value`s added to a `Span`]: super::subscriber::Subscriber::record
  247. /// [`Event`]: super::event::Event
  248. pub trait Visit {
  249. /// Visits an arbitrary type implementing the [`valuable`] crate's `Valuable` trait.
  250. ///
  251. /// [`valuable`]: https://docs.rs/valuable
  252. #[cfg(all(tracing_unstable, feature = "valuable"))]
  253. #[cfg_attr(docsrs, doc(cfg(all(tracing_unstable, feature = "valuable"))))]
  254. fn record_value(&mut self, field: &Field, value: valuable::Value<'_>) {
  255. self.record_debug(field, &value)
  256. }
  257. /// Visit a double-precision floating point value.
  258. fn record_f64(&mut self, field: &Field, value: f64) {
  259. self.record_debug(field, &value)
  260. }
  261. /// Visit a signed 64-bit integer value.
  262. fn record_i64(&mut self, field: &Field, value: i64) {
  263. self.record_debug(field, &value)
  264. }
  265. /// Visit an unsigned 64-bit integer value.
  266. fn record_u64(&mut self, field: &Field, value: u64) {
  267. self.record_debug(field, &value)
  268. }
  269. /// Visit a boolean value.
  270. fn record_bool(&mut self, field: &Field, value: bool) {
  271. self.record_debug(field, &value)
  272. }
  273. /// Visit a string value.
  274. fn record_str(&mut self, field: &Field, value: &str) {
  275. self.record_debug(field, &value)
  276. }
  277. /// Records a type implementing `Error`.
  278. ///
  279. /// <div class="example-wrap" style="display:inline-block">
  280. /// <pre class="ignore" style="white-space:normal;font:inherit;">
  281. /// <strong>Note</strong>: This is only enabled when the Rust standard library is
  282. /// present.
  283. /// </pre>
  284. #[cfg(feature = "std")]
  285. #[cfg_attr(docsrs, doc(cfg(feature = "std")))]
  286. fn record_error(&mut self, field: &Field, value: &(dyn std::error::Error + 'static)) {
  287. self.record_debug(field, &DisplayValue(value))
  288. }
  289. /// Visit a value implementing `fmt::Debug`.
  290. fn record_debug(&mut self, field: &Field, value: &dyn fmt::Debug);
  291. }
  292. /// A field value of an erased type.
  293. ///
  294. /// Implementors of `Value` may call the appropriate typed recording methods on
  295. /// the [visitor] passed to their `record` method in order to indicate how
  296. /// their data should be recorded.
  297. ///
  298. /// [visitor]: Visit
  299. pub trait Value: crate::sealed::Sealed {
  300. /// Visits this value with the given `Visitor`.
  301. fn record(&self, key: &Field, visitor: &mut dyn Visit);
  302. }
  303. /// A `Value` which serializes using `fmt::Display`.
  304. ///
  305. /// Uses `record_debug` in the `Value` implementation to
  306. /// avoid an unnecessary evaluation.
  307. #[derive(Clone)]
  308. pub struct DisplayValue<T: fmt::Display>(T);
  309. /// A `Value` which serializes as a string using `fmt::Debug`.
  310. #[derive(Clone)]
  311. pub struct DebugValue<T: fmt::Debug>(T);
  312. /// Wraps a type implementing `fmt::Display` as a `Value` that can be
  313. /// recorded using its `Display` implementation.
  314. pub fn display<T>(t: T) -> DisplayValue<T>
  315. where
  316. T: fmt::Display,
  317. {
  318. DisplayValue(t)
  319. }
  320. /// Wraps a type implementing `fmt::Debug` as a `Value` that can be
  321. /// recorded using its `Debug` implementation.
  322. pub fn debug<T>(t: T) -> DebugValue<T>
  323. where
  324. T: fmt::Debug,
  325. {
  326. DebugValue(t)
  327. }
  328. /// Wraps a type implementing [`Valuable`] as a `Value` that
  329. /// can be recorded using its `Valuable` implementation.
  330. ///
  331. /// [`Valuable`]: https://docs.rs/valuable/latest/valuable/trait.Valuable.html
  332. #[cfg(all(tracing_unstable, feature = "valuable"))]
  333. #[cfg_attr(docsrs, doc(cfg(all(tracing_unstable, feature = "valuable"))))]
  334. pub fn valuable<T>(t: &T) -> valuable::Value<'_>
  335. where
  336. T: valuable::Valuable,
  337. {
  338. t.as_value()
  339. }
  340. // ===== impl Visit =====
  341. impl<'a, 'b> Visit for fmt::DebugStruct<'a, 'b> {
  342. fn record_debug(&mut self, field: &Field, value: &dyn fmt::Debug) {
  343. self.field(field.name(), value);
  344. }
  345. }
  346. impl<'a, 'b> Visit for fmt::DebugMap<'a, 'b> {
  347. fn record_debug(&mut self, field: &Field, value: &dyn fmt::Debug) {
  348. self.entry(&format_args!("{}", field), value);
  349. }
  350. }
  351. impl<F> Visit for F
  352. where
  353. F: FnMut(&Field, &dyn fmt::Debug),
  354. {
  355. fn record_debug(&mut self, field: &Field, value: &dyn fmt::Debug) {
  356. (self)(field, value)
  357. }
  358. }
  359. // ===== impl Value =====
  360. macro_rules! impl_values {
  361. ( $( $record:ident( $( $whatever:tt)+ ) ),+ ) => {
  362. $(
  363. impl_value!{ $record( $( $whatever )+ ) }
  364. )+
  365. }
  366. }
  367. macro_rules! ty_to_nonzero {
  368. (u8) => {
  369. NonZeroU8
  370. };
  371. (u16) => {
  372. NonZeroU16
  373. };
  374. (u32) => {
  375. NonZeroU32
  376. };
  377. (u64) => {
  378. NonZeroU64
  379. };
  380. (u128) => {
  381. NonZeroU128
  382. };
  383. (usize) => {
  384. NonZeroUsize
  385. };
  386. (i8) => {
  387. NonZeroI8
  388. };
  389. (i16) => {
  390. NonZeroI16
  391. };
  392. (i32) => {
  393. NonZeroI32
  394. };
  395. (i64) => {
  396. NonZeroI64
  397. };
  398. (i128) => {
  399. NonZeroI128
  400. };
  401. (isize) => {
  402. NonZeroIsize
  403. };
  404. }
  405. macro_rules! impl_one_value {
  406. (f32, $op:expr, $record:ident) => {
  407. impl_one_value!(normal, f32, $op, $record);
  408. };
  409. (f64, $op:expr, $record:ident) => {
  410. impl_one_value!(normal, f64, $op, $record);
  411. };
  412. (bool, $op:expr, $record:ident) => {
  413. impl_one_value!(normal, bool, $op, $record);
  414. };
  415. ($value_ty:tt, $op:expr, $record:ident) => {
  416. impl_one_value!(normal, $value_ty, $op, $record);
  417. impl_one_value!(nonzero, $value_ty, $op, $record);
  418. };
  419. (normal, $value_ty:tt, $op:expr, $record:ident) => {
  420. impl $crate::sealed::Sealed for $value_ty {}
  421. impl $crate::field::Value for $value_ty {
  422. fn record(&self, key: &$crate::field::Field, visitor: &mut dyn $crate::field::Visit) {
  423. visitor.$record(key, $op(*self))
  424. }
  425. }
  426. };
  427. (nonzero, $value_ty:tt, $op:expr, $record:ident) => {
  428. // This `use num::*;` is reported as unused because it gets emitted
  429. // for every single invocation of this macro, so there are multiple `use`s.
  430. // All but the first are useless indeed.
  431. // We need this import because we can't write a path where one part is
  432. // the `ty_to_nonzero!($value_ty)` invocation.
  433. #[allow(clippy::useless_attribute, unused)]
  434. use num::*;
  435. impl $crate::sealed::Sealed for ty_to_nonzero!($value_ty) {}
  436. impl $crate::field::Value for ty_to_nonzero!($value_ty) {
  437. fn record(&self, key: &$crate::field::Field, visitor: &mut dyn $crate::field::Visit) {
  438. visitor.$record(key, $op(self.get()))
  439. }
  440. }
  441. };
  442. }
  443. macro_rules! impl_value {
  444. ( $record:ident( $( $value_ty:tt ),+ ) ) => {
  445. $(
  446. impl_one_value!($value_ty, |this: $value_ty| this, $record);
  447. )+
  448. };
  449. ( $record:ident( $( $value_ty:tt ),+ as $as_ty:ty) ) => {
  450. $(
  451. impl_one_value!($value_ty, |this: $value_ty| this as $as_ty, $record);
  452. )+
  453. };
  454. }
  455. // ===== impl Value =====
  456. impl_values! {
  457. record_u64(u64),
  458. record_u64(usize, u32, u16, u8 as u64),
  459. record_i64(i64),
  460. record_i64(isize, i32, i16, i8 as i64),
  461. record_bool(bool),
  462. record_f64(f64, f32 as f64)
  463. }
  464. impl<T: crate::sealed::Sealed> crate::sealed::Sealed for Wrapping<T> {}
  465. impl<T: crate::field::Value> crate::field::Value for Wrapping<T> {
  466. fn record(&self, key: &crate::field::Field, visitor: &mut dyn crate::field::Visit) {
  467. self.0.record(key, visitor)
  468. }
  469. }
  470. impl crate::sealed::Sealed for str {}
  471. impl Value for str {
  472. fn record(&self, key: &Field, visitor: &mut dyn Visit) {
  473. visitor.record_str(key, self)
  474. }
  475. }
  476. #[cfg(feature = "std")]
  477. impl crate::sealed::Sealed for dyn std::error::Error + 'static {}
  478. #[cfg(feature = "std")]
  479. #[cfg_attr(docsrs, doc(cfg(feature = "std")))]
  480. impl Value for dyn std::error::Error + 'static {
  481. fn record(&self, key: &Field, visitor: &mut dyn Visit) {
  482. visitor.record_error(key, self)
  483. }
  484. }
  485. #[cfg(feature = "std")]
  486. impl crate::sealed::Sealed for dyn std::error::Error + Send + 'static {}
  487. #[cfg(feature = "std")]
  488. #[cfg_attr(docsrs, doc(cfg(feature = "std")))]
  489. impl Value for dyn std::error::Error + Send + 'static {
  490. fn record(&self, key: &Field, visitor: &mut dyn Visit) {
  491. (self as &dyn std::error::Error).record(key, visitor)
  492. }
  493. }
  494. #[cfg(feature = "std")]
  495. impl crate::sealed::Sealed for dyn std::error::Error + Sync + 'static {}
  496. #[cfg(feature = "std")]
  497. #[cfg_attr(docsrs, doc(cfg(feature = "std")))]
  498. impl Value for dyn std::error::Error + Sync + 'static {
  499. fn record(&self, key: &Field, visitor: &mut dyn Visit) {
  500. (self as &dyn std::error::Error).record(key, visitor)
  501. }
  502. }
  503. #[cfg(feature = "std")]
  504. impl crate::sealed::Sealed for dyn std::error::Error + Send + Sync + 'static {}
  505. #[cfg(feature = "std")]
  506. #[cfg_attr(docsrs, doc(cfg(feature = "std")))]
  507. impl Value for dyn std::error::Error + Send + Sync + 'static {
  508. fn record(&self, key: &Field, visitor: &mut dyn Visit) {
  509. (self as &dyn std::error::Error).record(key, visitor)
  510. }
  511. }
  512. impl<'a, T: ?Sized> crate::sealed::Sealed for &'a T where T: Value + crate::sealed::Sealed + 'a {}
  513. impl<'a, T: ?Sized> Value for &'a T
  514. where
  515. T: Value + 'a,
  516. {
  517. fn record(&self, key: &Field, visitor: &mut dyn Visit) {
  518. (*self).record(key, visitor)
  519. }
  520. }
  521. impl<'a, T: ?Sized> crate::sealed::Sealed for &'a mut T where T: Value + crate::sealed::Sealed + 'a {}
  522. impl<'a, T: ?Sized> Value for &'a mut T
  523. where
  524. T: Value + 'a,
  525. {
  526. fn record(&self, key: &Field, visitor: &mut dyn Visit) {
  527. // Don't use `(*self).record(key, visitor)`, otherwise would
  528. // cause stack overflow due to `unconditional_recursion`.
  529. T::record(self, key, visitor)
  530. }
  531. }
  532. impl<'a> crate::sealed::Sealed for fmt::Arguments<'a> {}
  533. impl<'a> Value for fmt::Arguments<'a> {
  534. fn record(&self, key: &Field, visitor: &mut dyn Visit) {
  535. visitor.record_debug(key, self)
  536. }
  537. }
  538. impl<T: ?Sized> crate::sealed::Sealed for crate::stdlib::boxed::Box<T> where T: Value {}
  539. impl<T: ?Sized> Value for crate::stdlib::boxed::Box<T>
  540. where
  541. T: Value,
  542. {
  543. #[inline]
  544. fn record(&self, key: &Field, visitor: &mut dyn Visit) {
  545. self.as_ref().record(key, visitor)
  546. }
  547. }
  548. impl fmt::Debug for dyn Value {
  549. fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
  550. // We are only going to be recording the field value, so we don't
  551. // actually care about the field name here.
  552. struct NullCallsite;
  553. static NULL_CALLSITE: NullCallsite = NullCallsite;
  554. impl crate::callsite::Callsite for NullCallsite {
  555. fn set_interest(&self, _: crate::subscriber::Interest) {
  556. unreachable!("you somehow managed to register the null callsite?")
  557. }
  558. fn metadata(&self) -> &crate::Metadata<'_> {
  559. unreachable!("you somehow managed to access the null callsite?")
  560. }
  561. }
  562. static FIELD: Field = Field {
  563. i: 0,
  564. fields: FieldSet::new(&[], crate::identify_callsite!(&NULL_CALLSITE)),
  565. };
  566. let mut res = Ok(());
  567. self.record(&FIELD, &mut |_: &Field, val: &dyn fmt::Debug| {
  568. res = write!(f, "{:?}", val);
  569. });
  570. res
  571. }
  572. }
  573. impl fmt::Display for dyn Value {
  574. fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
  575. fmt::Debug::fmt(self, f)
  576. }
  577. }
  578. // ===== impl DisplayValue =====
  579. impl<T: fmt::Display> crate::sealed::Sealed for DisplayValue<T> {}
  580. impl<T> Value for DisplayValue<T>
  581. where
  582. T: fmt::Display,
  583. {
  584. fn record(&self, key: &Field, visitor: &mut dyn Visit) {
  585. visitor.record_debug(key, self)
  586. }
  587. }
  588. impl<T: fmt::Display> fmt::Debug for DisplayValue<T> {
  589. fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
  590. fmt::Display::fmt(self, f)
  591. }
  592. }
  593. impl<T: fmt::Display> fmt::Display for DisplayValue<T> {
  594. fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
  595. self.0.fmt(f)
  596. }
  597. }
  598. // ===== impl DebugValue =====
  599. impl<T: fmt::Debug> crate::sealed::Sealed for DebugValue<T> {}
  600. impl<T> Value for DebugValue<T>
  601. where
  602. T: fmt::Debug,
  603. {
  604. fn record(&self, key: &Field, visitor: &mut dyn Visit) {
  605. visitor.record_debug(key, &self.0)
  606. }
  607. }
  608. impl<T: fmt::Debug> fmt::Debug for DebugValue<T> {
  609. fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
  610. self.0.fmt(f)
  611. }
  612. }
  613. // ===== impl ValuableValue =====
  614. #[cfg(all(tracing_unstable, feature = "valuable"))]
  615. impl crate::sealed::Sealed for valuable::Value<'_> {}
  616. #[cfg(all(tracing_unstable, feature = "valuable"))]
  617. #[cfg_attr(docsrs, doc(cfg(all(tracing_unstable, feature = "valuable"))))]
  618. impl Value for valuable::Value<'_> {
  619. fn record(&self, key: &Field, visitor: &mut dyn Visit) {
  620. visitor.record_value(key, *self)
  621. }
  622. }
  623. #[cfg(all(tracing_unstable, feature = "valuable"))]
  624. impl crate::sealed::Sealed for &'_ dyn valuable::Valuable {}
  625. #[cfg(all(tracing_unstable, feature = "valuable"))]
  626. #[cfg_attr(docsrs, doc(cfg(all(tracing_unstable, feature = "valuable"))))]
  627. impl Value for &'_ dyn valuable::Valuable {
  628. fn record(&self, key: &Field, visitor: &mut dyn Visit) {
  629. visitor.record_value(key, self.as_value())
  630. }
  631. }
  632. impl crate::sealed::Sealed for Empty {}
  633. impl Value for Empty {
  634. #[inline]
  635. fn record(&self, _: &Field, _: &mut dyn Visit) {}
  636. }
  637. impl<T: Value> crate::sealed::Sealed for Option<T> {}
  638. impl<T: Value> Value for Option<T> {
  639. fn record(&self, key: &Field, visitor: &mut dyn Visit) {
  640. if let Some(v) = &self {
  641. v.record(key, visitor)
  642. }
  643. }
  644. }
  645. // ===== impl Field =====
  646. impl Field {
  647. /// Returns an [`Identifier`] that uniquely identifies the [`Callsite`]
  648. /// which defines this field.
  649. ///
  650. /// [`Identifier`]: super::callsite::Identifier
  651. /// [`Callsite`]: super::callsite::Callsite
  652. #[inline]
  653. pub fn callsite(&self) -> callsite::Identifier {
  654. self.fields.callsite()
  655. }
  656. /// Returns a string representing the name of the field.
  657. pub fn name(&self) -> &'static str {
  658. self.fields.names[self.i]
  659. }
  660. }
  661. impl fmt::Display for Field {
  662. fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
  663. f.pad(self.name())
  664. }
  665. }
  666. impl AsRef<str> for Field {
  667. fn as_ref(&self) -> &str {
  668. self.name()
  669. }
  670. }
  671. impl PartialEq for Field {
  672. fn eq(&self, other: &Self) -> bool {
  673. self.callsite() == other.callsite() && self.i == other.i
  674. }
  675. }
  676. impl Eq for Field {}
  677. impl Hash for Field {
  678. fn hash<H>(&self, state: &mut H)
  679. where
  680. H: Hasher,
  681. {
  682. self.callsite().hash(state);
  683. self.i.hash(state);
  684. }
  685. }
  686. impl Clone for Field {
  687. fn clone(&self) -> Self {
  688. Field {
  689. i: self.i,
  690. fields: FieldSet {
  691. names: self.fields.names,
  692. callsite: self.fields.callsite(),
  693. },
  694. }
  695. }
  696. }
  697. // ===== impl FieldSet =====
  698. impl FieldSet {
  699. /// Constructs a new `FieldSet` with the given array of field names and callsite.
  700. pub const fn new(names: &'static [&'static str], callsite: callsite::Identifier) -> Self {
  701. Self { names, callsite }
  702. }
  703. /// Returns an [`Identifier`] that uniquely identifies the [`Callsite`]
  704. /// which defines this set of fields..
  705. ///
  706. /// [`Identifier`]: super::callsite::Identifier
  707. /// [`Callsite`]: super::callsite::Callsite
  708. pub(crate) fn callsite(&self) -> callsite::Identifier {
  709. callsite::Identifier(self.callsite.0)
  710. }
  711. /// Returns the [`Field`] named `name`, or `None` if no such field exists.
  712. ///
  713. /// [`Field`]: super::Field
  714. pub fn field<Q: ?Sized>(&self, name: &Q) -> Option<Field>
  715. where
  716. Q: Borrow<str>,
  717. {
  718. let name = &name.borrow();
  719. self.names.iter().position(|f| f == name).map(|i| Field {
  720. i,
  721. fields: FieldSet {
  722. names: self.names,
  723. callsite: self.callsite(),
  724. },
  725. })
  726. }
  727. /// Returns `true` if `self` contains the given `field`.
  728. ///
  729. /// <div class="example-wrap" style="display:inline-block">
  730. /// <pre class="ignore" style="white-space:normal;font:inherit;">
  731. /// <strong>Note</strong>: If <code>field</code> shares a name with a field
  732. /// in this <code>FieldSet</code>, but was created by a <code>FieldSet</code>
  733. /// with a different callsite, this <code>FieldSet</code> does <em>not</em>
  734. /// contain it. This is so that if two separate span callsites define a field
  735. /// named "foo", the <code>Field</code> corresponding to "foo" for each
  736. /// of those callsites are not equivalent.
  737. /// </pre></div>
  738. pub fn contains(&self, field: &Field) -> bool {
  739. field.callsite() == self.callsite() && field.i <= self.len()
  740. }
  741. /// Returns an iterator over the `Field`s in this `FieldSet`.
  742. pub fn iter(&self) -> Iter {
  743. let idxs = 0..self.len();
  744. Iter {
  745. idxs,
  746. fields: FieldSet {
  747. names: self.names,
  748. callsite: self.callsite(),
  749. },
  750. }
  751. }
  752. /// Returns a new `ValueSet` with entries for this `FieldSet`'s values.
  753. ///
  754. /// Note that a `ValueSet` may not be constructed with arrays of over 32
  755. /// elements.
  756. #[doc(hidden)]
  757. pub fn value_set<'v, V>(&'v self, values: &'v V) -> ValueSet<'v>
  758. where
  759. V: ValidLen<'v>,
  760. {
  761. ValueSet {
  762. fields: self,
  763. values: values.borrow(),
  764. }
  765. }
  766. /// Returns the number of fields in this `FieldSet`.
  767. #[inline]
  768. pub fn len(&self) -> usize {
  769. self.names.len()
  770. }
  771. /// Returns whether or not this `FieldSet` has fields.
  772. #[inline]
  773. pub fn is_empty(&self) -> bool {
  774. self.names.is_empty()
  775. }
  776. }
  777. impl<'a> IntoIterator for &'a FieldSet {
  778. type IntoIter = Iter;
  779. type Item = Field;
  780. #[inline]
  781. fn into_iter(self) -> Self::IntoIter {
  782. self.iter()
  783. }
  784. }
  785. impl fmt::Debug for FieldSet {
  786. fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
  787. f.debug_struct("FieldSet")
  788. .field("names", &self.names)
  789. .field("callsite", &self.callsite)
  790. .finish()
  791. }
  792. }
  793. impl fmt::Display for FieldSet {
  794. fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
  795. f.debug_set()
  796. .entries(self.names.iter().map(display))
  797. .finish()
  798. }
  799. }
  800. // ===== impl Iter =====
  801. impl Iterator for Iter {
  802. type Item = Field;
  803. fn next(&mut self) -> Option<Field> {
  804. let i = self.idxs.next()?;
  805. Some(Field {
  806. i,
  807. fields: FieldSet {
  808. names: self.fields.names,
  809. callsite: self.fields.callsite(),
  810. },
  811. })
  812. }
  813. }
  814. // ===== impl ValueSet =====
  815. impl<'a> ValueSet<'a> {
  816. /// Returns an [`Identifier`] that uniquely identifies the [`Callsite`]
  817. /// defining the fields this `ValueSet` refers to.
  818. ///
  819. /// [`Identifier`]: super::callsite::Identifier
  820. /// [`Callsite`]: super::callsite::Callsite
  821. #[inline]
  822. pub fn callsite(&self) -> callsite::Identifier {
  823. self.fields.callsite()
  824. }
  825. /// Visits all the fields in this `ValueSet` with the provided [visitor].
  826. ///
  827. /// [visitor]: Visit
  828. pub fn record(&self, visitor: &mut dyn Visit) {
  829. let my_callsite = self.callsite();
  830. for (field, value) in self.values {
  831. if field.callsite() != my_callsite {
  832. continue;
  833. }
  834. if let Some(value) = value {
  835. value.record(field, visitor);
  836. }
  837. }
  838. }
  839. /// Returns the number of fields in this `ValueSet` that would be visited
  840. /// by a given [visitor] to the [`ValueSet::record()`] method.
  841. ///
  842. /// [visitor]: Visit
  843. /// [`ValueSet::record()`]: ValueSet::record()
  844. pub fn len(&self) -> usize {
  845. let my_callsite = self.callsite();
  846. self.values
  847. .iter()
  848. .filter(|(field, _)| field.callsite() == my_callsite)
  849. .count()
  850. }
  851. /// Returns `true` if this `ValueSet` contains a value for the given `Field`.
  852. pub(crate) fn contains(&self, field: &Field) -> bool {
  853. field.callsite() == self.callsite()
  854. && self
  855. .values
  856. .iter()
  857. .any(|(key, val)| *key == field && val.is_some())
  858. }
  859. /// Returns true if this `ValueSet` contains _no_ values.
  860. pub fn is_empty(&self) -> bool {
  861. let my_callsite = self.callsite();
  862. self.values
  863. .iter()
  864. .all(|(key, val)| val.is_none() || key.callsite() != my_callsite)
  865. }
  866. pub(crate) fn field_set(&self) -> &FieldSet {
  867. self.fields
  868. }
  869. }
  870. impl<'a> fmt::Debug for ValueSet<'a> {
  871. fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
  872. self.values
  873. .iter()
  874. .fold(&mut f.debug_struct("ValueSet"), |dbg, (key, v)| {
  875. if let Some(val) = v {
  876. val.record(key, dbg);
  877. }
  878. dbg
  879. })
  880. .field("callsite", &self.callsite())
  881. .finish()
  882. }
  883. }
  884. impl<'a> fmt::Display for ValueSet<'a> {
  885. fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
  886. self.values
  887. .iter()
  888. .fold(&mut f.debug_map(), |dbg, (key, v)| {
  889. if let Some(val) = v {
  890. val.record(key, dbg);
  891. }
  892. dbg
  893. })
  894. .finish()
  895. }
  896. }
  897. // ===== impl ValidLen =====
  898. mod private {
  899. use super::*;
  900. /// Marker trait implemented by arrays which are of valid length to
  901. /// construct a `ValueSet`.
  902. ///
  903. /// `ValueSet`s may only be constructed from arrays containing 32 or fewer
  904. /// elements, to ensure the array is small enough to always be allocated on the
  905. /// stack. This trait is only implemented by arrays of an appropriate length,
  906. /// ensuring that the correct size arrays are used at compile-time.
  907. pub trait ValidLen<'a>: Borrow<[(&'a Field, Option<&'a (dyn Value + 'a)>)]> {}
  908. }
  909. macro_rules! impl_valid_len {
  910. ( $( $len:tt ),+ ) => {
  911. $(
  912. impl<'a> private::ValidLen<'a> for
  913. [(&'a Field, Option<&'a (dyn Value + 'a)>); $len] {}
  914. )+
  915. }
  916. }
  917. impl_valid_len! {
  918. 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
  919. 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32
  920. }
  921. #[cfg(test)]
  922. mod test {
  923. use super::*;
  924. use crate::metadata::{Kind, Level, Metadata};
  925. use crate::stdlib::{borrow::ToOwned, string::String};
  926. struct TestCallsite1;
  927. static TEST_CALLSITE_1: TestCallsite1 = TestCallsite1;
  928. static TEST_META_1: Metadata<'static> = metadata! {
  929. name: "field_test1",
  930. target: module_path!(),
  931. level: Level::INFO,
  932. fields: &["foo", "bar", "baz"],
  933. callsite: &TEST_CALLSITE_1,
  934. kind: Kind::SPAN,
  935. };
  936. impl crate::callsite::Callsite for TestCallsite1 {
  937. fn set_interest(&self, _: crate::subscriber::Interest) {
  938. unimplemented!()
  939. }
  940. fn metadata(&self) -> &Metadata<'_> {
  941. &TEST_META_1
  942. }
  943. }
  944. struct TestCallsite2;
  945. static TEST_CALLSITE_2: TestCallsite2 = TestCallsite2;
  946. static TEST_META_2: Metadata<'static> = metadata! {
  947. name: "field_test2",
  948. target: module_path!(),
  949. level: Level::INFO,
  950. fields: &["foo", "bar", "baz"],
  951. callsite: &TEST_CALLSITE_2,
  952. kind: Kind::SPAN,
  953. };
  954. impl crate::callsite::Callsite for TestCallsite2 {
  955. fn set_interest(&self, _: crate::subscriber::Interest) {
  956. unimplemented!()
  957. }
  958. fn metadata(&self) -> &Metadata<'_> {
  959. &TEST_META_2
  960. }
  961. }
  962. #[test]
  963. fn value_set_with_no_values_is_empty() {
  964. let fields = TEST_META_1.fields();
  965. let values = &[
  966. (&fields.field("foo").unwrap(), None),
  967. (&fields.field("bar").unwrap(), None),
  968. (&fields.field("baz").unwrap(), None),
  969. ];
  970. let valueset = fields.value_set(values);
  971. assert!(valueset.is_empty());
  972. }
  973. #[test]
  974. fn empty_value_set_is_empty() {
  975. let fields = TEST_META_1.fields();
  976. let valueset = fields.value_set(&[]);
  977. assert!(valueset.is_empty());
  978. }
  979. #[test]
  980. fn value_sets_with_fields_from_other_callsites_are_empty() {
  981. let fields = TEST_META_1.fields();
  982. let values = &[
  983. (&fields.field("foo").unwrap(), Some(&1 as &dyn Value)),
  984. (&fields.field("bar").unwrap(), Some(&2 as &dyn Value)),
  985. (&fields.field("baz").unwrap(), Some(&3 as &dyn Value)),
  986. ];
  987. let valueset = TEST_META_2.fields().value_set(values);
  988. assert!(valueset.is_empty())
  989. }
  990. #[test]
  991. fn sparse_value_sets_are_not_empty() {
  992. let fields = TEST_META_1.fields();
  993. let values = &[
  994. (&fields.field("foo").unwrap(), None),
  995. (&fields.field("bar").unwrap(), Some(&57 as &dyn Value)),
  996. (&fields.field("baz").unwrap(), None),
  997. ];
  998. let valueset = fields.value_set(values);
  999. assert!(!valueset.is_empty());
  1000. }
  1001. #[test]
  1002. fn fields_from_other_callsets_are_skipped() {
  1003. let fields = TEST_META_1.fields();
  1004. let values = &[
  1005. (&fields.field("foo").unwrap(), None),
  1006. (
  1007. &TEST_META_2.fields().field("bar").unwrap(),
  1008. Some(&57 as &dyn Value),
  1009. ),
  1010. (&fields.field("baz").unwrap(), None),
  1011. ];
  1012. struct MyVisitor;
  1013. impl Visit for MyVisitor {
  1014. fn record_debug(&mut self, field: &Field, _: &dyn (crate::stdlib::fmt::Debug)) {
  1015. assert_eq!(field.callsite(), TEST_META_1.callsite())
  1016. }
  1017. }
  1018. let valueset = fields.value_set(values);
  1019. valueset.record(&mut MyVisitor);
  1020. }
  1021. #[test]
  1022. fn empty_fields_are_skipped() {
  1023. let fields = TEST_META_1.fields();
  1024. let values = &[
  1025. (&fields.field("foo").unwrap(), Some(&Empty as &dyn Value)),
  1026. (&fields.field("bar").unwrap(), Some(&57 as &dyn Value)),
  1027. (&fields.field("baz").unwrap(), Some(&Empty as &dyn Value)),
  1028. ];
  1029. struct MyVisitor;
  1030. impl Visit for MyVisitor {
  1031. fn record_debug(&mut self, field: &Field, _: &dyn (crate::stdlib::fmt::Debug)) {
  1032. assert_eq!(field.name(), "bar")
  1033. }
  1034. }
  1035. let valueset = fields.value_set(values);
  1036. valueset.record(&mut MyVisitor);
  1037. }
  1038. #[test]
  1039. fn record_debug_fn() {
  1040. let fields = TEST_META_1.fields();
  1041. let values = &[
  1042. (&fields.field("foo").unwrap(), Some(&1 as &dyn Value)),
  1043. (&fields.field("bar").unwrap(), Some(&2 as &dyn Value)),
  1044. (&fields.field("baz").unwrap(), Some(&3 as &dyn Value)),
  1045. ];
  1046. let valueset = fields.value_set(values);
  1047. let mut result = String::new();
  1048. valueset.record(&mut |_: &Field, value: &dyn fmt::Debug| {
  1049. use crate::stdlib::fmt::Write;
  1050. write!(&mut result, "{:?}", value).unwrap();
  1051. });
  1052. assert_eq!(result, "123".to_owned());
  1053. }
  1054. #[test]
  1055. #[cfg(feature = "std")]
  1056. fn record_error() {
  1057. let fields = TEST_META_1.fields();
  1058. let err: Box<dyn std::error::Error + Send + Sync + 'static> =
  1059. std::io::Error::new(std::io::ErrorKind::Other, "lol").into();
  1060. let values = &[
  1061. (&fields.field("foo").unwrap(), Some(&err as &dyn Value)),
  1062. (&fields.field("bar").unwrap(), Some(&Empty as &dyn Value)),
  1063. (&fields.field("baz").unwrap(), Some(&Empty as &dyn Value)),
  1064. ];
  1065. let valueset = fields.value_set(values);
  1066. let mut result = String::new();
  1067. valueset.record(&mut |_: &Field, value: &dyn fmt::Debug| {
  1068. use core::fmt::Write;
  1069. write!(&mut result, "{:?}", value).unwrap();
  1070. });
  1071. assert_eq!(result, format!("{}", err));
  1072. }
  1073. }