Skip to content

Commit 85f17fe

Browse files
committed
[fix] Don't evaluate threshold for historical data #666
Fixes #666
1 parent a9993c7 commit 85f17fe

File tree

2 files changed

+47
-0
lines changed

2 files changed

+47
-0
lines changed

openwisp_monitoring/monitoring/base/models.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -382,6 +382,10 @@ def check_threshold(self, value, time=None, retention_policy=None, send_alert=Tr
382382
alert_settings = self.alertsettings
383383
except ObjectDoesNotExist:
384384
return
385+
if time and alert_settings.is_historical_data(time):
386+
# Device is uploading historical data (could be due to a network outage).
387+
# We don't want to send alerts in this scenario.
388+
return
385389
is_healthy_changed = self._set_is_healthy(alert_settings, value)
386390
tolerance_healthy_changed_first_time = self._set_is_healthy_tolerant(
387391
alert_settings, value, time, retention_policy, send_alert
@@ -942,6 +946,15 @@ def operator(self):
942946
return self.config_dict['operator']
943947
return self.custom_operator
944948

949+
def is_historical_data(self, time):
950+
"""
951+
Data older than 1 hour is considered historical data.
952+
"""
953+
if not time or not isinstance(time, datetime):
954+
raise ValueError('Invalid time value')
955+
recent_time = timezone.now() - timedelta(minutes=60)
956+
return time < recent_time
957+
945958
def _value_crossed(self, current_value):
946959
threshold_value = self.threshold
947960
method = '__gt__' if self.operator == '>' else '__lt__'

openwisp_monitoring/monitoring/tests/test_monitoring_notifications.py

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -319,6 +319,40 @@ def test_object_check_threshold_crossed_for_long_time(self):
319319
self.assertEqual(om.is_healthy_tolerant, True)
320320
self.assertEqual(Notification.objects.count(), 2)
321321

322+
def test_object_check_threshold_crossed_historical_data(self):
323+
"""
324+
Do not evaluate threshold crossed for historical data
325+
"""
326+
self._create_admin()
327+
om = self._create_object_metric(name='load')
328+
self._create_alert_settings(
329+
metric=om, custom_operator='>', custom_threshold=90, custom_tolerance=10
330+
)
331+
332+
self._write_metric(om, 99, time=start_time - timedelta(minutes=120))
333+
om.refresh_from_db()
334+
self.assertEqual(om.is_healthy, True)
335+
self.assertEqual(om.is_healthy_tolerant, True)
336+
self.assertEqual(Notification.objects.count(), 0)
337+
338+
self._write_metric(om, 99, time=start_time - timedelta(minutes=61))
339+
om.refresh_from_db()
340+
self.assertEqual(om.is_healthy, True)
341+
self.assertEqual(om.is_healthy_tolerant, True)
342+
self.assertEqual(Notification.objects.count(), 0)
343+
344+
self._write_metric(om, 99, time=start_time - timedelta(minutes=60))
345+
om.refresh_from_db()
346+
self.assertEqual(om.is_healthy, True)
347+
self.assertEqual(om.is_healthy_tolerant, True)
348+
self.assertEqual(Notification.objects.count(), 0)
349+
350+
self._write_metric(om, 99, time=start_time - timedelta(minutes=10))
351+
om.refresh_from_db()
352+
self.assertEqual(om.is_healthy, False)
353+
self.assertEqual(om.is_healthy_tolerant, False)
354+
self.assertEqual(Notification.objects.count(), 1)
355+
322356
def test_flapping_metric_with_tolerance(self):
323357
self._create_admin()
324358
om = self._create_object_metric(name='ping')

0 commit comments

Comments
 (0)