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 <d.csapak@proxmox.com>
Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
This commit is contained in:
Dominik Csapak 2020-06-10 12:02:57 +02:00 committed by Wolfgang Bumiller
parent e693818afc
commit 431cc7b185
4 changed files with 51 additions and 38 deletions

View File

@ -18,6 +18,7 @@ use proxmox::try_block;
use proxmox::{http_err, identity, list_subdirs_api_method, sortable}; use proxmox::{http_err, identity, list_subdirs_api_method, sortable};
use crate::api2::types::*; use crate::api2::types::*;
use crate::api2::node::rrd::create_value_from_rrd;
use crate::backup::*; use crate::backup::*;
use crate::config::datastore; use crate::config::datastore;
use crate::config::cached_user_info::CachedUserInfo; use crate::config::cached_user_info::CachedUserInfo;
@ -855,10 +856,8 @@ fn get_rrd_stats(
_param: Value, _param: Value,
) -> Result<Value, Error> { ) -> Result<Value, Error> {
let rrd_dir = format!("datastore/{}", store); create_value_from_rrd(
&format!("datastore/{}", store),
crate::rrd::extract_data(
&rrd_dir,
&[ &[
"total", "used", "total", "used",
"read_ios", "read_bytes", "read_ios", "read_bytes",

View File

@ -9,7 +9,7 @@ mod syslog;
mod journal; mod journal;
mod services; mod services;
mod status; mod status;
mod rrd; pub(crate) mod rrd;
pub mod disks; pub mod disks;
pub const SUBDIRS: SubdirMap = &[ pub const SUBDIRS: SubdirMap = &[

View File

@ -1,9 +1,47 @@
use anyhow::Error; use anyhow::Error;
use serde_json::Value; use serde_json::{Value, json};
use proxmox::api::{api, Router}; use proxmox::api::{api, Router};
use crate::api2::types::*; 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<Value, Error> {
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( #[api(
input: { input: {
@ -27,7 +65,7 @@ fn get_node_stats(
_param: Value, _param: Value,
) -> Result<Value, Error> { ) -> Result<Value, Error> {
crate::rrd::extract_data( create_value_from_rrd(
"host", "host",
&[ &[
"cpu", "iowait", "cpu", "iowait",

View File

@ -4,7 +4,6 @@ use std::sync::{RwLock};
use anyhow::{format_err, Error}; use anyhow::{format_err, Error};
use lazy_static::lazy_static; use lazy_static::lazy_static;
use serde_json::{json, Value};
use proxmox::tools::fs::{create_path, CreateOptions}; use proxmox::tools::fs::{create_path, CreateOptions};
@ -103,41 +102,18 @@ pub fn extract_lists(
Ok((times, result)) Ok((times, result))
} }
pub fn extract_data( pub fn extract_cached_data(
base: &str, base: &str,
items: &[&str], name: &str,
now: f64,
timeframe: RRDTimeFrameResolution, timeframe: RRDTimeFrameResolution,
mode: RRDMode, mode: RRDMode,
) -> Result<Value, Error> { ) -> Option<(u64, u64, Vec<Option<f64>>)> {
let now = epoch_now_f64()?;
let map = RRD_CACHE.read().unwrap(); let map = RRD_CACHE.read().unwrap();
let mut result = Vec::new(); match map.get(&format!("{}/{}", base, name)) {
Some(rrd) => Some(rrd.extract_data(now, timeframe, mode)),
for name in items.iter() { None => None,
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;
}
}
Ok(result.into())
}