I'm writing tests for a Rust program that uses the tracing
crate for logging, and the test-log
crate to enable logging in the tests.
I have an arrange step that does quite a lot of things, which I want to log at the "info" level.
I want logging for the act step to be at "debug" level, so I can get useful logs in the test output, but only for the act step.
How can this be achieved?
Some things I tried:
// This works, but sets the level globally
#[tokio::test]
async fn test_dynamic_logging1() {
use tracing_subscriber::{ filter, fmt, reload, prelude::* };
let filter = filter::LevelFilter::INFO;
let (filter, reload_handle) = reload::Layer::new(filter);
tracing_subscriber::registry().with(filter).with(fmt::Layer::default()).init();
info!("This will be logged");
debug!("This will be ignored");
reload_handle
.modify(|filter| {
*filter = filter::LevelFilter::DEBUG;
})
.unwrap();
debug!("This will be logged");
}
// This doesn't work
#[tokio::test]
async fn test_dynamic_logging2() {
use tracing_subscriber::{ filter, fmt, reload, prelude::* };
let filter = filter::LevelFilter::INFO;
let (filter, reload_handle) = reload::Layer::new(filter);
tracing_subscriber::registry().with(filter).with(fmt::Layer::default()).init();
info!("This will be logged");
debug!("This will be ignored");
let debug_subscriber = fmt::Subscriber
::builder()
.with_max_level(tracing::Level::DEBUG)
.with_test_writer()
.finish();
tracing::subscriber::with_default(debug_subscriber, || {
debug!("This should be logged, but isn't");
});
info!("This will be logged");
debug!("This will be ignored");
}
A few minutes after posting this, I got it to work for test-log
as well:
#[test_log::test(tokio::test)]
async fn test_dynamic_logging3() {
debug!("This will be ignored");
let debug_subscriber = tracing_subscriber::fmt::Subscriber
::builder()
.with_max_level(tracing::Level::DEBUG)
.with_test_writer()
.finish();
tracing::subscriber::with_default(debug_subscriber, || {
debug!("This will be logged");
});
debug!("This will be ignored");
}
But in the real test, the code is async, and when I change it to this, the line isn't logged anymore:
tracing::subscriber::with_default(debug_subscriber, || async {
debug!("This will be logged");
}).await;