NetDesk 1.5.0 — source release
This commit is contained in:
commit
ec4955682f
227 files changed
+80669
No files matched your search
@@ -0,0 +1,118 @@
|
||||
//! Lightweight host metrics (CPU %, RAM, disk, battery, uptime) for the portal's
|
||||
//! live monitoring. Windows-only; sampled every few seconds by the engine and
|
||||
//! pushed to the server as a `host.telemetry` control message.
|
||||
#![cfg(windows)]
|
||||
|
||||
use serde_json::{json, Value};
|
||||
|
||||
/// Keeps the previous CPU time sample so each `sample()` yields a real % over
|
||||
/// the interval since the last call.
|
||||
pub struct Telemetry {
|
||||
prev_idle: u64,
|
||||
prev_total: u64,
|
||||
}
|
||||
|
||||
impl Telemetry {
|
||||
pub fn new() -> Self {
|
||||
Self { prev_idle: 0, prev_total: 0 }
|
||||
}
|
||||
|
||||
pub fn sample(&mut self) -> Value {
|
||||
let cpu = self.cpu_percent();
|
||||
let (ram_used, ram_total) = mem();
|
||||
let (disk_used, disk_total) = disk();
|
||||
let (battery, charging) = power();
|
||||
json!({
|
||||
"t": "host.telemetry",
|
||||
"cpu": cpu,
|
||||
"ram_used": ram_used, "ram_total": ram_total,
|
||||
"disk_used": disk_used, "disk_total": disk_total,
|
||||
"battery": battery, "charging": charging,
|
||||
"uptime": uptime_secs(),
|
||||
})
|
||||
}
|
||||
|
||||
fn cpu_percent(&mut self) -> u32 {
|
||||
use windows::Win32::Foundation::FILETIME;
|
||||
use windows::Win32::System::Threading::GetSystemTimes;
|
||||
unsafe {
|
||||
let mut idle = FILETIME::default();
|
||||
let mut kern = FILETIME::default();
|
||||
let mut user = FILETIME::default();
|
||||
if GetSystemTimes(Some(&mut idle), Some(&mut kern), Some(&mut user)).is_err() {
|
||||
return 0;
|
||||
}
|
||||
let ft = |f: FILETIME| ((f.dwHighDateTime as u64) << 32) | f.dwLowDateTime as u64;
|
||||
let idle_t = ft(idle);
|
||||
// Kernel time INCLUDES idle, so kernel+user is the full busy+idle total.
|
||||
let total_t = ft(kern) + ft(user);
|
||||
let d_total = total_t.saturating_sub(self.prev_total);
|
||||
let d_idle = idle_t.saturating_sub(self.prev_idle);
|
||||
self.prev_total = total_t;
|
||||
self.prev_idle = idle_t;
|
||||
if d_total == 0 {
|
||||
return 0;
|
||||
}
|
||||
let busy = d_total.saturating_sub(d_idle);
|
||||
((busy as f64 / d_total as f64) * 100.0).round().clamp(0.0, 100.0) as u32
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn mem() -> (u64, u64) {
|
||||
use windows::Win32::System::SystemInformation::{GlobalMemoryStatusEx, MEMORYSTATUSEX};
|
||||
unsafe {
|
||||
let mut m = MEMORYSTATUSEX {
|
||||
dwLength: std::mem::size_of::<MEMORYSTATUSEX>() as u32,
|
||||
..Default::default()
|
||||
};
|
||||
if GlobalMemoryStatusEx(&mut m).is_ok() {
|
||||
(m.ullTotalPhys.saturating_sub(m.ullAvailPhys), m.ullTotalPhys)
|
||||
} else {
|
||||
(0, 0)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn disk() -> (u64, u64) {
|
||||
use windows::core::PCWSTR;
|
||||
use windows::Win32::Storage::FileSystem::GetDiskFreeSpaceExW;
|
||||
unsafe {
|
||||
let path: Vec<u16> = "C:\\".encode_utf16().chain(std::iter::once(0)).collect();
|
||||
let mut free_avail = 0u64;
|
||||
let mut total = 0u64;
|
||||
let mut total_free = 0u64;
|
||||
if GetDiskFreeSpaceExW(
|
||||
PCWSTR(path.as_ptr()),
|
||||
Some(&mut free_avail),
|
||||
Some(&mut total),
|
||||
Some(&mut total_free),
|
||||
)
|
||||
.is_ok()
|
||||
{
|
||||
(total.saturating_sub(total_free), total)
|
||||
} else {
|
||||
(0, 0)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn power() -> (i32, bool) {
|
||||
use windows::Win32::System::Power::GetSystemPowerStatus;
|
||||
use windows::Win32::System::Power::SYSTEM_POWER_STATUS;
|
||||
unsafe {
|
||||
let mut s = SYSTEM_POWER_STATUS::default();
|
||||
if GetSystemPowerStatus(&mut s).is_ok() {
|
||||
let pct = if s.BatteryLifePercent == 255 { -1 } else { s.BatteryLifePercent as i32 };
|
||||
let charging = s.ACLineStatus == 1; // 1 = plugged in
|
||||
(pct, charging)
|
||||
} else {
|
||||
(-1, true)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn uptime_secs() -> u64 {
|
||||
use windows::Win32::System::SystemInformation::GetTickCount64;
|
||||
unsafe { GetTickCount64() / 1000 }
|
||||
}
|
||||
Reference in new issue
Block a user