Module tracing_forest::runtime
source · Expand description
Run asynchronous code in the context of a tracing-forest
subscriber.
This module provides useful abstractions for executing async code:
worker_task
for main
functions, and capture
for unit tests,
both of which return a configurable Builder
object.
Nonblocking log processing with worker_task
tracing-forest
collects trace data into trees, and can sometimes
produce large trees that need to be processed. To avoid blocking the main
task in these cases, a common strategy is to send this data to a worker
task for formatting and writing.
The worker_task
function provides this behavior as a first-class feature of this
crate, and handles the configuration, initialization, and graceful shutdown
of a subscriber with an associated worker task for formatting and writing.
Unlike tracing-appender
which uses a writer thread for formatted logs,
this module allows for log trees to be sent to a worker task before formatting,
allowing more log-related work to be offloaded to the worker task.
Examples
use tracing::{info, info_span};
#[tokio::main]
async fn main() {
tracing_forest::worker_task()
.build()
.on(async {
info!("Hello, world!");
info_span!("my_span").in_scope(|| {
info!("Relevant information");
})
})
.await;
}
Produces the output:
INFO i [info]: Hello, world!
INFO my_span [ 26.0µs | 100.000% ]
INFO ┕━ i [info]: Relevant information
For full configuration options, see the Builder
documentation.
Inspecting trace data in unit tests with capture
The capture
function offers the ability to programmatically inspect log
trees generated by tracing-forest
. It is the unit testing analog of
worker_task
, except it returns Vec<Tree>
after the future is completed,
which can be then be inspected.
Examples
use tracing_forest::tree::{Tree, Event, Span};
use tracing::{info, info_span};
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let logs: Vec<Tree> = tracing_forest::capture()
.build()
.on(async {
info!("Hello, world!");
info_span!("my_span").in_scope(|| {
info!("Relevant information");
})
})
.await;
// There is one event and one span at the root level
assert!(logs.len() == 2);
// Inspect the first event
let hello_world: &Event = logs[0].event()?;
assert!(hello_world.message() == Some("Hello, world!"));
// Inspect the span
let my_span: &Span = logs[1].span()?;
assert!(my_span.name() == "my_span");
// Only the `info` event is recorded
assert!(my_span.nodes().len() == 1);
let relevant_info: &Event = my_span.nodes()[0].event()?;
assert!(relevant_info.message() == Some("Relevant information"));
Ok(())
}
Additional options for tree inspection can be found in the
tree
module-level documentation
For full configuration options, see the Builder
documentation.
Structs
- Return type of
worker_task
andcapture
. - A marker type indicating that trace data should be captured for later use.
- The
Processor
used within atracing-forest
subscriber for sending logs to a processing task. - Execute a
Future
in the context of a subscriber with aForestLayer
. - A marker type indicating that trace data should be processed.
Functions
- Begins the configuration of a
ForestLayer
subscriber that sends log trees to a buffer that can later be inspected programatically. - Begins the configuration of a
ForestLayer
subscriber that sends log trees to a processing task for formatting and writing.