From 431cc7b185f8a981c6afb2057448a30a718a39e8 Mon Sep 17 00:00:00 2001 From: Dominik Csapak Date: Wed, 10 Jun 2020 12:02:57 +0200 Subject: [PATCH] rrd: move creation of serde value into api there is now a 'extract_cached_data' which just returns the data of the specified field, and an api function that converts a list of fields to the correct serde value this way we do not have to create a serde value in rrd/cache.rs (makes for a better interface) Signed-off-by: Dominik Csapak Signed-off-by: Wolfgang Bumiller --- src/api2/admin/datastore.rs | 7 +++---- src/api2/node.rs | 2 +- src/api2/node/rrd.rs | 42 +++++++++++++++++++++++++++++++++++-- src/rrd/cache.rs | 38 +++++++-------------------------- 4 files changed, 51 insertions(+), 38 deletions(-) diff --git a/src/api2/admin/datastore.rs b/src/api2/admin/datastore.rs index 222e4d21..5d0b8635 100644 --- a/src/api2/admin/datastore.rs +++ b/src/api2/admin/datastore.rs @@ -18,6 +18,7 @@ use proxmox::try_block; use proxmox::{http_err, identity, list_subdirs_api_method, sortable}; use crate::api2::types::*; +use crate::api2::node::rrd::create_value_from_rrd; use crate::backup::*; use crate::config::datastore; use crate::config::cached_user_info::CachedUserInfo; @@ -855,10 +856,8 @@ fn get_rrd_stats( _param: Value, ) -> Result { - let rrd_dir = format!("datastore/{}", store); - - crate::rrd::extract_data( - &rrd_dir, + create_value_from_rrd( + &format!("datastore/{}", store), &[ "total", "used", "read_ios", "read_bytes", diff --git a/src/api2/node.rs b/src/api2/node.rs index 8ff8220d..13ff282c 100644 --- a/src/api2/node.rs +++ b/src/api2/node.rs @@ -9,7 +9,7 @@ mod syslog; mod journal; mod services; mod status; -mod rrd; +pub(crate) mod rrd; pub mod disks; pub const SUBDIRS: SubdirMap = &[ diff --git a/src/api2/node/rrd.rs b/src/api2/node/rrd.rs index 80e5c35c..b857cd3a 100644 --- a/src/api2/node/rrd.rs +++ b/src/api2/node/rrd.rs @@ -1,9 +1,47 @@ use anyhow::Error; -use serde_json::Value; +use serde_json::{Value, json}; use proxmox::api::{api, Router}; use crate::api2::types::*; +use crate::tools::epoch_now_f64; +use crate::rrd::{extract_cached_data, RRD_DATA_ENTRIES}; + +pub fn create_value_from_rrd( + basedir: &str, + list: &[&str], + timeframe: RRDTimeFrameResolution, + cf: RRDMode, +) -> Result { + + let mut result = Vec::new(); + let now = epoch_now_f64()?; + + for name in list { + let (start, reso, list) = match extract_cached_data(basedir, name, now, timeframe, cf) { + Some(result) => result, + None => continue, + }; + + let mut t = start; + for index in 0..RRD_DATA_ENTRIES { + if result.len() <= index { + if let Some(value) = list[index] { + result.push(json!({ "time": t, *name: value })); + } else { + result.push(json!({ "time": t })); + } + } else { + if let Some(value) = list[index] { + result[index][name] = value.into(); + } + } + t += reso; + } + } + + Ok(result.into()) +} #[api( input: { @@ -27,7 +65,7 @@ fn get_node_stats( _param: Value, ) -> Result { - crate::rrd::extract_data( + create_value_from_rrd( "host", &[ "cpu", "iowait", diff --git a/src/rrd/cache.rs b/src/rrd/cache.rs index 90d2c9d1..ce3c551c 100644 --- a/src/rrd/cache.rs +++ b/src/rrd/cache.rs @@ -4,7 +4,6 @@ use std::sync::{RwLock}; use anyhow::{format_err, Error}; use lazy_static::lazy_static; -use serde_json::{json, Value}; use proxmox::tools::fs::{create_path, CreateOptions}; @@ -103,41 +102,18 @@ pub fn extract_lists( Ok((times, result)) } -pub fn extract_data( +pub fn extract_cached_data( base: &str, - items: &[&str], + name: &str, + now: f64, timeframe: RRDTimeFrameResolution, mode: RRDMode, -) -> Result { - - let now = epoch_now_f64()?; +) -> Option<(u64, u64, Vec>)> { let map = RRD_CACHE.read().unwrap(); - let mut result = Vec::new(); - - for name in items.iter() { - let rrd = match map.get(&format!("{}/{}", base, name)) { - Some(rrd) => rrd, - None => continue, - }; - let (start, reso, list) = rrd.extract_data(now, timeframe, mode); - let mut t = start; - for index in 0..RRD_DATA_ENTRIES { - if result.len() <= index { - if let Some(value) = list[index] { - result.push(json!({ "time": t, *name: value })); - } else { - result.push(json!({ "time": t })); - } - } else { - if let Some(value) = list[index] { - result[index][name] = value.into(); - } - } - t += reso; - } + match map.get(&format!("{}/{}", base, name)) { + Some(rrd) => Some(rrd.extract_data(now, timeframe, mode)), + None => None, } - - Ok(result.into()) }