tracing-bunyan-formatter
provides two [Layer
]s implementation to be used on top of
a [tracing
] [Subscriber
]:
JsonStorageLayer
], to attach contextual information to spans for ease of consumption by
downstream [Layer
]s, via [JsonStorage
] and [Span
]'s extensions
;BunyanFormattingLayer
]`, which emits a bunyan-compatible formatted record upon entering a span,
existing a span and event creation.Important: each span will inherit all fields and properties attached to its parent - this is
currently not the behaviour provided by tracing_subscriber::fmt::Layer
.
```rust use tracingbunyanformatter::{BunyanFormattingLayer, JsonStorageLayer, Config}; use tracing::instrument; use tracing::info; use tracingsubscriber::Registry; use tracingsubscriber::layer::SubscriberExt;
pub fn aunitofwork(firstparameter: u64) { for i in 0..2 { asubunitofwork(i); } info!(excited = "true", "Tracing is quite cool!"); }
pub fn asubunitofwork(sub_parameter: u64) { info!("Events have the full context of their parent span!"); }
fn main() { // UTC offset let config = Config { offset: 1 }; let formattinglayer = BunyanFormattingLayer::new("tracingdemo".into(), std::io::stdout, Some(config)); let subscriber = Registry::default() .with(JsonStorageLayer) .with(formattinglayer); tracing::subscriber::setglobal_default(subscriber).unwrap();
info!("Orphan event without a parent span");
a_unit_of_work(2);
} ```
If you pipe the output in the bunyan
CLI:
The layered approach we have pursued is not necessarily the most efficient,
but it makes it easier to separate different concerns and re-use common logic across multiple [Layer
]s.
While the current crate has no ambition to provide any sort of general purpose framework on top of
[tracing-subscriber
]'s [Layer
] trait, the information collected by [JsonStorageLayer
] can be leveraged via
its public API by other downstream layers outside of this crate whose main concern is formatting.
It significantly lowers the amount of complexity you have to deal with if you are interested
in implementing your own formatter, for whatever reason or purpose.
You can also add another enrichment layer following the [JsonStorageLayer
] to collect
additional information about each span and store it in [JsonStorage
].
We could have pursued this compositional approach to add elapsed_milliseconds
to each span
instead of baking it in [JsonStorage
] itself.
You can enable the arbitrary_precision
feature to handle numbers of arbitrary size losslessly. Be aware of a known issue with untagged deserialization.
Currently the tests only support being run sequentially, so the number of threads needs to be restricted:
cargo test -- --test-threads 1