Replies: 2 comments
-
The problem is that the two One option would be to have two different Example
use std::str::FromStr;
use tracing::Subscriber;
use tracing_subscriber::{
fmt::{
self,
format::{DefaultFields, Format, Full},
FormatEvent, FormatFields,
},
layer::SubscriberExt,
registry::LookupSpan,
reload,
util::SubscriberInitExt,
EnvFilter, Layer, Registry,
};
struct MyFormat;
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 {
writer.write_str("This is dimmed or something...")
}
}
enum Either<L, R> {
Left(L),
Right(R),
}
impl<L: Layer<S> + 'static, R: Layer<S> + 'static, S: Subscriber> Layer<S> for Either<L, R> {
fn on_event(&self, event: &tracing::Event<'_>, ctx: tracing_subscriber::layer::Context<'_, S>) {
match self {
Either::Left(left) => left.on_event(event, ctx),
Either::Right(right) => right.on_event(event, ctx),
}
}
}
type EitherFormat = Either<
fmt::Layer<Registry, DefaultFields, Format<Full>>,
fmt::Layer<Registry, DefaultFields, MyFormat>,
>;
fn main() {
let make_fmt_layer = || tracing_subscriber::fmt::Layer::default().with_ansi(true);
let filter = EnvFilter::from_str("info").unwrap();
let default_layer = EitherFormat::Left(make_fmt_layer()).with_filter(filter);
let (default_layer, reload_handle) = reload::Layer::new(default_layer);
tracing_subscriber::registry()
.with(default_layer)
.init();
tracing::info!("NORMAL");
reload_handle
.modify(|layer| {
*layer.inner_mut() = Either::Right(make_fmt_layer().event_format(MyFormat {}));
})
.unwrap();
tracing::info!("DIM");
} In an ideal world, you could just change the format, but there currently isn't a way to mutably borrow it to update it, but that seems like something that we might want to add. See the example but know it doesn't currently work because the method Details
use std::str::FromStr;
use tracing::Subscriber;
use tracing_subscriber::{
fmt::{
self,
format::{Format, Full},
FormatEvent, FormatFields,
},
layer::SubscriberExt,
registry::LookupSpan,
reload,
util::SubscriberInitExt,
EnvFilter, Layer,
};
struct MyFormat;
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 {
writer.write_str("This is dimmed or something...")
}
}
enum Either<L, R> {
Left(L),
Right(R),
}
type EitherFormat = Either<Format<Full>, MyFormat>;
impl<S, N, L: FormatEvent<S, N>, R: FormatEvent<S, N>> FormatEvent<S, N> for Either<L, R>
where
S: Subscriber + for<'a> LookupSpan<'a>,
N: for<'a> FormatFields<'a> + 'static,
{
fn format_event(
&self,
ctx: &fmt::FmtContext<'_, S, N>,
writer: fmt::format::Writer<'_>,
event: &tracing::Event<'_>,
) -> std::fmt::Result {
match self {
Either::Left(left) => left.format_event(ctx, writer, event),
Either::Right(right) => right.format_event(ctx, writer, event),
}
}
}
fn main() {
let filter = EnvFilter::from_str("info").unwrap();
let default_layer = tracing_subscriber::fmt::Layer::default()
.with_ansi(true)
.event_format(EitherFormat::Left(Format::default()))
.with_filter(filter);
let (default_layer, reload_handle) = reload::Layer::new(default_layer);
tracing_subscriber::registry().with(default_layer).init();
tracing::info!("NORMAL");
reload_handle
.modify(|layer| {
*layer.inner_mut().event_format_mut() = EitherFormat::Right(MyFormat);
})
.unwrap();
tracing::info!("DIM");
} |
Beta Was this translation helpful? Give feedback.
-
Hi @mladedav thanks for your answer. In the meantime I've solved it in a similar way: pub struct DynamicFormatter {
dim_format: DimFormat,
default_format: tracing_subscriber::fmt::format::Format,
dim: Arc<AtomicBool>,
}
impl<S, N> FormatEvent<S, N> for DynamicFormatter
where
S: Subscriber + for<'a> LookupSpan<'a>,
N: for<'a> FormatFields<'a> + 'static,
{
fn format_event(
&self,
ctx: &FmtContext<'_, S, N>,
writer: Writer<'_>,
event: &Event<'_>,
) -> std::fmt::Result {
if self.dim.load(Ordering::Relaxed) {
self.dim_format.format_event(ctx, writer, event)
} else {
self.default_format.format_event(ctx, writer, event)
}
}
}
impl DynamicFormatter {
pub fn new(dim: Arc<AtomicBool>) -> Self {
let dim_format = DimFormat::new();
let default_format = tracing_subscriber::fmt::format::Format::default();
Self {
dim_format,
default_format,
dim,
}
}
} With my own This does incur the overhead of checking the |
Beta Was this translation helpful? Give feedback.
-
Hi,
I've got the requirement to change the logging to dimmed if a certain condition arises. I've implemented a
FormatEvent
, and it works if I just register this withevent_format(MyFormat{})
.I'm trying with
reload::modify
, but having trouble with this. I'm trying:I'm getting the following error:
It seems like I'm close, but no cigar.
I find examples on how to replace the filter, but not for the
FormatEvent
.Can anyone help?
Beta Was this translation helpful? Give feedback.
All reactions