moved stats into own folder
Some checks failed
Rust Cross-Platform Build / Detect Rust Project (push) Successful in 4s
Rust Cross-Platform Build / Run Tests (push) Failing after 1m9s
Rust Cross-Platform Build / Build (x86_64-unknown-linux-gnu) (push) Has been skipped
Rust Cross-Platform Build / Build (x86_64-pc-windows-gnu) (push) Has been skipped
Rust Cross-Platform Build / Set Tag Name (push) Has been skipped
Rust Cross-Platform Build / Build and Push Docker Image (push) Has been skipped
Rust Cross-Platform Build / Create Tag (push) Has been skipped
Rust Cross-Platform Build / Workflow Summary (push) Successful in 2s
Some checks failed
Rust Cross-Platform Build / Detect Rust Project (push) Successful in 4s
Rust Cross-Platform Build / Run Tests (push) Failing after 1m9s
Rust Cross-Platform Build / Build (x86_64-unknown-linux-gnu) (push) Has been skipped
Rust Cross-Platform Build / Build (x86_64-pc-windows-gnu) (push) Has been skipped
Rust Cross-Platform Build / Set Tag Name (push) Has been skipped
Rust Cross-Platform Build / Build and Push Docker Image (push) Has been skipped
Rust Cross-Platform Build / Create Tag (push) Has been skipped
Rust Cross-Platform Build / Workflow Summary (push) Successful in 2s
This commit is contained in:
@@ -0,0 +1,96 @@
|
||||
use super::ContainerCpuInfo;
|
||||
use bollard::query_parameters::{ListContainersOptions, StatsOptions};
|
||||
use bollard::Docker;
|
||||
use futures_util::stream::TryStreamExt;
|
||||
use std::error::Error;
|
||||
|
||||
/// Get CPU statistics for all containers
|
||||
pub async fn get_all_containers_cpu_stats(
|
||||
docker: &Docker,
|
||||
) -> Result<Vec<ContainerCpuInfo>, Box<dyn Error + Send + Sync>> {
|
||||
let containers = docker
|
||||
.list_containers(Some(ListContainersOptions {
|
||||
all: true,
|
||||
..Default::default()
|
||||
}))
|
||||
.await?;
|
||||
|
||||
let mut cpu_infos = Vec::new();
|
||||
|
||||
for container in containers {
|
||||
let id = container.id.unwrap_or_default();
|
||||
|
||||
// Skip if no ID
|
||||
if id.is_empty() {
|
||||
continue;
|
||||
}
|
||||
|
||||
if let Some(cpu_info) = get_single_container_cpu_stats(docker, &id).await? {
|
||||
cpu_infos.push(cpu_info);
|
||||
}
|
||||
}
|
||||
|
||||
Ok(cpu_infos)
|
||||
}
|
||||
|
||||
/// Get CPU statistics for a specific container
|
||||
pub async fn get_single_container_cpu_stats(
|
||||
docker: &Docker,
|
||||
container_id: &str,
|
||||
) -> Result<Option<ContainerCpuInfo>, Box<dyn Error + Send + Sync>> {
|
||||
let mut stats_stream = docker.stats(
|
||||
container_id,
|
||||
Some(StatsOptions {
|
||||
stream: false,
|
||||
one_shot: true,
|
||||
}),
|
||||
);
|
||||
|
||||
if let Some(stats) = stats_stream.try_next().await? {
|
||||
if let (Some(cpu_stats), Some(precpu_stats)) = (&stats.cpu_stats, &stats.precpu_stats) {
|
||||
if let (Some(cpu_usage), Some(pre_cpu_usage)) =
|
||||
(&cpu_stats.cpu_usage, &precpu_stats.cpu_usage)
|
||||
{
|
||||
let cpu_delta = cpu_usage
|
||||
.total_usage
|
||||
.unwrap_or(0)
|
||||
.saturating_sub(pre_cpu_usage.total_usage.unwrap_or(0));
|
||||
|
||||
let system_delta = cpu_stats
|
||||
.system_cpu_usage
|
||||
.unwrap_or(0)
|
||||
.saturating_sub(precpu_stats.system_cpu_usage.unwrap_or(0));
|
||||
|
||||
let online_cpus = cpu_stats.online_cpus.unwrap_or(1);
|
||||
|
||||
let cpu_percent = if system_delta > 0 && online_cpus > 0 {
|
||||
(cpu_delta as f64 / system_delta as f64) * online_cpus as f64 * 100.0
|
||||
} else {
|
||||
0.0
|
||||
};
|
||||
|
||||
return Ok(Some(ContainerCpuInfo {
|
||||
container_id: container_id.to_string(),
|
||||
cpu_usage_percent: cpu_percent,
|
||||
system_cpu_usage: cpu_stats.system_cpu_usage.unwrap_or(0),
|
||||
container_cpu_usage: cpu_usage.total_usage.unwrap_or(0),
|
||||
online_cpus,
|
||||
}));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Ok(None)
|
||||
}
|
||||
|
||||
/// Get average CPU usage across all containers
|
||||
pub async fn get_average_cpu_usage(docker: &Docker) -> Result<f64, Box<dyn Error + Send + Sync>> {
|
||||
let cpu_infos = get_all_containers_cpu_stats(docker).await?;
|
||||
|
||||
if cpu_infos.is_empty() {
|
||||
return Ok(0.0);
|
||||
}
|
||||
|
||||
let total_cpu: f64 = cpu_infos.iter().map(|cpu| cpu.cpu_usage_percent).sum();
|
||||
Ok(total_cpu / cpu_infos.len() as f64)
|
||||
}
|
Reference in New Issue
Block a user