Skip to main content

elasticctl_api/compose/
alert_activity.rs

1use crate::alerts::{self, AlertHit};
2use elasticctl_core::{Error, ErrorKind, Result, Transport};
3use serde_json::json;
4#[derive(Debug)]
5pub struct AlertActivity {
6    pub window: String,
7    pub total: u64,
8    pub open: u64,
9    pub acknowledged: u64,
10    pub closed: u64,
11    pub other: u64,
12    pub recent: Vec<AlertHit>,
13}
14pub fn validate_since(value: &str) -> Result<()> {
15    let b = value.as_bytes();
16    if !(2..=5).contains(&b.len())
17        || b[0] == b'0'
18        || !b[..b.len() - 1].iter().all(u8::is_ascii_digit)
19        || !matches!(b[b.len() - 1], b's' | b'm' | b'h' | b'd' | b'w')
20    {
21        return Err(Error::new(ErrorKind::Error, "invalid since"));
22    }
23    Ok(())
24}
25pub async fn alert_activity(
26    t: &Transport,
27    rule_id: &str,
28    since: &str,
29    recent: usize,
30) -> Result<AlertActivity> {
31    validate_since(since)?;
32    let size = recent.min(super::RECENT_ALERTS);
33    let body = json!({"query":{"bool":{"filter":[{"term":{"kibana.alert.rule.rule_id":rule_id}},{"range":{"@timestamp":{"gte":format!("now-{since}")}}}]}},"sort":[{"@timestamp":{"order":"desc"}},{"kibana.alert.uuid":{"order":"asc"}}],"size":size,"track_total_hits":true,"aggs":{"status":{"terms":{"field":"kibana.alert.workflow_status","size":8}}}});
34    let page = alerts::search_activity(t, &body).await?;
35    let mut out = AlertActivity {
36        window: since.into(),
37        total: page.total,
38        open: 0,
39        acknowledged: 0,
40        closed: 0,
41        other: page.other,
42        recent: page.hits.into_iter().take(size).collect(),
43    };
44    for (key, n) in page.buckets {
45        let counter = match key.as_str() {
46            "open" => &mut out.open,
47            "acknowledged" => &mut out.acknowledged,
48            "closed" => &mut out.closed,
49            _ => &mut out.other,
50        };
51        *counter = counter
52            .checked_add(n)
53            .ok_or_else(|| Error::new(ErrorKind::Http, "activity count overflow"))?;
54    }
55    Ok(out)
56}