2024-03-23 02:22:52 +00:00
|
|
|
#![cfg_attr(docsrs, feature(doc_auto_cfg))]
|
2024-03-25 18:52:50 +00:00
|
|
|
#![doc(
|
|
|
|
html_logo_url = "https://bevyengine.org/assets/icon.png",
|
|
|
|
html_favicon_url = "https://bevyengine.org/assets/icon.png"
|
|
|
|
)]
|
2024-03-23 02:22:52 +00:00
|
|
|
|
2022-01-23 18:00:43 +00:00
|
|
|
//! This crate provides logging functions and configuration for [Bevy](https://bevyengine.org)
|
2024-07-31 21:16:05 +00:00
|
|
|
//! apps, and automatically configures platform specific log handlers (i.e. Wasm or Android).
|
2022-01-23 18:00:43 +00:00
|
|
|
//!
|
|
|
|
//! The macros provided for logging are reexported from [`tracing`](https://docs.rs/tracing),
|
|
|
|
//! and behave identically to it.
|
|
|
|
//!
|
|
|
|
//! By default, the [`LogPlugin`] from this crate is included in Bevy's `DefaultPlugins`
|
|
|
|
//! and the logging macros can be used out of the box, if used.
|
|
|
|
//!
|
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
|
|
|
//! For more fine-tuned control over logging behavior, set up the [`LogPlugin`] or
|
|
|
|
//! `DefaultPlugins` during app initialization.
|
2022-01-23 18:00:43 +00:00
|
|
|
|
2024-09-27 00:59:59 +00:00
|
|
|
extern crate alloc;
|
|
|
|
|
|
|
|
use core::error::Error;
|
2022-02-28 22:27:20 +00:00
|
|
|
|
2020-11-13 01:23:57 +00:00
|
|
|
#[cfg(target_os = "android")]
|
|
|
|
mod android_tracing;
|
|
|
|
|
2023-04-17 16:04:46 +00:00
|
|
|
#[cfg(feature = "trace_tracy_memory")]
|
|
|
|
#[global_allocator]
|
|
|
|
static GLOBAL: tracy_client::ProfiledAllocator<std::alloc::System> =
|
|
|
|
tracy_client::ProfiledAllocator::new(std::alloc::System, 100);
|
|
|
|
|
2024-09-08 17:10:57 +00:00
|
|
|
/// The log prelude.
|
|
|
|
///
|
|
|
|
/// This includes the most common types in this crate, re-exported for your convenience.
|
2020-11-13 01:23:57 +00:00
|
|
|
pub mod prelude {
|
2022-11-02 20:40:45 +00:00
|
|
|
#[doc(hidden)]
|
2020-11-13 01:23:57 +00:00
|
|
|
pub use bevy_utils::tracing::{
|
|
|
|
debug, debug_span, error, error_span, info, info_span, trace, trace_span, warn, warn_span,
|
|
|
|
};
|
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
|
|
|
|
2024-01-19 06:07:41 +00:00
|
|
|
#[doc(hidden)]
|
|
|
|
pub use bevy_utils::{debug_once, error_once, info_once, once, trace_once, warn_once};
|
2020-11-13 01:23:57 +00:00
|
|
|
}
|
2022-02-28 22:27:20 +00:00
|
|
|
|
2024-01-19 06:07:41 +00:00
|
|
|
pub use bevy_utils::{
|
|
|
|
debug_once, error_once, info_once, once, trace_once,
|
|
|
|
tracing::{
|
|
|
|
debug, debug_span, error, error_span, info, info_span, trace, trace_span, warn, warn_span,
|
|
|
|
Level,
|
|
|
|
},
|
|
|
|
warn_once,
|
2020-11-13 01:23:57 +00:00
|
|
|
};
|
2024-01-15 15:26:13 +00:00
|
|
|
pub use tracing_subscriber;
|
2020-11-13 01:23:57 +00:00
|
|
|
|
2021-07-27 20:21:06 +00:00
|
|
|
use bevy_app::{App, Plugin};
|
2021-06-28 19:23:45 +00:00
|
|
|
use tracing_log::LogTracer;
|
Improve error handling for log filter (#13897)
# Objective
This PR aims to improve error handling for log filters.
Closes #13850
## Solution
I changed the parsing of LogPlugin its filter to lossy, so that it
prints the directives with an error but does not skip them. I decided on
letting it gracefully handle the error instead of panicking to be
consistent with the parsing from an environment variable that it tries
to do before parsing it from the LogPlugin filter.
If the user decides to specify the filter by an environment variable, it
would silently fail and default to the LogPlugin filter value. It now
prints an error before defaulting to the LogPlugin filter value.
Unfortunately, I could not try and loosely set the filter from the
environment variable because the `tracing-subscriber` module does not
expose the function it uses to get the environment variable, and I would
rather not copy its code. We may want to check if the maintainers are
open to exposing the method.
## Testing
Consider the following bevy app, where the second of the 3 filters is
invalid:
```
use bevy::{log::LogPlugin, prelude::*};
fn main() {
App::new().add_plugins(DefaultPlugins
.set(LogPlugin {
filter: "wgpu=error,my_package=invalid_log_level,naga=warn".into(),
..default()
})
).run();
}
```
In the previous situation, it would panic with a non-descriptive error:
"called `Result::unwrap()` on an `Err` value: ParseError { kind:
Other(None) }", while only 1 of the 3 filters is invalid. When running
`cargo run`, it will now use the two valid filters and print an error on
the invalid filter.
> ignoring `my_package=invalid_log_level`: invalid filter directive
This error comes from `tracing-subscriber` and cannot be altered as far
as I can see.
To test setting the log filter through an environment variable, you can
use `RUST_LOG="wgpu=error,my_package=invalid_log_level,naga=warn" cargo
run` to run your app. In the previous situation it would silently fail
and use the LogPlugin filter. It will now print an error before using
the LogPlugin filter.
> LogPlugin failed to parse filter from env: invalid filter directive
## Changelog
- Added warning when using invalid filter in the RUST_LOG environment
variable
- Prevent the app from panicking when setting an invalid LogPlugin
filter
---------
Co-authored-by: Luc Drenth <luc.drenth@ing.com>
2024-06-19 13:46:03 +00:00
|
|
|
use tracing_subscriber::{
|
|
|
|
filter::{FromEnvError, ParseError},
|
|
|
|
prelude::*,
|
|
|
|
registry::Registry,
|
|
|
|
EnvFilter, Layer,
|
|
|
|
};
|
2024-05-06 21:15:10 +00:00
|
|
|
#[cfg(feature = "tracing-chrome")]
|
2024-09-27 00:59:59 +00:00
|
|
|
use {
|
|
|
|
bevy_ecs::system::Resource,
|
|
|
|
bevy_utils::synccell::SyncCell,
|
|
|
|
tracing_subscriber::fmt::{format::DefaultFields, FormattedFields},
|
|
|
|
};
|
2024-05-06 21:15:10 +00:00
|
|
|
|
|
|
|
/// Wrapper resource for `tracing-chrome`'s flush guard.
|
|
|
|
/// When the guard is dropped the chrome log is written to file.
|
|
|
|
#[cfg(feature = "tracing-chrome")]
|
2024-09-20 19:16:42 +00:00
|
|
|
#[expect(
|
|
|
|
dead_code,
|
|
|
|
reason = "`FlushGuard` never needs to be read, it just needs to be kept alive for the `App`'s lifetime."
|
|
|
|
)]
|
2024-05-06 21:15:10 +00:00
|
|
|
#[derive(Resource)]
|
|
|
|
pub(crate) struct FlushGuard(SyncCell<tracing_chrome::FlushGuard>);
|
2020-11-13 01:23:57 +00:00
|
|
|
|
2021-04-22 23:30:48 +00:00
|
|
|
/// 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`](https://crates.io/crates/tracing-subscriber) by default,
|
2024-06-17 17:22:01 +00:00
|
|
|
/// logging to `stdout`.
|
2021-04-22 23:30:48 +00:00
|
|
|
/// * Using [`android_log-sys`](https://crates.io/crates/android_log-sys) on Android,
|
2024-06-17 17:22:01 +00:00
|
|
|
/// logging to Android logs.
|
2024-07-31 21:16:05 +00:00
|
|
|
/// * Using [`tracing-wasm`](https://crates.io/crates/tracing-wasm) in Wasm, logging
|
2024-06-17 17:22:01 +00:00
|
|
|
/// to the browser console.
|
2021-04-22 23:30:48 +00:00
|
|
|
///
|
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 configure this plugin.
|
2021-04-22 23:30:48 +00:00
|
|
|
/// ```no_run
|
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
|
|
|
/// # use bevy_app::{App, NoopPluginGroup as DefaultPlugins, PluginGroup};
|
|
|
|
/// # use bevy_log::LogPlugin;
|
2021-04-22 23:30:48 +00:00
|
|
|
/// # use bevy_utils::tracing::Level;
|
|
|
|
/// fn main() {
|
2021-07-27 20:21:06 +00:00
|
|
|
/// 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(LogPlugin {
|
2021-04-22 23:30:48 +00:00
|
|
|
/// level: Level::DEBUG,
|
2022-03-05 03:00:31 +00:00
|
|
|
/// filter: "wgpu=error,bevy_render=info,bevy_ecs=trace".to_string(),
|
2024-05-12 21:16:56 +00:00
|
|
|
/// custom_layer: |_| None,
|
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
|
|
|
/// }))
|
2021-04-22 23:30:48 +00:00
|
|
|
/// .run();
|
|
|
|
/// }
|
|
|
|
/// ```
|
|
|
|
///
|
|
|
|
/// Log level can also be changed using the `RUST_LOG` environment variable.
|
2022-03-05 03:00:31 +00:00
|
|
|
/// For example, using `RUST_LOG=wgpu=error,bevy_render=info,bevy_ecs=trace cargo run ..`
|
|
|
|
///
|
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
|
|
|
/// It has the same syntax as the field [`LogPlugin::filter`], see [`EnvFilter`].
|
|
|
|
/// If you define the `RUST_LOG` environment variable, the [`LogPlugin`] settings
|
2021-11-11 01:43:51 +00:00
|
|
|
/// will be ignored.
|
2021-04-22 23:30:48 +00:00
|
|
|
///
|
2024-10-20 18:55:17 +00:00
|
|
|
/// Also, to disable color terminal output (ANSI escape codes), you can
|
2024-06-24 21:04:55 +00:00
|
|
|
/// set the environment variable `NO_COLOR` to any value. This common
|
|
|
|
/// convention is documented at [no-color.org](https://no-color.org/).
|
|
|
|
/// For example:
|
|
|
|
/// ```no_run
|
|
|
|
/// # use bevy_app::{App, NoopPluginGroup as DefaultPlugins, PluginGroup};
|
|
|
|
/// # use bevy_log::LogPlugin;
|
|
|
|
/// fn main() {
|
|
|
|
/// std::env::set_var("NO_COLOR", "1");
|
|
|
|
/// App::new()
|
|
|
|
/// .add_plugins(DefaultPlugins)
|
|
|
|
/// .run();
|
|
|
|
/// }
|
|
|
|
/// ```
|
|
|
|
///
|
2021-04-22 23:30:48 +00:00
|
|
|
/// If you want to setup your own tracing collector, you should disable this
|
Plugins own their settings. Rework PluginGroup trait. (#6336)
# Objective
Fixes #5884 #2879
Alternative to #2988 #5885 #2886
"Immutable" Plugin settings are currently represented as normal ECS resources, which are read as part of plugin init. This presents a number of problems:
1. If a user inserts the plugin settings resource after the plugin is initialized, it will be silently ignored (and use the defaults instead)
2. Users can modify the plugin settings resource after the plugin has been initialized. This creates a false sense of control over settings that can no longer be changed.
(1) and (2) are especially problematic and confusing for the `WindowDescriptor` resource, but this is a general problem.
## Solution
Immutable Plugin settings now live on each Plugin struct (ex: `WindowPlugin`). PluginGroups have been reworked to support overriding plugin values. This also removes the need for the `add_plugins_with` api, as the `add_plugins` api can use the builder pattern directly. Settings that can be used at runtime continue to be represented as ECS resources.
Plugins are now configured like this:
```rust
app.add_plugin(AssetPlugin {
watch_for_changes: true,
..default()
})
```
PluginGroups are now configured like this:
```rust
app.add_plugins(DefaultPlugins
.set(AssetPlugin {
watch_for_changes: true,
..default()
})
)
```
This is an alternative to #2988, which is similar. But I personally prefer this solution for a couple of reasons:
* ~~#2988 doesn't solve (1)~~ #2988 does solve (1) and will panic in that case. I was wrong!
* This PR directly ties plugin settings to Plugin types in a 1:1 relationship, rather than a loose "setup resource" <-> plugin coupling (where the setup resource is consumed by the first plugin that uses it).
* I'm not a huge fan of overloading the ECS resource concept and implementation for something that has very different use cases and constraints.
## Changelog
- PluginGroups can now be configured directly using the builder pattern. Individual plugin values can be overridden by using `plugin_group.set(SomePlugin {})`, which enables overriding default plugin values.
- `WindowDescriptor` plugin settings have been moved to `WindowPlugin` and `AssetServerSettings` have been moved to `AssetPlugin`
- `app.add_plugins_with` has been replaced by using `add_plugins` with the builder pattern.
## Migration Guide
The `WindowDescriptor` settings have been moved from a resource to `WindowPlugin::window`:
```rust
// Old (Bevy 0.8)
app
.insert_resource(WindowDescriptor {
width: 400.0,
..default()
})
.add_plugins(DefaultPlugins)
// New (Bevy 0.9)
app.add_plugins(DefaultPlugins.set(WindowPlugin {
window: WindowDescriptor {
width: 400.0,
..default()
},
..default()
}))
```
The `AssetServerSettings` resource has been removed in favor of direct `AssetPlugin` configuration:
```rust
// Old (Bevy 0.8)
app
.insert_resource(AssetServerSettings {
watch_for_changes: true,
..default()
})
.add_plugins(DefaultPlugins)
// New (Bevy 0.9)
app.add_plugins(DefaultPlugins.set(AssetPlugin {
watch_for_changes: true,
..default()
}))
```
`add_plugins_with` has been replaced by `add_plugins` in combination with the builder pattern:
```rust
// Old (Bevy 0.8)
app.add_plugins_with(DefaultPlugins, |group| group.disable::<AssetPlugin>());
// New (Bevy 0.9)
app.add_plugins(DefaultPlugins.build().disable::<AssetPlugin>());
```
2022-10-24 21:20:33 +00:00
|
|
|
/// plugin from `DefaultPlugins`:
|
2021-04-22 23:30:48 +00:00
|
|
|
/// ```no_run
|
Plugins own their settings. Rework PluginGroup trait. (#6336)
# Objective
Fixes #5884 #2879
Alternative to #2988 #5885 #2886
"Immutable" Plugin settings are currently represented as normal ECS resources, which are read as part of plugin init. This presents a number of problems:
1. If a user inserts the plugin settings resource after the plugin is initialized, it will be silently ignored (and use the defaults instead)
2. Users can modify the plugin settings resource after the plugin has been initialized. This creates a false sense of control over settings that can no longer be changed.
(1) and (2) are especially problematic and confusing for the `WindowDescriptor` resource, but this is a general problem.
## Solution
Immutable Plugin settings now live on each Plugin struct (ex: `WindowPlugin`). PluginGroups have been reworked to support overriding plugin values. This also removes the need for the `add_plugins_with` api, as the `add_plugins` api can use the builder pattern directly. Settings that can be used at runtime continue to be represented as ECS resources.
Plugins are now configured like this:
```rust
app.add_plugin(AssetPlugin {
watch_for_changes: true,
..default()
})
```
PluginGroups are now configured like this:
```rust
app.add_plugins(DefaultPlugins
.set(AssetPlugin {
watch_for_changes: true,
..default()
})
)
```
This is an alternative to #2988, which is similar. But I personally prefer this solution for a couple of reasons:
* ~~#2988 doesn't solve (1)~~ #2988 does solve (1) and will panic in that case. I was wrong!
* This PR directly ties plugin settings to Plugin types in a 1:1 relationship, rather than a loose "setup resource" <-> plugin coupling (where the setup resource is consumed by the first plugin that uses it).
* I'm not a huge fan of overloading the ECS resource concept and implementation for something that has very different use cases and constraints.
## Changelog
- PluginGroups can now be configured directly using the builder pattern. Individual plugin values can be overridden by using `plugin_group.set(SomePlugin {})`, which enables overriding default plugin values.
- `WindowDescriptor` plugin settings have been moved to `WindowPlugin` and `AssetServerSettings` have been moved to `AssetPlugin`
- `app.add_plugins_with` has been replaced by using `add_plugins` with the builder pattern.
## Migration Guide
The `WindowDescriptor` settings have been moved from a resource to `WindowPlugin::window`:
```rust
// Old (Bevy 0.8)
app
.insert_resource(WindowDescriptor {
width: 400.0,
..default()
})
.add_plugins(DefaultPlugins)
// New (Bevy 0.9)
app.add_plugins(DefaultPlugins.set(WindowPlugin {
window: WindowDescriptor {
width: 400.0,
..default()
},
..default()
}))
```
The `AssetServerSettings` resource has been removed in favor of direct `AssetPlugin` configuration:
```rust
// Old (Bevy 0.8)
app
.insert_resource(AssetServerSettings {
watch_for_changes: true,
..default()
})
.add_plugins(DefaultPlugins)
// New (Bevy 0.9)
app.add_plugins(DefaultPlugins.set(AssetPlugin {
watch_for_changes: true,
..default()
}))
```
`add_plugins_with` has been replaced by `add_plugins` in combination with the builder pattern:
```rust
// Old (Bevy 0.8)
app.add_plugins_with(DefaultPlugins, |group| group.disable::<AssetPlugin>());
// New (Bevy 0.9)
app.add_plugins(DefaultPlugins.build().disable::<AssetPlugin>());
```
2022-10-24 21:20:33 +00:00
|
|
|
/// # use bevy_app::{App, NoopPluginGroup as DefaultPlugins, PluginGroup};
|
2021-04-22 23:30:48 +00:00
|
|
|
/// # use bevy_log::LogPlugin;
|
|
|
|
/// fn main() {
|
2021-07-27 20:21:06 +00:00
|
|
|
/// App::new()
|
Plugins own their settings. Rework PluginGroup trait. (#6336)
# Objective
Fixes #5884 #2879
Alternative to #2988 #5885 #2886
"Immutable" Plugin settings are currently represented as normal ECS resources, which are read as part of plugin init. This presents a number of problems:
1. If a user inserts the plugin settings resource after the plugin is initialized, it will be silently ignored (and use the defaults instead)
2. Users can modify the plugin settings resource after the plugin has been initialized. This creates a false sense of control over settings that can no longer be changed.
(1) and (2) are especially problematic and confusing for the `WindowDescriptor` resource, but this is a general problem.
## Solution
Immutable Plugin settings now live on each Plugin struct (ex: `WindowPlugin`). PluginGroups have been reworked to support overriding plugin values. This also removes the need for the `add_plugins_with` api, as the `add_plugins` api can use the builder pattern directly. Settings that can be used at runtime continue to be represented as ECS resources.
Plugins are now configured like this:
```rust
app.add_plugin(AssetPlugin {
watch_for_changes: true,
..default()
})
```
PluginGroups are now configured like this:
```rust
app.add_plugins(DefaultPlugins
.set(AssetPlugin {
watch_for_changes: true,
..default()
})
)
```
This is an alternative to #2988, which is similar. But I personally prefer this solution for a couple of reasons:
* ~~#2988 doesn't solve (1)~~ #2988 does solve (1) and will panic in that case. I was wrong!
* This PR directly ties plugin settings to Plugin types in a 1:1 relationship, rather than a loose "setup resource" <-> plugin coupling (where the setup resource is consumed by the first plugin that uses it).
* I'm not a huge fan of overloading the ECS resource concept and implementation for something that has very different use cases and constraints.
## Changelog
- PluginGroups can now be configured directly using the builder pattern. Individual plugin values can be overridden by using `plugin_group.set(SomePlugin {})`, which enables overriding default plugin values.
- `WindowDescriptor` plugin settings have been moved to `WindowPlugin` and `AssetServerSettings` have been moved to `AssetPlugin`
- `app.add_plugins_with` has been replaced by using `add_plugins` with the builder pattern.
## Migration Guide
The `WindowDescriptor` settings have been moved from a resource to `WindowPlugin::window`:
```rust
// Old (Bevy 0.8)
app
.insert_resource(WindowDescriptor {
width: 400.0,
..default()
})
.add_plugins(DefaultPlugins)
// New (Bevy 0.9)
app.add_plugins(DefaultPlugins.set(WindowPlugin {
window: WindowDescriptor {
width: 400.0,
..default()
},
..default()
}))
```
The `AssetServerSettings` resource has been removed in favor of direct `AssetPlugin` configuration:
```rust
// Old (Bevy 0.8)
app
.insert_resource(AssetServerSettings {
watch_for_changes: true,
..default()
})
.add_plugins(DefaultPlugins)
// New (Bevy 0.9)
app.add_plugins(DefaultPlugins.set(AssetPlugin {
watch_for_changes: true,
..default()
}))
```
`add_plugins_with` has been replaced by `add_plugins` in combination with the builder pattern:
```rust
// Old (Bevy 0.8)
app.add_plugins_with(DefaultPlugins, |group| group.disable::<AssetPlugin>());
// New (Bevy 0.9)
app.add_plugins(DefaultPlugins.build().disable::<AssetPlugin>());
```
2022-10-24 21:20:33 +00:00
|
|
|
/// .add_plugins(DefaultPlugins.build().disable::<LogPlugin>())
|
2021-04-22 23:30:48 +00:00
|
|
|
/// .run();
|
|
|
|
/// }
|
|
|
|
/// ```
|
2022-01-23 18:00:43 +00:00
|
|
|
///
|
|
|
|
/// # 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.
|
2024-09-03 00:48:19 +00:00
|
|
|
///
|
|
|
|
/// # 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](https://docs.rs/log/#compile-time-filters)
|
|
|
|
/// provided by the [`log`](https://crates.io/crates/log) crate.
|
|
|
|
///
|
|
|
|
/// ```toml
|
|
|
|
/// # cargo.toml
|
|
|
|
/// [dependencies]
|
|
|
|
/// log = { version = "0.4", features = ["max_level_debug", "release_max_level_warn"] }
|
|
|
|
/// ```
|
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
|
|
|
pub struct LogPlugin {
|
2021-04-22 23:30:48 +00:00
|
|
|
/// Filters logs using the [`EnvFilter`] format
|
2020-11-13 01:23:57 +00:00
|
|
|
pub filter: String,
|
|
|
|
|
|
|
|
/// Filters out logs that are "less than" the given level.
|
|
|
|
/// This can be further filtered using the `filter` setting.
|
|
|
|
pub level: Level,
|
2024-01-15 15:26:13 +00:00
|
|
|
|
2024-05-12 21:16:56 +00:00
|
|
|
/// 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.
|
2024-03-04 00:01:05 +00:00
|
|
|
///
|
2024-07-11 13:08:31 +00:00
|
|
|
/// Access to [`App`] is also provided to allow for communication between the
|
|
|
|
/// [`Subscriber`](bevy_utils::tracing::Subscriber) and the [`App`].
|
2024-05-12 21:16:56 +00:00
|
|
|
///
|
|
|
|
/// Please see the `examples/log_layers.rs` for a complete example.
|
|
|
|
pub custom_layer: fn(app: &mut App) -> Option<BoxedLayer>,
|
2020-11-13 01:23:57 +00:00
|
|
|
}
|
|
|
|
|
2024-05-12 21:16:56 +00:00
|
|
|
/// A boxed [`Layer`] that can be used with [`LogPlugin`].
|
|
|
|
pub type BoxedLayer = Box<dyn Layer<Registry> + Send + Sync + 'static>;
|
2024-01-15 15:26:13 +00:00
|
|
|
|
2024-08-29 12:15:49 +00:00
|
|
|
/// The default [`LogPlugin`] [`EnvFilter`].
|
|
|
|
pub const DEFAULT_FILTER: &str = "wgpu=error,naga=warn";
|
|
|
|
|
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
|
|
|
impl Default for LogPlugin {
|
2020-11-13 01:23:57 +00:00
|
|
|
fn default() -> Self {
|
|
|
|
Self {
|
2024-08-29 12:15:49 +00:00
|
|
|
filter: DEFAULT_FILTER.to_string(),
|
2020-11-13 01:23:57 +00:00
|
|
|
level: Level::INFO,
|
2024-05-12 21:16:56 +00:00
|
|
|
custom_layer: |_| None,
|
2020-11-13 01:23:57 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl Plugin for LogPlugin {
|
2021-07-27 20:21:06 +00:00
|
|
|
fn build(&self, app: &mut App) {
|
2022-02-28 22:27:20 +00:00
|
|
|
#[cfg(feature = "trace")]
|
|
|
|
{
|
2024-09-27 00:59:59 +00:00
|
|
|
let old_handler = std::panic::take_hook();
|
|
|
|
std::panic::set_hook(Box::new(move |infos| {
|
2024-01-01 17:10:20 +00:00
|
|
|
eprintln!("{}", tracing_error::SpanTrace::capture());
|
2022-02-28 22:27:20 +00:00
|
|
|
old_handler(infos);
|
|
|
|
}));
|
|
|
|
}
|
|
|
|
|
2022-11-28 13:39:47 +00:00
|
|
|
let finished_subscriber;
|
2024-05-12 21:16:56 +00:00
|
|
|
let subscriber = Registry::default();
|
|
|
|
|
|
|
|
// add optional layer provided by user
|
|
|
|
let subscriber = subscriber.with((self.custom_layer)(app));
|
|
|
|
|
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
|
|
|
let default_filter = { format!("{},{}", self.level, self.filter) };
|
2020-11-13 01:23:57 +00:00
|
|
|
let filter_layer = EnvFilter::try_from_default_env()
|
Improve error handling for log filter (#13897)
# Objective
This PR aims to improve error handling for log filters.
Closes #13850
## Solution
I changed the parsing of LogPlugin its filter to lossy, so that it
prints the directives with an error but does not skip them. I decided on
letting it gracefully handle the error instead of panicking to be
consistent with the parsing from an environment variable that it tries
to do before parsing it from the LogPlugin filter.
If the user decides to specify the filter by an environment variable, it
would silently fail and default to the LogPlugin filter value. It now
prints an error before defaulting to the LogPlugin filter value.
Unfortunately, I could not try and loosely set the filter from the
environment variable because the `tracing-subscriber` module does not
expose the function it uses to get the environment variable, and I would
rather not copy its code. We may want to check if the maintainers are
open to exposing the method.
## Testing
Consider the following bevy app, where the second of the 3 filters is
invalid:
```
use bevy::{log::LogPlugin, prelude::*};
fn main() {
App::new().add_plugins(DefaultPlugins
.set(LogPlugin {
filter: "wgpu=error,my_package=invalid_log_level,naga=warn".into(),
..default()
})
).run();
}
```
In the previous situation, it would panic with a non-descriptive error:
"called `Result::unwrap()` on an `Err` value: ParseError { kind:
Other(None) }", while only 1 of the 3 filters is invalid. When running
`cargo run`, it will now use the two valid filters and print an error on
the invalid filter.
> ignoring `my_package=invalid_log_level`: invalid filter directive
This error comes from `tracing-subscriber` and cannot be altered as far
as I can see.
To test setting the log filter through an environment variable, you can
use `RUST_LOG="wgpu=error,my_package=invalid_log_level,naga=warn" cargo
run` to run your app. In the previous situation it would silently fail
and use the LogPlugin filter. It will now print an error before using
the LogPlugin filter.
> LogPlugin failed to parse filter from env: invalid filter directive
## Changelog
- Added warning when using invalid filter in the RUST_LOG environment
variable
- Prevent the app from panicking when setting an invalid LogPlugin
filter
---------
Co-authored-by: Luc Drenth <luc.drenth@ing.com>
2024-06-19 13:46:03 +00:00
|
|
|
.or_else(|from_env_error| {
|
|
|
|
_ = from_env_error
|
|
|
|
.source()
|
|
|
|
.and_then(|source| source.downcast_ref::<ParseError>())
|
|
|
|
.map(|parse_err| {
|
|
|
|
// we cannot use the `error!` macro here because the logger is not ready yet.
|
|
|
|
eprintln!("LogPlugin failed to parse filter from env: {}", parse_err);
|
|
|
|
});
|
|
|
|
|
|
|
|
Ok::<EnvFilter, FromEnvError>(EnvFilter::builder().parse_lossy(&default_filter))
|
|
|
|
})
|
2020-11-13 01:23:57 +00:00
|
|
|
.unwrap();
|
2024-05-12 21:16:56 +00:00
|
|
|
let subscriber = subscriber.with(filter_layer);
|
2020-11-13 01:23:57 +00:00
|
|
|
|
2022-02-28 22:27:20 +00:00
|
|
|
#[cfg(feature = "trace")]
|
|
|
|
let subscriber = subscriber.with(tracing_error::ErrorLayer::default());
|
|
|
|
|
2024-10-11 08:58:14 +00:00
|
|
|
#[cfg(all(
|
|
|
|
not(target_arch = "wasm32"),
|
|
|
|
not(target_os = "android"),
|
|
|
|
not(target_os = "ios")
|
|
|
|
))]
|
2020-11-13 01:23:57 +00:00
|
|
|
{
|
|
|
|
#[cfg(feature = "tracing-chrome")]
|
Add trace_tracy feature for Tracy profiling (#2832)
# Objective
[Tracy](https://github.com/wolfpld/tracy) is:
> A real time, nanosecond resolution, remote telemetry, hybrid frame and sampling profiler for games and other applications.
With the `trace_tracy` feature enabled, you run your bevy app and either a headless server (`capture`) or a live, interactive profiler UI (`Tracy`), and connect that to your bevy application to then stream the metric data and events, and save it or inspect it live/offline.
Previously when I implemented the spans across systems and stages and I was trying out different profiling tools, Tracy was too unstable on macOS to use. But now, quite some months later, it is working stably with Tracy 0.7.8. You can see timelines, aggregate statistics of mean system/stage execution times, and much more. It's very useful!
![Screenshot_2021-09-15_at_18 07 19](https://user-images.githubusercontent.com/302146/133554920-350d3d45-fbb8-479f-91f7-7a7a4f9f5873.png)
## Solution
- Use the `tracing-tracy` crate which supports our tracing spans
- Expose via the non-default feature `trace_tracy` for consistency with other `trace*` features
2021-09-16 23:39:22 +00:00
|
|
|
let chrome_layer = {
|
2022-05-03 15:35:04 +00:00
|
|
|
let mut layer = tracing_chrome::ChromeLayerBuilder::new();
|
|
|
|
if let Ok(path) = std::env::var("TRACE_CHROME") {
|
|
|
|
layer = layer.file(path);
|
|
|
|
}
|
|
|
|
let (chrome_layer, guard) = layer
|
2020-12-03 00:14:02 +00:00
|
|
|
.name_fn(Box::new(|event_or_span| match event_or_span {
|
|
|
|
tracing_chrome::EventOrSpan::Event(event) => event.metadata().name().into(),
|
|
|
|
tracing_chrome::EventOrSpan::Span(span) => {
|
|
|
|
if let Some(fields) =
|
|
|
|
span.extensions().get::<FormattedFields<DefaultFields>>()
|
|
|
|
{
|
|
|
|
format!("{}: {}", span.metadata().name(), fields.fields.as_str())
|
|
|
|
} else {
|
|
|
|
span.metadata().name().into()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}))
|
|
|
|
.build();
|
2024-05-06 21:15:10 +00:00
|
|
|
app.insert_resource(FlushGuard(SyncCell::new(guard)));
|
Add trace_tracy feature for Tracy profiling (#2832)
# Objective
[Tracy](https://github.com/wolfpld/tracy) is:
> A real time, nanosecond resolution, remote telemetry, hybrid frame and sampling profiler for games and other applications.
With the `trace_tracy` feature enabled, you run your bevy app and either a headless server (`capture`) or a live, interactive profiler UI (`Tracy`), and connect that to your bevy application to then stream the metric data and events, and save it or inspect it live/offline.
Previously when I implemented the spans across systems and stages and I was trying out different profiling tools, Tracy was too unstable on macOS to use. But now, quite some months later, it is working stably with Tracy 0.7.8. You can see timelines, aggregate statistics of mean system/stage execution times, and much more. It's very useful!
![Screenshot_2021-09-15_at_18 07 19](https://user-images.githubusercontent.com/302146/133554920-350d3d45-fbb8-479f-91f7-7a7a4f9f5873.png)
## Solution
- Use the `tracing-tracy` crate which supports our tracing spans
- Expose via the non-default feature `trace_tracy` for consistency with other `trace*` features
2021-09-16 23:39:22 +00:00
|
|
|
chrome_layer
|
|
|
|
};
|
|
|
|
|
|
|
|
#[cfg(feature = "tracing-tracy")]
|
2024-02-03 21:44:38 +00:00
|
|
|
let tracy_layer = tracing_tracy::TracyLayer::default();
|
Add trace_tracy feature for Tracy profiling (#2832)
# Objective
[Tracy](https://github.com/wolfpld/tracy) is:
> A real time, nanosecond resolution, remote telemetry, hybrid frame and sampling profiler for games and other applications.
With the `trace_tracy` feature enabled, you run your bevy app and either a headless server (`capture`) or a live, interactive profiler UI (`Tracy`), and connect that to your bevy application to then stream the metric data and events, and save it or inspect it live/offline.
Previously when I implemented the spans across systems and stages and I was trying out different profiling tools, Tracy was too unstable on macOS to use. But now, quite some months later, it is working stably with Tracy 0.7.8. You can see timelines, aggregate statistics of mean system/stage execution times, and much more. It's very useful!
![Screenshot_2021-09-15_at_18 07 19](https://user-images.githubusercontent.com/302146/133554920-350d3d45-fbb8-479f-91f7-7a7a4f9f5873.png)
## Solution
- Use the `tracing-tracy` crate which supports our tracing spans
- Expose via the non-default feature `trace_tracy` for consistency with other `trace*` features
2021-09-16 23:39:22 +00:00
|
|
|
|
2024-06-24 21:04:55 +00:00
|
|
|
// note: the implementation of `Default` reads from the env var NO_COLOR
|
|
|
|
// to decide whether to use ANSI color codes, which is common convention
|
|
|
|
// https://no-color.org/
|
2023-06-19 23:36:02 +00:00
|
|
|
let fmt_layer = tracing_subscriber::fmt::Layer::default().with_writer(std::io::stderr);
|
2022-12-20 23:45:43 +00:00
|
|
|
|
|
|
|
// bevy_render::renderer logs a `tracy.frame_mark` event every frame
|
|
|
|
// at Level::INFO. Formatted logs should omit it.
|
2022-04-08 22:50:23 +00:00
|
|
|
#[cfg(feature = "tracing-tracy")]
|
2022-12-20 23:45:43 +00:00
|
|
|
let fmt_layer =
|
|
|
|
fmt_layer.with_filter(tracing_subscriber::filter::FilterFn::new(|meta| {
|
|
|
|
meta.fields().field("tracy.frame_mark").is_none()
|
|
|
|
}));
|
2022-04-08 22:50:23 +00:00
|
|
|
|
Add trace_tracy feature for Tracy profiling (#2832)
# Objective
[Tracy](https://github.com/wolfpld/tracy) is:
> A real time, nanosecond resolution, remote telemetry, hybrid frame and sampling profiler for games and other applications.
With the `trace_tracy` feature enabled, you run your bevy app and either a headless server (`capture`) or a live, interactive profiler UI (`Tracy`), and connect that to your bevy application to then stream the metric data and events, and save it or inspect it live/offline.
Previously when I implemented the spans across systems and stages and I was trying out different profiling tools, Tracy was too unstable on macOS to use. But now, quite some months later, it is working stably with Tracy 0.7.8. You can see timelines, aggregate statistics of mean system/stage execution times, and much more. It's very useful!
![Screenshot_2021-09-15_at_18 07 19](https://user-images.githubusercontent.com/302146/133554920-350d3d45-fbb8-479f-91f7-7a7a4f9f5873.png)
## Solution
- Use the `tracing-tracy` crate which supports our tracing spans
- Expose via the non-default feature `trace_tracy` for consistency with other `trace*` features
2021-09-16 23:39:22 +00:00
|
|
|
let subscriber = subscriber.with(fmt_layer);
|
|
|
|
|
|
|
|
#[cfg(feature = "tracing-chrome")]
|
|
|
|
let subscriber = subscriber.with(chrome_layer);
|
|
|
|
#[cfg(feature = "tracing-tracy")]
|
|
|
|
let subscriber = subscriber.with(tracy_layer);
|
2024-05-12 21:16:56 +00:00
|
|
|
finished_subscriber = subscriber;
|
2020-11-13 01:23:57 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#[cfg(target_arch = "wasm32")]
|
|
|
|
{
|
2022-11-28 13:39:47 +00:00
|
|
|
finished_subscriber = subscriber.with(tracing_wasm::WASMLayer::new(
|
2020-11-13 01:23:57 +00:00
|
|
|
tracing_wasm::WASMLayerConfig::default(),
|
|
|
|
));
|
|
|
|
}
|
|
|
|
|
|
|
|
#[cfg(target_os = "android")]
|
|
|
|
{
|
2022-11-28 13:39:47 +00:00
|
|
|
finished_subscriber = subscriber.with(android_tracing::AndroidLayer::default());
|
|
|
|
}
|
|
|
|
|
2024-10-11 08:58:14 +00:00
|
|
|
#[cfg(target_os = "ios")]
|
|
|
|
{
|
|
|
|
finished_subscriber = subscriber.with(tracing_oslog::OsLogger::default());
|
|
|
|
}
|
|
|
|
|
2022-11-28 13:39:47 +00:00
|
|
|
let logger_already_set = LogTracer::init().is_err();
|
|
|
|
let subscriber_already_set =
|
|
|
|
bevy_utils::tracing::subscriber::set_global_default(finished_subscriber).is_err();
|
|
|
|
|
|
|
|
match (logger_already_set, subscriber_already_set) {
|
2024-02-23 18:49:32 +00:00
|
|
|
(true, true) => error!(
|
2022-11-28 13:39:47 +00:00
|
|
|
"Could not set global logger and tracing subscriber as they are already set. Consider disabling LogPlugin."
|
|
|
|
),
|
2024-02-23 18:49:32 +00:00
|
|
|
(true, false) => error!("Could not set global logger as it is already set. Consider disabling LogPlugin."),
|
|
|
|
(false, true) => error!("Could not set global tracing subscriber as it is already set. Consider disabling LogPlugin."),
|
|
|
|
(false, false) => (),
|
2020-11-13 01:23:57 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|