Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix cfg sys usage #2

Merged
merged 1 commit into from
Jan 2, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
}
}