use crate::window::Window;
pub const WINDOW_TOKEN: &str = "{{.window}}";
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum Sli {
Events {
error_query: String,
total_query: String,
},
Raw {
error_ratio_query: String,
},
}
impl Sli {
pub fn error_ratio_expr(&self, window: Window) -> String {
match self {
Sli::Events {
error_query,
total_query,
} => {
format!(
"({})\n/\n({})",
substitute_window(error_query, window),
substitute_window(total_query, window)
)
}
Sli::Raw { error_ratio_query } => substitute_window(error_ratio_query, window),
}
}
pub fn queries(&self) -> Vec<&str> {
match self {
Sli::Events {
error_query,
total_query,
} => vec![error_query, total_query],
Sli::Raw { error_ratio_query } => vec![error_ratio_query],
}
}
}
pub fn substitute_window(query: &str, window: Window) -> String {
let replacement = window.prometheus();
query
.replace("{{ .window }}", &replacement)
.replace(WINDOW_TOKEN, &replacement)
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn events_expr_divides_error_by_total() {
let sli = Sli::Events {
error_query: "sum(rate(errors[{{.window}}]))".to_string(),
total_query: "sum(rate(total[{{.window}}]))".to_string(),
};
let expr = sli.error_ratio_expr(Window::minutes(5));
assert_eq!(expr, "(sum(rate(errors[5m])))\n/\n(sum(rate(total[5m])))");
}
#[test]
fn raw_expr_substitutes_window() {
let sli = Sli::Raw {
error_ratio_query: "my_ratio[{{ .window }}]".to_string(),
};
assert_eq!(sli.error_ratio_expr(Window::hours(1)), "my_ratio[1h]");
}
}