forked from GithubBackups/healthchecks
Log auto-refreshes in the details page.
This commit is contained in:
parent
04fede0897
commit
a883fe38aa
@ -4,6 +4,7 @@ from hc.front import views
|
|||||||
|
|
||||||
check_urls = [
|
check_urls = [
|
||||||
path('name/', views.update_name, name="hc-update-name"),
|
path('name/', views.update_name, name="hc-update-name"),
|
||||||
|
path('details/', views.details, name="hc-details"),
|
||||||
path('timeout/', views.update_timeout, name="hc-update-timeout"),
|
path('timeout/', views.update_timeout, name="hc-update-timeout"),
|
||||||
path('pause/', views.pause, name="hc-pause"),
|
path('pause/', views.pause, name="hc-pause"),
|
||||||
path('remove/', views.remove_check, name="hc-remove-check"),
|
path('remove/', views.remove_check, name="hc-remove-check"),
|
||||||
|
@ -34,6 +34,7 @@ import requests
|
|||||||
VALID_SORT_VALUES = ("name", "-name", "last_ping", "-last_ping", "created")
|
VALID_SORT_VALUES = ("name", "-name", "last_ping", "-last_ping", "created")
|
||||||
STATUS_TEXT_TMPL = get_template("front/log_status_text.html")
|
STATUS_TEXT_TMPL = get_template("front/log_status_text.html")
|
||||||
LAST_PING_TMPL = get_template("front/last_ping_cell.html")
|
LAST_PING_TMPL = get_template("front/last_ping_cell.html")
|
||||||
|
EVENTS_TMPL = get_template("front/details_events.html")
|
||||||
|
|
||||||
|
|
||||||
def _tags_statuses(checks):
|
def _tags_statuses(checks):
|
||||||
@ -324,23 +325,10 @@ def remove_check(request, code):
|
|||||||
return redirect("hc-checks")
|
return redirect("hc-checks")
|
||||||
|
|
||||||
|
|
||||||
@login_required
|
def _get_events(check, limit):
|
||||||
def log(request, code):
|
pings = Ping.objects.filter(owner=check).order_by("-id")[:limit]
|
||||||
check = get_object_or_404(Check, code=code)
|
|
||||||
if check.user != request.team.user:
|
|
||||||
return HttpResponseForbidden()
|
|
||||||
|
|
||||||
limit = 20
|
|
||||||
team_limit = request.team.ping_log_limit
|
|
||||||
if "full_log" in request.GET:
|
|
||||||
limit = team_limit
|
|
||||||
|
|
||||||
pings = Ping.objects.filter(owner=check).order_by("-id")[:limit + 1]
|
|
||||||
pings = list(pings)
|
pings = list(pings)
|
||||||
|
|
||||||
can_load_more = len(pings) > limit
|
|
||||||
pings = pings[:limit]
|
|
||||||
|
|
||||||
alerts = []
|
alerts = []
|
||||||
if len(pings):
|
if len(pings):
|
||||||
cutoff = pings[-1].created
|
cutoff = pings[-1].created
|
||||||
@ -350,21 +338,42 @@ def log(request, code):
|
|||||||
|
|
||||||
events = pings + list(alerts)
|
events = pings + list(alerts)
|
||||||
events.sort(key=lambda el: el.created, reverse=True)
|
events.sort(key=lambda el: el.created, reverse=True)
|
||||||
|
return events
|
||||||
|
|
||||||
|
|
||||||
|
@login_required
|
||||||
|
def log(request, code):
|
||||||
|
check = get_object_or_404(Check, code=code)
|
||||||
|
if check.user != request.team.user:
|
||||||
|
return HttpResponseForbidden()
|
||||||
|
|
||||||
|
limit = request.team.ping_log_limit
|
||||||
|
ctx = {
|
||||||
|
"check": check,
|
||||||
|
"events": _get_events(check, limit),
|
||||||
|
"limit": limit,
|
||||||
|
"show_limit_notice": check.n_pings > limit and settings.USE_PAYMENTS
|
||||||
|
}
|
||||||
|
|
||||||
|
return render(request, "front/log.html", ctx)
|
||||||
|
|
||||||
|
|
||||||
|
@login_required
|
||||||
|
def details(request, code):
|
||||||
|
check = get_object_or_404(Check, code=code)
|
||||||
|
if check.user != request.team.user:
|
||||||
|
return HttpResponseForbidden()
|
||||||
|
|
||||||
channels = Channel.objects.filter(user=request.team.user)
|
channels = Channel.objects.filter(user=request.team.user)
|
||||||
channels = list(channels.order_by("created"))
|
channels = list(channels.order_by("created"))
|
||||||
|
|
||||||
ctx = {
|
ctx = {
|
||||||
"page": "log",
|
"page": "details",
|
||||||
"check": check,
|
"check": check,
|
||||||
"ping_endpoint": settings.PING_ENDPOINT,
|
"channels": channels
|
||||||
"channels": channels,
|
|
||||||
"events": events,
|
|
||||||
"num_showing": len(pings),
|
|
||||||
"can_load_more": can_load_more
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return render(request, "front/log.html", ctx)
|
return render(request, "front/details.html", ctx)
|
||||||
|
|
||||||
|
|
||||||
@login_required
|
@login_required
|
||||||
@ -374,9 +383,16 @@ def status_single(request, code):
|
|||||||
return HttpResponseForbidden()
|
return HttpResponseForbidden()
|
||||||
|
|
||||||
status = check.get_status()
|
status = check.get_status()
|
||||||
|
events = _get_events(check, 20)
|
||||||
|
updated = None
|
||||||
|
if len(events):
|
||||||
|
updated = events[0].created.isoformat()
|
||||||
|
|
||||||
return JsonResponse({
|
return JsonResponse({
|
||||||
"status": status,
|
"status": status,
|
||||||
"status_text": STATUS_TEXT_TMPL.render({"check": check})
|
"status_text": STATUS_TEXT_TMPL.render({"check": check}),
|
||||||
|
"events": EVENTS_TMPL.render({"check": check, "events": events}),
|
||||||
|
"updated": updated
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
|
@ -52,7 +52,7 @@ body {
|
|||||||
font-size: small;
|
font-size: small;
|
||||||
}
|
}
|
||||||
|
|
||||||
.page-checks .container-fluid, .page-log .container-fluid {
|
.page-checks .container-fluid, .page-details .container-fluid {
|
||||||
/* Fluid below 1320px, but max width capped to 1320px ... */
|
/* Fluid below 1320px, but max width capped to 1320px ... */
|
||||||
max-width: 1320px;
|
max-width: 1320px;
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
function adaptiveSetInterval(fn) {
|
function adaptiveSetInterval(fn, runNow) {
|
||||||
// unconditionally run every minute
|
// unconditionally run every minute
|
||||||
setInterval(fn, 60000);
|
setInterval(fn, 60000);
|
||||||
|
|
||||||
@ -39,4 +39,9 @@ function adaptiveSetInterval(fn) {
|
|||||||
quota = 20;
|
quota = 20;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
if (runNow) {
|
||||||
|
quota = 20;
|
||||||
|
scheduleRun();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -112,7 +112,7 @@ $(function () {
|
|||||||
|
|
||||||
$(".show-log").click(function(e) {
|
$(".show-log").click(function(e) {
|
||||||
var code = $(this).closest("tr.checks-row").attr("id");
|
var code = $(this).closest("tr.checks-row").attr("id");
|
||||||
var url = "/checks/" + code + "/log/";
|
var url = "/checks/" + code + "/details/";
|
||||||
window.location = url;
|
window.location = url;
|
||||||
return false;
|
return false;
|
||||||
});
|
});
|
||||||
|
108
static/js/details.js
Normal file
108
static/js/details.js
Normal file
@ -0,0 +1,108 @@
|
|||||||
|
$(function () {
|
||||||
|
$("#edit-name").click(function() {
|
||||||
|
$('#update-name-modal').modal("show");
|
||||||
|
$("#update-name-input").focus();
|
||||||
|
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
|
||||||
|
$("#pause").click(function(e) {
|
||||||
|
$("#pause-form").submit();
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
|
||||||
|
$("#ping-now").click(function(e) {
|
||||||
|
var button = this;
|
||||||
|
$.get(this.dataset.url, function() {
|
||||||
|
button.textContent = "Success!";
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
$("#ping-now").mouseout(function(e) {
|
||||||
|
setTimeout(function() {
|
||||||
|
e.target.textContent = "Ping Now!";
|
||||||
|
}, 300);
|
||||||
|
});
|
||||||
|
|
||||||
|
var code = document.getElementById("edit-timeout").dataset.code;
|
||||||
|
var statusUrl = "/checks/" + code + "/status/";
|
||||||
|
var lastStatusText = "";
|
||||||
|
var lastUpdated = "";
|
||||||
|
adaptiveSetInterval(function() {
|
||||||
|
$.ajax({
|
||||||
|
url: statusUrl,
|
||||||
|
dataType: "json",
|
||||||
|
timeout: 2000,
|
||||||
|
success: function(data) {
|
||||||
|
if (data.status_text != lastStatusText) {
|
||||||
|
lastStatusText = data.status_text;
|
||||||
|
$("#log-status-icon").attr("class", "status icon-" + data.status);
|
||||||
|
$("#log-status-text").text(data.status_text);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (data.updated != lastUpdated) {
|
||||||
|
lastUpdated = data.updated;
|
||||||
|
$("#events").html(data.events);
|
||||||
|
switchDateFormat(lastFormat);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}, true);
|
||||||
|
|
||||||
|
// Copy to clipboard
|
||||||
|
var clipboard = new Clipboard('button.copy-btn');
|
||||||
|
$("button.copy-btn").mouseout(function(e) {
|
||||||
|
setTimeout(function() {
|
||||||
|
e.target.textContent = e.target.dataset.label;
|
||||||
|
}, 300);
|
||||||
|
});
|
||||||
|
|
||||||
|
clipboard.on('success', function(e) {
|
||||||
|
e.trigger.textContent = "Copied!";
|
||||||
|
e.clearSelection();
|
||||||
|
});
|
||||||
|
|
||||||
|
clipboard.on('error', function(e) {
|
||||||
|
var text = e.trigger.getAttribute("data-clipboard-text");
|
||||||
|
prompt("Press Ctrl+C to select:", text)
|
||||||
|
});
|
||||||
|
|
||||||
|
$("#log tr.ok").on("click", function() {
|
||||||
|
$("#ping-details-body").text("Updating...");
|
||||||
|
$('#ping-details-modal').modal("show");
|
||||||
|
|
||||||
|
var token = $('input[name=csrfmiddlewaretoken]').val();
|
||||||
|
$.ajax({
|
||||||
|
url: this.dataset.url,
|
||||||
|
type: "post",
|
||||||
|
headers: {"X-CSRFToken": token},
|
||||||
|
success: function(data) {
|
||||||
|
$("#ping-details-body" ).html(data);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
|
||||||
|
var lastFormat = "local";
|
||||||
|
function switchDateFormat(format) {
|
||||||
|
lastFormat = format;
|
||||||
|
$("#log tr").each(function(index, row) {
|
||||||
|
var dt = moment(row.getAttribute("data-dt"));
|
||||||
|
format == "local" ? dt.local() : dt.utc();
|
||||||
|
|
||||||
|
$(".date", row).text(dt.format("MMM D"));
|
||||||
|
$(".time", row).text(dt.format("HH:mm"));
|
||||||
|
})
|
||||||
|
|
||||||
|
// The table is initially hidden to avoid flickering as we convert dates.
|
||||||
|
// Once it's ready, set it to visible:
|
||||||
|
$("#log").css("visibility", "visible");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
$("#format-switcher").click(function(ev) {
|
||||||
|
var format = ev.target.getAttribute("data-format");
|
||||||
|
switchDateFormat(format);
|
||||||
|
});
|
||||||
|
});
|
@ -1,66 +1,4 @@
|
|||||||
$(function () {
|
$(function () {
|
||||||
$("#edit-name").click(function() {
|
|
||||||
$('#update-name-modal').modal("show");
|
|
||||||
$("#update-name-input").focus();
|
|
||||||
|
|
||||||
return false;
|
|
||||||
});
|
|
||||||
|
|
||||||
$("#pause").click(function(e) {
|
|
||||||
$("#pause-form").submit();
|
|
||||||
return false;
|
|
||||||
});
|
|
||||||
|
|
||||||
$("#ping-now").click(function(e) {
|
|
||||||
var button = this;
|
|
||||||
$.get(this.dataset.url, function() {
|
|
||||||
button.textContent = "Success!";
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
$("#ping-now").mouseout(function(e) {
|
|
||||||
setTimeout(function() {
|
|
||||||
e.target.textContent = "Ping Now!";
|
|
||||||
}, 300);
|
|
||||||
});
|
|
||||||
|
|
||||||
var code = document.getElementById("edit-timeout").dataset.code;
|
|
||||||
var statusUrl = "/checks/" + code + "/status/";
|
|
||||||
var lastStatusText = "";
|
|
||||||
adaptiveSetInterval(function() {
|
|
||||||
$.ajax({
|
|
||||||
url: statusUrl,
|
|
||||||
dataType: "json",
|
|
||||||
timeout: 2000,
|
|
||||||
success: function(data) {
|
|
||||||
if (data.status_text == lastStatusText) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
lastStatusText = data.status_text;
|
|
||||||
$("#log-status-icon").attr("class", "status icon-" + data.status);
|
|
||||||
$("#log-status-text").text(data.status_text);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
// Copy to clipboard
|
|
||||||
var clipboard = new Clipboard('button.copy-btn');
|
|
||||||
$("button.copy-btn").mouseout(function(e) {
|
|
||||||
setTimeout(function() {
|
|
||||||
e.target.textContent = e.target.dataset.label;
|
|
||||||
}, 300);
|
|
||||||
});
|
|
||||||
|
|
||||||
clipboard.on('success', function(e) {
|
|
||||||
e.trigger.textContent = "Copied!";
|
|
||||||
e.clearSelection();
|
|
||||||
});
|
|
||||||
|
|
||||||
clipboard.on('error', function(e) {
|
|
||||||
var text = e.trigger.getAttribute("data-clipboard-text");
|
|
||||||
prompt("Press Ctrl+C to select:", text)
|
|
||||||
});
|
|
||||||
|
|
||||||
$("#log tr.ok").on("click", function() {
|
$("#log tr.ok").on("click", function() {
|
||||||
$("#ping-details-body").text("Updating...");
|
$("#ping-details-body").text("Updating...");
|
||||||
$('#ping-details-modal').modal("show");
|
$('#ping-details-modal').modal("show");
|
||||||
|
@ -45,7 +45,7 @@
|
|||||||
</head>
|
</head>
|
||||||
<body class="page-{{ page }}">
|
<body class="page-{{ page }}">
|
||||||
<nav class="navbar navbar-default">
|
<nav class="navbar navbar-default">
|
||||||
<div class="container{% if page == "checks" or page == "log" %}-fluid{% endif %}">
|
<div class="container{% if page == "checks" or page == "details" %}-fluid{% endif %}">
|
||||||
<div class="navbar-header">
|
<div class="navbar-header">
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
@ -154,13 +154,13 @@
|
|||||||
</nav>
|
</nav>
|
||||||
|
|
||||||
{% block containers %}
|
{% block containers %}
|
||||||
<div class="container{% if page == "checks" or page == "log" %}-fluid{% endif %}">
|
<div class="container{% if page == "checks" or page == "details" %}-fluid{% endif %}">
|
||||||
{% block content %}{% endblock %}
|
{% block content %}{% endblock %}
|
||||||
</div>
|
</div>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
<footer class="footer">
|
<footer class="footer">
|
||||||
<div class="container{% if page == "checks" or page == "log" %}-fluid{% endif %}">
|
<div class="container{% if page == "checks" or page == "details" %}-fluid{% endif %}">
|
||||||
<ul>
|
<ul>
|
||||||
<li>
|
<li>
|
||||||
Powered by Healthchecks open-source project
|
Powered by Healthchecks open-source project
|
||||||
|
185
templates/front/details.html
Normal file
185
templates/front/details.html
Normal file
@ -0,0 +1,185 @@
|
|||||||
|
{% extends "base.html" %}
|
||||||
|
{% load compress humanize static hc_extras %}
|
||||||
|
|
||||||
|
{% block title %}My Checks - {% site_name %}{% endblock %}
|
||||||
|
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
<div id="details-head" class="col-sm-12">
|
||||||
|
<h1>
|
||||||
|
{{ check.name_then_code }}
|
||||||
|
<button id="edit-name" class="btn btn-sm btn-default">Edit</button>
|
||||||
|
</h1>
|
||||||
|
{% for tag in check.tags_list %}
|
||||||
|
<span class="label label-tag">{{ tag }}</span>
|
||||||
|
{% endfor %}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
<div class="col-sm-5">
|
||||||
|
<div class="details-block">
|
||||||
|
<h2>How To Ping</h2>
|
||||||
|
<div>
|
||||||
|
<p>Keep this check up by making HTTP requests to this URL:</p>
|
||||||
|
<code>{{ check.url }}</code>
|
||||||
|
<p>Or by sending emails to this address:</p>
|
||||||
|
<code>{{ check.email }}</code>
|
||||||
|
</div>
|
||||||
|
<div class="text-right">
|
||||||
|
<button
|
||||||
|
data-label="Copy URL"
|
||||||
|
data-clipboard-text="{{ check.url }}"
|
||||||
|
class="btn btn-sm btn-default copy-btn">Copy URL</button>
|
||||||
|
<button
|
||||||
|
data-label="Copy Email"
|
||||||
|
data-clipboard-text="{{ check.email }}"
|
||||||
|
class="btn btn-sm btn-default copy-btn">Copy Email</button>
|
||||||
|
<button
|
||||||
|
data-toggle="modal"
|
||||||
|
data-target="#show-usage-modal"
|
||||||
|
class="btn btn-sm btn-default">Usage Examples</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="details-block">
|
||||||
|
<h2>Current Status</h2>
|
||||||
|
<table>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<span id="log-status-icon" class="status icon-{{ check.get_status }}"></span>
|
||||||
|
</td>
|
||||||
|
<td id="log-status-text">
|
||||||
|
{% include "front/log_status_text.html" %}
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
<div class="text-right">
|
||||||
|
<form action="{% url 'hc-pause' check.code %}" method="post">
|
||||||
|
{% csrf_token %}
|
||||||
|
<input type="submit" class="btn btn-sm btn-default" value="Pause" />
|
||||||
|
</form>
|
||||||
|
|
||||||
|
<button
|
||||||
|
id="ping-now"
|
||||||
|
data-url="{{ check.url }}"
|
||||||
|
class="btn btn-sm btn-default">Ping Now!</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="details-block">
|
||||||
|
<h2>Schedule</h2>
|
||||||
|
<table id="log-schedule">
|
||||||
|
<tr>
|
||||||
|
{% if check.kind == "simple" %}
|
||||||
|
<th>Period</th>
|
||||||
|
<td>
|
||||||
|
<span class="value">{{ check.timeout|hc_duration }}</span>
|
||||||
|
<div class="subtitle">
|
||||||
|
(Expected time between pings)
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
{% elif check.kind == "cron" %}
|
||||||
|
<th>Cron Expression</th>
|
||||||
|
<td>
|
||||||
|
<span class="value">{{ check.schedule }}</span>
|
||||||
|
</td>
|
||||||
|
{% endif %}
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th>Grace Time</th>
|
||||||
|
<td>
|
||||||
|
<span class="value">{{ check.grace|hc_duration }}</span>
|
||||||
|
<div class="subtitle">
|
||||||
|
(When a check is late, how long to wait until an alert is sent)
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
<div class="text-right">
|
||||||
|
<button
|
||||||
|
id="edit-timeout"
|
||||||
|
class="btn btn-sm btn-default timeout-grace"
|
||||||
|
data-code="{{ check.code }}"
|
||||||
|
data-kind="{{ check.kind }}"
|
||||||
|
data-timeout="{{ check.timeout.total_seconds }}"
|
||||||
|
data-grace="{{ check.grace.total_seconds }}"
|
||||||
|
data-schedule="{{ check.schedule }}"
|
||||||
|
data-tz="{{ check.tz }}">
|
||||||
|
Change Schedule</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="details-block">
|
||||||
|
<h2>Notification Methods</h2>
|
||||||
|
<table id="details-integrations" class="table">
|
||||||
|
{% for channel in channels %}
|
||||||
|
<tr>
|
||||||
|
<th>
|
||||||
|
{% if channel in check.channel_set.all %}
|
||||||
|
<span class="label label-success">ON</span>
|
||||||
|
{% else %}
|
||||||
|
<span class="label label-default">OFF</span>
|
||||||
|
{% endif %}
|
||||||
|
</th>
|
||||||
|
<td>
|
||||||
|
<span class="icon-{{ channel.kind }}"></span>
|
||||||
|
{{ channel }}
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
{% endfor %}
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="details-block">
|
||||||
|
<h2>Remove</h2>
|
||||||
|
<p>Permanently remove this check from your account.</p>
|
||||||
|
<div class="text-right">
|
||||||
|
<button
|
||||||
|
id="details-remove-check"
|
||||||
|
data-toggle="modal"
|
||||||
|
data-target="#remove-check-modal"
|
||||||
|
class="btn btn-sm btn-default">Remove This Check</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
<div id="events" class="col-sm-7">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="ping-details-modal" class="modal">
|
||||||
|
<div class="modal-dialog">
|
||||||
|
<div class="modal-content">
|
||||||
|
<div id="ping-details-body">Loading</div>
|
||||||
|
<div class="modal-footer">
|
||||||
|
<button type="button" class="btn btn-default" data-dismiss="modal">Got It!</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{% include "front/update_name_modal.html" %}
|
||||||
|
{% include "front/update_timeout_modal.html" %}
|
||||||
|
{% include "front/show_usage_modal.html" %}
|
||||||
|
{% include "front/remove_check_modal.html" %}
|
||||||
|
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
{% block scripts %}
|
||||||
|
{% compress js %}
|
||||||
|
<script src="{% static 'js/jquery-2.1.4.min.js' %}"></script>
|
||||||
|
<script src="{% static 'js/bootstrap.min.js' %}"></script>
|
||||||
|
<script src="{% static 'js/clipboard.min.js' %}"></script>
|
||||||
|
<script src="{% static 'js/selectize.min.js' %}"></script>
|
||||||
|
<script src="{% static 'js/nouislider.min.js' %}"></script>
|
||||||
|
<script src="{% static 'js/snippet-copy.js' %}"></script>
|
||||||
|
<script src="{% static 'js/moment.min.js' %}"></script>
|
||||||
|
<script src="{% static 'js/update-timeout-modal.js' %}"></script>
|
||||||
|
<script src="{% static 'js/adaptive-setinterval.js' %}"></script>
|
||||||
|
<script src="{% static 'js/details.js' %}"></script>
|
||||||
|
{% endcompress %}
|
||||||
|
{% endblock %}
|
110
templates/front/details_events.html
Normal file
110
templates/front/details_events.html
Normal file
@ -0,0 +1,110 @@
|
|||||||
|
{% load hc_extras %}
|
||||||
|
{% if events %}
|
||||||
|
<h2>
|
||||||
|
Log
|
||||||
|
<small>Click on individual items for details</small>
|
||||||
|
<div id="format-switcher" class="btn-group pull-right" data-toggle="buttons">
|
||||||
|
<label class="btn btn-default btn-xs" data-format="utc">
|
||||||
|
<input type="radio" name="date-format" checked>
|
||||||
|
UTC
|
||||||
|
</label>
|
||||||
|
|
||||||
|
<label class="btn btn-default btn-xs active" data-format="local">
|
||||||
|
<input type="radio" name="date-format">
|
||||||
|
Local Time
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
</h2>
|
||||||
|
|
||||||
|
<div id="log-container">
|
||||||
|
<table class="table" id="log">
|
||||||
|
{% for event in events %}
|
||||||
|
{% if event.n %}
|
||||||
|
<tr class="ok" data-dt="{{ event.created.isoformat }}" data-url="{% url 'hc-ping-details' check.code event.n %}">
|
||||||
|
<td class="n-cell">
|
||||||
|
<span class="hash">#</span>{{ event.n }}
|
||||||
|
</td>
|
||||||
|
<td class="date"></td>
|
||||||
|
<td class="time"></td>
|
||||||
|
<td class="text-right">
|
||||||
|
{% if event.fail %}
|
||||||
|
<span class="label label-danger">Failure</span>
|
||||||
|
{% else %}
|
||||||
|
<span class="label label-success">OK</span>
|
||||||
|
{% endif %}
|
||||||
|
</td>
|
||||||
|
<td class="details">
|
||||||
|
<div>
|
||||||
|
{% if event.scheme == "email" %}
|
||||||
|
{{ event.ua }}
|
||||||
|
<span class="ua-body">
|
||||||
|
{% if event.body %}
|
||||||
|
- {{ event.body|trunc }}
|
||||||
|
{% endif %}
|
||||||
|
</span>
|
||||||
|
{% else %}
|
||||||
|
{{ event.scheme|upper }}
|
||||||
|
{{ event.method }}
|
||||||
|
{% if event.remote_addr %}
|
||||||
|
from {{ event.remote_addr }}
|
||||||
|
{% endif %}
|
||||||
|
<span class="ua-body">
|
||||||
|
{% if event.ua %}
|
||||||
|
- {{ event.ua }}
|
||||||
|
{% endif %}
|
||||||
|
</span>
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
{% endif %}
|
||||||
|
{% if event.check_status %}
|
||||||
|
<tr class="missing" data-dt="{{ event.created.isoformat }}">
|
||||||
|
<td class="n-cell">
|
||||||
|
<span class="icon-missing"></span>
|
||||||
|
</td>
|
||||||
|
<td class="date"></td>
|
||||||
|
<td class="time"></td>
|
||||||
|
<td class="alert-info" colspan="2">
|
||||||
|
{% if event.channel.kind == "email" %}
|
||||||
|
Sent email alert to {{ event.channel.value }}
|
||||||
|
{% elif event.channel.kind == "slack" %}
|
||||||
|
Sent Slack alert
|
||||||
|
{% if event.channel.slack_channel %}
|
||||||
|
to {{ event.channel.slack_channel }}
|
||||||
|
{% endif %}
|
||||||
|
{% elif event.channel.kind == "pd" %}
|
||||||
|
Sent alert to PagerDuty
|
||||||
|
{% elif event.channel.kind == "pagertree" %}
|
||||||
|
Sent alert to PagerTree
|
||||||
|
{% elif event.channel.kind == "opsgenie" %}
|
||||||
|
Sent alert to OpsGenie
|
||||||
|
{% elif event.channel.kind == "hipchat" %}
|
||||||
|
Sent alert to HipChat
|
||||||
|
{% elif event.channel.kind == "po" %}
|
||||||
|
Sent a Pushover notification
|
||||||
|
{% elif event.channel.kind == "webhook" %}
|
||||||
|
Called webhook {{ event.channel.url_down }}
|
||||||
|
{% else %}
|
||||||
|
Sent alert to {{ event.channel.kind|capfirst }}
|
||||||
|
{% endif %}
|
||||||
|
{% if event.error %}
|
||||||
|
<br />
|
||||||
|
<strong>Error: {{ event.error }}</strong>
|
||||||
|
{% endif %}
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
{% endif %}
|
||||||
|
{% endfor %}
|
||||||
|
</table>
|
||||||
|
|
||||||
|
{% if check.n_pings > 20 %}
|
||||||
|
<p class="text-center">
|
||||||
|
<a href="{% url 'hc-log' check.code %}">Show More…</a>
|
||||||
|
</p>
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
{% else %}
|
||||||
|
<h2>Log</h2>
|
||||||
|
<div class="alert alert-info">This check has not received any pings yet.</div>
|
||||||
|
{% endif %}
|
@ -1,5 +1,5 @@
|
|||||||
{% extends "base.html" %}
|
{% extends "base.html" %}
|
||||||
{% load compress humanize static hc_extras %}
|
{% load compress humanize staticfiles hc_extras %}
|
||||||
|
|
||||||
{% block title %}My Checks - {% site_name %}{% endblock %}
|
{% block title %}My Checks - {% site_name %}{% endblock %}
|
||||||
|
|
||||||
@ -7,152 +7,18 @@
|
|||||||
{% block content %}
|
{% block content %}
|
||||||
|
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div id="details-head" class="col-sm-12">
|
<div class="col-sm-12">
|
||||||
<h1>
|
<ol class="breadcrumb">
|
||||||
|
<li><a href="{% url 'hc-checks' %}">Checks</a></li>
|
||||||
|
<li>
|
||||||
|
<a href="{% url 'hc-details' check.code %}">
|
||||||
{{ check.name_then_code }}
|
{{ check.name_then_code }}
|
||||||
<button id="edit-name" class="btn btn-sm btn-default">Edit</button>
|
</a>
|
||||||
</h1>
|
</li>
|
||||||
{% for tag in check.tags_list %}
|
<li class="active">Log</li>
|
||||||
<span class="label label-tag">{{ tag }}</span>
|
|
||||||
{% endfor %}
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
<li id="format-switcher-container" class="pull-right">
|
||||||
<div class="col-sm-5">
|
<div id="format-switcher" class="btn-group" data-toggle="buttons">
|
||||||
<div class="details-block">
|
|
||||||
<h2>How To Ping</h2>
|
|
||||||
<div>
|
|
||||||
<p>Keep this check up by making HTTP requests to this URL:</p>
|
|
||||||
<code>{{ check.url }}</code>
|
|
||||||
<p>Or by sending emails to this address:</p>
|
|
||||||
<code>{{ check.email }}</code>
|
|
||||||
</div>
|
|
||||||
<div class="text-right">
|
|
||||||
<button
|
|
||||||
data-label="Copy URL"
|
|
||||||
data-clipboard-text="{{ check.url }}"
|
|
||||||
class="btn btn-sm btn-default copy-btn">Copy URL</button>
|
|
||||||
<button
|
|
||||||
data-label="Copy Email"
|
|
||||||
data-clipboard-text="{{ check.email }}"
|
|
||||||
class="btn btn-sm btn-default copy-btn">Copy Email</button>
|
|
||||||
<button
|
|
||||||
data-toggle="modal"
|
|
||||||
data-target="#show-usage-modal"
|
|
||||||
class="btn btn-sm btn-default">Usage Examples</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="details-block">
|
|
||||||
<h2>Current Status</h2>
|
|
||||||
<table>
|
|
||||||
<tr>
|
|
||||||
<td>
|
|
||||||
<span id="log-status-icon" class="status icon-{{ check.get_status }}"></span>
|
|
||||||
</td>
|
|
||||||
<td id="log-status-text">
|
|
||||||
{% include "front/log_status_text.html" %}
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
</table>
|
|
||||||
<div class="text-right">
|
|
||||||
<form action="{% url 'hc-pause' check.code %}" method="post">
|
|
||||||
{% csrf_token %}
|
|
||||||
<input type="submit" class="btn btn-sm btn-default" value="Pause" />
|
|
||||||
</form>
|
|
||||||
|
|
||||||
<button
|
|
||||||
id="ping-now"
|
|
||||||
data-url="{{ check.url }}"
|
|
||||||
class="btn btn-sm btn-default">Ping Now!</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="details-block">
|
|
||||||
<h2>Schedule</h2>
|
|
||||||
<table id="log-schedule">
|
|
||||||
<tr>
|
|
||||||
{% if check.kind == "simple" %}
|
|
||||||
<th>Period</th>
|
|
||||||
<td>
|
|
||||||
<span class="value">{{ check.timeout|hc_duration }}</span>
|
|
||||||
<div class="subtitle">
|
|
||||||
(Expected time between pings)
|
|
||||||
</div>
|
|
||||||
</td>
|
|
||||||
{% elif check.kind == "cron" %}
|
|
||||||
<th>Cron Expression</th>
|
|
||||||
<td>
|
|
||||||
<span class="value">{{ check.schedule }}</span>
|
|
||||||
</td>
|
|
||||||
{% endif %}
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<th>Grace Time</th>
|
|
||||||
<td>
|
|
||||||
<span class="value">{{ check.grace|hc_duration }}</span>
|
|
||||||
<div class="subtitle">
|
|
||||||
(When a check is late, how long to wait until an alert is sent)
|
|
||||||
</div>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
</table>
|
|
||||||
<div class="text-right">
|
|
||||||
<button
|
|
||||||
id="edit-timeout"
|
|
||||||
class="btn btn-sm btn-default timeout-grace"
|
|
||||||
data-code="{{ check.code }}"
|
|
||||||
data-kind="{{ check.kind }}"
|
|
||||||
data-timeout="{{ check.timeout.total_seconds }}"
|
|
||||||
data-grace="{{ check.grace.total_seconds }}"
|
|
||||||
data-schedule="{{ check.schedule }}"
|
|
||||||
data-tz="{{ check.tz }}">
|
|
||||||
Change Schedule</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="details-block">
|
|
||||||
<h2>Notification Methods</h2>
|
|
||||||
<table id="details-integrations" class="table">
|
|
||||||
{% for channel in channels %}
|
|
||||||
<tr>
|
|
||||||
<th>
|
|
||||||
{% if channel in check.channel_set.all %}
|
|
||||||
<span class="label label-success">ON</span>
|
|
||||||
{% else %}
|
|
||||||
<span class="label label-default">OFF</span>
|
|
||||||
{% endif %}
|
|
||||||
</th>
|
|
||||||
<td>
|
|
||||||
<span class="icon-{{ channel.kind }}"></span>
|
|
||||||
{{ channel }}
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
{% endfor %}
|
|
||||||
</table>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="details-block">
|
|
||||||
<h2>Remove</h2>
|
|
||||||
<p>Permanently remove this check from your account.</p>
|
|
||||||
<div class="text-right">
|
|
||||||
<button
|
|
||||||
id="details-remove-check"
|
|
||||||
data-toggle="modal"
|
|
||||||
data-target="#remove-check-modal"
|
|
||||||
class="btn btn-sm btn-default">Remove This Check</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
<div class="col-sm-7">
|
|
||||||
{% if events %}
|
|
||||||
<h2>
|
|
||||||
Log
|
|
||||||
<small>Click on individual items for details</small>
|
|
||||||
<div id="format-switcher" class="btn-group pull-right" data-toggle="buttons">
|
|
||||||
<label class="btn btn-default btn-xs" data-format="utc">
|
<label class="btn btn-default btn-xs" data-format="utc">
|
||||||
<input type="radio" name="date-format" checked>
|
<input type="radio" name="date-format" checked>
|
||||||
UTC
|
UTC
|
||||||
@ -163,9 +29,11 @@
|
|||||||
Local Time
|
Local Time
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
</h2>
|
</li>
|
||||||
|
</ol>
|
||||||
|
|
||||||
<div id="log-container">
|
{% if events %}
|
||||||
|
<div class="table-responsive">
|
||||||
<table class="table" id="log">
|
<table class="table" id="log">
|
||||||
{% for event in events %}
|
{% for event in events %}
|
||||||
{% if event.n %}
|
{% if event.n %}
|
||||||
@ -201,6 +69,9 @@
|
|||||||
{% if event.ua %}
|
{% if event.ua %}
|
||||||
- {{ event.ua }}
|
- {{ event.ua }}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
{% if event.body %}
|
||||||
|
- {{ event.body|trunc }}
|
||||||
|
{% endif %}
|
||||||
</span>
|
</span>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
@ -247,17 +118,19 @@
|
|||||||
{% endfor %}
|
{% endfor %}
|
||||||
</table>
|
</table>
|
||||||
|
|
||||||
{% if can_load_more %}
|
{% if show_limit_notice and limit < 1000 %}
|
||||||
<p class="text-center">
|
<p class="alert alert-info">
|
||||||
Showing {{ num_showing }} most recent pings.
|
<strong>Showing last {{ limit }} pings.</strong>
|
||||||
<a href="?full_log=1">Load More…</a>
|
Want to see more?
|
||||||
|
<a href="{% url 'hc-pricing' %}">
|
||||||
|
Upgrade your account!
|
||||||
|
</a>
|
||||||
</p>
|
</p>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
{% else %}
|
{% else %}
|
||||||
<h2>Log</h2>
|
<div class="alert alert-info">Log is empty. This check has not received any pings yet.</div>
|
||||||
<div class="alert alert-info">This check has not received any pings yet.</div>
|
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -271,26 +144,18 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<form>
|
||||||
|
{% csrf_token %}
|
||||||
|
</form>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{% include "front/update_name_modal.html" %}
|
|
||||||
{% include "front/update_timeout_modal.html" %}
|
|
||||||
{% include "front/show_usage_modal.html" %}
|
|
||||||
{% include "front/remove_check_modal.html" %}
|
|
||||||
|
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block scripts %}
|
{% block scripts %}
|
||||||
{% compress js %}
|
{% compress js %}
|
||||||
<script src="{% static 'js/jquery-2.1.4.min.js' %}"></script>
|
<script src="{% static 'js/jquery-2.1.4.min.js' %}"></script>
|
||||||
<script src="{% static 'js/bootstrap.min.js' %}"></script>
|
<script src="{% static 'js/bootstrap.min.js' %}"></script>
|
||||||
<script src="{% static 'js/clipboard.min.js' %}"></script>
|
|
||||||
<script src="{% static 'js/selectize.min.js' %}"></script>
|
|
||||||
<script src="{% static 'js/nouislider.min.js' %}"></script>
|
|
||||||
<script src="{% static 'js/snippet-copy.js' %}"></script>
|
|
||||||
<script src="{% static 'js/moment.min.js' %}"></script>
|
<script src="{% static 'js/moment.min.js' %}"></script>
|
||||||
<script src="{% static 'js/update-timeout-modal.js' %}"></script>
|
|
||||||
<script src="{% static 'js/adaptive-setinterval.js' %}"></script>
|
|
||||||
<script src="{% static 'js/log.js' %}"></script>
|
<script src="{% static 'js/log.js' %}"></script>
|
||||||
{% endcompress %}
|
{% endcompress %}
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user