fn read_system_usage()

in rd-agent/src/report.rs [74:148]


fn read_system_usage(devnr: (u32, u32)) -> Result<(Usage, f64)> {
    let kstat = procfs::KernelStats::new()?;
    let cpu = &kstat.total;
    let mut cpu_total = cpu.user as f64
        + cpu.nice as f64
        + cpu.system as f64
        + cpu.idle as f64
        + cpu.iowait.unwrap() as f64
        + cpu.irq.unwrap() as f64
        + cpu.softirq.unwrap() as f64
        + cpu.steal.unwrap() as f64
        + cpu.guest.unwrap() as f64
        + cpu.guest_nice.unwrap() as f64;
    let mut cpu_busy = cpu_total - cpu.idle as f64 - cpu.iowait.unwrap() as f64;

    let tps = procfs::ticks_per_second()? as f64;
    let cpu_sys = cpu.system as f64 / tps;
    cpu_busy /= tps;
    cpu_total /= tps;

    let mstat = procfs::Meminfo::new()?;
    let mem_bytes = mstat.mem_total - mstat.mem_free;
    let swap_bytes = mstat.swap_total - mstat.swap_free;

    let mut io_rbytes = 0;
    let mut io_wbytes = 0;
    for dstat in linux_proc::diskstats::DiskStats::from_system()?.iter() {
        if dstat.major == devnr.0 as u64 && dstat.minor == devnr.1 as u64 {
            io_rbytes = dstat.sectors_read * 512;
            io_wbytes = dstat.sectors_written * 512;
        }
    }

    let mem_stat_path = "/sys/fs/cgroup/memory.stat";
    let mem_stat = match read_stat_file(&mem_stat_path) {
        Ok(v) => v,
        Err(e) => {
            debug!("report: Failed to read {} ({:?})", &mem_stat_path, &e);
            Default::default()
        }
    };

    let mut io_usage = 0;
    let mut io_stat = Default::default();
    if let Ok(mut is) = read_cgroup_nested_keyed_file("/sys/fs/cgroup/io.stat") {
        if let Some(is) = is.remove(&format!("{}:{}", devnr.0, devnr.1)) {
            if let Some(val) = is.get("cost.usage") {
                io_usage = scan_fmt!(&val, "{}", u64).unwrap_or(0);
            }
            io_stat = is
                .into_iter()
                .map(|(k, v)| (k, v.parse::<f64>().unwrap_or(0.0)))
                .collect();
        }
    }

    Ok((
        Usage {
            cpu_busy,
            cpu_sys,
            mem_bytes,
            swap_bytes,
            swap_free: mstat.swap_free,
            io_rbytes,
            io_wbytes,
            io_usage,
            mem_stat,
            io_stat,
            cpu_stalls: read_stalls("/proc/pressure/cpu")?,
            mem_stalls: read_stalls("/proc/pressure/memory")?,
            io_stalls: read_stalls("/proc/pressure/io")?,
        },
        cpu_total,
    ))
}