Skip to content

Commit 06690ed

Browse files
store mttr history for given date
add structs for daily mttr history add helper functions in object store to save mttr history
1 parent 2f2b324 commit 06690ed

File tree

4 files changed

+81
-9
lines changed

4 files changed

+81
-9
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 tokio::sync::{RwLock, mpsc};
2424
use ulid::Ulid;
@@ -35,7 +35,7 @@ use crate::{
3535
},
3636
metastore::metastore_traits::MetastoreObject,
3737
query::resolve_stream_names,
38-
storage::object_storage::{alert_json_path, alert_state_json_path},
38+
storage::object_storage::{alert_json_path, alert_state_json_path, mttr_json_path},
3939
};
4040

4141
/// Helper struct for basic alert fields during migration
@@ -610,6 +610,32 @@ pub struct AggregatedMTTRStats {
610610
pub per_alert_stats: HashMap<String, MTTRStats>,
611611
}
612612

613+
/// Daily MTTR statistics for a specific date
614+
#[derive(Debug, Clone, Serialize, Deserialize)]
615+
#[serde(rename_all = "camelCase")]
616+
pub struct DailyMTTRStats {
617+
/// Date in YYYY-MM-DD format
618+
pub date: NaiveDate,
619+
/// Aggregated MTTR statistics for this date
620+
pub stats: AggregatedMTTRStats,
621+
}
622+
623+
/// MTTR history containing array of daily MTTR objects
624+
#[derive(Debug, Clone, Serialize, Deserialize)]
625+
#[serde(rename_all = "camelCase")]
626+
pub struct MTTRHistory {
627+
/// Array of daily MTTR statistics
628+
pub daily_stats: Vec<DailyMTTRStats>,
629+
}
630+
631+
/// Query parameters for MTTR API endpoint
632+
#[derive(Debug, Clone, Serialize, Deserialize)]
633+
#[serde(rename_all = "camelCase")]
634+
pub struct MTTRQueryParams {
635+
pub start_date: Option<String>,
636+
pub end_date: Option<String>,
637+
}
638+
613639
impl AggregatedMTTRStats {
614640
/// Calculate aggregated MTTR stats from multiple alert state entries
615641
pub fn from_alert_states(alert_states: Vec<AlertStateEntry>) -> Self {
@@ -775,3 +801,13 @@ impl MetastoreObject for AlertConfig {
775801
alert_json_path(self.id).to_string()
776802
}
777803
}
804+
805+
impl MetastoreObject for MTTRHistory {
806+
fn get_object_id(&self) -> String {
807+
"mttr".to_string()
808+
}
809+
810+
fn get_object_path(&self) -> String {
811+
mttr_json_path().to_string()
812+
}
813+
}

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 & 5 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},
@@ -110,10 +113,7 @@ impl Metastore for ObjectStoreMetastore {
110113
/// Delete an overview
111114
async fn delete_overview(&self, stream: &str) -> Result<(), MetastoreError> {
112115
let path = RelativePathBuf::from_iter([stream, "overview"]);
113-
Ok(self
114-
.storage
115-
.delete_object(&path)
116-
.await?)
116+
Ok(self.storage.delete_object(&path).await?)
117117
}
118118

119119
/// This function fetches all the keystones from the underlying object store
@@ -306,6 +306,28 @@ impl Metastore for ObjectStoreMetastore {
306306
.await?)
307307
}
308308

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