pub struct LogPlugin {
pub filter: String,
pub level: Level,
pub custom_layer: fn(_: &mut App) -> Option<Box<dyn Layer<Registry> + Send + Sync>>,
}
Expand description
Adds logging to Apps. This plugin is part of the DefaultPlugins
. Adding
this plugin will setup a collector appropriate to your target platform:
- Using
tracing-subscriber
by default, logging tostdout
. - Using
android_log-sys
on Android, logging to Android logs. - Using
tracing-wasm
in Wasm, logging to the browser console.
You can configure this plugin.
fn main() {
App::new()
.add_plugins(DefaultPlugins.set(LogPlugin {
level: Level::DEBUG,
filter: "wgpu=error,bevy_render=info,bevy_ecs=trace".to_string(),
custom_layer: |_| None,
}))
.run();
}
Log level can also be changed using the RUST_LOG
environment variable.
For example, using RUST_LOG=wgpu=error,bevy_render=info,bevy_ecs=trace cargo run ..
It has the same syntax as the field LogPlugin::filter
, see EnvFilter
.
If you define the RUST_LOG
environment variable, the LogPlugin
settings
will be ignored.
Also, to disable color terminal output (ANSI escape codes), you can
set the environment variable NO_COLOR
to any value. This common
convention is documented at no-color.org.
For example:
fn main() {
std::env::set_var("NO_COLOR", "1");
App::new()
.add_plugins(DefaultPlugins)
.run();
}
If you want to setup your own tracing collector, you should disable this
plugin from DefaultPlugins
:
fn main() {
App::new()
.add_plugins(DefaultPlugins.build().disable::<LogPlugin>())
.run();
}
§Example Setup
For a quick setup that enables all first-party logging while not showing any of your dependencies’ log data, you can configure the plugin as shown below.
App::new()
.add_plugins(DefaultPlugins.set(LogPlugin {
filter: "warn,my_crate=trace".to_string(), //specific filters
level: Level::TRACE,//Change this to be globally change levels
..Default::default()
}))
.run();
The filter (in this case an EnvFilter
) chooses whether to print the log. The most specific filters apply with higher priority.
Let’s start with an example: filter: "warn".to_string()
will only print logs with level warn
level or greater.
From here, we can change to filter: "warn,my_crate=trace".to_string()
. Logs will print at level warn
unless it’s in mycrate
,
which will instead print at trace
level because my_crate=trace
is more specific.
§Log levels
Events can be logged at various levels of importance. Only events at your configured log level and higher will be shown.
// here is how you write new logs at each "log level" (in "most important" to
// "least important" order)
error!("something failed");
warn!("something bad happened that isn't a failure, but that's worth calling out");
info!("helpful information that is worth printing by default");
debug!("helpful for debugging");
trace!("very noisy");
In addition to format!
style arguments, you can print a variable’s debug
value by using syntax like: trace(?my_value)
.
§Per module logging levels
Modules can have different logging levels using syntax like crate_name::module_name=debug
.
App::new()
.add_plugins(DefaultPlugins.set(LogPlugin {
filter: "warn,my_crate=trace,my_crate::my_module=debug".to_string(), // Specific filters
level: Level::TRACE, // Change this to be globally change levels
..Default::default()
}))
.run();
The idea is that instead of deleting logs when they are no longer immediately applicable, you just disable them. If you do need to log in the future, then you can enable the logs instead of having to rewrite them.
§Further reading
The tracing
crate has much more functionality than these examples can show.
Much of this configuration can be done with “layers” in the log
crate.
Check out:
- Using spans to add more fine grained filters to logs
- Adding instruments to capture more function information
- Creating layers to add additional context such as line numbers
§Panics
This plugin should not be added multiple times in the same process. This plugin sets up global logging configuration for all Apps in a given process, and rerunning the same initialization multiple times will lead to a panic.
§Performance
Filters applied through this plugin are computed at runtime, which will
have a non-zero impact on performance.
To achieve maximum performance, consider using
compile time filters
provided by the log
crate.
# cargo.toml
[dependencies]
log = { version = "0.4", features = ["max_level_debug", "release_max_level_warn"] }
Fields§
§filter: String
Filters logs using the EnvFilter
format
level: Level
Filters out logs that are “less than” the given level.
This can be further filtered using the filter
setting.
custom_layer: fn(_: &mut App) -> Option<Box<dyn Layer<Registry> + Send + Sync>>
Optionally add an extra Layer
to the tracing subscriber
This function is only called once, when the plugin is built.
Because BoxedLayer
takes a dyn Layer
, Vec<Layer>
is also an acceptable return value.
Access to App
is also provided to allow for communication between the
Subscriber
and the App
.
Please see the examples/log_layers.rs
for a complete example.
Trait Implementations§
Source§impl Plugin for LogPlugin
impl Plugin for LogPlugin
Source§fn ready(&self, _app: &App) -> bool
fn ready(&self, _app: &App) -> bool
finish
should be called.Source§fn finish(&self, _app: &mut App)
fn finish(&self, _app: &mut App)
App
, once all plugins registered are ready. This can
be useful for plugins that depends on another plugin asynchronous setup, like the renderer.Source§fn cleanup(&self, _app: &mut App)
fn cleanup(&self, _app: &mut App)
Auto Trait Implementations§
impl Freeze for LogPlugin
impl RefUnwindSafe for LogPlugin
impl Send for LogPlugin
impl Sync for LogPlugin
impl Unpin for LogPlugin
impl UnwindSafe for LogPlugin
Blanket Implementations§
Source§impl<T, U> AsBindGroupShaderType<U> for T
impl<T, U> AsBindGroupShaderType<U> for T
Source§fn as_bind_group_shader_type(&self, _images: &RenderAssets<GpuImage>) -> U
fn as_bind_group_shader_type(&self, _images: &RenderAssets<GpuImage>) -> U
T
ShaderType
for self
. When used in AsBindGroup
derives, it is safe to assume that all images in self
exist.Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> Downcast for Twhere
T: Any,
impl<T> Downcast for Twhere
T: Any,
Source§fn into_any(self: Box<T>) -> Box<dyn Any>
fn into_any(self: Box<T>) -> Box<dyn Any>
Box<dyn Trait>
(where Trait: Downcast
) to Box<dyn Any>
, which can then be
downcast
into Box<dyn ConcreteType>
where ConcreteType
implements Trait
.Source§fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
Rc<Trait>
(where Trait: Downcast
) to Rc<Any>
, which can then be further
downcast
into Rc<ConcreteType>
where ConcreteType
implements Trait
.Source§fn as_any(&self) -> &(dyn Any + 'static)
fn as_any(&self) -> &(dyn Any + 'static)
&Trait
(where Trait: Downcast
) to &Any
. This is needed since Rust cannot
generate &Any
’s vtable from &Trait
’s.Source§fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
&mut Trait
(where Trait: Downcast
) to &Any
. This is needed since Rust cannot
generate &mut Any
’s vtable from &mut Trait
’s.Source§impl<T> Downcast for Twhere
T: Any,
impl<T> Downcast for Twhere
T: Any,
Source§fn into_any(self: Box<T>) -> Box<dyn Any>
fn into_any(self: Box<T>) -> Box<dyn Any>
Box<dyn Trait>
(where Trait: Downcast
) to Box<dyn Any>
. Box<dyn Any>
can
then be further downcast
into Box<ConcreteType>
where ConcreteType
implements Trait
.Source§fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
Rc<Trait>
(where Trait: Downcast
) to Rc<Any>
. Rc<Any>
can then be
further downcast
into Rc<ConcreteType>
where ConcreteType
implements Trait
.Source§fn as_any(&self) -> &(dyn Any + 'static)
fn as_any(&self) -> &(dyn Any + 'static)
&Trait
(where Trait: Downcast
) to &Any
. This is needed since Rust cannot
generate &Any
’s vtable from &Trait
’s.Source§fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
&mut Trait
(where Trait: Downcast
) to &Any
. This is needed since Rust cannot
generate &mut Any
’s vtable from &mut Trait
’s.Source§impl<T> DowncastSend for T
impl<T> DowncastSend for T
Source§impl<T> DowncastSync for T
impl<T> DowncastSync for T
Source§impl<T> FromWorld for Twhere
T: Default,
impl<T> FromWorld for Twhere
T: Default,
Source§fn from_world(_world: &mut World) -> T
fn from_world(_world: &mut World) -> T
Creates Self
using default()
.
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
Source§fn in_current_span(self) -> Instrumented<Self> ⓘ
fn in_current_span(self) -> Instrumented<Self> ⓘ
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
self
into a Left
variant of Either<Self, Self>
if into_left
is true
.
Converts self
into a Right
variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
self
into a Left
variant of Either<Self, Self>
if into_left(&self)
returns true
.
Converts self
into a Right
variant of Either<Self, Self>
otherwise. Read more