Browse Source

Add some logic for sending uptime notifications

David Burke 3 years ago
parent
commit
6688b6bcd9
2 changed files with 23 additions and 3 deletions
  1. 21 2
      uptime/tasks.py
  2. 2 1
      uptime/tests.py

+ 21 - 2
uptime/tasks.py

@@ -52,10 +52,19 @@ def perform_checks(monitor_ids: List[int], now=None):
     if now is None:
         now = timezone.now()
     # Convert queryset to raw list[dict] for asyncio operations
-    monitors = list(Monitor.objects.filter(pk__in=monitor_ids).values())
+    latest_is_up = Subquery(
+        MonitorCheck.objects.filter(monitor_id=OuterRef("id"))
+        .order_by("-start_check")
+        .values("is_up")[:1]
+    )
+    monitors = list(
+        Monitor.objects.filter(pk__in=monitor_ids)
+        .annotate(latest_is_up=latest_is_up)
+        .values()
+    )
     loop = asyncio.get_event_loop()
     results = loop.run_until_complete(fetch_all(monitors, loop))
-    MonitorCheck.objects.bulk_create(
+    monitor_checks = MonitorCheck.objects.bulk_create(
         [
             MonitorCheck(
                 monitor_id=result["id"],
@@ -67,3 +76,13 @@ def perform_checks(monitor_ids: List[int], now=None):
             for result in results
         ]
     )
+    for i, result in enumerate(results):
+        if result["latest_is_up"] is True and result["is_up"] is False:
+            send_monitor_notification.delay(monitor_checks[i].pk, True)
+        elif result["latest_is_up"] is False and result["is_up"] is True:
+            send_monitor_notification.delay(monitor_checks[i].pk, False)
+
+
+@shared_task
+def send_monitor_notification(monitor_check_id: int, went_down: bool):
+    check = MonitorCheck.objects.get(pk=monitor_check_id).select_related("monitor")

+ 2 - 1
uptime/tests.py

@@ -51,5 +51,6 @@ class UptimeTestCase(TestCase):
         self.assertEqual(mon.checks.count(), 1)
 
         with freeze_time("2020-01-02"):
-            dispatch_checks()
+            with self.assertNumQueries(3):
+                dispatch_checks()
         self.assertEqual(mon.checks.count(), 2)