diff --git a/hc/api/management/commands/healthcheck_migration.py b/hc/api/management/commands/healthcheck_migration.py index 35271e9a..841bcc9a 100644 --- a/hc/api/management/commands/healthcheck_migration.py +++ b/hc/api/management/commands/healthcheck_migration.py @@ -5,17 +5,9 @@ from django.core.management.base import BaseCommand from hc.api.models import Check, DEFAULT_TIMEOUT -PROJECT_ID_TO_API_KEY_MAP = { - 2: 'eB-PDSWREOVFjjxZr1ena3hOqB9EglWX', - 1: 'RZ9BZERmgS40paCpfsGw9zomL1VIxlYe', - 3: '5IVMol_f50_6DjsGCImPIcawsNzEZoxb', -} - -PROJECT_ID_TO_INTEGRATION_ID_MAP = { - 2: 'https://hooks.slack.com/services/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', - 1: 'https://hooks.slack.com/services/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', - 3: 'https://hooks.slack.com/services/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', -} +PROJECT_ID_TO_API_KEY_MAP = {} + +PROJECT_ID_TO_INTEGRATION_ID_MAP = {} API_CHECKS_URL = 'https://healthchecks.io/api/v1/checks/' diff --git a/hc/api/management/commands/sendalerts.py b/hc/api/management/commands/sendalerts.py index 737bedf1..4f18bf9e 100644 --- a/hc/api/management/commands/sendalerts.py +++ b/hc/api/management/commands/sendalerts.py @@ -1,6 +1,7 @@ from datetime import timedelta as td import time import requests +from django.db.models import F from threading import Thread from django.core.management.base import BaseCommand @@ -69,12 +70,17 @@ class Command(BaseCommand): ) def process_one_flip(self, use_threads=True): + def _notify(_flip): + if use_threads: + notify_on_thread(_flip.id, self.stdout) + else: + notify(_flip.id, self.stdout) + """ Find unprocessed flip, send notifications. """ # Order by processed, otherwise Django will automatically order by id # and make the query less efficient - q = Flip.objects.filter(processed=None).order_by("processed") - flip = q.first() + flip = Flip.objects.filter(processed=None).order_by("processed").first() if flip is None: return False @@ -83,11 +89,20 @@ class Command(BaseCommand): if num_updated != 1: # Nothing got updated: another worker process got there first. return True + _notify(flip) - if use_threads: - notify_on_thread(flip.id, self.stdout) - else: - notify(flip.id, self.stdout) + #### + # This is custom code for Squad following the above practices, since don't want to change logic much + # #### + flip = Flip.objects.filter(next_alert_at__lte=timezone.now()).order_by("id").first() + if flip is None: + return False + + q = Flip.objects.filter(id=flip.id, next_alert_at__lte=timezone.now()) + num_updated = q.updated(next_alert_at=F('next_alert_at') + flip.check.timeout) + if num_updated != 1: + return True + _notify(flip) return True @@ -104,7 +119,6 @@ class Command(BaseCommand): old_status = check.status q = Check.objects.filter(id=check.id, status=old_status) - try: status = check.get_status(with_started=False) except Exception as e: @@ -129,6 +143,7 @@ class Command(BaseCommand): flip = Flip(owner=check) flip.created = flip_time flip.old_status = old_status + flip.next_alert_at = flip_time + check.timeout flip.new_status = "down" flip.save() diff --git a/hc/api/models.py b/hc/api/models.py index ba5aa13f..e29eb525 100644 --- a/hc/api/models.py +++ b/hc/api/models.py @@ -9,6 +9,7 @@ from croniter import croniter from django.conf import settings from django.core.signing import TimestampSigner from django.db import models +from django.db.models import Max from django.urls import reverse from django.utils import timezone from hc.accounts.models import Project @@ -749,6 +750,13 @@ class Flip(models.Model): old_status = models.CharField(max_length=8, choices=STATUSES) new_status = models.CharField(max_length=8, choices=STATUSES) + next_alert_at = models.DateTimeField( + null=True, blank=True, + help_text="Denotes the time next alerts should be sent in case this " + "flip does not come back to success from failure", + db_index=True + ) + class Meta: indexes = [ # For quickly looking up unprocessed flips. @@ -760,6 +768,19 @@ class Flip(models.Model): ) ] + def x(cls): + check_to_latest_flip_id_map = cls.objects.values('owner_id').order_by('id').annotate(latest_flip=Max('id')) + flip_id_to_obj_map = cls.objects.filter(id__in=check_to_latest_flip_id_map.values()).in_bulk() + + for flip_id, flip_obj in flip_id_to_obj_map.items(): + if flip_obj.new_status == "down": + if flip_obj.processed <= flip_obj.check.timeout + flip_obj.check.grace: + pass + + pass + else: + pass + def to_dict(self): return { "timestamp": isostring(self.created),