Skip to content

Instantly share code, notes, and snippets.

@enomado
Created March 14, 2025 11:44
Show Gist options
  • Save enomado/75bee71c53a971345606c9b4203ae9bc to your computer and use it in GitHub Desktop.
Save enomado/75bee71c53a971345606c9b4203ae9bc to your computer and use it in GitHub Desktop.
use std::{
env,
fmt::{Debug, Pointer, Write},
io,
};
use tracing::{Instrument, Level, Subscriber, instrument::WithSubscriber, level_filters::LevelFilter, span};
use tracing_appender::non_blocking::WorkerGuard;
use tracing_subscriber::{
EnvFilter,
Layer,
filter::{self, FilterExt},
fmt::{FormatEvent, FormatFields},
layer::SubscriberExt,
registry::LookupSpan,
util::SubscriberInitExt,
};
use tracing_subscriber::{self, fmt};
pub struct LogGuards {
pub stdout: WorkerGuard,
}
// just a way to distinguish loggers from each other
pub struct MyFormat {
pub logger_name: String,
}
impl<S, N> FormatEvent<S, N> for MyFormat
where
S: Subscriber + for<'a> LookupSpan<'a>,
N: for<'a> FormatFields<'a> + 'static,
{
fn format_event(
&self,
ctx: &tracing_subscriber::fmt::FmtContext<'_, S, N>,
mut writer: tracing_subscriber::fmt::format::Writer<'_>,
event: &tracing::Event<'_>,
) -> std::fmt::Result {
write!(writer, "{} ", &self.logger_name)?;
ctx.format_fields(writer.by_ref(), event)?;
write!(writer, "\n")?;
Ok(())
}
}
pub fn setup_logger() -> LogGuards {
let (stdout_non_blocking, guard_stdout) = tracing_appender::non_blocking(std::io::stdout());
let format = MyFormat {
logger_name: "gtd ".to_owned(),
};
let layer_gtd = fmt::Layer::default()
.event_format(format)
.with_writer(stdout_non_blocking.clone());
let format = MyFormat {
logger_name: "other".to_owned(),
};
let layer_all_except_gtd = fmt::Layer::default()
.event_format(format)
.with_writer(stdout_non_blocking);
// gtd here
let gtd_filter = EnvFilter::builder().parse_lossy("[gtd]");
let gtd = layer_gtd.with_filter(gtd_filter);
// all except gtd here <- not works :(
let gtd_filter = EnvFilter::builder().parse_lossy("[gtd]");
let not_gtd = layer_all_except_gtd.with_filter(gtd_filter.not());
tracing_subscriber::registry().with(gtd).with(not_gtd).init();
LogGuards { stdout: guard_stdout }
}
// current output:
// gtd gtd
// other gtd
// other other
// output I except
// gtd gtd
// other other
// should I use so called global filtering?
#[test]
fn run() {
let t = setup_logger();
{
let p = span!(Level::TRACE, "gtd");
let s = p.enter();
tracing::error!("gtd");
}
tracing::error!("other");
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment