forked from GithubBackups/healthchecks
Log: instead of timeline, show placeholders for "expected but not received" pings.
This commit is contained in:
parent
4e12193d8c
commit
f178981334
@ -1,5 +1,6 @@
|
|||||||
from collections import Counter
|
from collections import Counter
|
||||||
from datetime import timedelta as td
|
from datetime import timedelta as td
|
||||||
|
from itertools import tee
|
||||||
|
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
from django.contrib.auth.decorators import login_required
|
from django.contrib.auth.decorators import login_required
|
||||||
@ -15,6 +16,14 @@ from hc.api.models import Channel, Check, Ping
|
|||||||
from hc.front.forms import AddChannelForm, NameTagsForm, TimeoutForm
|
from hc.front.forms import AddChannelForm, NameTagsForm, TimeoutForm
|
||||||
|
|
||||||
|
|
||||||
|
# from itertools recipes:
|
||||||
|
def pairwise(iterable):
|
||||||
|
"s -> (s0,s1), (s1,s2), (s2, s3), ..."
|
||||||
|
a, b = tee(iterable)
|
||||||
|
next(b, None)
|
||||||
|
return zip(a, b)
|
||||||
|
|
||||||
|
|
||||||
@login_required
|
@login_required
|
||||||
def my_checks(request):
|
def my_checks(request):
|
||||||
checks = Check.objects.filter(user=request.user).order_by("created")
|
checks = Check.objects.filter(user=request.user).order_by("created")
|
||||||
@ -185,30 +194,31 @@ def log(request, code):
|
|||||||
|
|
||||||
profile = Profile.objects.for_user(request.user)
|
profile = Profile.objects.for_user(request.user)
|
||||||
limit = profile.ping_log_limit
|
limit = profile.ping_log_limit
|
||||||
pings = Ping.objects.filter(owner=check).order_by("-created")[:limit]
|
pings = Ping.objects.filter(owner=check).order_by("created")[:limit]
|
||||||
|
pings = list(pings)
|
||||||
|
|
||||||
|
# Add a dummy ping object at the end. We iterate over *pairs* of pings
|
||||||
|
# and don't want to handle a special case of a check with a single ping.
|
||||||
|
pings.append(Ping(created=timezone.now()))
|
||||||
|
|
||||||
# Now go through pings, calculate time gaps, and decorate
|
# Now go through pings, calculate time gaps, and decorate
|
||||||
# the pings list for convenient use in template
|
# the pings list for convenient use in template
|
||||||
wrapped = []
|
wrapped = []
|
||||||
now = timezone.now()
|
|
||||||
for i, ping in enumerate(pings):
|
|
||||||
prev = now if i == 0 else pings[i - 1].created
|
|
||||||
|
|
||||||
duration = prev - ping.created
|
early = False
|
||||||
if duration > check.timeout:
|
for older, newer in pairwise(pings):
|
||||||
downtime = {"prev_date": prev, "date": ping.created}
|
wrapped.append({"ping": older, "early": early})
|
||||||
if i > 0:
|
|
||||||
wrapped[-1]["status"] = "late"
|
|
||||||
|
|
||||||
if duration > check.timeout + check.grace:
|
# Fill in "missed ping" placeholders:
|
||||||
downtime["down"] = True
|
expected_date = older.created + check.timeout
|
||||||
if i > 0:
|
while expected_date + check.grace < newer.created:
|
||||||
wrapped[-1]["status"] = "down"
|
wrapped.append({"placeholder_date": expected_date})
|
||||||
|
expected_date = expected_date + check.timeout
|
||||||
|
|
||||||
wrapped.append(downtime)
|
# Prepare early flag for next ping to come
|
||||||
|
early = older.created + check.timeout > newer.created + check.grace
|
||||||
wrapped.append({"ping": ping})
|
|
||||||
|
|
||||||
|
wrapped.reverse()
|
||||||
ctx = {
|
ctx = {
|
||||||
"check": check,
|
"check": check,
|
||||||
"pings": wrapped
|
"pings": wrapped
|
||||||
|
@ -5,7 +5,6 @@
|
|||||||
|
|
||||||
#log td {
|
#log td {
|
||||||
color: #444;
|
color: #444;
|
||||||
padding: 16px 8px;
|
|
||||||
position: relative;
|
position: relative;
|
||||||
border: 0;
|
border: 0;
|
||||||
border-bottom: 1px solid #E5E5E5;
|
border-bottom: 1px solid #E5E5E5;
|
||||||
@ -15,7 +14,7 @@
|
|||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
}
|
}
|
||||||
|
|
||||||
#log .date {
|
#log .date, #log .time {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
width: 70px;
|
width: 70px;
|
||||||
}
|
}
|
||||||
@ -36,52 +35,12 @@
|
|||||||
font-size: 11px;
|
font-size: 11px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#log .ok {
|
||||||
#log .bullet {
|
color: #5cb85c;
|
||||||
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 {
|
#log tr.missing td {
|
||||||
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;
|
color: #d9534f;
|
||||||
|
background: #fff3f2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -20,7 +20,6 @@
|
|||||||
Note: Dates and times are displayed in <strong>UTC</strong>.
|
Note: Dates and times are displayed in <strong>UTC</strong>.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
|
|
||||||
<div class="table-responsive">
|
<div class="table-responsive">
|
||||||
<table class="table" id="log">
|
<table class="table" id="log">
|
||||||
<tr>
|
<tr>
|
||||||
@ -35,11 +34,9 @@
|
|||||||
</tr>
|
</tr>
|
||||||
{% for record in pings %}
|
{% for record in pings %}
|
||||||
{% if record.ping %}
|
{% if record.ping %}
|
||||||
<tr>
|
<tr class="ok {% if record.early %} early {% endif %}">
|
||||||
<td class="tl-cell">
|
<td class="icon">
|
||||||
<div class="tl top"></div>
|
<span class="glyphicon glyphicon-ok ok"></span>
|
||||||
<div class="tl bottom {{ record.status }}"></div>
|
|
||||||
<div class="bullet"></div>
|
|
||||||
</td>
|
</td>
|
||||||
<td class="datetime">
|
<td class="datetime">
|
||||||
<div>
|
<div>
|
||||||
@ -49,6 +46,9 @@
|
|||||||
<span class="time">
|
<span class="time">
|
||||||
{{ record.ping.created|date:"H:i" }}
|
{{ record.ping.created|date:"H:i" }}
|
||||||
</span>
|
</span>
|
||||||
|
{% if record.early %}
|
||||||
|
<span class="label label-tag">early</span>
|
||||||
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
<td class="ip">
|
<td class="ip">
|
||||||
@ -62,22 +62,24 @@
|
|||||||
{{ record.ping.ua }}
|
{{ record.ping.ua }}
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</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 %}
|
{% endif %}
|
||||||
<tr>
|
{% if record.placeholder_date %}
|
||||||
<td class="tl-cell">
|
<tr class="missing">
|
||||||
<div class="tl top late"></div>
|
<td class="icon">
|
||||||
<div class="tl bottom"></div>
|
<span class="glyphicon glyphicon-remove"></span>
|
||||||
|
</td>
|
||||||
|
<td class="datetime">
|
||||||
|
<div>
|
||||||
|
<span class="date">
|
||||||
|
{{ record.placeholder_date|date:"N j" }}
|
||||||
|
</span>
|
||||||
|
<span class="time">
|
||||||
|
{{ record.placeholder_date|date:"H:i" }}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
<td colspan="4">
|
||||||
|
<small>Ping expected but not received</small>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user