• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //! # tracing-serde
2 //!
3 //! An adapter for serializing [`tracing`] types using [`serde`].
4 //!
5 //! [![Documentation][docs-badge]][docs-url]
6 //! [![Documentation (master)][docs-master-badge]][docs-master-url]
7 //!
8 //! [docs-badge]: https://docs.rs/tracing-serde/badge.svg
9 //! [docs-url]: https://docs.rs/tracing-serde
10 //! [docs-master-badge]: https://img.shields.io/badge/docs-master-blue
11 //! [docs-master-url]: https://tracing-rs.netlify.com/tracing_serde
12 //!
13 //! ## Overview
14 //!
15 //! [`tracing`] is a framework for instrumenting Rust programs to collect
16 //! scoped, structured, and async-aware diagnostics.`tracing-serde` enables
17 //! serializing `tracing` types using [`serde`].
18 //!
19 //! Traditional logging is based on human-readable text messages.
20 //! `tracing` gives us machine-readable structured diagnostic
21 //! information. This lets us interact with diagnostic data
22 //! programmatically. With `tracing-serde`, you can implement a
23 //! `Subscriber` to serialize your `tracing` types and make use of the
24 //! existing ecosystem of `serde` serializers to talk with distributed
25 //! tracing systems.
26 //!
27 //! Serializing diagnostic information allows us to do more with our logged
28 //! values. For instance, when working with logging data in JSON gives us
29 //! pretty-print when we're debugging in development and you can emit JSON
30 //! and tracing data to monitor your services in production.
31 //!
32 //! The `tracing` crate provides the APIs necessary for instrumenting
33 //! libraries and applications to emit trace data.
34 //!
35 //! *Compiler support: [requires `rustc` 1.49+][msrv]*
36 //!
37 //! [msrv]: #supported-rust-versions
38 //!
39 //! ## Usage
40 //!
41 //! First, add this to your `Cargo.toml`:
42 //!
43 //! ```toml
44 //! [dependencies]
45 //! tracing = "0.1"
46 //! tracing-serde = "0.1"
47 //! ```
48 //!
49 //! Next, add this to your crate:
50 //!
51 //! ```rust
52 //! use tracing_serde::AsSerde;
53 //! ```
54 //!
55 //! Please read the [`tracing` documentation](https://docs.rs/tracing/latest/tracing/index.html)
56 //! for more information on how to create trace data.
57 //!
58 //! This crate provides the `as_serde` function, via the `AsSerde` trait,
59 //! which enables serializing the `Attributes`, `Event`, `Id`, `Metadata`,
60 //! and `Record` `tracing` values.
61 //!
62 //! For the full example, please see the [examples](../examples) folder.
63 //!
64 //! Implement a `Subscriber` to format the serialization of `tracing`
65 //! types how you'd like.
66 //!
67 //! ```rust
68 //! # use tracing_core::{Subscriber, Metadata, Event};
69 //! # use tracing_core::span::{Attributes, Id, Record};
70 //! # use std::sync::atomic::{AtomicUsize, Ordering};
71 //! use tracing_serde::AsSerde;
72 //! use serde_json::json;
73 //!
74 //! pub struct JsonSubscriber {
75 //!     next_id: AtomicUsize, // you need to assign span IDs, so you need a counter
76 //! }
77 //!
78 //! impl Subscriber for JsonSubscriber {
79 //!
80 //!     fn new_span(&self, attrs: &Attributes<'_>) -> Id {
81 //!         let id = self.next_id.fetch_add(1, Ordering::Relaxed);
82 //!         let id = Id::from_u64(id as u64);
83 //!         let json = json!({
84 //!         "new_span": {
85 //!             "attributes": attrs.as_serde(),
86 //!             "id": id.as_serde(),
87 //!         }});
88 //!         println!("{}", json);
89 //!         id
90 //!     }
91 //!
92 //!     fn event(&self, event: &Event<'_>) {
93 //!         let json = json!({
94 //!            "event": event.as_serde(),
95 //!         });
96 //!         println!("{}", json);
97 //!     }
98 //!
99 //!     // ...
100 //!     # fn enabled(&self, _: &Metadata<'_>) -> bool { false }
101 //!     # fn enter(&self, _: &Id) {}
102 //!     # fn exit(&self, _: &Id) {}
103 //!     # fn record(&self, _: &Id, _: &Record<'_>) {}
104 //!     # fn record_follows_from(&self, _: &Id, _: &Id) {}
105 //! }
106 //! ```
107 //!
108 //! After you implement your `Subscriber`, you can use your `tracing`
109 //! subscriber (`JsonSubscriber` in the above example) to record serialized
110 //! trace data.
111 //!
112 //! ### Unstable Features
113 //!
114 //! These feature flags enable **unstable** features. The public API may break in 0.1.x
115 //! releases. To enable these features, the `--cfg tracing_unstable` must be passed to
116 //! `rustc` when compiling.
117 //!
118 //! The following unstable feature flags are currently available:
119 //!
120 //! * `valuable`: Enables [`Visit::record_value`] implementations, for
121 //!   serializing values recorded using the [`valuable`] crate.
122 //!
123 //! #### Enabling Unstable Features
124 //!
125 //! The easiest way to set the `tracing_unstable` cfg is to use the `RUSTFLAGS`
126 //! env variable when running `cargo` commands:
127 //!
128 //! ```shell
129 //! RUSTFLAGS="--cfg tracing_unstable" cargo build
130 //! ```
131 //! Alternatively, the following can be added to the `.cargo/config` file in a
132 //! project to automatically enable the cfg flag for that project:
133 //!
134 //! ```toml
135 //! [build]
136 //! rustflags = ["--cfg", "tracing_unstable"]
137 //! ```
138 //!
139 //! [feature flags]: https://doc.rust-lang.org/cargo/reference/manifest.html#the-features-section
140 //! [`valuable`]: https://crates.io/crates/valuable
141 //!
142 //! ## Supported Rust Versions
143 //!
144 //! Tracing is built against the latest stable release. The minimum supported
145 //! version is 1.49. The current Tracing version is not guaranteed to build on
146 //! Rust versions earlier than the minimum supported version.
147 //!
148 //! Tracing follows the same compiler support policies as the rest of the Tokio
149 //! project. The current stable Rust compiler and the three most recent minor
150 //! versions before it will always be supported. For example, if the current
151 //! stable compiler version is 1.45, the minimum supported version will not be
152 //! increased past 1.42, three minor versions prior. Increasing the minimum
153 //! supported compiler version is not considered a semver breaking change as
154 //! long as doing so complies with this policy.
155 //!
156 //! [`tracing`]: https://crates.io/crates/tracing
157 //! [`serde`]: https://crates.io/crates/serde
158 #![doc(html_root_url = "https://docs.rs/tracing-serde/0.1.3")]
159 #![doc(
160     html_logo_url = "https://raw.githubusercontent.com/tokio-rs/tracing/master/assets/logo-type.png",
161     issue_tracker_base_url = "https://github.com/tokio-rs/tracing/issues/"
162 )]
163 #![cfg_attr(docsrs, feature(doc_cfg))]
164 #![cfg_attr(docsrs, deny(rustdoc::broken_intra_doc_links))]
165 #![warn(
166     missing_debug_implementations,
167     // missing_docs, // TODO: add documentation
168     rust_2018_idioms,
169     unreachable_pub,
170     bad_style,
171     const_err,
172     dead_code,
173     improper_ctypes,
174     non_shorthand_field_patterns,
175     no_mangle_generic_items,
176     overflowing_literals,
177     path_statements,
178     patterns_in_fns_without_body,
179     private_in_public,
180     unconditional_recursion,
181     unused,
182     unused_allocation,
183     unused_comparisons,
184     unused_parens,
185     while_true
186 )]
187 use std::fmt;
188 
189 use serde::{
190     ser::{SerializeMap, SerializeSeq, SerializeStruct, SerializeTupleStruct, Serializer},
191     Serialize,
192 };
193 
194 use tracing_core::{
195     event::Event,
196     field::{Field, FieldSet, Visit},
197     metadata::{Level, Metadata},
198     span::{Attributes, Id, Record},
199 };
200 
201 pub mod fields;
202 
203 #[derive(Debug)]
204 pub struct SerializeField(Field);
205 
206 impl Serialize for SerializeField {
serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> where S: Serializer,207     fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
208     where
209         S: Serializer,
210     {
211         serializer.serialize_str(self.0.name())
212     }
213 }
214 
215 #[derive(Debug)]
216 pub struct SerializeFieldSet<'a>(&'a FieldSet);
217 
218 impl<'a> Serialize for SerializeFieldSet<'a> {
serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> where S: Serializer,219     fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
220     where
221         S: Serializer,
222     {
223         let mut seq = serializer.serialize_seq(Some(self.0.len()))?;
224         for element in self.0 {
225             seq.serialize_element(element.name())?;
226         }
227         seq.end()
228     }
229 }
230 
231 #[derive(Debug)]
232 pub struct SerializeLevel<'a>(&'a Level);
233 
234 impl<'a> Serialize for SerializeLevel<'a> {
serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> where S: Serializer,235     fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
236     where
237         S: Serializer,
238     {
239         if self.0 == &Level::ERROR {
240             serializer.serialize_str("ERROR")
241         } else if self.0 == &Level::WARN {
242             serializer.serialize_str("WARN")
243         } else if self.0 == &Level::INFO {
244             serializer.serialize_str("INFO")
245         } else if self.0 == &Level::DEBUG {
246             serializer.serialize_str("DEBUG")
247         } else if self.0 == &Level::TRACE {
248             serializer.serialize_str("TRACE")
249         } else {
250             unreachable!()
251         }
252     }
253 }
254 
255 #[derive(Debug)]
256 pub struct SerializeId<'a>(&'a Id);
257 
258 impl<'a> Serialize for SerializeId<'a> {
serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> where S: Serializer,259     fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
260     where
261         S: Serializer,
262     {
263         let mut state = serializer.serialize_tuple_struct("Id", 1)?;
264         state.serialize_field(&self.0.into_u64())?;
265         state.end()
266     }
267 }
268 
269 #[derive(Debug)]
270 pub struct SerializeMetadata<'a>(&'a Metadata<'a>);
271 
272 impl<'a> Serialize for SerializeMetadata<'a> {
serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> where S: Serializer,273     fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
274     where
275         S: Serializer,
276     {
277         let mut state = serializer.serialize_struct("Metadata", 9)?;
278         state.serialize_field("name", self.0.name())?;
279         state.serialize_field("target", self.0.target())?;
280         state.serialize_field("level", &SerializeLevel(self.0.level()))?;
281         state.serialize_field("module_path", &self.0.module_path())?;
282         state.serialize_field("file", &self.0.file())?;
283         state.serialize_field("line", &self.0.line())?;
284         state.serialize_field("fields", &SerializeFieldSet(self.0.fields()))?;
285         state.serialize_field("is_span", &self.0.is_span())?;
286         state.serialize_field("is_event", &self.0.is_event())?;
287         state.end()
288     }
289 }
290 
291 /// Implements `serde::Serialize` to write `Event` data to a serializer.
292 #[derive(Debug)]
293 pub struct SerializeEvent<'a>(&'a Event<'a>);
294 
295 impl<'a> Serialize for SerializeEvent<'a> {
serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> where S: Serializer,296     fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
297     where
298         S: Serializer,
299     {
300         let mut serializer = serializer.serialize_struct("Event", 2)?;
301         serializer.serialize_field("metadata", &SerializeMetadata(self.0.metadata()))?;
302         let mut visitor = SerdeStructVisitor {
303             serializer,
304             state: Ok(()),
305         };
306         self.0.record(&mut visitor);
307         visitor.finish()
308     }
309 }
310 
311 /// Implements `serde::Serialize` to write `Attributes` data to a serializer.
312 #[derive(Debug)]
313 pub struct SerializeAttributes<'a>(&'a Attributes<'a>);
314 
315 impl<'a> Serialize for SerializeAttributes<'a> {
serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> where S: Serializer,316     fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
317     where
318         S: Serializer,
319     {
320         let mut serializer = serializer.serialize_struct("Attributes", 3)?;
321         serializer.serialize_field("metadata", &SerializeMetadata(self.0.metadata()))?;
322         serializer.serialize_field("parent", &self.0.parent().map(SerializeId))?;
323         serializer.serialize_field("is_root", &self.0.is_root())?;
324 
325         let mut visitor = SerdeStructVisitor {
326             serializer,
327             state: Ok(()),
328         };
329         self.0.record(&mut visitor);
330         visitor.finish()
331     }
332 }
333 
334 /// Implements `serde::Serialize` to write `Record` data to a serializer.
335 #[derive(Debug)]
336 pub struct SerializeRecord<'a>(&'a Record<'a>);
337 
338 impl<'a> Serialize for SerializeRecord<'a> {
serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> where S: Serializer,339     fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
340     where
341         S: Serializer,
342     {
343         let serializer = serializer.serialize_map(None)?;
344         let mut visitor = SerdeMapVisitor::new(serializer);
345         self.0.record(&mut visitor);
346         visitor.finish()
347     }
348 }
349 
350 /// Implements `tracing_core::field::Visit` for some `serde::ser::SerializeMap`.
351 #[derive(Debug)]
352 pub struct SerdeMapVisitor<S: SerializeMap> {
353     serializer: S,
354     state: Result<(), S::Error>,
355 }
356 
357 impl<S> SerdeMapVisitor<S>
358 where
359     S: SerializeMap,
360 {
361     /// Create a new map visitor.
new(serializer: S) -> Self362     pub fn new(serializer: S) -> Self {
363         Self {
364             serializer,
365             state: Ok(()),
366         }
367     }
368 
369     /// Completes serializing the visited object, returning `Ok(())` if all
370     /// fields were serialized correctly, or `Error(S::Error)` if a field could
371     /// not be serialized.
finish(self) -> Result<S::Ok, S::Error>372     pub fn finish(self) -> Result<S::Ok, S::Error> {
373         self.state?;
374         self.serializer.end()
375     }
376 
377     /// Completes serializing the visited object, returning ownership of the underlying serializer
378     /// if all fields were serialized correctly, or `Err(S::Error)` if a field could not be
379     /// serialized.
take_serializer(self) -> Result<S, S::Error>380     pub fn take_serializer(self) -> Result<S, S::Error> {
381         self.state?;
382         Ok(self.serializer)
383     }
384 }
385 
386 impl<S> Visit for SerdeMapVisitor<S>
387 where
388     S: SerializeMap,
389 {
390     #[cfg(all(tracing_unstable, feature = "valuable"))]
391     #[cfg_attr(docsrs, doc(cfg(all(tracing_unstable, feature = "valuable"))))]
record_value(&mut self, field: &Field, value: valuable_crate::Value<'_>)392     fn record_value(&mut self, field: &Field, value: valuable_crate::Value<'_>) {
393         if self.state.is_ok() {
394             self.state = self
395                 .serializer
396                 .serialize_entry(field.name(), &valuable_serde::Serializable::new(value));
397         }
398     }
399 
record_bool(&mut self, field: &Field, value: bool)400     fn record_bool(&mut self, field: &Field, value: bool) {
401         // If previous fields serialized successfully, continue serializing,
402         // otherwise, short-circuit and do nothing.
403         if self.state.is_ok() {
404             self.state = self.serializer.serialize_entry(field.name(), &value)
405         }
406     }
407 
record_debug(&mut self, field: &Field, value: &dyn fmt::Debug)408     fn record_debug(&mut self, field: &Field, value: &dyn fmt::Debug) {
409         if self.state.is_ok() {
410             self.state = self
411                 .serializer
412                 .serialize_entry(field.name(), &format_args!("{:?}", value))
413         }
414     }
415 
record_u64(&mut self, field: &Field, value: u64)416     fn record_u64(&mut self, field: &Field, value: u64) {
417         if self.state.is_ok() {
418             self.state = self.serializer.serialize_entry(field.name(), &value)
419         }
420     }
421 
record_i64(&mut self, field: &Field, value: i64)422     fn record_i64(&mut self, field: &Field, value: i64) {
423         if self.state.is_ok() {
424             self.state = self.serializer.serialize_entry(field.name(), &value)
425         }
426     }
427 
record_f64(&mut self, field: &Field, value: f64)428     fn record_f64(&mut self, field: &Field, value: f64) {
429         if self.state.is_ok() {
430             self.state = self.serializer.serialize_entry(field.name(), &value)
431         }
432     }
433 
record_str(&mut self, field: &Field, value: &str)434     fn record_str(&mut self, field: &Field, value: &str) {
435         if self.state.is_ok() {
436             self.state = self.serializer.serialize_entry(field.name(), &value)
437         }
438     }
439 }
440 
441 /// Implements `tracing_core::field::Visit` for some `serde::ser::SerializeStruct`.
442 #[derive(Debug)]
443 pub struct SerdeStructVisitor<S: SerializeStruct> {
444     serializer: S,
445     state: Result<(), S::Error>,
446 }
447 
448 impl<S> Visit for SerdeStructVisitor<S>
449 where
450     S: SerializeStruct,
451 {
452     #[cfg(all(tracing_unstable, feature = "valuable"))]
453     #[cfg_attr(docsrs, doc(cfg(all(tracing_unstable, feature = "valuable"))))]
record_value(&mut self, field: &Field, value: valuable_crate::Value<'_>)454     fn record_value(&mut self, field: &Field, value: valuable_crate::Value<'_>) {
455         if self.state.is_ok() {
456             self.state = self
457                 .serializer
458                 .serialize_field(field.name(), &valuable_serde::Serializable::new(value));
459         }
460     }
461 
record_bool(&mut self, field: &Field, value: bool)462     fn record_bool(&mut self, field: &Field, value: bool) {
463         // If previous fields serialized successfully, continue serializing,
464         // otherwise, short-circuit and do nothing.
465         if self.state.is_ok() {
466             self.state = self.serializer.serialize_field(field.name(), &value)
467         }
468     }
469 
record_debug(&mut self, field: &Field, value: &dyn fmt::Debug)470     fn record_debug(&mut self, field: &Field, value: &dyn fmt::Debug) {
471         if self.state.is_ok() {
472             self.state = self
473                 .serializer
474                 .serialize_field(field.name(), &format_args!("{:?}", value))
475         }
476     }
477 
record_u64(&mut self, field: &Field, value: u64)478     fn record_u64(&mut self, field: &Field, value: u64) {
479         if self.state.is_ok() {
480             self.state = self.serializer.serialize_field(field.name(), &value)
481         }
482     }
483 
record_i64(&mut self, field: &Field, value: i64)484     fn record_i64(&mut self, field: &Field, value: i64) {
485         if self.state.is_ok() {
486             self.state = self.serializer.serialize_field(field.name(), &value)
487         }
488     }
489 
record_f64(&mut self, field: &Field, value: f64)490     fn record_f64(&mut self, field: &Field, value: f64) {
491         if self.state.is_ok() {
492             self.state = self.serializer.serialize_field(field.name(), &value)
493         }
494     }
495 
record_str(&mut self, field: &Field, value: &str)496     fn record_str(&mut self, field: &Field, value: &str) {
497         if self.state.is_ok() {
498             self.state = self.serializer.serialize_field(field.name(), &value)
499         }
500     }
501 }
502 
503 impl<S: SerializeStruct> SerdeStructVisitor<S> {
504     /// Completes serializing the visited object, returning `Ok(())` if all
505     /// fields were serialized correctly, or `Error(S::Error)` if a field could
506     /// not be serialized.
finish(self) -> Result<S::Ok, S::Error>507     pub fn finish(self) -> Result<S::Ok, S::Error> {
508         self.state?;
509         self.serializer.end()
510     }
511 }
512 
513 pub trait AsSerde<'a>: self::sealed::Sealed {
514     type Serializable: serde::Serialize + 'a;
515 
516     /// `as_serde` borrows a `tracing` value and returns the serialized value.
as_serde(&'a self) -> Self::Serializable517     fn as_serde(&'a self) -> Self::Serializable;
518 }
519 
520 impl<'a> AsSerde<'a> for tracing_core::Metadata<'a> {
521     type Serializable = SerializeMetadata<'a>;
522 
as_serde(&'a self) -> Self::Serializable523     fn as_serde(&'a self) -> Self::Serializable {
524         SerializeMetadata(self)
525     }
526 }
527 
528 impl<'a> AsSerde<'a> for tracing_core::Event<'a> {
529     type Serializable = SerializeEvent<'a>;
530 
as_serde(&'a self) -> Self::Serializable531     fn as_serde(&'a self) -> Self::Serializable {
532         SerializeEvent(self)
533     }
534 }
535 
536 impl<'a> AsSerde<'a> for tracing_core::span::Attributes<'a> {
537     type Serializable = SerializeAttributes<'a>;
538 
as_serde(&'a self) -> Self::Serializable539     fn as_serde(&'a self) -> Self::Serializable {
540         SerializeAttributes(self)
541     }
542 }
543 
544 impl<'a> AsSerde<'a> for tracing_core::span::Id {
545     type Serializable = SerializeId<'a>;
546 
as_serde(&'a self) -> Self::Serializable547     fn as_serde(&'a self) -> Self::Serializable {
548         SerializeId(self)
549     }
550 }
551 
552 impl<'a> AsSerde<'a> for tracing_core::span::Record<'a> {
553     type Serializable = SerializeRecord<'a>;
554 
as_serde(&'a self) -> Self::Serializable555     fn as_serde(&'a self) -> Self::Serializable {
556         SerializeRecord(self)
557     }
558 }
559 
560 impl<'a> AsSerde<'a> for Level {
561     type Serializable = SerializeLevel<'a>;
562 
as_serde(&'a self) -> Self::Serializable563     fn as_serde(&'a self) -> Self::Serializable {
564         SerializeLevel(self)
565     }
566 }
567 
568 impl<'a> AsSerde<'a> for FieldSet {
569     type Serializable = SerializeFieldSet<'a>;
570 
as_serde(&'a self) -> Self::Serializable571     fn as_serde(&'a self) -> Self::Serializable {
572         SerializeFieldSet(self)
573     }
574 }
575 
576 impl<'a> self::sealed::Sealed for Event<'a> {}
577 
578 impl<'a> self::sealed::Sealed for Attributes<'a> {}
579 
580 impl self::sealed::Sealed for Id {}
581 
582 impl self::sealed::Sealed for Level {}
583 
584 impl<'a> self::sealed::Sealed for Record<'a> {}
585 
586 impl<'a> self::sealed::Sealed for Metadata<'a> {}
587 
588 impl self::sealed::Sealed for FieldSet {}
589 
590 mod sealed {
591     pub trait Sealed {}
592 }
593