Struct tracing_forest::runtime::Builder
source · pub struct Builder<Tx, Rx, T> { /* private fields */ }
Expand description
Return type of worker_task
and capture
.
Configuring a Runtime
Builder
follows the builder pattern to configure a Runtime
.
Configuration options include:
- Setting the tag.
- Installing globally.
- Configuring the internal sender with fallbacks.
- Configuring the processor in the worker task.
To finish the Runtime
, call the build
method to compose the configured
ForestLayer
onto a Registry
. Alternatively, the build_on
method
can be used construct arbitrary Subscriber
s from the configured ForestLayer
,
which is used in the returned Runtime
.
Implementations§
source§impl<Tx, P, T> Builder<Tx, WorkerTask<P>, T>where
P: Processor,
impl<Tx, P, T> Builder<Tx, WorkerTask<P>, T>where P: Processor,
sourcepub fn map_receiver<F, P2>(self, f: F) -> Builder<Tx, WorkerTask<P2>, T>where
F: FnOnce(P) -> P2,
P2: Processor,
pub fn map_receiver<F, P2>(self, f: F) -> Builder<Tx, WorkerTask<P2>, T>where F: FnOnce(P) -> P2, P2: Processor,
Configure the processor on the receiving end of the log channel. This is particularly useful for adding fallbacks.
This method accepts a closure that accepts the current Processor
on the
worker task, and maps it to another Processor
.
Note
This method is only available if called after worker_task
.
Examples
Configuring the writing task to write to a file, or else fall back to stderr.
use tracing_forest::traits::*;
use std::fs::File;
let out = File::create("out.log").unwrap();
tracing_forest::worker_task()
.map_receiver(|printer| printer
.writer(out)
.or_stderr()
)
.build()
.on(async {
// ...
})
.await;
source§impl<Tx, Rx, T> Builder<Tx, Rx, T>where
Tx: Processor + Sealed,
T: TagParser,
impl<Tx, Rx, T> Builder<Tx, Rx, T>where Tx: Processor + Sealed, T: TagParser,
sourcepub fn map_sender<F, Tx2>(self, f: F) -> Builder<Tx2, Rx, T>where
F: FnOnce(Tx) -> Tx2,
Tx2: Processor + Sealed,
pub fn map_sender<F, Tx2>(self, f: F) -> Builder<Tx2, Rx, T>where F: FnOnce(Tx) -> Tx2, Tx2: Processor + Sealed,
Configure the processer within the subscriber that sends log trees to a processing task. This allows for dangling tasks to still generate trace data, even after the worker task closes.
Examples
Allowing the subscriber to defer to stderr if the worker task finished.
use tracing_forest::traits::*;
tracing_forest::worker_task()
.map_sender(|sender| sender.or_stderr())
.build()
.on(async {
// The handle is immediately dropped, leaving the task dangling
tokio::spawn(async {
// Some unending task
});
// Wait until the user stops the application
tokio::signal::ctrl_c().await.expect("Failed to listen for CTRL-C");
})
.await;
// The worker task is completed and the channel is closed at this point.
// Any new trace data generated by the dangling task at this point
// is deferred to stderr because of the added fallback.
Since dropping the sender half would make the receiver task useless, this method uses traits to enforce at compile time that the function returns some derivation of the sender. Currently, the only accepted wrapping is through adding a fallback.
use tracing_forest::PrettyPrinter;
tracing_forest::worker_task()
.map_sender(|_sender| {
// Some variation of the sender isn't returned, so this won't compile.
PrettyPrinter::new()
})
.build()
.on(async {
// ...
})
.await;
sourcepub fn set_global(self, is_global: bool) -> Self
pub fn set_global(self, is_global: bool) -> Self
Set whether or not the subscriber should be set globally.
Setting the subscriber globally is intended for main
functions, since
it allows logs to be be collected across multithreaded environments. Not
setting globally is intended for test functions, which need to set a new
subscriber multiple times in the same program.
Examples
For multithreaded tests, set_global
can be used so that the subscriber
applies to all the threads. However, each function that sets a global
subscriber must be in its own compilation unit, like an integration test,
otherwise the global subscriber will carry over across tests.
#[tokio::test(flavor = "multi_thread")]
async fn test_multithreading() {
let logs = tracing_forest::capture()
.set_global(true)
.build()
.on(async {
// spawn some tasks
})
.await;
// inspect logs...
}
sourcepub fn build(self) -> Runtime<Layered<ForestLayer<Tx, T>, Registry>, Rx>
pub fn build(self) -> Runtime<Layered<ForestLayer<Tx, T>, Registry>, Rx>
Finishes the ForestLayer
by composing it into a Registry
, and
returns it as a Runtime
.
This method is useful for a basic configuration of a Subscriber
. For
a more advanced configuration, see the build_on
and build_with
methods.
Examples
#[tokio::main]
async fn main() {
tracing_forest::worker_task()
.build()
.on(async {
// ...
})
.await;
}
sourcepub fn build_on<F, S>(self, f: F) -> Runtime<S, Rx>where
F: FnOnce(Layered<ForestLayer<Tx, T>, Registry>) -> S,
S: Subscriber,
pub fn build_on<F, S>(self, f: F) -> Runtime<S, Rx>where F: FnOnce(Layered<ForestLayer<Tx, T>, Registry>) -> S, S: Subscriber,
Finishes the ForestLayer
by calling a function to build a Subscriber
,
and returns in as a Runtime
.
Unlike build_with
, this method composes the layer onto a Registry
prior to passing it into the function. This makes it more convenient for
the majority of use cases.
This method is useful for advanced configuration of Subscriber
s as
defined in tracing-subscriber
s documentation. For a basic configuration,
see the build
method.
Examples
Composing a Subscriber
with multiple layers:
use tracing_forest::{traits::*, util::*};
#[tokio::main]
async fn main() {
tracing_forest::worker_task()
.build_on(|subscriber| subscriber.with(LevelFilter::INFO))
.on(async {
// ...
})
.await;
}
sourcepub fn build_with<F, S>(self, f: F) -> Runtime<S, Rx>where
F: FnOnce(ForestLayer<Tx, T>) -> S,
S: Subscriber,
pub fn build_with<F, S>(self, f: F) -> Runtime<S, Rx>where F: FnOnce(ForestLayer<Tx, T>) -> S, S: Subscriber,
Finishes the ForestLayer
by calling a function to build a Subscriber
,
and returns it as a Runtime
.
Unlike build_on
, this method passes the ForestLayer
to the function
without presupposing a Registry
base. This makes it the most flexible
option for construction.
This method is useful for advanced configuration of Subscriber
s as
defined in tracing-subscriber
s documentation. For a basic configuration,
see the build
method.
Examples
Composing a Subscriber
with multiple layers:
use tracing_subscriber::Registry;
use tracing_forest::{traits::*, util::*};
#[tokio::main]
async fn main() {
tracing_forest::worker_task()
.build_with(|layer: ForestLayer<_, _>| {
Registry::default()
.with(layer)
.with(LevelFilter::INFO)
})
.on(async {
// ...
})
.await;
}