diff --git a/hc/front/tests/test_log.py b/hc/front/tests/test_log.py index 78188add..7a4a46fa 100644 --- a/hc/front/tests/test_log.py +++ b/hc/front/tests/test_log.py @@ -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/" diff --git a/hc/front/views.py b/hc/front/views.py index f5dc41e5..4f1de064 100644 --- a/hc/front/views.py +++ b/hc/front/views.py @@ -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) diff --git a/static/css/bootstrap.css b/static/css/bootstrap.css index ece5bbfa..668e7384 100644 --- a/static/css/bootstrap.css +++ b/static/css/bootstrap.css @@ -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; diff --git a/static/css/log.css b/static/css/log.css index b695101a..cd419af1 100644 --- a/static/css/log.css +++ b/static/css/log.css @@ -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; } \ No newline at end of file diff --git a/stuff/bootstrap/bootstrap.less b/stuff/bootstrap/bootstrap.less index b53cef47..a4333692 100755 --- a/stuff/bootstrap/bootstrap.less +++ b/stuff/bootstrap/bootstrap.less @@ -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"; diff --git a/templates/base.html b/templates/base.html index 2aa059c7..dec36838 100644 --- a/templates/base.html +++ b/templates/base.html @@ -24,6 +24,7 @@ + {% endcompress %}
diff --git a/templates/front/log.html b/templates/front/log.html index 082aab76..52d3f64f 100644 --- a/templates/front/log.html +++ b/templates/front/log.html @@ -5,39 +5,82 @@ {% block content %} ++ Note: Dates and times are displayed in UTC. +
+ +Transport | -Time | -Remote IP | -User Agent | ++ | + Date + Time + | +IP | +Protocol | +User Agent |
---|---|---|---|---|---|---|---|---|
- {% if ping.scheme == "email" %} - Email - {% elif ping.scheme == "http" %} - HTTP - {% elif ping.scheme == "https" %} - HTTPS - {% endif %} - | -- - {{ ping.created|naturaltime }} - - | -{{ ping.remote_addr }} | -{{ ping.ua }} | ++ + + + | +
+
+
+ {{ record.ping.created|date:"N j" }}
+
+
+ {{ record.ping.created|date:"H:i" }}
+
+
+ |
+ + {{ record.ping.remote_addr|default:"" }} + | ++ {{ record.ping.scheme }} + | + ++ {{ record.ping.ua }} + | +
+ + | +
+ No ping received for {{ record.date|timesince:record.prev_date }} + + |
+ |||||||
+ + + |