use crate::error::Result;
use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct RecordingRule {
pub record: String,
pub expr: String,
pub labels: Option<std::collections::HashMap<String, String>>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct RuleGroup {
pub name: String,
pub interval: String,
pub rules: Vec<RecordingRule>,
}
pub fn create_oxigdal_rules() -> Vec<RuleGroup> {
vec![
RuleGroup {
name: "oxigdal_raster".to_string(),
interval: "30s".to_string(),
rules: vec![
RecordingRule {
record: "oxigdal:raster:read_rate:5m".to_string(),
expr: "rate(oxigdal_raster_read_count[5m])".to_string(),
labels: None,
},
RecordingRule {
record: "oxigdal:raster:write_rate:5m".to_string(),
expr: "rate(oxigdal_raster_write_count[5m])".to_string(),
labels: None,
},
RecordingRule {
record: "oxigdal:raster:read_throughput_mbps:5m".to_string(),
expr: "rate(oxigdal_raster_read_bytes[5m]) / 1024 / 1024".to_string(),
labels: None,
},
],
},
RuleGroup {
name: "oxigdal_cache".to_string(),
interval: "30s".to_string(),
rules: vec![
RecordingRule {
record: "oxigdal:cache:hit_ratio:5m".to_string(),
expr: "rate(oxigdal_cache_hits[5m]) / (rate(oxigdal_cache_hits[5m]) + rate(oxigdal_cache_misses[5m]))".to_string(),
labels: None,
},
RecordingRule {
record: "oxigdal:cache:eviction_rate:5m".to_string(),
expr: "rate(oxigdal_cache_evictions[5m])".to_string(),
labels: None,
},
],
},
RuleGroup {
name: "oxigdal_query".to_string(),
interval: "30s".to_string(),
rules: vec![
RecordingRule {
record: "oxigdal:query:duration:p95".to_string(),
expr: "histogram_quantile(0.95, rate(oxigdal_query_duration_bucket[5m]))".to_string(),
labels: None,
},
RecordingRule {
record: "oxigdal:query:duration:p99".to_string(),
expr: "histogram_quantile(0.99, rate(oxigdal_query_duration_bucket[5m]))".to_string(),
labels: None,
},
RecordingRule {
record: "oxigdal:query:error_rate:5m".to_string(),
expr: "rate(oxigdal_query_errors[5m]) / rate(oxigdal_query_count[5m])".to_string(),
labels: None,
},
],
},
]
}
pub fn export_prometheus_yaml(groups: &[RuleGroup]) -> Result<String> {
serde_json::to_string_pretty(&serde_json::json!({
"groups": groups
}))
.map_err(crate::error::ObservabilityError::Serialization)
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_create_rules() {
let rules = create_oxigdal_rules();
assert!(!rules.is_empty());
}
#[test]
fn test_export_yaml() {
let rules = create_oxigdal_rules();
let yaml = export_prometheus_yaml(&rules);
assert!(yaml.is_ok());
}
}