mirror of
https://github.com/moghtech/komodo.git
synced 2026-01-23 13:09:08 -06:00
0.1.5
This commit is contained in:
36
Cargo.lock
generated
36
Cargo.lock
generated
@@ -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",
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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" }
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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),
|
||||
}}
|
||||
>
|
||||
|
||||
@@ -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={
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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"
|
||||
@@ -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"
|
||||
|
||||
@@ -185,4 +185,4 @@ fn parse_extra_args(extra_args: &Vec<String>) -> String {
|
||||
} else {
|
||||
args
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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"] }
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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"] }
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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,
|
||||
}
|
||||
|
||||
@@ -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"] }
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
@@ -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(),
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user