From 24e35597d458986cd7b36b66ebb1efbf6207f9aa Mon Sep 17 00:00:00 2001 From: IceSentry Date: Mon, 26 Dec 2022 15:16:46 +0000 Subject: [PATCH] log system info on startup (#5454) # Objective - We already log the adapter info on startup when bevy_render is present. It would be nice to have more info about the system to be able to ask users to submit it in bug reports ## Solution - Use the `sysinfo` crate to get all the information - I made sure it _only_ gets the required informations to avoid unnecessary system request - Add a system that logs this on startup - This system is currently in `bevy_diagnostics` because I didn't really know where to put it. Here's an example log from my system: ```log INFO bevy_diagnostic: SystemInformation { os: "Windows 10 Pro", kernel: "19044", cpu: "AMD Ryzen 7 5800X 8-Core Processor", core_count: "8", memory: "34282242 KB" } ``` --- ## Changelog - Added a new default log when starting a bevy app that logs the system information --- crates/bevy_diagnostic/Cargo.toml | 11 +++++++ crates/bevy_diagnostic/src/lib.rs | 55 ++++++++++++++++++++++++++++++- 2 files changed, 65 insertions(+), 1 deletion(-) diff --git a/crates/bevy_diagnostic/Cargo.toml b/crates/bevy_diagnostic/Cargo.toml index 2b8a1f2fa0a29c..7bd1249cbefaa9 100644 --- a/crates/bevy_diagnostic/Cargo.toml +++ b/crates/bevy_diagnostic/Cargo.toml @@ -17,3 +17,14 @@ bevy_ecs = { path = "../bevy_ecs", version = "0.9.0" } bevy_log = { path = "../bevy_log", version = "0.9.0" } bevy_time = { path = "../bevy_time", version = "0.9.0" } bevy_utils = { path = "../bevy_utils", version = "0.9.0" } + +# MacOS +[target.'cfg(all(target_os="macos"))'.dependencies] +# Some features of sysinfo are not supported by apple. This will disable those features on apple devices +sysinfo = { version = "0.27.1", default-features = false, features = [ + "apple-app-store", +] } + +# Only include when not bevy_dynamic_plugin and on linux/windows/android +[target.'cfg(any(target_os = "linux", target_os = "windows", target_os = "android"))'.dependencies] +sysinfo = { version = "0.27.1", default-features = false } diff --git a/crates/bevy_diagnostic/src/lib.rs b/crates/bevy_diagnostic/src/lib.rs index 076618bcde060b..5cef8389ac0929 100644 --- a/crates/bevy_diagnostic/src/lib.rs +++ b/crates/bevy_diagnostic/src/lib.rs @@ -2,6 +2,7 @@ mod diagnostic; mod entity_count_diagnostics_plugin; mod frame_time_diagnostics_plugin; mod log_diagnostics_plugin; +use bevy_log::info; pub use diagnostic::*; pub use entity_count_diagnostics_plugin::EntityCountDiagnosticsPlugin; pub use frame_time_diagnostics_plugin::FrameTimeDiagnosticsPlugin; @@ -15,10 +16,62 @@ pub struct DiagnosticsPlugin; impl Plugin for DiagnosticsPlugin { fn build(&self, app: &mut App) { - app.init_resource::(); + app.init_resource::() + .add_startup_system(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); + } +}