Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix time display bug and type metrics #2490

Merged
merged 5 commits into from
Nov 1, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -200,7 +200,7 @@ frontend/config.json: $(GIT_HASH_FILE) frontend/config-sample.json
jq '.useMocks = false' frontend/config-sample.json | jq '.gitHash = "$(shell cat GIT_HASH.txt)"' > frontend/config.json

frontend/patchdb-ui-seed.json: frontend/package.json
jq '."ack-welcome" = $(shell yq '.version' frontend/package.json)' frontend/patchdb-ui-seed.json > ui-seed.tmp
jq '."ack-welcome" = $(shell jq '.version' frontend/package.json)' frontend/patchdb-ui-seed.json > ui-seed.tmp
mv ui-seed.tmp frontend/patchdb-ui-seed.json

patch-db/client/node_modules: patch-db/client/package.json
Expand Down
76 changes: 30 additions & 46 deletions backend/src/system.rs
Original file line number Diff line number Diff line change
Expand Up @@ -360,60 +360,44 @@ impl<'de> Deserialize<'de> for GigaBytes {
}

#[derive(Deserialize, Serialize, Clone, Debug)]
#[serde(rename_all = "kebab-case")]
pub struct MetricsGeneral {
#[serde(rename = "Temperature")]
temperature: Option<Celsius>,
pub temperature: Option<Celsius>,
}
#[derive(Deserialize, Serialize, Clone, Debug)]
#[serde(rename_all = "kebab-case")]
pub struct MetricsMemory {
#[serde(rename = "Percentage Used")]
pub percentage_used: Percentage,
#[serde(rename = "Total")]
pub total: MebiBytes,
#[serde(rename = "Available")]
pub available: MebiBytes,
#[serde(rename = "Used")]
pub used: MebiBytes,
#[serde(rename = "Swap Total")]
pub swap_total: MebiBytes,
#[serde(rename = "Swap Free")]
pub swap_free: MebiBytes,
#[serde(rename = "Swap Used")]
pub swap_used: MebiBytes,
pub zram_total: MebiBytes,
pub zram_available: MebiBytes,
pub zram_used: MebiBytes,
}
#[derive(Deserialize, Serialize, Clone, Debug)]
#[serde(rename_all = "kebab-case")]
pub struct MetricsCpu {
#[serde(rename = "User Space")]
percentage_used: Percentage,
idle: Percentage,
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)]
#[serde(rename_all = "kebab-case")]
pub struct MetricsDisk {
#[serde(rename = "Size")]
size: GigaBytes,
#[serde(rename = "Used")]
percentage_used: Percentage,
used: GigaBytes,
#[serde(rename = "Available")]
available: GigaBytes,
#[serde(rename = "Percentage Used")]
used_percentage: Percentage,
capacity: GigaBytes,
}
#[derive(Deserialize, Serialize, Clone, Debug)]
#[serde(rename_all = "kebab-case")]
pub struct Metrics {
#[serde(rename = "General")]
general: MetricsGeneral,
#[serde(rename = "Memory")]
memory: MetricsMemory,
#[serde(rename = "CPU")]
cpu: MetricsCpu,
#[serde(rename = "Disk")]
disk: MetricsDisk,
}

Expand Down Expand Up @@ -739,7 +723,7 @@ async fn get_cpu_info(last: &mut ProcStat) -> Result<MetricsCpu, Error> {
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),
percentage_used: Percentage((new.used() - last.used()) as f64 * 100.0 / total_diff as f64),
};
*last = new;
Ok(res)
Expand All @@ -752,8 +736,8 @@ pub struct MemInfo {
buffers: Option<u64>,
cached: Option<u64>,
slab: Option<u64>,
swap_total: Option<u64>,
swap_free: Option<u64>,
zram_total: Option<u64>,
zram_free: Option<u64>,
}
#[instrument(skip_all)]
pub async fn get_mem_info() -> Result<MetricsMemory, Error> {
Expand All @@ -765,8 +749,8 @@ pub async fn get_mem_info() -> Result<MetricsMemory, Error> {
buffers: None,
cached: None,
slab: None,
swap_total: None,
swap_free: None,
zram_total: None,
zram_free: None,
};
fn get_num_kb(l: &str) -> Result<u64, Error> {
let e = Error::new(
Expand All @@ -791,8 +775,8 @@ pub async fn get_mem_info() -> Result<MetricsMemory, Error> {
_ if entry.starts_with("Buffers") => mem_info.buffers = Some(get_num_kb(entry)?),
_ if entry.starts_with("Cached") => mem_info.cached = Some(get_num_kb(entry)?),
_ if entry.starts_with("Slab") => mem_info.slab = Some(get_num_kb(entry)?),
_ if entry.starts_with("SwapTotal") => mem_info.swap_total = Some(get_num_kb(entry)?),
_ if entry.starts_with("SwapFree") => mem_info.swap_free = Some(get_num_kb(entry)?),
_ if entry.starts_with("SwapTotal") => mem_info.zram_total = Some(get_num_kb(entry)?),
_ if entry.starts_with("SwapFree") => mem_info.zram_free = Some(get_num_kb(entry)?),
_ => (),
}
}
Expand All @@ -808,24 +792,24 @@ pub async fn get_mem_info() -> Result<MetricsMemory, Error> {
let buffers = ensure_present(mem_info.buffers, "Buffers")?;
let cached = ensure_present(mem_info.cached, "Cached")?;
let slab = ensure_present(mem_info.slab, "Slab")?;
let swap_total_k = ensure_present(mem_info.swap_total, "SwapTotal")?;
let swap_free_k = ensure_present(mem_info.swap_free, "SwapFree")?;
let zram_total_k = ensure_present(mem_info.zram_total, "SwapTotal")?;
let zram_free_k = ensure_present(mem_info.zram_free, "SwapFree")?;

let total = MebiBytes(mem_total as f64 / 1024.0);
let available = MebiBytes(mem_available as f64 / 1024.0);
let used = MebiBytes((mem_total - mem_free - buffers - cached - slab) as f64 / 1024.0);
let swap_total = MebiBytes(swap_total_k as f64 / 1024.0);
let swap_free = MebiBytes(swap_free_k as f64 / 1024.0);
let swap_used = MebiBytes((swap_total_k - swap_free_k) as f64 / 1024.0);
let zram_total = MebiBytes(zram_total_k as f64 / 1024.0);
let zram_available = MebiBytes(zram_free_k as f64 / 1024.0);
let zram_used = MebiBytes((zram_total_k - zram_free_k) as f64 / 1024.0);
let percentage_used = Percentage((total.0 - available.0) / total.0 * 100.0);
Ok(MetricsMemory {
percentage_used,
total,
available,
used,
swap_total,
swap_free,
swap_used,
zram_total,
zram_available,
zram_used,
})
}

Expand All @@ -849,10 +833,10 @@ async fn get_disk_info() -> Result<MetricsDisk, Error> {
let total_percentage = total_used as f64 / total_size as f64 * 100.0f64;

Ok(MetricsDisk {
size: GigaBytes(total_size as f64 / 1_000_000_000.0),
capacity: GigaBytes(total_size as f64 / 1_000_000_000.0),
used: GigaBytes(total_used as f64 / 1_000_000_000.0),
available: GigaBytes(total_available as f64 / 1_000_000_000.0),
used_percentage: Percentage(total_percentage as f64),
percentage_used: Percentage(total_percentage as f64),
})
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,74 +11,155 @@
</ion-header>

<ion-content class="ion-padding with-widgets">
<skeleton-list *ngIf="loading" [groups]="2"></skeleton-list>

<div id="metricSection">
<ng-container *ngIf="!loading">
<ion-item-group>
<!-- <ion-item-divider>Time</ion-item-divider> -->
<ion-item *ngIf="now$ | async as now; else timeLoading">
<ion-label>
<h1>System Time</h1>
<h2>
<ion-text style="color: white">
<b>{{ now.value | date:'MMMM d, y, h:mm a z':'UTC' }}</b>
</ion-text>
</h2>
<p *ngIf="!now.synced">
<ion-text color="warning">
NTP not synced, time could be wrong
</ion-text>
</p>
</ion-label>
<ion-note slot="end" class="metric-note"></ion-note>
</ion-item>
<ion-item-group>
<ion-item>
<ion-label>
<h1>System Time</h1>
<ng-container *ngIf="now$ | async as now; else timeLoading">
<h2>
<ion-text style="color: white">
<b>{{ now.value | date:'MMMM d, y, h:mm a z':'UTC' }}</b>
</ion-text>
</h2>
<p *ngIf="!now.synced">
<ion-text color="warning">
NTP not synced, time could be wrong
</ion-text>
</p>
</ng-container>
<ng-template #timeLoading>
<ion-item>
<ion-label>
<h1>System Time</h1>
<p>Loading...</p>
</ion-label>
<ion-note slot="end" class="metric-note"></ion-note>
</ion-item>
<h2>Loading...</h2>
</ng-template>
</ion-label>
<ion-note slot="end" class="metric-note"></ion-note>
</ion-item>

<ion-item>
<ion-label>
<h1>System Uptime</h1>
<h2>
<ion-text style="color: white">
<ng-container *ngIf="uptime$ | async as uptime">
<b>{{ uptime.days }}</b>
Days,
<b>{{ uptime.hours }}</b>
Hours,
<b>{{ uptime.minutes }}</b>
Minutes,
<b>{{ uptime.seconds }}</b>
Seconds
</ng-container>
</ion-text>
</h2>
</ion-label>
</ion-item>
</ion-item-group>
<ion-item>
<ion-label>
<h1>System Uptime</h1>
<h2>
<ion-text style="color: white">
<ng-container *ngIf="uptime$ | async as uptime; else uptimeLoading">
<b>{{ uptime.days }}</b>
Days,
<b>{{ uptime.hours }}</b>
Hours,
<b>{{ uptime.minutes }}</b>
Minutes,
<b>{{ uptime.seconds }}</b>
Seconds
</ng-container>
<ng-template #uptimeLoading>Loading...</ng-template>
</ion-text>
</h2>
</ion-label>
</ion-item>
</ion-item-group>

<ion-item-group
*ngFor="let metricGroup of metrics | keyvalue : asIsOrder"
>
<ion-item-divider>{{ metricGroup.key }}</ion-item-divider>
<ion-item
*ngFor="let metric of metricGroup.value | keyvalue : asIsOrder"
>
<ion-label>{{ metric.key }}</ion-label>
<ion-note *ngIf="metric.value" slot="end" class="metric-note">
<ion-text style="color: white">
{{ metric.value.value }} {{ metric.value.unit }}
</ion-text>
</ion-note>
</ion-item>
</ion-item-group>
</ng-container>
</div>
<ng-container *ngIf="metrics$ | async as metrics; else loading">
<ion-item-group *ngIf="metrics.general as general">
<ion-item-divider>General</ion-item-divider>
<ion-item>
<ion-label>Temperature</ion-label>
<ion-note slot="end">
<ng-container *ngIf="general.temperature; else noTemp">
{{ general.temperature.value }} &deg;C
</ng-container>
<ng-template #noTemp>N/A</ng-template>
</ion-note>
</ion-item>
</ion-item-group>

<ion-item-group *ngIf="metrics.memory as memory">
<ion-item-divider>Memory</ion-item-divider>
<ion-item>
<ion-label>Percentage Used</ion-label>
<ion-note slot="end">{{ memory['percentage-used'].value }} %</ion-note>
</ion-item>
<ion-item>
<ion-label>Total</ion-label>
<ion-note slot="end">
<ion-text>{{ memory.total.value }} MiB</ion-text>
</ion-note>
</ion-item>
<ion-item>
<ion-label>Used</ion-label>
<ion-note slot="end">
<ion-text>{{ memory.used.value }} MiB</ion-text>
</ion-note>
</ion-item>
<ion-item>
<ion-label>Available</ion-label>
<ion-note slot="end">{{ memory.available.value }} MiB</ion-note>
</ion-item>
<ion-item>
<ion-label>zram Used</ion-label>
<ion-note slot="end">{{ memory['zram-used'].value }} MiB</ion-note>
</ion-item>
<ion-item>
<ion-label>zram Total</ion-label>
<ion-note slot="end">{{ memory['zram-total'].value }} MiB</ion-note>
</ion-item>
<ion-item>
<ion-label>zram Available</ion-label>
<ion-note slot="end">{{ memory['zram-available'].value }} MiB</ion-note>
</ion-item>
</ion-item-group>

<ion-item-group *ngIf="metrics.cpu as cpu">
<ion-item-divider>CPU</ion-item-divider>
<ion-item>
<ion-label>Percentage Used</ion-label>
<ion-note slot="end">{{ cpu['percentage-used'].value }} %</ion-note>
</ion-item>
<ion-item>
<ion-label>User Space</ion-label>
<ion-note slot="end">
<ion-text>{{ cpu['user-space'].value }} %</ion-text>
</ion-note>
</ion-item>
<ion-item>
<ion-label>Kernel Space</ion-label>
<ion-note slot="end">
<ion-text>{{ cpu['kernel-space'].value }} %</ion-text>
</ion-note>
</ion-item>
<ion-item>
<ion-label>Idle</ion-label>
<ion-note slot="end">{{ cpu.idle.value }} %</ion-note>
</ion-item>
<ion-item>
<ion-label>I/O Wait</ion-label>
<ion-note slot="end">{{ cpu.wait.value }} %</ion-note>
</ion-item>
</ion-item-group>

<ion-item-group *ngIf="metrics.disk as disk">
<ion-item-divider>Disk</ion-item-divider>
<ion-item>
<ion-label>Percentage Used</ion-label>
<ion-note slot="end">{{ disk['percentage-used'].value }} %</ion-note>
</ion-item>
<ion-item>
<ion-label>Capacity</ion-label>
<ion-note slot="end">
<ion-text>{{ disk.capacity.value }} GB</ion-text>
</ion-note>
</ion-item>
<ion-item>
<ion-label>Used</ion-label>
<ion-note slot="end">
<ion-text>{{ disk.used.value }} GB</ion-text>
</ion-note>
</ion-item>
<ion-item>
<ion-label>Available</ion-label>
<ion-note slot="end">{{ disk.available.value }} GB</ion-note>
</ion-item>
</ion-item-group>
</ng-container>

<ng-template #loading>
<skeleton-list [groups]="4"></skeleton-list>
</ng-template>
</ion-content>
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
.metric-note {
ion-note {
font-size: 16px;
color: white;
}
Loading