forked from GithubBackups/healthchecks
Keep a log of pings
This commit is contained in:
parent
d8828b2d25
commit
3550218129
@ -1,16 +1,18 @@
|
||||
from django.contrib import admin
|
||||
|
||||
from hc.api.models import Check
|
||||
from hc.api.models import Check, Ping
|
||||
|
||||
|
||||
@admin.register(Check)
|
||||
class ChecksAdmin(admin.ModelAdmin):
|
||||
|
||||
class Media:
|
||||
css = {
|
||||
'all': ('css/admin/checks.css',)
|
||||
}
|
||||
|
||||
list_display = ("id", "name", "created", "code", "status", "email", "last_ping")
|
||||
list_display = ("id", "name", "created", "code", "status", "email",
|
||||
"last_ping")
|
||||
list_select_related = ("user", )
|
||||
actions = ["send_alert"]
|
||||
|
||||
@ -24,3 +26,8 @@ class ChecksAdmin(admin.ModelAdmin):
|
||||
self.message_user(request, "%d alert(s) sent" % qs.count())
|
||||
|
||||
send_alert.short_description = "Send Alert"
|
||||
|
||||
|
||||
@admin.register(Ping)
|
||||
class PingsAdmin(admin.ModelAdmin):
|
||||
list_display = ("id", "created", "owner", "method", "ua")
|
||||
|
26
hc/api/migrations/0007_ping.py
Normal file
26
hc/api/migrations/0007_ping.py
Normal file
@ -0,0 +1,26 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from django.db import models, migrations
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('api', '0006_check_grace'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='Ping',
|
||||
fields=[
|
||||
('id', models.AutoField(primary_key=True, serialize=False, auto_created=True, verbose_name='ID')),
|
||||
('created', models.DateTimeField(auto_now_add=True)),
|
||||
('remote_addr', models.GenericIPAddressField()),
|
||||
('method', models.CharField(max_length=10)),
|
||||
('ua', models.CharField(max_length=100, blank=True)),
|
||||
('body', models.TextField(blank=True)),
|
||||
('owner', models.ForeignKey(to='api.Check')),
|
||||
],
|
||||
),
|
||||
]
|
@ -1,3 +1,5 @@
|
||||
# coding: utf-8
|
||||
|
||||
from datetime import timedelta as td
|
||||
import uuid
|
||||
|
||||
@ -24,6 +26,9 @@ class Check(models.Model):
|
||||
alert_after = models.DateTimeField(null=True, blank=True, editable=False)
|
||||
status = models.CharField(max_length=6, choices=STATUSES, default="new")
|
||||
|
||||
def __str__(self):
|
||||
return "Check(%s)" % self.code
|
||||
|
||||
def url(self):
|
||||
return settings.PING_ENDPOINT + str(self.code)
|
||||
|
||||
@ -53,3 +58,12 @@ class Check(models.Model):
|
||||
return "grace"
|
||||
|
||||
return "down"
|
||||
|
||||
|
||||
class Ping(models.Model):
|
||||
owner = models.ForeignKey(Check)
|
||||
created = models.DateTimeField(auto_now_add=True)
|
||||
remote_addr = models.GenericIPAddressField()
|
||||
method = models.CharField(max_length=10)
|
||||
ua = models.CharField(max_length=100, blank=True)
|
||||
body = models.TextField(blank=True)
|
||||
|
@ -5,7 +5,7 @@ from django.http import HttpResponse, HttpResponseBadRequest
|
||||
from django.utils import timezone
|
||||
from django.views.decorators.csrf import csrf_exempt
|
||||
|
||||
from hc.api.models import Check
|
||||
from hc.api.models import Check, Ping
|
||||
|
||||
|
||||
@csrf_exempt
|
||||
@ -21,6 +21,14 @@ def ping(request, code):
|
||||
|
||||
check.save()
|
||||
|
||||
ping = Ping(owner=check)
|
||||
headers = request.META
|
||||
ping.remote_addr = headers.get("X_REAL_IP", headers["REMOTE_ADDR"])
|
||||
ping.method = headers["REQUEST_METHOD"]
|
||||
ping.ua = headers.get("HTTP_USER_AGENT", "")
|
||||
ping.body = request.body
|
||||
ping.save()
|
||||
|
||||
response = HttpResponse("OK")
|
||||
response["Access-Control-Allow-Origin"] = "*"
|
||||
return response
|
||||
|
@ -3,13 +3,14 @@ from django.conf.urls import url
|
||||
from hc.front import views
|
||||
|
||||
urlpatterns = [
|
||||
url(r'^$', views.index, name="hc-index"),
|
||||
url(r'^checks/add/$', views.add_check, name="hc-add-check"),
|
||||
url(r'^checks/([\w-]+)/name/$', views.update_name, name="hc-update-name"),
|
||||
url(r'^$', views.index, name="hc-index"),
|
||||
url(r'^checks/add/$', views.add_check, name="hc-add-check"),
|
||||
url(r'^checks/([\w-]+)/name/$', views.update_name, name="hc-update-name"),
|
||||
url(r'^checks/([\w-]+)/timeout/$', views.update_timeout, name="hc-update-timeout"),
|
||||
url(r'^checks/([\w-]+)/email/$', views.email_preview),
|
||||
url(r'^checks/([\w-]+)/remove/$', views.remove, name="hc-remove-check"),
|
||||
url(r'^pricing/$', views.pricing, name="hc-pricing"),
|
||||
url(r'^docs/$', views.docs, name="hc-docs"),
|
||||
url(r'^about/$', views.about, name="hc-about"),
|
||||
url(r'^checks/([\w-]+)/email/$', views.email_preview),
|
||||
url(r'^checks/([\w-]+)/remove/$', views.remove, name="hc-remove-check"),
|
||||
url(r'^checks/([\w-]+)/log/$', views.log, name="hc-log"),
|
||||
url(r'^pricing/$', views.pricing, name="hc-pricing"),
|
||||
url(r'^docs/$', views.docs, name="hc-docs"),
|
||||
url(r'^about/$', views.about, name="hc-about"),
|
||||
]
|
||||
|
@ -6,7 +6,7 @@ from django.http import HttpResponseForbidden
|
||||
from django.shortcuts import redirect, render
|
||||
from django.utils import timezone
|
||||
|
||||
from hc.api.models import Check
|
||||
from hc.api.models import Check, Ping
|
||||
from hc.front.forms import TimeoutForm
|
||||
|
||||
|
||||
@ -147,3 +147,21 @@ def remove(request, code):
|
||||
check.delete()
|
||||
|
||||
return redirect("hc-index")
|
||||
|
||||
|
||||
@login_required
|
||||
def log(request, code):
|
||||
|
||||
check = Check.objects.get(code=code)
|
||||
if check.user != request.user:
|
||||
return HttpResponseForbidden()
|
||||
|
||||
pings = Ping.objects.filter(owner=check).order_by("-created")[:100]
|
||||
|
||||
ctx = {
|
||||
"check": check,
|
||||
"pings": pings
|
||||
|
||||
}
|
||||
|
||||
return render(request, "front/log.html", ctx)
|
||||
|
@ -131,7 +131,7 @@ table.table tr > th.th-name {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.my-checks-name:hover {
|
||||
#checks-table tr:hover .my-checks-name {
|
||||
border: 1px dotted #AAA;
|
||||
}
|
||||
|
||||
@ -142,6 +142,7 @@ table.table tr > th.th-name {
|
||||
|
||||
.url-cell {
|
||||
font-size: small;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
td.inactive .popover {
|
||||
@ -167,7 +168,7 @@ td.inactive .popover {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.timeout_grace:hover {
|
||||
#checks-table tr:hover .timeout_grace {
|
||||
border: 1px dotted #AAA;
|
||||
}
|
||||
|
||||
@ -243,3 +244,8 @@ tr:hover .check-menu {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
/* Log */
|
||||
|
||||
.log-table .remote-addr, .log-table .ua {
|
||||
font-family: monospace;
|
||||
}
|
42
templates/front/log.html
Normal file
42
templates/front/log.html
Normal file
@ -0,0 +1,42 @@
|
||||
{% extends "base.html" %}
|
||||
{% load compress humanize staticfiles hc_extras %}
|
||||
|
||||
{% block title %}My Checks - healthchecks.io{% endblock %}
|
||||
|
||||
|
||||
{% block content %}
|
||||
<div class="row">
|
||||
<div class="col-sm-12">
|
||||
<h1>Log for {{ check.name|default:check.code }}</h1>
|
||||
{% if pings %}
|
||||
<table class="table table-striped log-table">
|
||||
<tr>
|
||||
<th>Time</th>
|
||||
<th>Remote IP</th>
|
||||
<th>Method</th>
|
||||
<th>User Agent</th>
|
||||
</tr>
|
||||
{% for ping in pings %}
|
||||
<tr>
|
||||
<td>
|
||||
<span
|
||||
data-toggle="tooltip"
|
||||
title="{{ ping.created }}">
|
||||
{{ ping.created }}
|
||||
</span>
|
||||
</td>
|
||||
<td class="remote-addr">{{ ping.remote_addr }}</td>
|
||||
<td class="method">
|
||||
<span class="label label-default">{{ ping.method }}</span>
|
||||
</td>
|
||||
<td class="ua">{{ ping.ua }}</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</table>
|
||||
{% else %}
|
||||
<div class="alert alert-info">Log is empty. This check has not received any pings yet.</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
@ -75,6 +75,13 @@
|
||||
<span class="glyphicon glyphicon-cog" aria-hidden="true"></span>
|
||||
</button>
|
||||
<ul class="dropdown-menu">
|
||||
<li>
|
||||
<a href="{% url 'hc-log' check.code %}">
|
||||
<span class="glyphicon glyphicon-time"></span>
|
||||
Log
|
||||
</a>
|
||||
</li>
|
||||
<li role="separator" class="divider"></li>
|
||||
<li>
|
||||
<a href="#" class="check-menu-remove"
|
||||
data-name="{{ check.name|default:check.code }}"
|
||||
|
Loading…
x
Reference in New Issue
Block a user