Skip to content

Commit

Permalink
Merge pull request #2 from IceSentry/fix-sysuage-info
Browse files Browse the repository at this point in the history
fix cfg sys usage
  • Loading branch information
l1npengtul authored Jan 2, 2023
2 parents 888c26c + c51e9fc commit 4cc8ab7
Show file tree
Hide file tree
Showing 2 changed files with 119 additions and 109 deletions.
54 changes: 1 addition & 53 deletions crates/bevy_diagnostic/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,62 +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 bevy_log::info;
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);
}
}
174 changes: 118 additions & 56 deletions crates/bevy_diagnostic/src/system_information_diagnostics_plugin.rs
Original file line number Diff line number Diff line change
@@ -1,20 +1,5 @@
use crate::{Diagnostic, DiagnosticId, Diagnostics, BYTES_TO_GIB};
use crate::DiagnosticId;
use bevy_app::{App, Plugin};
use bevy_ecs::prelude::{ResMut, Resource};
use sysinfo::{CpuExt, System, SystemExt};

#[derive(Resource)]
pub struct SystemInfoResource {
pub sys: System,
}

impl Default for SystemInfoResource {
fn default() -> Self {
SystemInfoResource {
sys: System::new_all(),
}
}
}

/// Adds a System Information Diagnostic, specifically `cpu_usage` (in %) and `mem_usage` (in %)
///
Expand All @@ -27,36 +12,10 @@ impl Default for SystemInfoResource {
/// 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) {
// 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")
))]
{
app.insert_resource(SystemInfoResource::default());
app.add_startup_system(Self::setup_system)
.add_system(Self::diagnostic_system);
}
#[cfg(not(all(
any(
target_os = "linux",
target_os = "windows",
target_os = "android",
target_os = "macos"
),
not(feature = "bevy_dynamic_plugin")
)))]
{
bevy_log::warn!("This platform and/or configuration is not supported!")
}
app.add_startup_system(internal::setup_system)
.add_system(internal::diagnostic_system);
}
}

Expand All @@ -65,33 +24,136 @@ impl SystemInformationDiagnosticsPlugin {
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};

pub fn setup_system(mut diagnostics: ResMut<Diagnostics>) {
diagnostics.add(Diagnostic::new(Self::CPU_USAGE, "cpu_usage", 20).with_suffix("%"));
diagnostics.add(Diagnostic::new(Self::MEM_USAGE, "mem_usage", 20).with_suffix("%"));
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 fn diagnostic_system(
pub(crate) fn diagnostic_system(
mut diagnostics: ResMut<Diagnostics>,
mut sysinfo: ResMut<SystemInfoResource>,
mut sysinfo: Local<Option<System>>,
) {
sysinfo.sys.refresh_cpu();
sysinfo.sys.refresh_memory();
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 = sysinfo.sys.cpus();
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 = sysinfo.sys.total_memory() as f64 / BYTES_TO_GIB;
let used_mem = sysinfo.sys.used_memory() as f64 / BYTES_TO_GIB;
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(Self::CPU_USAGE, || current_cpu_usage as f64);
diagnostics.add_measurement(Self::MEM_USAGE, || current_used_mem);
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
}
}

0 comments on commit 4cc8ab7

Please sign in to comment.