Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 38 additions & 2 deletions src/alerts/alert_structs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@

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

use chrono::{DateTime, Utc};
use chrono::{DateTime, NaiveDate, Utc};
use serde::{Deserialize, Serialize};
use serde_json::Value;
use tokio::sync::{RwLock, mpsc};
Expand All @@ -36,7 +36,7 @@ use crate::{
},
metastore::metastore_traits::MetastoreObject,
query::resolve_stream_names,
storage::object_storage::{alert_json_path, alert_state_json_path},
storage::object_storage::{alert_json_path, alert_state_json_path, mttr_json_path},
};

const RESERVED_FIELDS: &[&str] = &[
Expand Down Expand Up @@ -695,6 +695,32 @@ pub struct AggregatedMTTRStats {
pub per_alert_stats: HashMap<String, MTTRStats>,
}

/// Daily MTTR statistics for a specific date
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct DailyMTTRStats {
/// Date in YYYY-MM-DD format
pub date: NaiveDate,
/// Aggregated MTTR statistics for this date
pub stats: AggregatedMTTRStats,
}

/// MTTR history containing array of daily MTTR objects
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct MTTRHistory {
/// Array of daily MTTR statistics
pub daily_stats: Vec<DailyMTTRStats>,
}

/// Query parameters for MTTR API endpoint
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct MTTRQueryParams {
pub start_date: Option<String>,
pub end_date: Option<String>,
}

impl AggregatedMTTRStats {
/// Calculate aggregated MTTR stats from multiple alert state entries
pub fn from_alert_states(alert_states: Vec<AlertStateEntry>) -> Self {
Expand Down Expand Up @@ -860,3 +886,13 @@ impl MetastoreObject for AlertConfig {
alert_json_path(self.id).to_string()
}
}

impl MetastoreObject for MTTRHistory {
fn get_object_id(&self) -> String {
"mttr".to_string()
}

fn get_object_path(&self) -> String {
mttr_json_path().to_string()
}
}
9 changes: 8 additions & 1 deletion src/metastore/metastore_traits.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,10 @@ use tonic::async_trait;
use ulid::Ulid;

use crate::{
alerts::{alert_structs::AlertStateEntry, target::Target},
alerts::{
alert_structs::{AlertStateEntry, MTTRHistory},
target::Target,
},
catalog::manifest::Manifest,
handlers::http::modal::NodeType,
metastore::MetastoreError,
Expand Down Expand Up @@ -77,6 +80,10 @@ pub trait Metastore: std::fmt::Debug + Send + Sync {
async fn put_alert_state(&self, obj: &dyn MetastoreObject) -> Result<(), MetastoreError>;
async fn delete_alert_state(&self, obj: &dyn MetastoreObject) -> Result<(), MetastoreError>;

/// mttr history
async fn get_mttr_history(&self) -> Result<Option<MTTRHistory>, MetastoreError>;
async fn put_mttr_history(&self, obj: &dyn MetastoreObject) -> Result<(), MetastoreError>;

/// llmconfig
async fn get_llmconfigs(&self) -> Result<Vec<Bytes>, MetastoreError>;
async fn put_llmconfig(&self, obj: &dyn MetastoreObject) -> Result<(), MetastoreError>;
Expand Down
29 changes: 27 additions & 2 deletions src/metastore/metastores/object_store_metastore.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,10 @@ use tracing::warn;
use ulid::Ulid;

use crate::{
alerts::{alert_structs::AlertStateEntry, target::Target},
alerts::{
alert_structs::{AlertStateEntry, MTTRHistory},
target::Target,
},
catalog::{manifest::Manifest, partition_path},
handlers::http::{
modal::{Metadata, NodeMetadata, NodeType},
Expand All @@ -49,7 +52,7 @@ use crate::{
SETTINGS_ROOT_DIRECTORY, STREAM_METADATA_FILE_NAME, STREAM_ROOT_DIRECTORY,
TARGETS_ROOT_DIRECTORY,
object_storage::{
alert_json_path, alert_state_json_path, filter_path, manifest_path,
alert_json_path, alert_state_json_path, filter_path, manifest_path, mttr_json_path,
parseable_json_path, schema_path, stream_json_path, to_bytes,
},
},
Expand Down Expand Up @@ -305,6 +308,28 @@ impl Metastore for ObjectStoreMetastore {
.await?)
}

/// Get MTTR history from storage
async fn get_mttr_history(&self) -> Result<Option<MTTRHistory>, MetastoreError> {
let path = mttr_json_path();
match self.storage.get_object(&path).await {
Ok(bytes) => {
if let Ok(history) = serde_json::from_slice::<MTTRHistory>(&bytes) {
Ok(Some(history))
} else {
Ok(None)
}
}
Err(ObjectStorageError::NoSuchKey(_)) => Ok(None),
Err(e) => Err(MetastoreError::ObjectStorageError(e)),
}
}

/// Put MTTR history to storage
async fn put_mttr_history(&self, obj: &dyn MetastoreObject) -> Result<(), MetastoreError> {
let path = RelativePathBuf::from(obj.get_object_path());
Ok(self.storage.put_object(&path, to_bytes(obj)).await?)
}

/// This function fetches all the llmconfigs from the underlying object store
async fn get_llmconfigs(&self) -> Result<Vec<Bytes>, MetastoreError> {
let base_path = RelativePathBuf::from_iter([SETTINGS_ROOT_DIRECTORY, "llmconfigs"]);
Expand Down
9 changes: 8 additions & 1 deletion src/storage/object_storage.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1152,7 +1152,7 @@ pub fn target_json_path(target_id: &Ulid) -> RelativePathBuf {
}

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

/// Constructs the path for storing MTTR history JSON file
/// Format: ".alerts/mttr.json"
#[inline(always)]
pub fn mttr_json_path() -> RelativePathBuf {
RelativePathBuf::from_iter([ALERTS_ROOT_DIRECTORY, "mttr.json"])
}

#[inline(always)]
pub fn manifest_path(prefix: &str) -> RelativePathBuf {
let hostname = hostname::get()
Expand Down
Loading