]>
Commit | Line | Data |
---|---|---|
1198f8d4 | 1 | use anyhow::{bail, Error}; |
dc7a5b34 | 2 | use serde_json::{json, Value}; |
1198f8d4 | 3 | use std::collections::BTreeMap; |
a2f862ee | 4 | |
6ef1b649 | 5 | use proxmox_router::{Permission, Router}; |
93e9e8b6 | 6 | use proxmox_rrd_api_types::{RrdMode, RrdTimeframe}; |
6ef1b649 | 7 | use proxmox_schema::api; |
a2f862ee | 8 | |
f9843eec | 9 | use pbs_api_types::{NODE_SCHEMA, PRIV_SYS_AUDIT}; |
d1c3bc53 | 10 | |
fae4f6c5 | 11 | use crate::rrd_cache::extract_rrd_data; |
431cc7b1 DC |
12 | |
13 | pub fn create_value_from_rrd( | |
14 | basedir: &str, | |
15 | list: &[&str], | |
93e9e8b6 WB |
16 | timeframe: RrdTimeframe, |
17 | mode: RrdMode, | |
431cc7b1 | 18 | ) -> Result<Value, Error> { |
1198f8d4 | 19 | let mut result: Vec<Value> = Vec::new(); |
fa49d0fd | 20 | |
1198f8d4 DM |
21 | let mut timemap = BTreeMap::new(); |
22 | ||
23 | let mut last_resolution = None; | |
24 | ||
431cc7b1 | 25 | for name in list { |
eb37d4ec | 26 | let (start, reso, data) = match extract_rrd_data(basedir, name, timeframe, mode)? { |
92ead5d3 | 27 | Some(result) => result.into(), |
431cc7b1 DC |
28 | None => continue, |
29 | }; | |
30 | ||
dc7a5b34 | 31 | if let Some(expected_resolution) = last_resolution { |
1198f8d4 | 32 | if reso != expected_resolution { |
dc7a5b34 TL |
33 | bail!( |
34 | "got unexpected RRD resolution ({} != {})", | |
35 | reso, | |
36 | expected_resolution | |
37 | ); | |
1198f8d4 DM |
38 | } |
39 | } else { | |
40 | last_resolution = Some(reso); | |
41 | } | |
42 | ||
431cc7b1 | 43 | let mut t = start; |
1198f8d4 | 44 | |
e1db0670 FG |
45 | for value in data { |
46 | let entry = timemap.entry(t).or_insert_with(|| json!({ "time": t })); | |
47 | if let Some(value) = value { | |
1198f8d4 | 48 | entry[*name] = value.into(); |
431cc7b1 DC |
49 | } |
50 | t += reso; | |
51 | } | |
52 | } | |
53 | ||
1198f8d4 DM |
54 | for item in timemap.values() { |
55 | result.push(item.clone()); | |
56 | } | |
57 | ||
431cc7b1 DC |
58 | Ok(result.into()) |
59 | } | |
a2f862ee DM |
60 | |
61 | #[api( | |
62 | input: { | |
63 | properties: { | |
64 | node: { | |
65 | schema: NODE_SCHEMA, | |
66 | }, | |
67 | timeframe: { | |
93e9e8b6 | 68 | type: RrdTimeframe, |
a2f862ee DM |
69 | }, |
70 | cf: { | |
93e9e8b6 | 71 | type: RrdMode, |
a2f862ee DM |
72 | }, |
73 | }, | |
74 | }, | |
463c0346 FG |
75 | access: { |
76 | permission: &Permission::Privilege(&["system", "status"], PRIV_SYS_AUDIT, false), | |
77 | }, | |
a2f862ee | 78 | )] |
a4a3f7ca | 79 | /// Read node stats |
93e9e8b6 | 80 | fn get_node_stats(timeframe: RrdTimeframe, cf: RrdMode, _param: Value) -> Result<Value, Error> { |
431cc7b1 | 81 | create_value_from_rrd( |
a4a3f7ca | 82 | "host", |
3e930f2b | 83 | &[ |
dc7a5b34 TL |
84 | "cpu", |
85 | "iowait", | |
86 | "memtotal", | |
87 | "memused", | |
88 | "swaptotal", | |
89 | "swapused", | |
90 | "netin", | |
91 | "netout", | |
d8dc2819 | 92 | "loadavg", |
dc7a5b34 TL |
93 | "total", |
94 | "used", | |
95 | "read_ios", | |
96 | "read_bytes", | |
97 | "write_ios", | |
98 | "write_bytes", | |
c94e1f65 | 99 | "io_ticks", |
dc7a5b34 | 100 | ], |
a4a3f7ca DM |
101 | timeframe, |
102 | cf, | |
103 | ) | |
a2f862ee DM |
104 | } |
105 | ||
dc7a5b34 | 106 | pub const ROUTER: Router = Router::new().get(&API_METHOD_GET_NODE_STATS); |