bevy/examples/app/logs.rs

84 lines
2.9 KiB
Rust
Raw Normal View History

//! This example illustrates how to use logs in bevy.
Add helper macro's for logging only once (#10808) # Objective Fixes #10291 This adds a way to easily log messages once within system which are called every frame. ## Solution Opted for a macro-based approach. The fact that the 'once' call is tracked per call site makes the `log_once!()` macro very versatile and easy-to-use. I suspect it will be very handy for all of us, but especially beginners, to get some initial feedback from systems without spamming up the place! I've made the macro's return its internal `has_fired` state, for situations in which that might be useful to know (trigger something else alongside the log, for example). Please let me know if I placed the macro's in the right location, and if you would like me to do something more clever with the macro's themselves, since its looking quite copy-pastey at the moment. I've tried ways to replace 5 with 1 macro's, but no success yet. One downside of this approach is: Say you wish to warn the user if a resource is invalid. In this situation, the `resource.is_valid()` check would still be performed every frame: ```rust fn my_system(my_res: Res<MyResource>) { if !my_res.is_valid() { warn_once!("resource is invalid!"); } } ``` If you want to prevent that, you would still need to introduce a local boolean. I don't think this is a very big deal, as expensive checks shouldn't be called every frame in any case. ## Changelog Added: `trace_once!()`, `debug_once!()`, `info_once!()`, `warn_once!()`, and `error_once!()` log macros which fire only once per call site.
2023-12-05 01:56:40 +00:00
use bevy::log::once;
2020-11-13 01:23:57 +00:00
use bevy::prelude::*;
fn main() {
App::new()
Use plugin setup for resource only used at setup time (#6360) # Objective - Build on #6336 for more plugin configurations ## Solution - `LogSettings`, `ImageSettings` and `DefaultTaskPoolOptions` are now plugins settings rather than resources --- ## Changelog - `LogSettings` plugin settings have been move to `LogPlugin`, `ImageSettings` to `ImagePlugin` and `DefaultTaskPoolOptions` to `CorePlugin` ## Migration Guide The `LogSettings` settings have been moved from a resource to `LogPlugin` configuration: ```rust // Old (Bevy 0.8) app .insert_resource(LogSettings { level: Level::DEBUG, filter: "wgpu=error,bevy_render=info,bevy_ecs=trace".to_string(), }) .add_plugins(DefaultPlugins) // New (Bevy 0.9) app.add_plugins(DefaultPlugins.set(LogPlugin { level: Level::DEBUG, filter: "wgpu=error,bevy_render=info,bevy_ecs=trace".to_string(), })) ``` The `ImageSettings` settings have been moved from a resource to `ImagePlugin` configuration: ```rust // Old (Bevy 0.8) app .insert_resource(ImageSettings::default_nearest()) .add_plugins(DefaultPlugins) // New (Bevy 0.9) app.add_plugins(DefaultPlugins.set(ImagePlugin::default_nearest())) ``` The `DefaultTaskPoolOptions` settings have been moved from a resource to `CorePlugin::task_pool_options`: ```rust // Old (Bevy 0.8) app .insert_resource(DefaultTaskPoolOptions::with_num_threads(4)) .add_plugins(DefaultPlugins) // New (Bevy 0.9) app.add_plugins(DefaultPlugins.set(CorePlugin { task_pool_options: TaskPoolOptions::with_num_threads(4), })) ```
2022-10-25 22:19:34 +00:00
.add_plugins(DefaultPlugins.set(bevy::log::LogPlugin {
// Uncomment this to override the default log settings:
// level: bevy::log::Level::TRACE,
// filter: "wgpu=warn,bevy_ecs=info".to_string(),
..default()
}))
.add_systems(Startup, setup)
.add_systems(Update, log_system)
Add helper macro's for logging only once (#10808) # Objective Fixes #10291 This adds a way to easily log messages once within system which are called every frame. ## Solution Opted for a macro-based approach. The fact that the 'once' call is tracked per call site makes the `log_once!()` macro very versatile and easy-to-use. I suspect it will be very handy for all of us, but especially beginners, to get some initial feedback from systems without spamming up the place! I've made the macro's return its internal `has_fired` state, for situations in which that might be useful to know (trigger something else alongside the log, for example). Please let me know if I placed the macro's in the right location, and if you would like me to do something more clever with the macro's themselves, since its looking quite copy-pastey at the moment. I've tried ways to replace 5 with 1 macro's, but no success yet. One downside of this approach is: Say you wish to warn the user if a resource is invalid. In this situation, the `resource.is_valid()` check would still be performed every frame: ```rust fn my_system(my_res: Res<MyResource>) { if !my_res.is_valid() { warn_once!("resource is invalid!"); } } ``` If you want to prevent that, you would still need to introduce a local boolean. I don't think this is a very big deal, as expensive checks shouldn't be called every frame in any case. ## Changelog Added: `trace_once!()`, `debug_once!()`, `info_once!()`, `warn_once!()`, and `error_once!()` log macros which fire only once per call site.
2023-12-05 01:56:40 +00:00
.add_systems(Update, log_once_system)
.add_systems(Update, panic_on_p)
2020-11-13 01:23:57 +00:00
.run();
}
fn setup(mut commands: Commands) {
commands.spawn(Camera2dBundle::default());
commands.spawn(TextBundle {
text: Text::from_section("Press P to panic", TextStyle::default()),
style: Style {
position_type: PositionType::Absolute,
top: Val::Px(12.0),
left: Val::Px(12.0),
..default()
},
..default()
});
}
fn panic_on_p(keys: Res<ButtonInput<KeyCode>>) {
if keys.just_pressed(KeyCode::KeyP) {
panic!("P pressed, panicking");
}
}
2020-11-13 01:23:57 +00:00
fn log_system() {
// here is how you write new logs at each "log level" (in "least important" to "most important"
// order)
2020-11-13 01:23:57 +00:00
trace!("very noisy");
debug!("helpful for debugging");
info!("helpful information that is worth printing by default");
warn!("something bad happened that isn't a failure, but thats worth calling out");
error!("something failed");
// by default, trace and debug logs are ignored because they are "noisy"
Use plugin setup for resource only used at setup time (#6360) # Objective - Build on #6336 for more plugin configurations ## Solution - `LogSettings`, `ImageSettings` and `DefaultTaskPoolOptions` are now plugins settings rather than resources --- ## Changelog - `LogSettings` plugin settings have been move to `LogPlugin`, `ImageSettings` to `ImagePlugin` and `DefaultTaskPoolOptions` to `CorePlugin` ## Migration Guide The `LogSettings` settings have been moved from a resource to `LogPlugin` configuration: ```rust // Old (Bevy 0.8) app .insert_resource(LogSettings { level: Level::DEBUG, filter: "wgpu=error,bevy_render=info,bevy_ecs=trace".to_string(), }) .add_plugins(DefaultPlugins) // New (Bevy 0.9) app.add_plugins(DefaultPlugins.set(LogPlugin { level: Level::DEBUG, filter: "wgpu=error,bevy_render=info,bevy_ecs=trace".to_string(), })) ``` The `ImageSettings` settings have been moved from a resource to `ImagePlugin` configuration: ```rust // Old (Bevy 0.8) app .insert_resource(ImageSettings::default_nearest()) .add_plugins(DefaultPlugins) // New (Bevy 0.9) app.add_plugins(DefaultPlugins.set(ImagePlugin::default_nearest())) ``` The `DefaultTaskPoolOptions` settings have been moved from a resource to `CorePlugin::task_pool_options`: ```rust // Old (Bevy 0.8) app .insert_resource(DefaultTaskPoolOptions::with_num_threads(4)) .add_plugins(DefaultPlugins) // New (Bevy 0.9) app.add_plugins(DefaultPlugins.set(CorePlugin { task_pool_options: TaskPoolOptions::with_num_threads(4), })) ```
2022-10-25 22:19:34 +00:00
// you can control what level is logged by setting up the LogPlugin
2020-11-13 01:23:57 +00:00
// alternatively you can set the log level via the RUST_LOG=LEVEL environment variable
// ex: RUST_LOG=trace, RUST_LOG=info,bevy_ecs=warn
// the format used here is super flexible. check out this documentation for more info:
// https://docs.rs/tracing-subscriber/*/tracing_subscriber/filter/struct.EnvFilter.html
}
Add helper macro's for logging only once (#10808) # Objective Fixes #10291 This adds a way to easily log messages once within system which are called every frame. ## Solution Opted for a macro-based approach. The fact that the 'once' call is tracked per call site makes the `log_once!()` macro very versatile and easy-to-use. I suspect it will be very handy for all of us, but especially beginners, to get some initial feedback from systems without spamming up the place! I've made the macro's return its internal `has_fired` state, for situations in which that might be useful to know (trigger something else alongside the log, for example). Please let me know if I placed the macro's in the right location, and if you would like me to do something more clever with the macro's themselves, since its looking quite copy-pastey at the moment. I've tried ways to replace 5 with 1 macro's, but no success yet. One downside of this approach is: Say you wish to warn the user if a resource is invalid. In this situation, the `resource.is_valid()` check would still be performed every frame: ```rust fn my_system(my_res: Res<MyResource>) { if !my_res.is_valid() { warn_once!("resource is invalid!"); } } ``` If you want to prevent that, you would still need to introduce a local boolean. I don't think this is a very big deal, as expensive checks shouldn't be called every frame in any case. ## Changelog Added: `trace_once!()`, `debug_once!()`, `info_once!()`, `warn_once!()`, and `error_once!()` log macros which fire only once per call site.
2023-12-05 01:56:40 +00:00
fn log_once_system() {
// The 'once' variants of each log level are useful when a system is called every frame,
// but we still wish to inform the user only once. In other words, use these to prevent spam :)
trace_once!("one time noisy message");
debug_once!("one time debug message");
info_once!("some info which is printed only once");
warn_once!("some warning we wish to call out only once");
error_once!("some error we wish to report only once");
for i in 0..10 {
info_once!("logs once per call site, so this works just fine: {}", i);
}
// you can also use the `once!` macro directly,
// in situations where you want to do something expensive only once
// within the context of a continuous system.
Add helper macro's for logging only once (#10808) # Objective Fixes #10291 This adds a way to easily log messages once within system which are called every frame. ## Solution Opted for a macro-based approach. The fact that the 'once' call is tracked per call site makes the `log_once!()` macro very versatile and easy-to-use. I suspect it will be very handy for all of us, but especially beginners, to get some initial feedback from systems without spamming up the place! I've made the macro's return its internal `has_fired` state, for situations in which that might be useful to know (trigger something else alongside the log, for example). Please let me know if I placed the macro's in the right location, and if you would like me to do something more clever with the macro's themselves, since its looking quite copy-pastey at the moment. I've tried ways to replace 5 with 1 macro's, but no success yet. One downside of this approach is: Say you wish to warn the user if a resource is invalid. In this situation, the `resource.is_valid()` check would still be performed every frame: ```rust fn my_system(my_res: Res<MyResource>) { if !my_res.is_valid() { warn_once!("resource is invalid!"); } } ``` If you want to prevent that, you would still need to introduce a local boolean. I don't think this is a very big deal, as expensive checks shouldn't be called every frame in any case. ## Changelog Added: `trace_once!()`, `debug_once!()`, `info_once!()`, `warn_once!()`, and `error_once!()` log macros which fire only once per call site.
2023-12-05 01:56:40 +00:00
once!({
info!("doing expensive things");
let mut a: u64 = 0;
for i in 0..100000000 {
a += i;
}
info!("result of some expensive one time calculation: {}", a);
});
}