This commit is contained in:
mbecker20
2023-01-11 08:42:09 +00:00
parent f885398d7c
commit 4fb3eb12ba
19 changed files with 301 additions and 73 deletions

36
Cargo.lock generated
View File

@@ -408,8 +408,8 @@ dependencies = [
"hex",
"hmac",
"jwt",
"monitor_helpers 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
"monitor_types 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
"monitor_helpers 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
"monitor_types 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
"mungos",
"periphery_client",
"serde",
@@ -647,7 +647,7 @@ name = "db_client"
version = "0.1.4"
dependencies = [
"anyhow",
"monitor_types 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
"monitor_types 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
"mungos",
]
@@ -1472,7 +1472,7 @@ dependencies = [
[[package]]
name = "monitor_cli"
version = "0.1.4"
version = "0.1.5"
dependencies = [
"async_timing_util",
"clap",
@@ -1488,11 +1488,11 @@ dependencies = [
[[package]]
name = "monitor_client"
version = "0.1.4"
version = "0.1.5"
dependencies = [
"anyhow",
"futures-util",
"monitor_types 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
"monitor_types 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
"reqwest",
"serde",
"serde_derive",
@@ -1504,7 +1504,7 @@ dependencies = [
[[package]]
name = "monitor_helpers"
version = "0.1.4"
version = "0.1.5"
dependencies = [
"anyhow",
"async_timing_util",
@@ -1512,7 +1512,7 @@ dependencies = [
"bollard",
"futures",
"futures-util",
"monitor_types 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
"monitor_types 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
"rand",
"run_command",
"serde",
@@ -1523,9 +1523,9 @@ dependencies = [
[[package]]
name = "monitor_helpers"
version = "0.1.4"
version = "0.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "048843e188f7658059225caf86bba7d866e5f0d3c4a1deadbb1c9bb9c9991914"
checksum = "3bd93c7b3cc694e97bd465b0aeee9ae469abf034f12ec29fcc8c8a3de9fd3734"
dependencies = [
"anyhow",
"async_timing_util",
@@ -1533,7 +1533,7 @@ dependencies = [
"bollard",
"futures",
"futures-util",
"monitor_types 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
"monitor_types 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
"rand",
"run_command",
"serde",
@@ -1555,8 +1555,8 @@ dependencies = [
"dotenv",
"envy",
"futures-util",
"monitor_helpers 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
"monitor_types 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
"monitor_helpers 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
"monitor_types 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
"run_command",
"serde",
"serde_derive",
@@ -1570,7 +1570,7 @@ dependencies = [
[[package]]
name = "monitor_types"
version = "0.1.4"
version = "0.1.5"
dependencies = [
"anyhow",
"bollard",
@@ -1587,9 +1587,9 @@ dependencies = [
[[package]]
name = "monitor_types"
version = "0.1.4"
version = "0.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "45486f7899a0b71dedc06aba7a6a37186a5563d3ea24efc29d35820e14534e46"
checksum = "58e0d8bdd2e64ed2d4253d69ec0816b57205c5f4fc0a831aa0a4ce3b0122a006"
dependencies = [
"anyhow",
"bollard",
@@ -1843,8 +1843,8 @@ version = "0.1.4"
dependencies = [
"anyhow",
"futures-util",
"monitor_helpers 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
"monitor_types 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
"monitor_helpers 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
"monitor_types 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
"reqwest",
"serde",
"serde_json",

View File

@@ -1,6 +1,6 @@
[package]
name = "monitor_cli"
version = "0.1.4"
version = "0.1.5"
edition = "2021"
authors = ["MoghTech"]
description = "monitor cli | tools to setup monitor system"

View File

@@ -8,8 +8,8 @@ edition = "2021"
[dependencies]
# helpers = { package = "monitor_helpers", path = "../lib/helpers" }
# types = { package = "monitor_types", path = "../lib/types" }
helpers = { package = "monitor_helpers", version = "0.1.4" }
types = { package = "monitor_types", version = "0.1.4" }
helpers = { package = "monitor_helpers", version = "0.1.5" }
types = { package = "monitor_types", version = "0.1.5" }
db = { package = "db_client", path = "../lib/db_client" }
periphery = { package = "periphery_client", path = "../lib/periphery_client" }
axum_oauth2 = { path = "../lib/axum_oauth2" }

View File

@@ -14,8 +14,8 @@ use tokio_tungstenite::tungstenite::Message;
use tokio_util::sync::CancellationToken;
use types::{
traits::Permissioned, BasicContainerInfo, HistoricalStatsQuery, ImageSummary, Network,
PermissionLevel, Server, ServerActionState, ServerStatus, ServerWithStatus, SystemStats,
SystemStatsQuery, SystemStatsRecord,
PermissionLevel, Server, ServerActionState, ServerStatus, ServerWithStatus, SystemInformation,
SystemStats, SystemStatsQuery, SystemStatsRecord,
};
use typeshare::typeshare;
@@ -132,6 +132,34 @@ pub fn router() -> Router {
},
),
)
.route(
"/:id/version",
get(
|state: StateExtension,
user: RequestUserExtension,
Path(ServerId { id })| async move {
let stats = state
.get_server_version(&id, &user)
.await
.map_err(handle_anyhow_error)?;
response!(Json(stats))
},
),
)
.route(
"/:id/system_information",
get(
|state: StateExtension,
user: RequestUserExtension,
Path(ServerId { id })| async move {
let stats = state
.get_server_system_info(&id, &user)
.await
.map_err(handle_anyhow_error)?;
response!(Json(stats))
},
),
)
.route(
"/:id/stats",
get(
@@ -380,6 +408,40 @@ impl State {
Ok(join_all(futures).await)
}
async fn get_server_version(
&self,
server_id: &str,
user: &RequestUser,
) -> anyhow::Result<String> {
let server = self
.get_server_check_permissions(server_id, user, PermissionLevel::Read)
.await?;
let version = self.periphery.get_version(&server).await.context(format!(
"failed to get system information from server {}",
server.name
))?;
Ok(version)
}
async fn get_server_system_info(
&self,
server_id: &str,
user: &RequestUser,
) -> anyhow::Result<SystemInformation> {
let server = self
.get_server_check_permissions(server_id, user, PermissionLevel::Read)
.await?;
let stats = self
.periphery
.get_system_information(&server)
.await
.context(format!(
"failed to get system information from server {}",
server.name
))?;
Ok(stats)
}
async fn get_server_stats(
&self,
server_id: &str,

View File

@@ -8,6 +8,8 @@ const Grid: Component<
placeItems?: string;
style?: JSX.CSSProperties;
class?: string;
gridTemplateRows?: string;
gridTemplateColumns?: string;
} & JSX.HTMLAttributes<HTMLDivElement>
> = (p) => {
return (
@@ -17,6 +19,8 @@ const Grid: Component<
style={{
gap: p.gap,
"place-items": p.placeItems,
"grid-template-rows": p.gridTemplateRows,
"grid-template-columns": p.gridTemplateColumns,
...(p.style as any),
}}
>

View File

@@ -38,8 +38,8 @@ const Stats: Component<{}> = () => {
const [wsOpen, setWsOpen] = createSignal(false);
return (
<Grid class={s.Content}>
<Grid class={s.HeaderArea} placeItems="center start">
<Header view={view()} open={wsOpen()} />
<Grid class={s.HeaderArea}>
<Header view={view()} open={wsOpen()} setView={setView} />
<Show when={view() === "historical"} fallback={<div />}>
<Flex alignItems="center" style={{ "place-self": "center" }}>
<PageManager page={page} setPage={setPage} />
@@ -54,14 +54,14 @@ const Stats: Component<{}> = () => {
/>
</Flex>
</Show>
<Selector
{/* <Selector
containerStyle={{ "place-self": "center end" }}
targetClass="grey"
selected={view()}
items={VIEWS}
onSelect={setView}
position="bottom right"
/>
/> */}
</Grid>
<Switch>
<Match when={view() === "current"}>
@@ -75,13 +75,29 @@ const Stats: Component<{}> = () => {
);
};
export const Header: Component<{ view: string, open: boolean }> = (p) => {
export const Header: Component<{ view: string, setView: (view: string) => void; open: boolean }> = (p) => {
const { servers } = useAppState();
const params = useParams();
const server = () => servers.get(params.id);
return (
<Flex alignItems="center">
<h1>{server()?.server.name} - system stats</h1>
<Flex alignItems="center" style={{ height: "fit-content" }}>
<h1>{server()?.server.name}</h1>
<Grid gap="0" gridTemplateColumns="repeat(2, 1fr)">
<button
class={p.view === "current" ? "selected" : "grey"}
style={{ width: "100%" }}
onClick={() => p.setView("current")}
>
current
</button>
<button
class={p.view === "historical" ? "selected" : "grey"}
style={{ width: "100%" }}
onClick={() => p.setView("historical")}
>
historical
</button>
</Grid>
<Show when={p.view === "current"}>
<HoverMenu
target={

View File

@@ -200,6 +200,7 @@ export interface ServerActionState {
}
export interface SystemStatsQuery {
cpus?: boolean;
disks?: boolean;
networks?: boolean;
components?: boolean;
@@ -207,10 +208,13 @@ export interface SystemStatsQuery {
}
export interface SystemStats {
system_load?: number;
cpu_perc: number;
cpu_freq_mhz: number;
mem_used_gb: number;
mem_total_gb: number;
disk: DiskUsage;
cpus?: SingleCpuUsage[];
networks?: SystemNetwork[];
components?: SystemComponent[];
processes?: SystemProcess[];
@@ -219,6 +223,11 @@ export interface SystemStats {
refresh_list_ts: number;
}
export interface SingleCpuUsage {
name: string;
usage: number;
}
export interface DiskUsage {
used_gb: number;
total_gb: number;
@@ -261,10 +270,13 @@ export interface SystemStatsRecord {
_id?: string;
server_id: string;
ts: number;
system_load: number;
cpu_perc: number;
cpu_freq_mhz: number;
mem_used_gb: number;
mem_total_gb: number;
disk: DiskUsage;
cpus?: SingleCpuUsage[];
networks?: SystemNetwork[];
components?: SystemComponent[];
processes?: SystemProcess[];
@@ -279,6 +291,15 @@ export interface HistoricalStatsQuery {
components?: boolean;
}
export interface SystemInformation {
name?: string;
os?: string;
kernel?: string;
core_count?: number;
host_name?: string;
cpu_brand: string;
}
export interface Update {
_id?: string;
target: UpdateTarget;

View File

@@ -6,7 +6,7 @@ edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
types = { package = "monitor_types", version = "0.1.4" }
types = { package = "monitor_types", version = "0.1.5" }
# types = { package = "monitor_types", path = "../types" }
mungos = "0.3.0"
anyhow = "1.0"

View File

@@ -1,6 +1,6 @@
[package]
name = "monitor_helpers"
version = "0.1.4"
version = "0.1.5"
edition = "2021"
authors = ["MoghTech"]
description = "helpers used as dependency for mogh tech monitor"
@@ -10,7 +10,7 @@ license = "GPL-3.0-or-later"
[dependencies]
# types = { package = "monitor_types", path = "../types" }
types = { package = "monitor_types", version = "0.1.4" }
types = { package = "monitor_types", version = "0.1.5" }
async_timing_util = "0.1.12"
bollard = "0.13"
anyhow = "1.0"

View File

@@ -185,4 +185,4 @@ fn parse_extra_args(extra_args: &Vec<String>) -> String {
} else {
args
}
}
}

View File

@@ -1,6 +1,6 @@
[package]
name = "monitor_client"
version = "0.1.4"
version = "0.1.5"
edition = "2021"
authors = ["MoghTech"]
description = "a client to interact with the monitor system"
@@ -9,7 +9,7 @@ license = "GPL-3.0-or-later"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
monitor_types = "0.1.4"
monitor_types = "0.1.5"
# monitor_types = { path = "../types" }
reqwest = { version = "0.11", features = ["json"] }
tokio-tungstenite = { version = "0.18", features=["native-tls"] }

View File

@@ -2,7 +2,7 @@ use anyhow::{anyhow, Context};
use futures_util::{SinkExt, StreamExt};
use monitor_types::{
BasicContainerInfo, HistoricalStatsQuery, ImageSummary, Log, Network, Server,
ServerActionState, ServerWithStatus, SystemStats, SystemStatsQuery, SystemStatsRecord,
ServerActionState, ServerWithStatus, SystemStats, SystemStatsQuery, SystemStatsRecord, SystemInformation,
};
use serde_json::{json, Value};
use tokio::{
@@ -86,6 +86,24 @@ impl MonitorClient {
.context("failed at update server")
}
pub async fn get_server_version(
&self,
server_id: &str
) -> anyhow::Result<String> {
self.get(&format!("/api/server/{server_id}/version"), Option::<()>::None)
.await
.context(format!("failed to get server version at id {server_id}"))
}
pub async fn get_server_system_information(
&self,
server_id: &str
) -> anyhow::Result<SystemInformation> {
self.get(&format!("/api/server/{server_id}/system_information"), Option::<()>::None)
.await
.context(format!("failed to get server system information at id {server_id}"))
}
pub async fn get_server_stats(
&self,
server_id: &str,

View File

@@ -6,8 +6,8 @@ edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
helpers = { package = "monitor_helpers", version = "0.1.4" }
types = { package = "monitor_types", version = "0.1.4" }
helpers = { package = "monitor_helpers", version = "0.1.5" }
types = { package = "monitor_types", version = "0.1.5" }
# types = { package = "monitor_types", path = "../types" }
# helpers = { package = "monitor_helpers", path = "../helpers" }
tokio-tungstenite = { version = "0.18", features=["native-tls"] }

View File

@@ -3,7 +3,7 @@ use reqwest::StatusCode;
use serde::{de::DeserializeOwned, Serialize};
use tokio::net::TcpStream;
use tokio_tungstenite::{connect_async, MaybeTlsStream, WebSocketStream};
use types::{Server, SystemStats, SystemStatsQuery};
use types::{Server, SystemInformation, SystemStats, SystemStatsQuery};
mod build;
mod command;
@@ -42,6 +42,15 @@ impl PeripheryClient {
.context("failed to get docker accounts from periphery")
}
pub async fn get_system_information(
&self,
server: &Server,
) -> anyhow::Result<SystemInformation> {
self.get_json(server, "/system_information")
.await
.context("failed to get system information from periphery")
}
pub async fn get_system_stats(
&self,
server: &Server,

View File

@@ -1,6 +1,6 @@
[package]
name = "monitor_types"
version = "0.1.4"
version = "0.1.5"
edition = "2021"
authors = ["MoghTech"]
description = "types for the mogh tech monitor"

View File

@@ -139,6 +139,8 @@ pub enum ServerStatus {
#[typeshare]
#[derive(Serialize, Deserialize, Debug, Clone, Copy, Default)]
pub struct SystemStatsQuery {
#[serde(default)]
pub cpus: bool,
#[serde(default)]
pub disks: bool,
#[serde(default)]
@@ -152,6 +154,7 @@ pub struct SystemStatsQuery {
impl SystemStatsQuery {
pub fn all() -> SystemStatsQuery {
SystemStatsQuery {
cpus: true,
disks: true,
networks: true,
components: true,
@@ -167,11 +170,16 @@ impl SystemStatsQuery {
#[typeshare]
#[derive(Serialize, Deserialize, Debug, Default, Clone)]
pub struct SystemStats {
pub cpu_perc: f32, // in %
#[serde(default)]
pub system_load: f64,
pub cpu_perc: f32,
pub cpu_freq_mhz: f64,
pub mem_used_gb: f64, // in GB
pub mem_total_gb: f64, // in GB
pub disk: DiskUsage,
#[serde(default)]
pub cpus: Vec<SingleCpuUsage>,
#[serde(default)]
pub networks: Vec<SystemNetwork>,
#[serde(default)]
pub components: Vec<SystemComponent>,
@@ -182,6 +190,13 @@ pub struct SystemStats {
pub refresh_list_ts: u128,
}
#[typeshare]
#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct SingleCpuUsage {
pub name: String,
pub usage: f32,
}
#[typeshare]
#[derive(Serialize, Deserialize, Debug, Default, Clone)]
pub struct DiskUsage {
@@ -244,12 +259,16 @@ pub struct SystemStatsRecord {
)]
pub id: String,
pub server_id: String,
pub ts: f64, // unix ts milliseconds
pub ts: f64, // unix ts milliseconds
pub system_load: f64,
pub cpu_perc: f32, // in %
pub cpu_freq_mhz: f64, // in MHz
pub mem_used_gb: f64, // in GB
pub mem_total_gb: f64, // in GB
pub disk: DiskUsage,
#[serde(default)]
pub cpus: Vec<SingleCpuUsage>,
#[serde(default)]
pub networks: Vec<SystemNetwork>,
#[serde(default)]
pub components: Vec<SystemComponent>,
@@ -264,10 +283,13 @@ impl SystemStatsRecord {
id: String::new(),
server_id,
ts: ts as f64,
system_load: stats.system_load,
cpu_perc: stats.cpu_perc,
cpu_freq_mhz: stats.cpu_freq_mhz,
mem_used_gb: stats.mem_used_gb,
mem_total_gb: stats.mem_total_gb,
disk: stats.disk,
cpus: stats.cpus,
networks: stats.networks,
components: stats.components,
processes: stats.processes,
@@ -310,3 +332,14 @@ fn default_interval() -> Timelength {
fn default_limit() -> f64 {
100.0
}
#[typeshare]
#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct SystemInformation {
pub name: Option<String>,
pub os: Option<String>,
pub kernel: Option<String>,
pub core_count: Option<u32>,
pub host_name: Option<String>,
pub cpu_brand: String,
}

View File

@@ -15,8 +15,8 @@ path = "src/main.rs"
[dependencies]
# helpers = { package = "monitor_helpers", path = "../lib/helpers" }
# types = { package = "monitor_types", path = "../lib/types" }
helpers = { package = "monitor_helpers", version = "0.1.4" }
types = { package = "monitor_types", version = "0.1.4" }
helpers = { package = "monitor_helpers", version = "0.1.5" }
types = { package = "monitor_types", version = "0.1.5" }
run_command = { version = "0.0.5", features = ["async_tokio"] }
async_timing_util = "0.1.12"
tokio = { version = "1.24", features = ["full"] }
@@ -29,7 +29,7 @@ serde_json = "1.0"
bollard = "0.13"
anyhow = "1.0"
envy = "0.4"
sysinfo = "0.27.2"
sysinfo = "0.27.5"
toml = "0.5"
daemonize = "0.4"
clap = { version = "4.0", features = ["derive"] }

View File

@@ -15,6 +15,8 @@ use types::{monitor_timestamp, PeripheryConfig};
use crate::{HomeDirExtension, PeripheryConfigExtension};
use self::stats::{StatsClient, StatsExtension};
mod accounts;
mod build;
mod command;
@@ -28,19 +30,23 @@ pub fn router(config: PeripheryConfigExtension, home_dir: HomeDirExtension) -> R
Router::new()
.route("/health", get(|| async {}))
.route("/version", get(|| async { env!("CARGO_PKG_VERSION") }))
.route(
"/system_information",
get(|sys: StatsExtension| async move { Json(sys.read().unwrap().info.clone()) }),
)
.route("/accounts/:account_type", get(accounts::get_accounts))
.nest("/command", command::router())
.nest("/container", container::router())
.nest("/network", network::router())
.nest(
"/stats",
stats::router(config.stats_polling_rate.to_string().parse().unwrap()),
)
.nest("/stats", stats::router())
.nest("/git", git::router())
.nest("/build", build::router())
.nest("/image", image::router())
.layer(DockerClient::extension())
.layer(middleware::from_fn(guard_request))
.layer(StatsClient::extension(
config.stats_polling_rate.to_string().parse().unwrap(),
))
.layer(config)
.layer(home_dir)
}

View File

@@ -18,16 +18,16 @@ use tokio::{
};
use tokio_util::sync::CancellationToken;
use types::{
DiskUsage, SingleDiskUsage, SystemComponent, SystemNetwork, SystemProcess, SystemStats,
SystemStatsQuery, Timelength,
DiskUsage, SingleCpuUsage, SingleDiskUsage, SystemComponent, SystemInformation, SystemNetwork,
SystemProcess, SystemStats, SystemStatsQuery, Timelength,
};
pub fn router(stats_polling_rate: Timelength) -> Router {
pub fn router() -> Router {
Router::new()
.route(
"/",
get(
|Extension(sys): StatsExtension, Query(query): Query<SystemStatsQuery>| async move {
|sys: StatsExtension, Query(query): Query<SystemStatsQuery>| async move {
let stats = sys.read().unwrap().get_cached_stats(query);
Json(stats)
},
@@ -36,19 +36,19 @@ pub fn router(stats_polling_rate: Timelength) -> Router {
.route(
"/ws",
get(
|Extension(sys): StatsExtension,
|sys: StatsExtension,
Query(query): Query<SystemStatsQuery>,
ws: WebSocketUpgrade| async move {
sys.read().unwrap().ws_subscribe(ws, Arc::new(query))
},
),
)
.layer(StatsClient::extension(stats_polling_rate))
}
type StatsExtension = Extension<Arc<RwLock<StatsClient>>>;
pub type StatsExtension = Extension<Arc<RwLock<StatsClient>>>;
struct StatsClient {
pub struct StatsClient {
pub info: SystemInformation,
sys: sysinfo::System,
cache: SystemStats,
polling_rate: Timelength,
@@ -62,10 +62,12 @@ const BYTES_PER_MB: f64 = 1048576.0;
const BYTES_PER_KB: f64 = 1024.0;
impl StatsClient {
fn extension(polling_rate: Timelength) -> StatsExtension {
pub fn extension(polling_rate: Timelength) -> StatsExtension {
let (sender, receiver) = broadcast::channel::<SystemStats>(10);
let sys = sysinfo::System::new_all();
let client = StatsClient {
sys: sysinfo::System::new_all(),
info: get_system_information(&sys),
sys,
cache: SystemStats::default(),
polling_rate,
refresh_ts: 0,
@@ -118,6 +120,9 @@ impl StatsClient {
_ = cancel_clone.cancelled() => break,
stats = reciever.recv() => { stats.expect("failed to recv stats msg") }
};
if query.cpus {
stats.cpus = vec![]
}
if !query.disks {
stats.disk.disks = vec![]
}
@@ -175,28 +180,59 @@ impl StatsClient {
}
fn get_cached_stats(&self, query: SystemStatsQuery) -> SystemStats {
let mut stats = self.cache.clone();
if !query.disks {
stats.disk.disks = vec![]
SystemStats {
system_load: self.cache.system_load,
cpu_perc: self.cache.cpu_perc,
cpu_freq_mhz: self.cache.cpu_freq_mhz,
mem_used_gb: self.cache.mem_used_gb,
mem_total_gb: self.cache.mem_total_gb,
disk: DiskUsage {
used_gb: self.cache.disk.used_gb,
total_gb: self.cache.disk.total_gb,
read_kb: self.cache.disk.read_kb,
write_kb: self.cache.disk.write_kb,
disks: if query.disks {
self.cache.disk.disks.clone()
} else {
vec![]
},
},
cpus: if query.cpus {
self.cache.cpus.clone()
} else {
vec![]
},
networks: if query.networks {
self.cache.networks.clone()
} else {
vec![]
},
components: if query.components {
self.cache.components.clone()
} else {
vec![]
},
processes: if query.processes {
self.cache.processes.clone()
} else {
vec![]
},
polling_rate: self.cache.polling_rate,
refresh_ts: self.cache.refresh_ts,
refresh_list_ts: self.cache.refresh_list_ts,
}
if !query.networks {
stats.networks = vec![];
}
if !query.components {
stats.components = vec![];
}
if !query.processes {
stats.processes = vec![];
}
stats
}
fn get_stats(&self) -> SystemStats {
let cpu = self.sys.global_cpu_info();
SystemStats {
system_load: self.sys.load_average().one,
cpu_perc: self.sys.global_cpu_info().cpu_usage(),
cpu_freq_mhz: cpu.frequency() as f64,
mem_used_gb: self.sys.used_memory() as f64 / BYTES_PER_GB,
mem_total_gb: self.sys.total_memory() as f64 / BYTES_PER_GB,
disk: self.get_disk_usage(),
cpus: self.get_cpus(),
networks: self.get_networks(),
components: self.get_components(),
processes: self.get_processes(),
@@ -206,6 +242,17 @@ impl StatsClient {
}
}
fn get_cpus(&self) -> Vec<SingleCpuUsage> {
self.sys
.cpus()
.into_iter()
.map(|cpu| SingleCpuUsage {
name: cpu.name().to_string(),
usage: cpu.cpu_usage(),
})
.collect()
}
fn get_networks(&self) -> Vec<SystemNetwork> {
self.sys
.networks()
@@ -316,3 +363,15 @@ impl StatsClient {
procs
}
}
fn get_system_information(sys: &sysinfo::System) -> SystemInformation {
let cpu = sys.global_cpu_info();
SystemInformation {
name: sys.name(),
os: sys.long_os_version(),
kernel: sys.kernel_version(),
core_count: sys.physical_core_count().map(|c| c as u32),
host_name: sys.host_name(),
cpu_brand: cpu.brand().to_string(),
}
}