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
pub
pub use SproutError;
pub type Result<T> = Result;
pub use TrunkLayer;