Make SystemInfo a Resource (#12584)

# Objective

We already collect a lot of system information on startup when possible
but we don't make this information available. With the upcoming work on
a diagnostic overlay it would be useful to be able to display this
information.

## Solution

Make the already existing SystemInfo a Resource

---

## Changelog

Added `SystemInfo` Resource

---------

Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
Co-authored-by: Afonso Lage <lage.afonso@gmail.com>
This commit is contained in:
IceSentry 2024-03-23 02:16:02 -04:00 committed by GitHub
parent 34c8778bf0
commit 85b488b73d
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 60 additions and 42 deletions

View file

@ -19,7 +19,7 @@ pub use entity_count_diagnostics_plugin::EntityCountDiagnosticsPlugin;
pub use frame_time_diagnostics_plugin::FrameTimeDiagnosticsPlugin;
pub use log_diagnostics_plugin::LogDiagnosticsPlugin;
#[cfg(feature = "sysinfo_plugin")]
pub use system_information_diagnostics_plugin::SystemInformationDiagnosticsPlugin;
pub use system_information_diagnostics_plugin::{SystemInfo, SystemInformationDiagnosticsPlugin};
use bevy_app::prelude::*;
@ -28,12 +28,11 @@ use bevy_app::prelude::*;
pub struct DiagnosticsPlugin;
impl Plugin for DiagnosticsPlugin {
fn build(&self, _app: &mut App) {
fn build(&self, app: &mut App) {
app.init_resource::<DiagnosticsStore>();
#[cfg(feature = "sysinfo_plugin")]
_app.init_resource::<DiagnosticsStore>().add_systems(
Startup,
system_information_diagnostics_plugin::internal::log_system_info,
);
app.init_resource::<system_information_diagnostics_plugin::SystemInfo>();
}
}

View file

@ -1,5 +1,6 @@
use crate::DiagnosticPath;
use bevy_app::prelude::*;
use bevy_ecs::system::Resource;
/// Adds a System Information Diagnostic, specifically `cpu_usage` (in %) and `mem_usage` (in %)
///
@ -24,10 +25,27 @@ impl Plugin for SystemInformationDiagnosticsPlugin {
}
impl SystemInformationDiagnosticsPlugin {
/// Total system cpu usage in %
pub const CPU_USAGE: DiagnosticPath = DiagnosticPath::const_new("system/cpu_usage");
/// Total system memory usage in %
pub const MEM_USAGE: DiagnosticPath = DiagnosticPath::const_new("system/mem_usage");
}
/// A resource that stores diagnostic information about the system.
/// This information can be useful for debugging and profiling purposes.
///
/// # See also
///
/// [`SystemInformationDiagnosticsPlugin`] for more information.
#[derive(Debug, Resource)]
pub struct SystemInfo {
pub os: String,
pub kernel: String,
pub cpu: String,
pub core_count: String,
pub memory: String,
}
// NOTE: sysinfo fails to compile when using bevy dynamic or on iOS and does nothing on wasm
#[cfg(all(
any(
@ -45,7 +63,7 @@ pub mod internal {
use crate::{Diagnostic, Diagnostics, DiagnosticsStore};
use super::SystemInformationDiagnosticsPlugin;
use super::{SystemInfo, SystemInformationDiagnosticsPlugin};
const BYTES_TO_GIB: f64 = 1.0 / 1024.0 / 1024.0 / 1024.0;
@ -87,41 +105,33 @@ pub mod internal {
});
}
#[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,
}
impl Default for SystemInfo {
fn default() -> Self {
let sys = System::new_with_specifics(
RefreshKind::new()
.with_cpu(CpuRefreshKind::new())
.with_memory(MemoryRefreshKind::new().with_ram()),
);
pub(crate) fn log_system_info() {
let sys = System::new_with_specifics(
RefreshKind::new()
.with_cpu(CpuRefreshKind::new())
.with_memory(MemoryRefreshKind::new().with_ram()),
);
let system_info = SystemInfo {
os: System::long_os_version().unwrap_or_else(|| String::from("not available")),
kernel: System::kernel_version().unwrap_or_else(|| String::from("not available")),
cpu: sys
.cpus()
.first()
.map(|cpu| cpu.brand().trim().to_string())
.unwrap_or_else(|| String::from("not available")),
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),
};
let info = SystemInfo {
os: System::long_os_version().unwrap_or_else(|| String::from("not available")),
kernel: System::kernel_version().unwrap_or_else(|| String::from("not available")),
cpu: sys
.cpus()
.first()
.map(|cpu| cpu.brand().trim().to_string())
.unwrap_or_else(|| String::from("not available")),
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);
info!("{:?}", system_info);
system_info
}
}
}
@ -143,7 +153,16 @@ pub mod internal {
// no-op
}
pub(crate) fn log_system_info() {
// no-op
impl Default for super::SystemInfo {
fn default() -> Self {
let unknown = "Unknown".to_string();
Self {
os: unknown.clone(),
kernel: unknown.clone(),
cpu: unknown.clone(),
core_count: unknown.clone(),
memory: unknown.clone(),
}
}
}
}