forked from GithubBackups/healthchecks
Better style for Log page.
This commit is contained in:
parent
3a8a41f7a5
commit
aa2bc72293
@ -1,6 +1,6 @@
|
||||
from django.contrib.auth.models import User
|
||||
from django.test import TestCase
|
||||
from hc.api.models import Check
|
||||
from hc.api.models import Check, Ping
|
||||
|
||||
|
||||
class LogTestCase(TestCase):
|
||||
@ -13,12 +13,15 @@ class LogTestCase(TestCase):
|
||||
self.check = Check(user=self.alice)
|
||||
self.check.save()
|
||||
|
||||
ping = Ping(owner=self.check)
|
||||
ping.save()
|
||||
|
||||
def test_it_works(self):
|
||||
url = "/checks/%s/log/" % self.check.code
|
||||
|
||||
self.client.login(username="alice", password="password")
|
||||
r = self.client.get(url)
|
||||
self.assertContains(r, "Log for", status_code=200)
|
||||
self.assertContains(r, "Dates and times are", status_code=200)
|
||||
|
||||
def test_it_handles_bad_uuid(self):
|
||||
url = "/checks/not-uuid/log/"
|
||||
|
@ -161,10 +161,30 @@ def log(request, code):
|
||||
|
||||
pings = Ping.objects.filter(owner=check).order_by("-created")[:100]
|
||||
|
||||
# Now go through pings, calculate time gaps, and decorate
|
||||
# the pings list for convenient use in template
|
||||
wrapped = []
|
||||
for i, ping in enumerate(pings):
|
||||
prev = timezone.now() if i == 0 else pings[i - 1].created
|
||||
|
||||
duration = prev - ping.created
|
||||
if duration > check.timeout:
|
||||
downtime = {"prev_date": prev, "date": ping.created}
|
||||
if i > 0:
|
||||
wrapped[-1]["status"] = "late"
|
||||
|
||||
if duration > check.timeout + check.grace:
|
||||
downtime["down"] = True
|
||||
if i > 0:
|
||||
wrapped[-1]["status"] = "down"
|
||||
|
||||
wrapped.append(downtime)
|
||||
|
||||
wrapped.append({"ping": ping})
|
||||
|
||||
ctx = {
|
||||
"check": check,
|
||||
"pings": pings
|
||||
|
||||
"pings": wrapped
|
||||
}
|
||||
|
||||
return render(request, "front/log.html", ctx)
|
||||
|
18
static/css/bootstrap.css
vendored
18
static/css/bootstrap.css
vendored
@ -4541,6 +4541,24 @@ fieldset[disabled] .navbar-inverse .btn-link:hover,
|
||||
fieldset[disabled] .navbar-inverse .btn-link:focus {
|
||||
color: #444444;
|
||||
}
|
||||
.breadcrumb {
|
||||
padding: 8px 15px;
|
||||
margin-bottom: 20px;
|
||||
list-style: none;
|
||||
background-color: #f5f5f5;
|
||||
border-radius: 4px;
|
||||
}
|
||||
.breadcrumb > li {
|
||||
display: inline-block;
|
||||
}
|
||||
.breadcrumb > li + li:before {
|
||||
content: "/\00a0";
|
||||
padding: 0 5px;
|
||||
color: #cccccc;
|
||||
}
|
||||
.breadcrumb > .active {
|
||||
color: #777777;
|
||||
}
|
||||
.label {
|
||||
display: inline;
|
||||
padding: .2em .6em .3em;
|
||||
|
@ -1,3 +1,87 @@
|
||||
.log-table .remote-addr, .log-table .ua {
|
||||
#log th {
|
||||
border-top: 0;
|
||||
border-bottom: 1px solid #E5E5E5;
|
||||
}
|
||||
|
||||
#log td {
|
||||
color: #444;
|
||||
padding: 16px 8px;
|
||||
position: relative;
|
||||
border: 0;
|
||||
border-bottom: 1px solid #E5E5E5;
|
||||
}
|
||||
|
||||
#log .datetime {
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
#log .date {
|
||||
display: inline-block;
|
||||
width: 70px;
|
||||
}
|
||||
|
||||
#log .protocol {
|
||||
white-space: nowrap;
|
||||
padding-left: 16px;
|
||||
padding-right: 16px;
|
||||
}
|
||||
|
||||
#log .ip {
|
||||
padding-left: 16px;
|
||||
padding-right: 16px;
|
||||
}
|
||||
|
||||
#log td.ua {
|
||||
font-family: monospace;
|
||||
font-size: 11px;
|
||||
}
|
||||
|
||||
|
||||
#log .bullet {
|
||||
position: absolute;
|
||||
display: block;
|
||||
top: 50%;
|
||||
margin-top: -6px;
|
||||
left: 0;
|
||||
width: 12px;
|
||||
height: 12px;
|
||||
border: 2px solid #FFF;
|
||||
border-radius: 6px;
|
||||
background: #376f37;
|
||||
}
|
||||
|
||||
#log .tl {
|
||||
position: absolute;
|
||||
left: 4px;
|
||||
width: 4px;
|
||||
background: #5cb85c;
|
||||
}
|
||||
|
||||
#log .top {
|
||||
top: 0;
|
||||
height: 50%;
|
||||
}
|
||||
|
||||
#log .bottom {
|
||||
top: 50%;
|
||||
height: 50%;
|
||||
}
|
||||
|
||||
#log .full-down {
|
||||
top: 0;
|
||||
height: 100%;
|
||||
background: #d9534f;
|
||||
}
|
||||
|
||||
#log .down { background: #d9534f; }
|
||||
#log .late { background: #f0ad4e; }
|
||||
|
||||
#log .tl-cell {
|
||||
border: 0;
|
||||
}
|
||||
|
||||
#log .downtime-cell {
|
||||
border: 0;
|
||||
font-size: small;
|
||||
color: #d9534f;
|
||||
}
|
2
stuff/bootstrap/bootstrap.less
vendored
2
stuff/bootstrap/bootstrap.less
vendored
@ -29,7 +29,7 @@
|
||||
@import "input-groups.less";
|
||||
@import "navs.less";
|
||||
@import "navbar.less";
|
||||
// @import "breadcrumbs.less";
|
||||
@import "breadcrumbs.less";
|
||||
// @import "pagination.less";
|
||||
// @import "pager.less";
|
||||
@import "labels.less";
|
||||
|
@ -24,6 +24,7 @@
|
||||
<link rel="stylesheet" href="{% static 'css/syntax.css' %}" type="text/css">
|
||||
<link rel="stylesheet" href="{% static 'css/channels.css' %}" type="text/css">
|
||||
<link rel="stylesheet" href="{% static 'css/channel_checks.css' %}" type="text/css">
|
||||
<link rel="stylesheet" href="{% static 'css/log.css' %}" type="text/css">
|
||||
{% endcompress %}
|
||||
</head>
|
||||
<body class="page-{{ page }}">
|
||||
|
@ -5,39 +5,82 @@
|
||||
|
||||
|
||||
{% block content %}
|
||||
|
||||
<div class="row">
|
||||
<div class="col-sm-12">
|
||||
<h1>Log for “{{ check.name_then_code }}”</h1>
|
||||
<ol class="breadcrumb">
|
||||
<li><a href="{% url 'hc-checks' %}">Checks</a></li>
|
||||
<li>{{ check.name_then_code }}</li>
|
||||
<li class="active">Log</li>
|
||||
</ol>
|
||||
|
||||
{% if pings %}
|
||||
|
||||
<p class="log-notes">
|
||||
Note: Dates and times are displayed in <strong>UTC</strong>.
|
||||
</p>
|
||||
|
||||
|
||||
<div class="table-responsive">
|
||||
<table class="table table-striped log-table">
|
||||
<table class="table" id="log">
|
||||
<tr>
|
||||
<th>Transport</th>
|
||||
<th>Time</th>
|
||||
<th>Remote IP</th>
|
||||
<th>User Agent</th>
|
||||
<th></th>
|
||||
<th class="datetime">
|
||||
<span class="date">Date</span>
|
||||
<span class="time">Time</span>
|
||||
</th>
|
||||
<th class="ip">IP</th>
|
||||
<th class="protocol">Protocol</th>
|
||||
<th class="ua">User Agent</th>
|
||||
</tr>
|
||||
{% for ping in pings %}
|
||||
{% for record in pings %}
|
||||
{% if record.ping %}
|
||||
<tr>
|
||||
<td>
|
||||
{% if ping.scheme == "email" %}
|
||||
Email
|
||||
{% elif ping.scheme == "http" %}
|
||||
HTTP
|
||||
{% elif ping.scheme == "https" %}
|
||||
HTTPS
|
||||
{% endif %}
|
||||
<td class="tl-cell">
|
||||
<div class="tl top"></div>
|
||||
<div class="tl bottom {{ record.status }}"></div>
|
||||
<div class="bullet"></div>
|
||||
</td>
|
||||
<td>
|
||||
<span
|
||||
data-toggle="tooltip"
|
||||
title="{{ ping.created }} GMT">
|
||||
{{ ping.created|naturaltime }}
|
||||
</span>
|
||||
<td class="datetime">
|
||||
<div>
|
||||
<span class="date">
|
||||
{{ record.ping.created|date:"N j" }}
|
||||
</span>
|
||||
<span class="time">
|
||||
{{ record.ping.created|date:"H:i" }}
|
||||
</span>
|
||||
</div>
|
||||
</td>
|
||||
<td class="ip">
|
||||
{{ record.ping.remote_addr|default:"" }}
|
||||
</td>
|
||||
<td class="protocol">
|
||||
{{ record.ping.scheme }}
|
||||
</td>
|
||||
|
||||
<td class="ua">
|
||||
{{ record.ping.ua }}
|
||||
</td>
|
||||
<td class="remote-addr">{{ ping.remote_addr }}</td>
|
||||
<td class="ua">{{ ping.ua }}</td>
|
||||
</tr>
|
||||
{% else %}
|
||||
{% if record.down %}
|
||||
<tr>
|
||||
<td class="tl-cell">
|
||||
<div class="tl full-down"></div>
|
||||
</td>
|
||||
<td class="downtime-cell" colspan="4">
|
||||
<p>No ping received for {{ record.date|timesince:record.prev_date }}</p>
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
{% endif %}
|
||||
<tr>
|
||||
<td class="tl-cell">
|
||||
<div class="tl top late"></div>
|
||||
<div class="tl bottom"></div>
|
||||
</td>
|
||||
</tr>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
</table>
|
||||
</div>
|
||||
|
Loading…
x
Reference in New Issue
Block a user