fix docker cpu usage

This commit is contained in:
Robin Appelman 2021-03-29 23:28:32 +02:00
commit 9a1b8ca9f2
4 changed files with 43 additions and 26 deletions

2
Cargo.lock generated
View file

@ -76,8 +76,6 @@ dependencies = [
[[package]] [[package]]
name = "bollard" name = "bollard"
version = "0.10.1" version = "0.10.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "699194c00f3a2effd3358d47f880646818e3d483190b17ebcdf598c654fb77e9"
dependencies = [ dependencies = [
"base64", "base64",
"bollard-stubs", "bollard-stubs",

View file

@ -15,7 +15,7 @@ once_cell = "1"
hostname = "0.3" hostname = "0.3"
libc = "0.2" libc = "0.2"
ahash = "0.7" ahash = "0.7"
bollard = "0.10" bollard = { version = "0.10", path = "../bollard" }
futures-util = "0.3" futures-util = "0.3"
[dev-dependencies] [dev-dependencies]

View file

@ -1,23 +1,16 @@
use bollard::container::Stats; use crate::sensors::clock_ticks;
use bollard::container::{Stats, StatsOptions};
use bollard::Docker; use bollard::Docker;
use color_eyre::Result; use color_eyre::Result;
use futures_util::stream::{iter, Stream, StreamExt}; use futures_util::future::ready;
use futures_util::stream::{FuturesUnordered, Stream, StreamExt};
use std::fmt::Write; use std::fmt::Write;
#[derive(Debug)]
pub struct Container { pub struct Container {
name: String, name: String,
memory: u64, memory: u64,
cpu_time: u64, cpu_time: f64,
}
impl From<Stats> for Container {
fn from(stats: Stats) -> Self {
Container {
name: stats.name,
memory: stats.memory_stats.usage.unwrap_or_default(),
cpu_time: stats.cpu_stats.cpu_usage.total_usage,
}
}
} }
impl Container { impl Container {
@ -30,11 +23,22 @@ impl Container {
.ok(); .ok();
writeln!( writeln!(
&mut w, &mut w,
"container_cpu_time{{host=\"{}\", container=\"{}\"}} {}", "container_cpu_time{{host=\"{}\", container=\"{}\"}} {:.3}",
hostname, self.name, self.cpu_time hostname, self.name, self.cpu_time
) )
.ok(); .ok();
} }
fn from(stats: Stats, ticks: u64) -> Self {
Container {
name: stats.name,
memory: stats.memory_stats.usage.unwrap_or_default(),
cpu_time: stats.cpu_stats.cpu_usage.total_usage as f64
/ 1_000_000.0
/ ticks as f64
/ stats.cpu_stats.online_cpus.unwrap_or(1) as f64,
}
}
} }
pub async fn get_docker() -> Option<Docker> { pub async fn get_docker() -> Option<Docker> {
@ -49,13 +53,28 @@ pub async fn get_docker() -> Option<Docker> {
} }
pub async fn stat(docker: Docker) -> Result<impl Stream<Item = Container>> { pub async fn stat(docker: Docker) -> Result<impl Stream<Item = Container>> {
let ticks = clock_ticks()?;
let containers = docker.list_containers::<String>(None).await?; let containers = docker.list_containers::<String>(None).await?;
Ok(iter(containers.into_iter()).filter_map(move |container| { Ok(containers
let docker = docker.clone(); .into_iter()
async move { .map(move |container| {
let id = container.id.unwrap(); let docker = docker.clone();
let stats: Stats = docker.stats(&id, None).next().await?.ok()?; async move {
Some(stats.into()) let id = container.id.unwrap();
} let stats: Stats = docker
})) .stats(
&id,
Some(StatsOptions {
stream: false,
one_shot: true,
}),
)
.next()
.await?
.ok()?;
Some(Container::from(stats, ticks))
}
})
.collect::<FuturesUnordered<_>>()
.filter_map(|opt| ready(opt)))
} }

View file

@ -246,7 +246,7 @@ pub fn disk_usage() -> Result<impl Iterator<Item = DiskUsage>> {
})) }))
} }
fn clock_ticks() -> Result<u64> { pub fn clock_ticks() -> Result<u64> {
let result = unsafe { libc::sysconf(libc::_SC_CLK_TCK) }; let result = unsafe { libc::sysconf(libc::_SC_CLK_TCK) };
if result > 0 { if result > 0 {