Skip to content

Commit 16189eb

Browse files
store mttr history for given date (#1451)
* store mttr history for given date add structs for daily mttr history add helper functions in object store to save mttr history * update mttr path
1 parent 9926adb commit 16189eb

File tree

4 files changed

+81
-6
lines changed

4 files changed

+81
-6
lines changed

src/alerts/alert_structs.rs

Lines changed: 38 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818

1919
use std::{collections::HashMap, time::Duration};
2020

21-
use chrono::{DateTime, Utc};
21+
use chrono::{DateTime, NaiveDate, Utc};
2222
use serde::{Deserialize, Serialize};
2323
use serde_json::Value;
2424
use tokio::sync::{RwLock, mpsc};
@@ -36,7 +36,7 @@ use crate::{
3636
},
3737
metastore::metastore_traits::MetastoreObject,
3838
query::resolve_stream_names,
39-
storage::object_storage::{alert_json_path, alert_state_json_path},
39+
storage::object_storage::{alert_json_path, alert_state_json_path, mttr_json_path},
4040
};
4141

4242
const RESERVED_FIELDS: &[&str] = &[
@@ -695,6 +695,32 @@ pub struct AggregatedMTTRStats {
695695
pub per_alert_stats: HashMap<String, MTTRStats>,
696696
}
697697

698+
/// Daily MTTR statistics for a specific date
699+
#[derive(Debug, Clone, Serialize, Deserialize)]
700+
#[serde(rename_all = "camelCase")]
701+
pub struct DailyMTTRStats {
702+
/// Date in YYYY-MM-DD format
703+
pub date: NaiveDate,
704+
/// Aggregated MTTR statistics for this date
705+
pub stats: AggregatedMTTRStats,
706+
}
707+
708+
/// MTTR history containing array of daily MTTR objects
709+
#[derive(Debug, Clone, Serialize, Deserialize)]
710+
#[serde(rename_all = "camelCase")]
711+
pub struct MTTRHistory {
712+
/// Array of daily MTTR statistics
713+
pub daily_stats: Vec<DailyMTTRStats>,
714+
}
715+
716+
/// Query parameters for MTTR API endpoint
717+
#[derive(Debug, Clone, Serialize, Deserialize)]
718+
#[serde(rename_all = "camelCase")]
719+
pub struct MTTRQueryParams {
720+
pub start_date: Option<String>,
721+
pub end_date: Option<String>,
722+
}
723+
698724
impl AggregatedMTTRStats {
699725
/// Calculate aggregated MTTR stats from multiple alert state entries
700726
pub fn from_alert_states(alert_states: Vec<AlertStateEntry>) -> Self {
@@ -860,3 +886,13 @@ impl MetastoreObject for AlertConfig {
860886
alert_json_path(self.id).to_string()
861887
}
862888
}
889+
890+
impl MetastoreObject for MTTRHistory {
891+
fn get_object_id(&self) -> String {
892+
"mttr".to_string()
893+
}
894+
895+
fn get_object_path(&self) -> String {
896+
mttr_json_path().to_string()
897+
}
898+
}

src/metastore/metastore_traits.rs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,10 @@ use tonic::async_trait;
2727
use ulid::Ulid;
2828

2929
use crate::{
30-
alerts::{alert_structs::AlertStateEntry, target::Target},
30+
alerts::{
31+
alert_structs::{AlertStateEntry, MTTRHistory},
32+
target::Target,
33+
},
3134
catalog::manifest::Manifest,
3235
handlers::http::modal::NodeType,
3336
metastore::MetastoreError,
@@ -77,6 +80,10 @@ pub trait Metastore: std::fmt::Debug + Send + Sync {
7780
async fn put_alert_state(&self, obj: &dyn MetastoreObject) -> Result<(), MetastoreError>;
7881
async fn delete_alert_state(&self, obj: &dyn MetastoreObject) -> Result<(), MetastoreError>;
7982

83+
/// mttr history
84+
async fn get_mttr_history(&self) -> Result<Option<MTTRHistory>, MetastoreError>;
85+
async fn put_mttr_history(&self, obj: &dyn MetastoreObject) -> Result<(), MetastoreError>;
86+
8087
/// llmconfig
8188
async fn get_llmconfigs(&self) -> Result<Vec<Bytes>, MetastoreError>;
8289
async fn put_llmconfig(&self, obj: &dyn MetastoreObject) -> Result<(), MetastoreError>;

src/metastore/metastores/object_store_metastore.rs

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,10 @@ use tracing::warn;
3232
use ulid::Ulid;
3333

3434
use crate::{
35-
alerts::{alert_structs::AlertStateEntry, target::Target},
35+
alerts::{
36+
alert_structs::{AlertStateEntry, MTTRHistory},
37+
target::Target,
38+
},
3639
catalog::{manifest::Manifest, partition_path},
3740
handlers::http::{
3841
modal::{Metadata, NodeMetadata, NodeType},
@@ -49,7 +52,7 @@ use crate::{
4952
SETTINGS_ROOT_DIRECTORY, STREAM_METADATA_FILE_NAME, STREAM_ROOT_DIRECTORY,
5053
TARGETS_ROOT_DIRECTORY,
5154
object_storage::{
52-
alert_json_path, alert_state_json_path, filter_path, manifest_path,
55+
alert_json_path, alert_state_json_path, filter_path, manifest_path, mttr_json_path,
5356
parseable_json_path, schema_path, stream_json_path, to_bytes,
5457
},
5558
},
@@ -305,6 +308,28 @@ impl Metastore for ObjectStoreMetastore {
305308
.await?)
306309
}
307310

311+
/// Get MTTR history from storage
312+
async fn get_mttr_history(&self) -> Result<Option<MTTRHistory>, MetastoreError> {
313+
let path = mttr_json_path();
314+
match self.storage.get_object(&path).await {
315+
Ok(bytes) => {
316+
if let Ok(history) = serde_json::from_slice::<MTTRHistory>(&bytes) {
317+
Ok(Some(history))
318+
} else {
319+
Ok(None)
320+
}
321+
}
322+
Err(ObjectStorageError::NoSuchKey(_)) => Ok(None),
323+
Err(e) => Err(MetastoreError::ObjectStorageError(e)),
324+
}
325+
}
326+
327+
/// Put MTTR history to storage
328+
async fn put_mttr_history(&self, obj: &dyn MetastoreObject) -> Result<(), MetastoreError> {
329+
let path = RelativePathBuf::from(obj.get_object_path());
330+
Ok(self.storage.put_object(&path, to_bytes(obj)).await?)
331+
}
332+
308333
/// This function fetches all the llmconfigs from the underlying object store
309334
async fn get_llmconfigs(&self) -> Result<Vec<Bytes>, MetastoreError> {
310335
let base_path = RelativePathBuf::from_iter([SETTINGS_ROOT_DIRECTORY, "llmconfigs"]);

src/storage/object_storage.rs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1152,7 +1152,7 @@ pub fn target_json_path(target_id: &Ulid) -> RelativePathBuf {
11521152
}
11531153

11541154
/// Constructs the path for storing alert state JSON files
1155-
/// Format: ".parseable/alerts/alert_state_{alert_id}.json"
1155+
/// Format: ".alerts/alert_state_{alert_id}.json"
11561156
#[inline(always)]
11571157
pub fn alert_state_json_path(alert_id: Ulid) -> RelativePathBuf {
11581158
RelativePathBuf::from_iter([
@@ -1161,6 +1161,13 @@ pub fn alert_state_json_path(alert_id: Ulid) -> RelativePathBuf {
11611161
])
11621162
}
11631163

1164+
/// Constructs the path for storing MTTR history JSON file
1165+
/// Format: ".alerts/mttr.json"
1166+
#[inline(always)]
1167+
pub fn mttr_json_path() -> RelativePathBuf {
1168+
RelativePathBuf::from_iter([ALERTS_ROOT_DIRECTORY, "mttr.json"])
1169+
}
1170+
11641171
#[inline(always)]
11651172
pub fn manifest_path(prefix: &str) -> RelativePathBuf {
11661173
let hostname = hostname::get()

0 commit comments

Comments
 (0)