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

[Merged by Bors] - add system information plugin and update relevant examples #5911

Closed
wants to merge 21 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
59ec59c
add system information plugin and update relevant examples
l1npengtul Sep 8, 2022
b7c5680
fix docs and typo
l1npengtul Sep 8, 2022
0059b34
Merge branch 'main' into sys-usage-info
l1npengtul Dec 1, 2022
ca5b05a
Merge branch 'bevyengine:main' into sys-usage-info
l1npengtul Dec 2, 2022
19b6f31
fix messed up cargo toml
l1npengtul Dec 2, 2022
28dee0e
Update crates/bevy_diagnostic/src/system_information_diagnostics_plug…
l1npengtul Dec 3, 2022
a110617
Merge branch 'bevyengine:main' into sys-usage-info
l1npengtul Dec 23, 2022
c008554
simplify cargo toml according to 5454
l1npengtul Dec 23, 2022
38e8442
implement suggestions, remove sus (very sad)
l1npengtul Dec 23, 2022
2792d23
Merge branch 'main' into sys-usage-info
l1npengtul Dec 28, 2022
e9d174a
add ghost plugin
l1npengtul Dec 28, 2022
d6695eb
fix compile error, let me out of HS omori
l1npengtul Dec 28, 2022
a2f20bc
add warning about unsupporoted platforms on doc for plugin
l1npengtul Dec 28, 2022
08b5295
madotsuki you forgot to derive madotsuki no dont go to the balcony
l1npengtul Dec 28, 2022
7fc4b25
sunny removes the unused import warningand fixes the nonexistant syst…
l1npengtul Dec 28, 2022
1ae255e
add back #bevy
l1npengtul Dec 28, 2022
59f3e4c
remove code duplication
IceSentry Dec 30, 2022
b37721a
clean up
IceSentry Dec 30, 2022
888c26c
Merge pull request #1 from IceSentry/log-sysinfo-usage
l1npengtul Dec 30, 2022
c51e9fc
fix cfg sys usage
IceSentry Jan 2, 2023
4cc8ab7
Merge pull request #2 from IceSentry/fix-sysuage-info
l1npengtul Jan 2, 2023
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
60 changes: 5 additions & 55 deletions crates/bevy_diagnostic/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)]
Expand All @@ -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);
}
}
159 changes: 159 additions & 0 deletions crates/bevy_diagnostic/src/system_information_diagnostics_plugin.rs
Original file line number Diff line number Diff line change
@@ -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
}
}
2 changes: 2 additions & 0 deletions examples/diagnostics/log_diagnostics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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();
}