How to test tracing setup?

I want to test that my tracing setup works.

I have a simple default subscriber which writes the trace data to stdout. Now the module to setup tracing is simple, but it will get more complicated in the future and I like to use unit tests right away.

Here is how it looks so far:

use anyhow::Result;
use tracing::subscriber::set_global_default;
use tracing_subscriber::FmtSubscriber;

pub fn setup_tracing() -> Result<()> {
	let subscriber = FmtSubscriber::new();
	set_global_default(subscriber)?;
	Ok(())
}

#[cfg(test)]
mod tests {
	use super::*;
	use tracing::info;
	use tracing_test::traced_test;

	#[test]
	#[traced_test]
	fn default_subscriber_prints_to_stdout_when_receiving_tracing_data() {
		setup_tracing().unwrap();
		info!("something happened");
		assert!(logs_contain("something happened"));
	}
}

Unfortunately I get the error message: a global default trace dispatcher has already been set.

Does anybody experiences the same?

I tried to also use gag and run the test with --nocapture but this did also not work.

tracing_test::traced_test creates and registers a global subscriber, so you don't need to call setup_tracing in your test (if you do, you get the panic you see due to a global subscriber already being registered). Alternatively to tracing-test, you could have a look at the tracing-fluent-assertions crate, which takes a different approach towards testing your tracing setup, which does not involve the crate registering a default subscriber under the hood.

It seems that the lib I'm using to check for the logs (tracing_test) is causing the error. I opened an issue in the corresponding repository. I may get rid of the lib and check for the logs myself

thank you! I also just figured that! :smiley: any idea how to get around that?

I guess I have to change stdout to something I have better access to, so I can do the test assertions

tracing-fluent-assertions looks promising. thank you!

1 Like

I looked at tracing-fluent-assertions closer but it turned out that this package solves different problems.

what I'm looking for is a way to test that my subscriber actually prints to stdout. the lib you mention focuses on question around spans mainly, and does not use check on stdout at all it seems.

Neither does tracing-test:

The macro provided in this crate registers a global default subscriber instead. This subscriber contains a writer which logs into a global static in-memory buffer.

It creates a MockWriter around a global buffer which is used by the subscriber they register when you use the #[traced_test] macro.

If you must use your own subscriber rather than the one tracing_test creates, maybe raising an issue with the project might be a good idea? I feel like the basic building blocks are already there, the interface just needs to be extended a bit.

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.