]> git.proxmox.com Git - proxmox-backup.git/blob - src/rrd/cache.rs
avoid chrono dependency, depend on proxmox 0.3.8
[proxmox-backup.git] / src / rrd / cache.rs
1 use std::path::PathBuf;
2 use std::collections::HashMap;
3 use std::sync::{RwLock};
4
5 use anyhow::{format_err, Error};
6 use lazy_static::lazy_static;
7
8 use proxmox::tools::fs::{create_path, CreateOptions};
9
10 use crate::api2::types::{RRDMode, RRDTimeFrameResolution};
11
12 use super::*;
13
14 const PBS_RRD_BASEDIR: &str = "/var/lib/proxmox-backup/rrdb";
15
16 lazy_static!{
17 static ref RRD_CACHE: RwLock<HashMap<String, RRD>> = {
18 RwLock::new(HashMap::new())
19 };
20 }
21
22 /// Create rrdd stat dir with correct permission
23 pub fn create_rrdb_dir() -> Result<(), Error> {
24
25 let backup_user = crate::backup::backup_user()?;
26 let opts = CreateOptions::new()
27 .owner(backup_user.uid)
28 .group(backup_user.gid);
29
30 create_path(PBS_RRD_BASEDIR, None, Some(opts))
31 .map_err(|err: Error| format_err!("unable to create rrdb stat dir - {}", err))?;
32
33 Ok(())
34 }
35
36 pub fn update_value(rel_path: &str, value: f64, dst: DST, save: bool) -> Result<(), Error> {
37
38 let mut path = PathBuf::from(PBS_RRD_BASEDIR);
39 path.push(rel_path);
40
41 std::fs::create_dir_all(path.parent().unwrap())?;
42
43 let mut map = RRD_CACHE.write().unwrap();
44 let now = proxmox::tools::time::epoch_f64();
45
46 if let Some(rrd) = map.get_mut(rel_path) {
47 rrd.update(now, value);
48 if save { rrd.save(&path)?; }
49 } else {
50 let mut rrd = match RRD::load(&path) {
51 Ok(rrd) => rrd,
52 Err(err) => {
53 if err.kind() != std::io::ErrorKind::NotFound {
54 eprintln!("overwriting RRD file {:?}, because of load error: {}", path, err);
55 }
56 RRD::new(dst)
57 },
58 };
59 rrd.update(now, value);
60 if save { rrd.save(&path)?; }
61 map.insert(rel_path.into(), rrd);
62 }
63
64 Ok(())
65 }
66
67 pub fn extract_cached_data(
68 base: &str,
69 name: &str,
70 now: f64,
71 timeframe: RRDTimeFrameResolution,
72 mode: RRDMode,
73 ) -> Option<(u64, u64, Vec<Option<f64>>)> {
74
75 let map = RRD_CACHE.read().unwrap();
76
77 match map.get(&format!("{}/{}", base, name)) {
78 Some(rrd) => Some(rrd.extract_data(now, timeframe, mode)),
79 None => None,
80 }
81 }