Bugfix/metrics rendering (#586)

* stubs for Serialize

* serialization instances

* render percentages as 100x
This commit is contained in:
Keagan McClelland
2021-10-05 14:26:59 -06:00
committed by Aiden McClelland
parent 1732e5403b
commit c8d2520248

View File

@@ -1,7 +1,8 @@
use std::fmt; use std::fmt;
use rpc_toolkit::command; use rpc_toolkit::command;
use serde::{Deserialize, Serialize}; use serde::ser::SerializeStruct;
use serde::{Deserialize, Deserializer, Serialize, Serializer};
use tokio::sync::broadcast::Receiver; use tokio::sync::broadcast::Receiver;
use tokio::sync::RwLock; use tokio::sync::RwLock;
@@ -28,54 +29,173 @@ pub async fn logs(
.await?) .await?)
} }
#[derive(Deserialize, Serialize, Clone, Debug)] #[derive(Serialize, Deserialize)]
pub struct MetricLeaf<T> {
value: T,
unit: Option<String>,
}
#[derive(Clone, Debug)]
pub struct Celsius(f64); pub struct Celsius(f64);
impl fmt::Display for Celsius { impl fmt::Display for Celsius {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{:.1}°C", self.0) write!(f, "{:.1}°C", self.0)
} }
} }
#[derive(Deserialize, Serialize, Clone, Debug)] impl Serialize for Celsius {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
MetricLeaf {
value: format!("{:.1}", self.0),
unit: Some(String::from("°C")),
}
.serialize(serializer)
}
}
impl<'de> Deserialize<'de> for Celsius {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
let s = MetricLeaf::<String>::deserialize(deserializer)?;
Ok(Celsius(s.value.parse().map_err(serde::de::Error::custom)?))
}
}
#[derive(Clone, Debug)]
pub struct Percentage(f64); pub struct Percentage(f64);
#[derive(Deserialize, Serialize, Clone, Debug)] impl Serialize for Percentage {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
MetricLeaf {
value: format!("{:.1}", self.0),
unit: Some(String::from("%")),
}
.serialize(serializer)
}
}
impl<'de> Deserialize<'de> for Percentage {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
let s = MetricLeaf::<String>::deserialize(deserializer)?;
Ok(Percentage(
s.value.parse().map_err(serde::de::Error::custom)?,
))
}
}
#[derive(Clone, Debug)]
pub struct MebiBytes(f64); pub struct MebiBytes(f64);
#[derive(Deserialize, Serialize, Clone, Debug)] impl Serialize for MebiBytes {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
MetricLeaf {
value: format!("{:.2}", self.0),
unit: Some(String::from("MiB")),
}
.serialize(serializer)
}
}
impl<'de> Deserialize<'de> for MebiBytes {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
let s = MetricLeaf::<String>::deserialize(deserializer)?;
Ok(MebiBytes(
s.value.parse().map_err(serde::de::Error::custom)?,
))
}
}
#[derive(Clone, Debug)]
pub struct GigaBytes(f64); pub struct GigaBytes(f64);
impl Serialize for GigaBytes {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
MetricLeaf {
value: format!("{:.2}", self.0),
unit: Some(String::from("GB")),
}
.serialize(serializer)
}
}
impl<'de> Deserialize<'de> for GigaBytes {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
let s = MetricLeaf::<String>::deserialize(deserializer)?;
Ok(GigaBytes(
s.value.parse().map_err(serde::de::Error::custom)?,
))
}
}
#[derive(Deserialize, Serialize, Clone, Debug)] #[derive(Deserialize, Serialize, Clone, Debug)]
pub struct MetricsGeneral { pub struct MetricsGeneral {
#[serde(rename = "Temparature")]
temperature: Celsius, temperature: Celsius,
} }
#[derive(Deserialize, Serialize, Clone, Debug)] #[derive(Deserialize, Serialize, Clone, Debug)]
pub struct MetricsMemory { pub struct MetricsMemory {
#[serde(rename = "Percentage Used")]
percentage_used: Percentage, percentage_used: Percentage,
#[serde(rename = "Total")]
total: MebiBytes, total: MebiBytes,
#[serde(rename = "Available")]
available: MebiBytes, available: MebiBytes,
#[serde(rename = "Used")]
used: MebiBytes, used: MebiBytes,
#[serde(rename = "Swap Total")]
swap_total: MebiBytes, swap_total: MebiBytes,
#[serde(rename = "Swap Free")]
swap_free: MebiBytes, swap_free: MebiBytes,
#[serde(rename = "Swap Used")]
swap_used: MebiBytes, swap_used: MebiBytes,
} }
#[derive(Deserialize, Serialize, Clone, Debug)] #[derive(Deserialize, Serialize, Clone, Debug)]
pub struct MetricsCpu { pub struct MetricsCpu {
#[serde(rename = "User Space")]
user_space: Percentage, user_space: Percentage,
#[serde(rename = "Kernel Space")]
kernel_space: Percentage, kernel_space: Percentage,
#[serde(rename = "I/O Wait")]
wait: Percentage, wait: Percentage,
#[serde(rename = "Idle")]
idle: Percentage, idle: Percentage,
#[serde(rename = "Usage")]
usage: Percentage, usage: Percentage,
} }
#[derive(Deserialize, Serialize, Clone, Debug)] #[derive(Deserialize, Serialize, Clone, Debug)]
pub struct MetricsDisk { pub struct MetricsDisk {
#[serde(rename = "Size")]
size: GigaBytes, size: GigaBytes,
#[serde(rename = "Used")]
used: GigaBytes, used: GigaBytes,
#[serde(rename = "Available")]
available: GigaBytes, available: GigaBytes,
#[serde(rename = "Percentage Used")]
used_percentage: Percentage, used_percentage: Percentage,
} }
#[derive(Deserialize, Serialize, Clone, Debug)] #[derive(Deserialize, Serialize, Clone, Debug)]
pub struct Metrics { pub struct Metrics {
#[serde(rename = "General")]
general: MetricsGeneral, general: MetricsGeneral,
#[serde(rename = "Memory")]
memory: MetricsMemory, memory: MetricsMemory,
#[serde(rename = "CPU")]
cpu: MetricsCpu, cpu: MetricsCpu,
#[serde(rename = "Disk")]
disk: MetricsDisk, disk: MetricsDisk,
} }
@@ -358,11 +478,11 @@ async fn get_cpu_info(last: &mut ProcStat) -> Result<MetricsCpu, Error> {
let total_new = new.total(); let total_new = new.total();
let total_diff = total_new - total_old; let total_diff = total_new - total_old;
let res = MetricsCpu { let res = MetricsCpu {
user_space: Percentage((new.user() - last.user()) as f64 / total_diff as f64), user_space: Percentage((new.user() - last.user()) as f64 * 100.0 / total_diff as f64),
kernel_space: Percentage((new.system() - last.system()) as f64 / total_diff as f64), kernel_space: Percentage((new.system() - last.system()) as f64 * 100.0 / total_diff as f64),
idle: Percentage((new.idle - last.idle) as f64 / total_diff as f64), idle: Percentage((new.idle - last.idle) as f64 * 100.0 / total_diff as f64),
wait: Percentage((new.iowait - last.iowait) as f64 / total_diff as f64), wait: Percentage((new.iowait - last.iowait) as f64 * 100.0 / total_diff as f64),
usage: Percentage((new.used() - last.used()) as f64 / total_diff as f64), usage: Percentage((new.used() - last.used()) as f64 * 100.0 / total_diff as f64),
}; };
*last = new; *last = new;
Ok(res) Ok(res)