Browse Source

Keep a log of pings

pull/7/head
Pēteris Caune 9 years ago
parent
commit
3550218129
9 changed files with 143 additions and 14 deletions
  1. +9
    -2
      hc/api/admin.py
  2. +26
    -0
      hc/api/migrations/0007_ping.py
  3. +14
    -0
      hc/api/models.py
  4. +9
    -1
      hc/api/views.py
  5. +9
    -8
      hc/front/urls.py
  6. +19
    -1
      hc/front/views.py
  7. +8
    -2
      static/css/style.css
  8. +42
    -0
      templates/front/log.html
  9. +7
    -0
      templates/front/my_checks.html

+ 9
- 2
hc/api/admin.py View File

@ -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
- 0
hc/api/migrations/0007_ping.py View 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')),
],
),
]

+ 14
- 0
hc/api/models.py View File

@ -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)

+ 9
- 1
hc/api/views.py View File

@ -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


+ 9
- 8
hc/front/urls.py View File

@ -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"),
]

+ 19
- 1
hc/front/views.py View File

@ -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)

+ 8
- 2
static/css/style.css View File

@ -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
- 0
templates/front/log.html View 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 %}

+ 7
- 0
templates/front/my_checks.html View File

@ -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…
Cancel
Save