forked from GithubBackups/healthchecks
Background worker to send notifications
This commit is contained in:
parent
7997879bd8
commit
aad4bd2ffb
@ -2,6 +2,7 @@ from django.contrib import admin
|
||||
|
||||
from hc.api.models import Check
|
||||
|
||||
|
||||
@admin.register(Check)
|
||||
class ChecksAdmin(admin.ModelAdmin):
|
||||
list_display = ("id", "code", "user", "last_ping")
|
||||
|
27
hc/api/management/commands/ensuretriggers.py
Normal file
27
hc/api/management/commands/ensuretriggers.py
Normal file
@ -0,0 +1,27 @@
|
||||
from django.core.management.base import BaseCommand
|
||||
from django.db import connection
|
||||
|
||||
|
||||
class Command(BaseCommand):
|
||||
help = 'Ensures triggers exist in database'
|
||||
|
||||
def handle(self, *args, **options):
|
||||
cursor = connection.cursor()
|
||||
|
||||
cursor.execute("""
|
||||
CREATE OR REPLACE FUNCTION update_alert_after()
|
||||
RETURNS trigger AS $update_alert_after$
|
||||
BEGIN
|
||||
IF NEW.last_ping IS NOT NULL THEN
|
||||
NEW.alert_after := NEW.last_ping + NEW.timeout;
|
||||
END IF;
|
||||
RETURN NEW;
|
||||
END;
|
||||
$update_alert_after$ LANGUAGE plpgsql;
|
||||
|
||||
DROP TRIGGER IF EXISTS update_alert_after ON api_check;
|
||||
|
||||
CREATE TRIGGER update_alert_after
|
||||
BEFORE INSERT OR UPDATE OF last_ping, timeout ON api_check
|
||||
FOR EACH ROW EXECUTE PROCEDURE update_alert_after();
|
||||
""")
|
45
hc/api/management/commands/sendalerts.py
Normal file
45
hc/api/management/commands/sendalerts.py
Normal file
@ -0,0 +1,45 @@
|
||||
import sys
|
||||
import time
|
||||
|
||||
from django.core.management.base import BaseCommand
|
||||
from django.utils import timezone
|
||||
|
||||
from hc.api.models import Check
|
||||
from hc.lib.emails import send_status_notification
|
||||
|
||||
|
||||
def _log(message):
|
||||
sys.stdout.write(message)
|
||||
sys.stdout.flush()
|
||||
|
||||
|
||||
class Command(BaseCommand):
|
||||
help = 'Ensures triggers exist in database'
|
||||
|
||||
def handle(self, *args, **options):
|
||||
|
||||
while True:
|
||||
# Gone down?
|
||||
query = Check.objects
|
||||
query = query.filter(alert_after__lt=timezone.now())
|
||||
query = query.filter(enabled=True, status="up")
|
||||
for check in query:
|
||||
check.status = "down"
|
||||
check.save()
|
||||
|
||||
_log("\nSending email about going down for %s\n" % check.code)
|
||||
send_status_notification(check)
|
||||
|
||||
# Gone up?
|
||||
query = Check.objects
|
||||
query = query.filter(alert_after__gt=timezone.now())
|
||||
query = query.filter(enabled=True, status="down")
|
||||
for check in query:
|
||||
check.status = "up"
|
||||
check.save()
|
||||
|
||||
_log("\nSending email about going up for %s\n" % check.code)
|
||||
send_status_notification(check)
|
||||
|
||||
time.sleep(1)
|
||||
_log(".")
|
35
hc/api/migrations/0002_auto_20150616_0732.py
Normal file
35
hc/api/migrations/0002_auto_20150616_0732.py
Normal file
@ -0,0 +1,35 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from django.db import models, migrations
|
||||
import datetime
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('api', '0001_initial'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='check',
|
||||
name='alert_after',
|
||||
field=models.DateTimeField(null=True, blank=True),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='check',
|
||||
name='enabled',
|
||||
field=models.BooleanField(default=True),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='check',
|
||||
name='status',
|
||||
field=models.CharField(max_length=6, choices=[('up', 'Up'), ('down', 'Down'), ('new', 'New')], default='new'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='check',
|
||||
name='timeout',
|
||||
field=models.DurationField(choices=[(datetime.timedelta(0, 300), '5 minutes'), (datetime.timedelta(0, 600), '10 minutes'), (datetime.timedelta(0, 1800), '30 minutes'), (datetime.timedelta(0, 3600), '1 hour'), (datetime.timedelta(0, 7200), '2 hours'), (datetime.timedelta(0, 21600), '6 hours'), (datetime.timedelta(0, 43200), '12 hours'), (datetime.timedelta(1), '1 day'), (datetime.timedelta(2), '2 days'), (datetime.timedelta(7), '1 week'), (datetime.timedelta(14), '2 weeks')], default=datetime.timedelta(1)),
|
||||
),
|
||||
]
|
@ -1,10 +1,31 @@
|
||||
from datetime import timedelta as td
|
||||
import uuid
|
||||
|
||||
from django.contrib.auth.models import User
|
||||
from django.db import models
|
||||
|
||||
STATUSES = (("up", "Up"), ("down", "Down"), ("new", "New"))
|
||||
ONEDAY = td(days=1)
|
||||
DURATIONS = (
|
||||
(td(minutes=5), "5 minutes"),
|
||||
(td(minutes=10), "10 minutes"),
|
||||
(td(minutes=30), "30 minutes"),
|
||||
(td(hours=1), "1 hour"),
|
||||
(td(hours=2), "2 hours"),
|
||||
(td(hours=6), "6 hours"),
|
||||
(td(hours=12), "12 hours"),
|
||||
(ONEDAY, "1 day"),
|
||||
(td(days=2), "2 days"),
|
||||
(td(weeks=1), "1 week"),
|
||||
(td(weeks=2), "2 weeks")
|
||||
)
|
||||
|
||||
|
||||
class Check(models.Model):
|
||||
code = models.UUIDField(default=uuid.uuid4, editable=False)
|
||||
user = models.ForeignKey(User)
|
||||
enabled = models.BooleanField(default=True)
|
||||
timeout = models.DurationField(default=ONEDAY)
|
||||
last_ping = models.DateTimeField(null=True, blank=True)
|
||||
alert_after = models.DateTimeField(null=True, blank=True, editable=False)
|
||||
status = models.CharField(max_length=6, choices=STATUSES, default="new")
|
||||
|
@ -11,6 +11,9 @@ def ping(request, code):
|
||||
return HttpResponseBadRequest()
|
||||
|
||||
check.last_ping = timezone.now()
|
||||
if check.status == "new":
|
||||
check.status = "up"
|
||||
|
||||
check.save()
|
||||
|
||||
return HttpResponse()
|
||||
|
15
hc/lib/emails.py
Normal file
15
hc/lib/emails.py
Normal file
@ -0,0 +1,15 @@
|
||||
from django.core.mail import send_mail
|
||||
|
||||
|
||||
def send_status_notification(check):
|
||||
if check.status == "down":
|
||||
subject = "Alert DOWN"
|
||||
body = "Hi, the check %s has gone down" % check.code
|
||||
elif check.status == "up":
|
||||
subject = "Alert UP"
|
||||
body = "Hi, the check %s has gone up" % check.code
|
||||
else:
|
||||
raise NotImplemented("Unexpected status: %s" % check.status)
|
||||
|
||||
send_mail(subject, body, 'cuu508@gmail.com', [check.user.email],
|
||||
fail_silently=False)
|
@ -85,7 +85,7 @@ DATABASES = {
|
||||
'NAME': 'hc',
|
||||
'USER': 'hc',
|
||||
'PASSWORD': '',
|
||||
'HOST': '192.168.1.111',
|
||||
'HOST': '192.168.1.112',
|
||||
'PORT': 5432,
|
||||
'TEST': {'CHARSET': 'UTF8'}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user