1use serde_json::Value;
2
3#[derive(Deserialize, Debug, PartialEq, Clone)]
5pub struct PGMap {
6 pub osd_stats_sum: OsdStatsSum,
7 pub pg_stats_delta: PgStatsDelta,
8 pub min_last_epoch_clean: Option<i32>,
9 pub stamp: String,
10 pub pg_stats_sum: PgStatsSum,
11 pub last_pg_scan: i32,
12 pub full_ratio: Option<Value>,
13 pub pool_stats: Vec<PoolStats>,
14 pub version: i32,
15 pub last_osdmap_epoch: i32,
16 pub near_full_ratio: Option<Value>,
17 pub osd_stats: Vec<OsdStats>,
18 pub pg_stats: Vec<PgStats>,
19}
20
21#[derive(Deserialize, Debug, PartialEq, Clone)]
22pub struct OsdStats {
23 pub snap_trim_queue_len: i32,
24 pub kb: i32,
25 pub fs_perf_stat: Option<FsPerfStat>,
26 pub hb_in: Option<Vec<i32>>,
27 pub num_snap_trimming: i32,
28 pub hb_out: Option<Vec<i32>>,
29 pub kb_avail: i32,
30 pub kb_used: i32,
31 pub op_queue_age_hist: OpQueueAgeHist,
32 pub osd: i32,
33}
34
35#[derive(Deserialize, Debug, PartialEq, Clone)]
36pub struct PgStatsDelta {
37 pub acting: Option<i32>,
38 pub log_size: i32,
39 pub ondisk_log_size: i32,
40 pub stat_sum: StatSum,
41 pub up: Option<i32>,
42}
43
44#[derive(Deserialize, Debug, PartialEq, Clone)]
45pub struct StatSum {
46 pub num_evict: Option<i32>,
47 pub num_evict_kb: Option<i32>,
48 pub num_bytes_hit_set_archive: Option<i32>,
49 pub num_whiteouts: i32,
50 pub num_objects_pinned: Option<i32>,
51 pub num_scrub_errors: i32,
52 pub num_evict_mode_full: Option<i32>,
53 pub num_read: i32,
54 pub num_objects_recovered: i32,
55 pub num_objects_omap: i32,
56 pub num_objects_missing_on_primary: i32,
57 pub num_write: i32,
58 pub num_object_clones: i32,
59 pub num_objects: i32,
60 pub num_deep_scrub_errors: i32,
61 pub num_shallow_scrub_errors: i32,
62 pub num_read_kb: i32,
63 pub num_objects_missing: Option<i32>,
64 pub num_flush_kb: Option<i32>,
65 pub num_flush_mode_high: Option<i32>,
66 pub num_write_kb: i32,
67 pub num_evict_mode_some: Option<i32>,
68 pub num_objects_degraded: i32,
69 pub num_flush: Option<i32>,
70 pub num_objects_misplaced: Option<i32>,
71 pub num_bytes_recovered: i32,
72 pub num_objects_hit_set_archive: i32,
73 pub num_keys_recovered: i32,
74 pub num_flush_mode_low: Option<i32>,
75 pub num_objects_unfound: i32,
76 pub num_promote: Option<i32>,
77 pub num_object_copies: i32,
78 pub num_bytes: i32,
79 pub num_objects_dirty: i32,
80}
81
82#[derive(Deserialize, Debug, PartialEq, Clone)]
83pub struct PgStatsSum {
84 pub acting: Option<i32>,
85 pub log_size: i32,
86 pub ondisk_log_size: i32,
87 pub stat_sum: StatSum,
88 pub up: Option<i32>,
89}
90
91#[derive(Deserialize, Debug, PartialEq, Clone)]
92pub struct OsdStatsSum {
93 pub snap_trim_queue_len: i32,
94 pub kb: i32,
95 pub fs_perf_stat: Option<FsPerfStat>,
96 pub hb_in: Option<Vec<i32>>,
97 pub num_snap_trimming: i32,
98 pub hb_out: Option<Vec<i32>>,
99 pub kb_avail: i32,
100 pub kb_used: i32,
101 pub op_queue_age_hist: OpQueueAgeHist,
102}
103
104#[derive(Deserialize, Debug, PartialEq, Clone)]
105pub struct OpQueueAgeHist {
106 pub upper_bound: i32,
107 pub histogram: Vec<i32>,
108}
109
110#[derive(Deserialize, Debug, PartialEq, Clone)]
111pub struct FsPerfStat {
112 pub apply_latency_ms: i32,
113 pub commit_latency_ms: i32,
114}
115
116#[derive(Deserialize, Debug, PartialEq, Clone)]
117pub struct PoolStats {
118 pub log_size: i32,
119 pub ondisk_log_size: i32,
120 pub up: Option<i32>,
121 pub acting: Option<i32>,
122 pub poolid: i32,
123 pub stat_sum: StatSum,
124}
125
126#[derive(Deserialize, Debug, PartialEq, Clone)]
127pub struct PgStats {
128 pub last_scrub: String,
129 pub last_clean_scrub_stamp: String,
130 pub parent_split_bits: i32,
131 pub last_active: String,
132 pub pin_stats_invalid: Option<bool>,
133 pub reported_epoch: String,
134 pub log_start: String,
135 pub log_size: i32,
136 pub hitset_stats_invalid: Option<bool>,
137 pub stats_invalid: Value,
138 pub acting_primary: i32,
139 pub reported_seq: String,
140 pub ondisk_log_size: i32,
141 pub mapping_epoch: i32,
142 pub dirty_stats_invalid: Option<bool>,
143 pub state: String,
144 pub version: String,
145 pub last_became_peered: Option<String>,
146 pub last_undegraded: Option<String>,
147 pub pgid: String,
148 pub parent: String,
149 pub acting: Vec<i32>,
150 pub up_primary: i32,
151 pub last_fullsized: Option<String>,
152 pub last_epoch_clean: i32,
153 pub last_deep_scrub_stamp: String,
154 pub stat_sum: StatSum,
155 pub last_deep_scrub: String,
156 pub last_fresh: String,
157 pub last_scrub_stamp: String,
158 pub created: i32,
159 pub up: Vec<i32>,
160 pub hitset_bytes_stats_invalid: Option<bool>,
161 pub last_peered: Option<String>,
162 pub last_became_active: String,
163 pub omap_stats_invalid: Option<bool>,
164 pub last_clean: String,
165 pub last_unstale: String,
166 pub last_change: String,
167 pub blocked_by: Option<Vec<i32>>,
168 pub ondisk_log_start: String,
169}
170
171#[cfg(test)]
172mod tests {
173 use super::PGMap;
174 use crate::from::FromFile;
175
176 #[test]
178 #[should_panic]
179 fn pgmap_from_jewel_file_panic() {
180 let pgmap = PGMap::from_file("test/jewel/pg_dump_safe.json").unwrap();
181 assert_eq!(pgmap.pg_stats.first().unwrap().up.len(), 0);
183 }
184
185 #[test]
186 fn pgmap_from_jewel_file() {
187 let pgmap = PGMap::from_file("test/jewel/pg_dump_safe.json").unwrap();
188 assert_eq!(pgmap.pg_stats.first().unwrap().up.len() as i32, 3);
190 }
191
192 #[test]
193 #[should_panic]
194 fn pgmap_from_jewel_file_no_osd_panic() {
195 let pgmap = PGMap::from_file("test/jewel/pg_dump_no_osd.json").unwrap();
196 assert_eq!(
198 pgmap.pg_stats.first().unwrap().state,
199 "active+clean".to_owned()
200 );
201 }
202
203 #[test]
204 fn pgmap_from_jewel_file_no_osd() {
205 let pgmap = PGMap::from_file("test/jewel/pg_dump_no_osd.json").unwrap();
206 assert_eq!(pgmap.pg_stats.first().unwrap().up.len() as i32, 0);
208 }
209
210 #[test]
211 fn pgmap_from_jewel_file_non_safe() {
212 let pgmap = PGMap::from_file("test/jewel/pg_dump_non_safe.json").unwrap();
213 assert_eq!(pgmap.pg_stats.first().unwrap().up.len() as i32, 2);
215 assert_eq!(pgmap.pg_stats.first().unwrap().acting.len() as i32, 2);
216 }
217
218 #[test]
219 #[should_panic]
220 fn pgmap_from_jewel_file_non_safe_panic() {
221 let pgmap = PGMap::from_file("test/jewel/pg_dump_non_safe.json").unwrap();
222 assert_eq!(pgmap.pg_stats.first().unwrap().up.len() as i32, 3);
223 }
224
225 #[test]
227 fn pgmap_from_firefly_file() {
228 let pgmap = PGMap::from_file("test/firefly/pg_dump_safe.json").unwrap();
229 assert_eq!(pgmap.pg_stats.first().unwrap().up.len() as i32, 3);
230 }
231
232 #[test]
233 #[should_panic]
234 fn pgmap_from_firefly_file_panic() {
235 let pgmap = PGMap::from_file("test/firefly/pg_dump_safe.json").unwrap();
236 assert_eq!(pgmap.pg_stats.first().unwrap().acting.len() as i32, 0);
237 }
238
239 #[test]
240 #[should_panic]
241 fn pgmap_from_ceph_panic() {
242 use crate::from::FromCeph;
243 let pgmap = PGMap::from_ceph("pg dump");
244 assert_eq!(pgmap.is_ok(), true);
245 }
246}