add system information plugin and update relevant examples (#5911)
# Objective Solve #5464 ## Solution Adds a `SystemInformationDiagnosticsPlugin` to add diagnostics. Adds `Cargo.toml` flags to fix building on different platforms. --- ## Changelog Adds `sysinfo` crate to `bevy-diagnostics`. Changes in import order are due to clippy. Co-authored-by: l1npengtul <35755164+l1npengtul@users.noreply.github.com> Co-authored-by: IceSentry <c.giguere42@gmail.com>
This commit is contained in:
parent
b027d402e2
commit
290d6363b8
@ -2,13 +2,14 @@ mod diagnostic;
|
||||
mod entity_count_diagnostics_plugin;
|
||||
mod frame_time_diagnostics_plugin;
|
||||
mod log_diagnostics_plugin;
|
||||
use bevy_log::info;
|
||||
mod system_information_diagnostics_plugin;
|
||||
|
||||
use bevy_app::prelude::*;
|
||||
pub use diagnostic::*;
|
||||
pub use entity_count_diagnostics_plugin::EntityCountDiagnosticsPlugin;
|
||||
pub use frame_time_diagnostics_plugin::FrameTimeDiagnosticsPlugin;
|
||||
pub use log_diagnostics_plugin::LogDiagnosticsPlugin;
|
||||
|
||||
use bevy_app::prelude::*;
|
||||
pub use system_information_diagnostics_plugin::SystemInformationDiagnosticsPlugin;
|
||||
|
||||
/// Adds core diagnostics resources to an App.
|
||||
#[derive(Default)]
|
||||
@ -17,61 +18,10 @@ pub struct DiagnosticsPlugin;
|
||||
impl Plugin for DiagnosticsPlugin {
|
||||
fn build(&self, app: &mut App) {
|
||||
app.init_resource::<Diagnostics>()
|
||||
.add_startup_system(log_system_info);
|
||||
.add_startup_system(system_information_diagnostics_plugin::internal::log_system_info);
|
||||
}
|
||||
}
|
||||
|
||||
/// The width which diagnostic names will be printed as
|
||||
/// Plugin names should not be longer than this value
|
||||
pub const MAX_DIAGNOSTIC_NAME_WIDTH: usize = 32;
|
||||
|
||||
#[derive(Debug)]
|
||||
// This is required because the Debug trait doesn't detect it's used when it's only used in a print :(
|
||||
#[allow(dead_code)]
|
||||
struct SystemInfo {
|
||||
os: String,
|
||||
kernel: String,
|
||||
cpu: String,
|
||||
core_count: String,
|
||||
memory: String,
|
||||
}
|
||||
|
||||
const BYTES_TO_GIB: f64 = 1.0 / 1024.0 / 1024.0 / 1024.0;
|
||||
|
||||
fn log_system_info() {
|
||||
// NOTE: sysinfo fails to compile when using bevy dynamic or on iOS and does nothing on wasm
|
||||
#[cfg(all(
|
||||
any(
|
||||
target_os = "linux",
|
||||
target_os = "windows",
|
||||
target_os = "android",
|
||||
target_os = "macos"
|
||||
),
|
||||
not(feature = "bevy_dynamic_plugin")
|
||||
))]
|
||||
{
|
||||
use sysinfo::{CpuExt, SystemExt};
|
||||
|
||||
let mut sys = sysinfo::System::new();
|
||||
sys.refresh_cpu();
|
||||
sys.refresh_memory();
|
||||
|
||||
let info = SystemInfo {
|
||||
os: sys
|
||||
.long_os_version()
|
||||
.unwrap_or_else(|| String::from("not available")),
|
||||
kernel: sys
|
||||
.kernel_version()
|
||||
.unwrap_or_else(|| String::from("not available")),
|
||||
cpu: sys.global_cpu_info().brand().trim().to_string(),
|
||||
core_count: sys
|
||||
.physical_core_count()
|
||||
.map(|x| x.to_string())
|
||||
.unwrap_or_else(|| String::from("not available")),
|
||||
// Convert from Bytes to GibiBytes since it's probably what people expect most of the time
|
||||
memory: format!("{:.1} GiB", sys.total_memory() as f64 * BYTES_TO_GIB),
|
||||
};
|
||||
|
||||
info!("{:?}", info);
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,159 @@
|
||||
use crate::DiagnosticId;
|
||||
use bevy_app::{App, Plugin};
|
||||
|
||||
/// Adds a System Information Diagnostic, specifically `cpu_usage` (in %) and `mem_usage` (in %)
|
||||
///
|
||||
/// Supported targets:
|
||||
/// * linux,
|
||||
/// * windows,
|
||||
/// * android,
|
||||
/// * macos
|
||||
///
|
||||
/// NOT supported when using the `bevy/dynamic` feature even when using previously mentioned targets
|
||||
#[derive(Default)]
|
||||
pub struct SystemInformationDiagnosticsPlugin;
|
||||
impl Plugin for SystemInformationDiagnosticsPlugin {
|
||||
fn build(&self, app: &mut App) {
|
||||
app.add_startup_system(internal::setup_system)
|
||||
.add_system(internal::diagnostic_system);
|
||||
}
|
||||
}
|
||||
|
||||
impl SystemInformationDiagnosticsPlugin {
|
||||
pub const CPU_USAGE: DiagnosticId =
|
||||
DiagnosticId::from_u128(78494871623549551581510633532637320956);
|
||||
pub const MEM_USAGE: DiagnosticId =
|
||||
DiagnosticId::from_u128(42846254859293759601295317811892519825);
|
||||
}
|
||||
|
||||
// NOTE: sysinfo fails to compile when using bevy dynamic or on iOS and does nothing on wasm
|
||||
#[cfg(all(
|
||||
any(
|
||||
target_os = "linux",
|
||||
target_os = "windows",
|
||||
target_os = "android",
|
||||
target_os = "macos"
|
||||
),
|
||||
not(feature = "bevy_dynamic_plugin")
|
||||
))]
|
||||
pub mod internal {
|
||||
use bevy_ecs::{prelude::ResMut, system::Local};
|
||||
use bevy_log::info;
|
||||
use sysinfo::{CpuExt, System, SystemExt};
|
||||
|
||||
use crate::{Diagnostic, Diagnostics};
|
||||
|
||||
const BYTES_TO_GIB: f64 = 1.0 / 1024.0 / 1024.0 / 1024.0;
|
||||
|
||||
pub(crate) fn setup_system(mut diagnostics: ResMut<Diagnostics>) {
|
||||
diagnostics.add(
|
||||
Diagnostic::new(
|
||||
super::SystemInformationDiagnosticsPlugin::CPU_USAGE,
|
||||
"cpu_usage",
|
||||
20,
|
||||
)
|
||||
.with_suffix("%"),
|
||||
);
|
||||
diagnostics.add(
|
||||
Diagnostic::new(
|
||||
super::SystemInformationDiagnosticsPlugin::MEM_USAGE,
|
||||
"mem_usage",
|
||||
20,
|
||||
)
|
||||
.with_suffix("%"),
|
||||
);
|
||||
}
|
||||
|
||||
pub(crate) fn diagnostic_system(
|
||||
mut diagnostics: ResMut<Diagnostics>,
|
||||
mut sysinfo: Local<Option<System>>,
|
||||
) {
|
||||
if sysinfo.is_none() {
|
||||
*sysinfo = Some(System::new_all());
|
||||
}
|
||||
let Some(sys) = sysinfo.as_mut() else {
|
||||
return;
|
||||
};
|
||||
|
||||
sys.refresh_cpu();
|
||||
sys.refresh_memory();
|
||||
let current_cpu_usage = {
|
||||
let mut usage = 0.0;
|
||||
let cpus = sys.cpus();
|
||||
for cpu in cpus {
|
||||
usage += cpu.cpu_usage(); // NOTE: this returns a value from 0.0 to 100.0
|
||||
}
|
||||
// average
|
||||
usage / cpus.len() as f32
|
||||
};
|
||||
// `memory()` fns return a value in bytes
|
||||
let total_mem = sys.total_memory() as f64 / BYTES_TO_GIB;
|
||||
let used_mem = sys.used_memory() as f64 / BYTES_TO_GIB;
|
||||
let current_used_mem = used_mem / total_mem * 100.0;
|
||||
|
||||
diagnostics.add_measurement(super::SystemInformationDiagnosticsPlugin::CPU_USAGE, || {
|
||||
current_cpu_usage as f64
|
||||
});
|
||||
diagnostics.add_measurement(super::SystemInformationDiagnosticsPlugin::MEM_USAGE, || {
|
||||
current_used_mem
|
||||
});
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
// This is required because the Debug trait doesn't detect it's used when it's only used in a print :(
|
||||
#[allow(dead_code)]
|
||||
struct SystemInfo {
|
||||
os: String,
|
||||
kernel: String,
|
||||
cpu: String,
|
||||
core_count: String,
|
||||
memory: String,
|
||||
}
|
||||
|
||||
pub(crate) fn log_system_info() {
|
||||
let mut sys = sysinfo::System::new();
|
||||
sys.refresh_cpu();
|
||||
sys.refresh_memory();
|
||||
|
||||
let info = SystemInfo {
|
||||
os: sys
|
||||
.long_os_version()
|
||||
.unwrap_or_else(|| String::from("not available")),
|
||||
kernel: sys
|
||||
.kernel_version()
|
||||
.unwrap_or_else(|| String::from("not available")),
|
||||
cpu: sys.global_cpu_info().brand().trim().to_string(),
|
||||
core_count: sys
|
||||
.physical_core_count()
|
||||
.map(|x| x.to_string())
|
||||
.unwrap_or_else(|| String::from("not available")),
|
||||
// Convert from Bytes to GibiBytes since it's probably what people expect most of the time
|
||||
memory: format!("{:.1} GiB", sys.total_memory() as f64 * BYTES_TO_GIB),
|
||||
};
|
||||
|
||||
info!("{:?}", info);
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(all(
|
||||
any(
|
||||
target_os = "linux",
|
||||
target_os = "windows",
|
||||
target_os = "android",
|
||||
target_os = "macos"
|
||||
),
|
||||
not(feature = "bevy_dynamic_plugin")
|
||||
)))]
|
||||
pub mod internal {
|
||||
pub(crate) fn setup_system() {
|
||||
bevy_log::warn!("This platform and/or configuration is not supported!");
|
||||
}
|
||||
|
||||
pub(crate) fn diagnostic_system() {
|
||||
// no-op
|
||||
}
|
||||
|
||||
pub(crate) fn log_system_info() {
|
||||
// no-op
|
||||
}
|
||||
}
|
@ -17,5 +17,7 @@ fn main() {
|
||||
// .add_plugin(bevy::diagnostic::EntityCountDiagnosticsPlugin::default())
|
||||
// Uncomment this to add an asset count diagnostics:
|
||||
// .add_plugin(bevy::asset::diagnostic::AssetCountDiagnosticsPlugin::<Texture>::default())
|
||||
// Uncomment this to add system info diagnostics:
|
||||
// .add_plugin(bevy::diagnostic::SystemInformationDiagnosticsPlugin::default())
|
||||
.run();
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user