From ce997f0d42b8a52f6e6737b4c9e3719dd006aea2 Mon Sep 17 00:00:00 2001 From: Vladimir Filonov Date: Fri, 18 Oct 2024 12:25:34 +0400 Subject: [PATCH] /incident/{incident-id}/alerts now return only alerts with unique fingerprints --- keep/api/core/db.py | 29 ++++++++++++++++++++++++----- tests/test_rules_engine.py | 10 ++++++---- 2 files changed, 30 insertions(+), 9 deletions(-) diff --git a/keep/api/core/db.py b/keep/api/core/db.py index 10a00c445..6bea7abb3 100644 --- a/keep/api/core/db.py +++ b/keep/api/core/db.py @@ -2838,21 +2838,38 @@ def get_incident_alerts_and_links_by_incident_id( tenant_id: str, incident_id: UUID | str, limit: Optional[int] = None, - offset: Optional[int] = None, + offset: Optional[int] = 0, session: Optional[Session] = None, include_unlinked: bool = False, ) -> tuple[List[tuple[Alert, AlertToIncident]], int]: with existed_or_new_session(session) as session: + + last_fingerprints_subquery = ( + session.query(Alert.fingerprint, func.max(Alert.timestamp).label("max_timestamp")) + .join(AlertToIncident, AlertToIncident.alert_id == Alert.id) + .filter( + AlertToIncident.tenant_id == tenant_id, + AlertToIncident.incident_id == incident_id, + ) + .group_by(Alert.fingerprint) + .subquery() + ) + query = ( session.query( Alert, AlertToIncident, ) + .select_from(last_fingerprints_subquery) + .outerjoin(Alert, and_( + last_fingerprints_subquery.c.fingerprint == Alert.fingerprint, + last_fingerprints_subquery.c.max_timestamp == Alert.timestamp, + + )) .join(AlertToIncident, AlertToIncident.alert_id == Alert.id) - .join(Incident, AlertToIncident.incident_id == Incident.id) .filter( AlertToIncident.tenant_id == tenant_id, - Incident.id == incident_id, + AlertToIncident.incident_id == incident_id, ) .order_by(col(Alert.timestamp).desc()) ) @@ -2863,8 +2880,10 @@ def get_incident_alerts_and_links_by_incident_id( total_count = query.count() - if limit and offset: - query = query.limit(limit).offset(offset) + if limit: + query = query.limit(limit) + if offset: + query = query.offset(offset) return query.all(), total_count diff --git a/tests/test_rules_engine.py b/tests/test_rules_engine.py index 7c032feeb..5abf1f5a9 100644 --- a/tests/test_rules_engine.py +++ b/tests/test_rules_engine.py @@ -385,6 +385,7 @@ def test_incident_resolution_on_all(db_session, create_alert): ) assert alert_count == 2 + # Same fingerprint create_alert( f"Something went wrong", AlertStatus.RESOLVED, @@ -409,7 +410,8 @@ def test_incident_resolution_on_all(db_session, create_alert): limit=10, offset=0, ) - assert alert_count == 3 + # Still 2 alerts, since 2 unique fingerprints + assert alert_count == 2 assert incident.status == IncidentStatus.FIRING.value create_alert( @@ -436,7 +438,7 @@ def test_incident_resolution_on_all(db_session, create_alert): limit=10, offset=0, ) - assert alert_count == 4 + assert alert_count == 2 assert incident.status == IncidentStatus.RESOLVED.value @@ -528,7 +530,7 @@ def test_incident_resolution_on_edge(db_session, create_alert, direction, second limit=10, offset=0, ) - assert alert_count == 3 + assert alert_count == 2 assert incident.status == IncidentStatus.FIRING.value create_alert( @@ -555,7 +557,7 @@ def test_incident_resolution_on_edge(db_session, create_alert, direction, second limit=10, offset=0, ) - assert alert_count == 4 + assert alert_count == 2 assert incident.status == IncidentStatus.RESOLVED.value # Next steps: