tracing-forest

![github-img] ![crates-img] ![docs-img]

Preserve contextual coherence among trace data from concurrent tasks.

Overview

[tracing] is a framework for instrumenting programs to collect structured and async-aware diagnostics. The [tracing-subscriber] crate provides tools for working with [tracing]. This crate extends [tracing-subscriber] by providing types capable of preserving contextual coherence of trace data from concurrent tasks when logging.

This crate is intended for programs running many nontrivial and disjoint tasks concurrently, like server backends. Unlike other Subscribers which simply keep track of the context of an event, tracing-forest preserves the contextual coherence when writing logs, allowing readers to easily trace a sequence of events from the same task.

tracing-forest provides many tools for authoring applications, but can also be extended to author other libraries.

Getting started

The easiest way to get started is to enable all features. Do this by adding the following to your Cargo.toml file: toml tracing-forest = { version = "1", features = ["full"] } Then, add the #[tracing_forest::main] attribute to your main function: ```rust

[tracing_forest::main]

fn main() { // do stuff here... tracing::trace!("Hello, world!"); } ```

Contextual Coherence in action

This example contains two counters, one for evens and another for odds. Running it will emit trace data at the root level, implying that all the events are independent, meaning each trace will be processed and written as it's collected. In this case, the logs will count up chronologically. ``rust let evens = async { for i in 0..3 { tracing::info!("{}", i * 2); // pause forodds` sleep(Duration::from_millis(100)).await; } };

let odds = async { // pause for evens sleep(Duration::frommillis(50)).await; for i in 0..3 { tracing::info!("{}", i * 2 + 1); // pause for evens sleep(Duration::frommillis(100)).await; } };

let _ = tokio::join!(evens, odds); log INFO ๐Ÿ’ฌ [info]: 0 INFO ๐Ÿ’ฌ [info]: 1 INFO ๐Ÿ’ฌ [info]: 2 INFO ๐Ÿ’ฌ [info]: 3 INFO ๐Ÿ’ฌ [info]: 4 INFO ๐Ÿ’ฌ [info]: 5 Instrumenting the counters tells the `TreeLayer` in the current subscriber to preserve the contextual coherence of trace data from each task. Traces from the `even` counter will be grouped, and traces from the `odd` counter will be grouped. rust let evens = async { // ... }.instrument(tracing::tracespan!("countingevens"));

let odds = async { // ... }.instrument(tracing::tracespan!("countingodds"));

let _ = tokio::join!(evens, odds); log TRACE countingevens [ 409ยตs | 100.000% ] INFO โ”•โ” ๐Ÿ’ฌ [info]: 0 INFO โ”•โ” ๐Ÿ’ฌ [info]: 2 INFO โ”•โ” ๐Ÿ’ฌ [info]: 4 TRACE countingodds [ 320ยตs | 100.000% ] INFO โ”•โ” ๐Ÿ’ฌ [info]: 1 INFO โ”•โ” ๐Ÿ’ฌ [info]: 3 INFO โ”•โ” ๐Ÿ’ฌ [info]: 5 ``` Although the numbers were logged chronologically, they appear grouped in the spans they originated from.

License

tracing-forest is open-source software, distributed under the MIT license.