1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
//! # Tracing Sprout
//!
//! A tokio-rs/tracing structured JSON formatting layer for the fledgling logger
//!
//! This subscriber layer is derived from [Tracing Bunyan Formatter](https://github.com/LukeMathWalker/tracing-bunyan-formatter),
//! with a few tweaks to internals and some of the formatting (and rules surrounding it).
//!
//! ## Features
//! - All traces will receive their parent's attributes as well as their own, child attributes will
//! take precedence if there are collisions
//! - There is a very minimal timing capability that adds elapsed time to `EVENT` and `EXIT` traces
//! - `TRACE`, `DEBUG` and `ERROR` logs get slighly more metadata (file name, line number, module path & target) attached
//! to them
//! - Avoids panics - as much as possible it opts to handle failure by `eprintln`ing to `stdout`.
//! These scenarios should be few and far between, but it's better that a failure in your tracing
//! implementation doesn't poison your main application.
//!
//! ## Example
//!
//! ```no_run
//! use tracing::{subscriber::set_global_default, Subscriber};
//! use tracing_sprout::TrunkLayer;
//! use tracing_subscriber::prelude::*;
//! use tracing_subscriber::{EnvFilter, Registry};
//!
//! let env_filter = EnvFilter::try_from_default_env().unwrap_or_else(|_| EnvFilter::new("info"));
//! let formatting_layer = TrunkLayer::new("My Application".to_string(), std::io::stdout);
//! let subscriber = Registry::default()
//!      .with(env_filter)
//!      .with(formatting_layer);
//!
//! set_global_default(subscriber).expect("failed to set up global tracing subscriber")
//! ```
//!
//! ## Developing on an application using this
//!
//! Generally structured JSON logs are great for machines to read, but not so kind for humans. If
//! you're developing an application that uses this layer it would be advisable to download some
//! kind of CLI tool that outputs these logs in a slightly nicer format, a good example would be
//! the node.js's [pino-pretty](https://github.com/pinojs/pino-pretty), from there you can just pipe
//! your logs into it for a nicer development experience
//!
//! ```sh
//! cargo run | pino-pretty
//! ```
//!
//! ## Log output and a more detailed example
//!
//! See the [examples](https://github.com/naamancurtis/tracing-sprout/tree/main/examples) for a basic demonstration of how this can be used. The **basic.rs** example in there would output logs like the following:
//!
//! ```txt
//! {"app_name":"I'm Groot","pid":2735,"id":"1","time":"Sat, 13 Feb 2021 14:16:15 +0000","timestamp":1613225775,"msg":"[EPIC MONTAGE | START]","level":"info","span.type":"enter"}
//! {"app_name":"I'm Groot","pid":2735,"id":"1","group":"[\"Peter Quill\", \"Gamora\", \"Drax\", \"Rocket\"]","time":"Sat, 13 Feb 2021 14:16:15 +0000","timestamp":1613225775,"msg":"[EVENT] Trying to plug in the power","level":"trace","file":"examples/basic.rs","line":32,"module":"basic","target":"basic","thread_id":"ThreadId(1)","thread_name":"main","span.type":"event"}
//! {"app_name":"I'm Groot","pid":2735,"id":"2","info":"I'm overwriting my parents ID","time":"Sat, 13 Feb 2021 14:16:15 +0000","timestamp":1613225775,"msg":"[MUSIC IS PLAYING | START]","level":"debug","file":"examples/basic.rs","line":34,"module":"basic","target":"basic","thread_id":"ThreadId(1)","thread_name":"main","span.type":"enter"}
//! ...
//! ```
//!
//! However _(excuse the verbosity here)_, by piping it through a tool like the one mentioned above
//! _(pino-pretty)_ you get the following output
//!
//! ```txt
//! [Sat, 13 Feb 2021 14:14:54 +0000] INFO (1331): [EPIC MONTAGE | START]
//!     app_name: "I'm Groot"
//!     id: "1"
//!     span.type: "enter"
//! [Sat, 13 Feb 2021 14:14:54 +0000] TRACE (1331): [EVENT] Trying to plug in the power
//!     app_name: "I'm Groot"
//!     id: "1"
//!     group: "[\"Peter Quill\", \"Gamora\", \"Drax\", \"Rocket\"]"
//!     file: "examples/basic.rs"
//!     line: 32
//!     module: "basic"
//!     target: "basic"
//!     thread_id: "ThreadId(1)"
//!     thread_name: "main"
//!     span.type: "event"
//! [Sat, 13 Feb 2021 14:14:54 +0000] DEBUG (1331): [MUSIC IS PLAYING | START]
//!     app_name: "I'm Groot"
//!     id: "2"
//!     info: "I'm overwriting my parents ID"
//!     file: "examples/basic.rs"
//!     line: 34
//!     module: "basic"
//!     target: "basic"
//!     thread_id: "ThreadId(1)"
//!     thread_name: "main"
//!     span.type: "enter"
//!     ...
//! ```

pub(crate) mod constants;
mod error;
mod formatting;
mod storage;
pub(crate) mod util;

pub(crate) use error::SproutError;
pub(crate) type Result<T> = std::result::Result<T, SproutError>;

pub use formatting::TrunkLayer;