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 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::RwLock;
@@ -28,54 +29,173 @@ pub async fn logs(
.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);
impl fmt::Display for Celsius {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
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);
#[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);
#[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);
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)]
pub struct MetricsGeneral {
#[serde(rename = "Temparature")]
temperature: Celsius,
}
#[derive(Deserialize, Serialize, Clone, Debug)]
pub struct MetricsMemory {
#[serde(rename = "Percentage Used")]
percentage_used: Percentage,
#[serde(rename = "Total")]
total: MebiBytes,
#[serde(rename = "Available")]
available: MebiBytes,
#[serde(rename = "Used")]
used: MebiBytes,
#[serde(rename = "Swap Total")]
swap_total: MebiBytes,
#[serde(rename = "Swap Free")]
swap_free: MebiBytes,
#[serde(rename = "Swap Used")]
swap_used: MebiBytes,
}
#[derive(Deserialize, Serialize, Clone, Debug)]
pub struct MetricsCpu {
#[serde(rename = "User Space")]
user_space: Percentage,
#[serde(rename = "Kernel Space")]
kernel_space: Percentage,
#[serde(rename = "I/O Wait")]
wait: Percentage,
#[serde(rename = "Idle")]
idle: Percentage,
#[serde(rename = "Usage")]
usage: Percentage,
}
#[derive(Deserialize, Serialize, Clone, Debug)]
pub struct MetricsDisk {
#[serde(rename = "Size")]
size: GigaBytes,
#[serde(rename = "Used")]
used: GigaBytes,
#[serde(rename = "Available")]
available: GigaBytes,
#[serde(rename = "Percentage Used")]
used_percentage: Percentage,
}
#[derive(Deserialize, Serialize, Clone, Debug)]
pub struct Metrics {
#[serde(rename = "General")]
general: MetricsGeneral,
#[serde(rename = "Memory")]
memory: MetricsMemory,
#[serde(rename = "CPU")]
cpu: MetricsCpu,
#[serde(rename = "Disk")]
disk: MetricsDisk,
}
@@ -358,11 +478,11 @@ async fn get_cpu_info(last: &mut ProcStat) -> Result<MetricsCpu, Error> {
let total_new = new.total();
let total_diff = total_new - total_old;
let res = MetricsCpu {
user_space: Percentage((new.user() - last.user()) as f64 / total_diff as f64),
kernel_space: Percentage((new.system() - last.system()) as f64 / total_diff as f64),
idle: Percentage((new.idle - last.idle) as f64 / total_diff as f64),
wait: Percentage((new.iowait - last.iowait) as f64 / total_diff as f64),
usage: Percentage((new.used() - last.used()) 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 * 100.0 / 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 * 100.0 / total_diff as f64),
usage: Percentage((new.used() - last.used()) as f64 * 100.0 / total_diff as f64),
};
*last = new;
Ok(res)