Skip to content

Commit b8b55a6

Browse files
JeanMertzandrewzhurov
authored andcommitted
feat(log): support customizing default log formatting (bevyengine#17722)
The LogPlugin now allows overriding the default `tracing_subscriber::fmt::Layer` through a new `fmt_layer` option. This enables customization of the default log output format without having to replace the entire logging system. For example, to disable timestamps in the log output: ```rust fn fmt_layer(_app: &mut App) -> Option<bevy::log::BoxedFmtLayer> { Some(Box::new( bevy::log::tracing_subscriber::fmt::Layer::default() .without_time() .with_writer(std::io::stderr), )) } fn main() { App::new() .add_plugins(DefaultPlugins.set(bevy::log::LogPlugin { fmt_layer, ..default() })) .run(); } ``` This is different from the existing `custom_layer` option, because that option _adds_ additional layers to the subscriber, but can't modify the default formatter layer (at least, not to my knowledge). I almost always disable timestamps in my Bevy logs, and usually also tweak other default log formatting (such as `with_span_events`), which made it so that I always had to disable the default logger. This allows me to use everything the Bevy logger supports (including tracy support), while still formatting the default logs the way I like them. --------- Signed-off-by: Jean Mertz <[email protected]>
1 parent 638de64 commit b8b55a6

File tree

3 files changed

+53
-6
lines changed

3 files changed

+53
-6
lines changed

crates/bevy_log/src/lib.rs

Lines changed: 37 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ use bevy_app::{App, Plugin};
5656
use tracing_log::LogTracer;
5757
use tracing_subscriber::{
5858
filter::{FromEnvError, ParseError},
59+
layer::Layered,
5960
prelude::*,
6061
registry::Registry,
6162
EnvFilter, Layer,
@@ -97,6 +98,7 @@ pub(crate) struct FlushGuard(SyncCell<tracing_chrome::FlushGuard>);
9798
/// level: Level::DEBUG,
9899
/// filter: "wgpu=error,bevy_render=info,bevy_ecs=trace".to_string(),
99100
/// custom_layer: |_| None,
101+
/// fmt_layer: |_| None,
100102
/// }))
101103
/// .run();
102104
/// }
@@ -240,11 +242,38 @@ pub struct LogPlugin {
240242
///
241243
/// Please see the `examples/log_layers.rs` for a complete example.
242244
pub custom_layer: fn(app: &mut App) -> Option<BoxedLayer>,
245+
246+
/// Override the default [`tracing_subscriber::fmt::Layer`] with a custom one.
247+
///
248+
/// This differs from [`custom_layer`](Self::custom_layer) in that
249+
/// [`fmt_layer`](Self::fmt_layer) allows you to overwrite the default formatter layer, while
250+
/// `custom_layer` only allows you to add additional layers (which are unable to modify the
251+
/// default formatter).
252+
///
253+
/// For example, you can use [`tracing_subscriber::fmt::Layer::without_time`] to remove the
254+
/// timestamp from the log output.
255+
///
256+
/// Please see the `examples/log_layers.rs` for a complete example.
257+
pub fmt_layer: fn(app: &mut App) -> Option<BoxedFmtLayer>,
243258
}
244259

245-
/// A boxed [`Layer`] that can be used with [`LogPlugin`].
260+
/// A boxed [`Layer`] that can be used with [`LogPlugin::custom_layer`].
246261
pub type BoxedLayer = Box<dyn Layer<Registry> + Send + Sync + 'static>;
247262

263+
#[cfg(feature = "trace")]
264+
type BaseSubscriber =
265+
Layered<EnvFilter, Layered<Option<Box<dyn Layer<Registry> + Send + Sync>>, Registry>>;
266+
267+
#[cfg(feature = "trace")]
268+
type PreFmtSubscriber = Layered<tracing_error::ErrorLayer<BaseSubscriber>, BaseSubscriber>;
269+
270+
#[cfg(not(feature = "trace"))]
271+
type PreFmtSubscriber =
272+
Layered<EnvFilter, Layered<Option<Box<dyn Layer<Registry> + Send + Sync>>, Registry>>;
273+
274+
/// A boxed [`Layer`] that can be used with [`LogPlugin::fmt_layer`].
275+
pub type BoxedFmtLayer = Box<dyn Layer<PreFmtSubscriber> + Send + Sync + 'static>;
276+
248277
/// The default [`LogPlugin`] [`EnvFilter`].
249278
pub const DEFAULT_FILTER: &str = "wgpu=error,naga=warn";
250279

@@ -254,6 +283,7 @@ impl Default for LogPlugin {
254283
filter: DEFAULT_FILTER.to_string(),
255284
level: Level::INFO,
256285
custom_layer: |_| None,
286+
fmt_layer: |_| None,
257287
}
258288
}
259289
}
@@ -328,10 +358,12 @@ impl Plugin for LogPlugin {
328358
#[cfg(feature = "tracing-tracy")]
329359
let tracy_layer = tracing_tracy::TracyLayer::default();
330360

331-
// note: the implementation of `Default` reads from the env var NO_COLOR
332-
// to decide whether to use ANSI color codes, which is common convention
333-
// https://no-color.org/
334-
let fmt_layer = tracing_subscriber::fmt::Layer::default().with_writer(std::io::stderr);
361+
let fmt_layer = (self.fmt_layer)(app).unwrap_or_else(|| {
362+
// note: the implementation of `Default` reads from the env var NO_COLOR
363+
// to decide whether to use ANSI color codes, which is common convention
364+
// https://no-color.org/
365+
Box::new(tracing_subscriber::fmt::Layer::default().with_writer(std::io::stderr))
366+
});
335367

336368
// bevy_render::renderer logs a `tracy.frame_mark` event every frame
337369
// at Level::INFO. Formatted logs should omit it.

examples/app/log_layers.rs

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ use bevy::{
44
log::{
55
tracing::{self, Subscriber},
66
tracing_subscriber::Layer,
7-
BoxedLayer,
7+
BoxedFmtLayer, BoxedLayer,
88
},
99
prelude::*,
1010
};
@@ -36,10 +36,24 @@ fn custom_layer(_app: &mut App) -> Option<BoxedLayer> {
3636
]))
3737
}
3838

39+
// While `custom_layer` allows you to add _additional_ layers, it won't allow you to override the
40+
// default `tracing_subscriber::fmt::Layer` added by `LogPlugin`. To do that, you can use the
41+
// `fmt_layer` option.
42+
//
43+
// In this example, we're disabling the timestamp in the log output.
44+
fn fmt_layer(_app: &mut App) -> Option<BoxedFmtLayer> {
45+
Some(Box::new(
46+
bevy::log::tracing_subscriber::fmt::Layer::default()
47+
.without_time()
48+
.with_writer(std::io::stderr),
49+
))
50+
}
51+
3952
fn main() {
4053
App::new()
4154
.add_plugins(DefaultPlugins.set(bevy::log::LogPlugin {
4255
custom_layer,
56+
fmt_layer,
4357

4458
..default()
4559
}))

examples/app/log_layers_ecs.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ fn main() {
3030
level: Level::TRACE,
3131
filter: "warn,log_layers_ecs=trace".to_string(),
3232
custom_layer,
33+
..default()
3334
}))
3435
.add_systems(Startup, (log_system, setup))
3536
.add_systems(Update, print_logs)

0 commit comments

Comments
 (0)