Consider the following code, I am writing the log into both standard output and a file. This is approached by Layer
, while I don't know how to filter based on level.
pub fn trace() -> tracing_appender::non_blocking::WorkerGuard {
let mut log_dir = std::env::current_exe().expect("failed to read cur exe");
log_dir.pop();
log_dir.push("server_log");
let file_appender = tracing_appender::rolling::daily(log_dir, "chat");
let (non_blocking, guard) = tracing_appender::non_blocking(file_appender);
let time_offset = offset!(+9);
let time_description = format_description!("[year]/[month]/[day]-[hour]:[minute]:[second]");
let timer = OffsetTime::new(time_offset, time_description);
let file_layer = fmt::layer()
.with_timer(timer.clone())
.with_line_number(true)
.with_thread_ids(true)
.with_span_events(FmtSpan::ACTIVE)
.with_file(true)
.with_writer(non_blocking)
.with_ansi(false)
.compact();
let std_layer = fmt::layer()
.with_timer(timer)
.with_line_number(true)
.with_thread_ids(true)
.with_file(true)
.with_span_events(FmtSpan::ACTIVE)
.compact();
tracing_subscriber::registry()
.with(file_layer)
.with(std_layer)
.init();
guard
}
How can I avoid Level Trace
appear in my log? that is, I want only Info
, Error
, etc. What if I want different filter level for each layer
The way to do it is by using a filter, either in a layer or for all in the registry.
Therefore, define your filter, like with env filter:
let the_env_filter = tracing_subscriber::EnvFilter::try_from_default_env().unwrap_or_else(|_| {
"your_app=debug,tower_http=debug,axum::rejection=trace".into()
});
Then, use it either:
per layer:
let std_layer = fmt::layer()
.with_timer(timer)
.with_line_number(true)
.with_thread_ids(true)
.with_file(true)
.with_span_events(FmtSpan::ACTIVE)
.compact()
.with_filter(the_env_filter);
or at registry (for all layers):
tracing_subscriber::registry()
.with(file_layer)
.with(std_layer)
.with(the_env_filter)
.init();
More info on the official docs:
I hope this helps!