entrenar/monitor/storage/
json_file.rs1use std::path::Path;
4
5use super::error::{StorageError, StorageResult};
6use super::in_memory::InMemoryStore;
7use super::traits::MetricsStore;
8use crate::monitor::{Metric, MetricRecord, MetricStats};
9
10pub struct JsonFileStore {
12 path: std::path::PathBuf,
13 records: Vec<MetricRecord>,
14 dirty: bool,
15}
16
17impl JsonFileStore {
18 pub fn open<P: AsRef<Path>>(path: P) -> StorageResult<Self> {
20 let path = path.as_ref().to_path_buf();
21 let records = if path.exists() {
22 let content = std::fs::read_to_string(&path)?;
23 serde_json::from_str(&content)
24 .map_err(|e| StorageError::Serialization(e.to_string()))?
25 } else {
26 Vec::new()
27 };
28
29 Ok(Self { path, records, dirty: false })
30 }
31
32 pub fn path(&self) -> &Path {
34 &self.path
35 }
36}
37
38impl MetricsStore for JsonFileStore {
39 fn write_batch(&mut self, records: &[MetricRecord]) -> StorageResult<()> {
40 self.records.extend(records.iter().cloned());
41 self.dirty = true;
42 Ok(())
43 }
44
45 fn query_range(
46 &self,
47 metric: &Metric,
48 start_ts: u64,
49 end_ts: u64,
50 ) -> StorageResult<Vec<MetricRecord>> {
51 Ok(self
52 .records
53 .iter()
54 .filter(|r| &r.metric == metric && r.timestamp >= start_ts && r.timestamp <= end_ts)
55 .cloned()
56 .collect())
57 }
58
59 fn query_all(&self, metric: &Metric) -> StorageResult<Vec<MetricRecord>> {
60 Ok(self.records.iter().filter(|r| &r.metric == metric).cloned().collect())
61 }
62
63 fn query_stats(&self, metric: &Metric) -> StorageResult<Option<MetricStats>> {
64 let mem_store = InMemoryStore { records: self.records.clone() };
66 mem_store.query_stats(metric)
67 }
68
69 fn count(&self) -> StorageResult<usize> {
70 Ok(self.records.len())
71 }
72
73 fn flush(&mut self) -> StorageResult<()> {
74 if self.dirty {
75 let json = serde_json::to_string_pretty(&self.records)
76 .map_err(|e| StorageError::Serialization(e.to_string()))?;
77 std::fs::write(&self.path, json)?;
78 self.dirty = false;
79 }
80 Ok(())
81 }
82}
83
84impl Drop for JsonFileStore {
85 fn drop(&mut self) {
86 let _ = self.flush();
87 }
88}