statping/source/tmpl/service.gohtml

340 lines
12 KiB
Plaintext
Raw Normal View History

2018-10-02 06:21:14 +00:00
{{define "title"}}{{.Service.Name}} Status{{end}}
2018-11-06 07:15:55 +00:00
{{define "description"}}{{$s := .Service}}{{if $s.Online }}{{.Service.Name}} is currently online and responding within {{$s.AvgTime}} milliseconds with {{$s.TotalUptime}}% total uptime on {{$s.Domain}}.{{else}}{{.Service.Name}} is currently offline on {{$s.Domain}}. Notify the admin to let them know their service is offline.{{end}}{{end}}
2018-10-02 06:21:14 +00:00
{{ define "content" }}
2018-09-18 22:02:27 +00:00
{{$s := .Service}}
2019-01-04 06:16:44 +00:00
{{$failures := $s.LimitedFailures 16}}
{{$checkinFailures := $s.LimitedCheckinFailures 16}}
{{$isAdmin := Auth}}
2018-06-24 11:51:07 +00:00
<div class="container col-md-7 col-sm-12 mt-md-5 bg-light">
2018-06-11 03:41:02 +00:00
{{if IsUser}}
2018-06-11 03:41:02 +00:00
{{template "nav"}}
{{end}}
2018-10-02 06:21:14 +00:00
<div class="col-12 mb-4">
2018-06-11 03:41:02 +00:00
{{if $s.Online }}
<span class="mt-3 mb-3 text-white d-md-none btn bg-success d-block d-md-none">ONLINE</span>
{{ else }}
<span class="mt-3 mb-3 text-white d-md-none btn bg-danger d-block d-md-none">OFFLINE</span>
{{end}}
2018-10-02 06:21:14 +00:00
<h4 class="mt-2"><a href="/">{{CoreApp.Name}}</a> - {{ $s.Name }}
2018-10-02 06:21:14 +00:00
{{if $s.Online }}
<span class="badge bg-success float-right d-none d-md-block">ONLINE</span>
{{ else }}
<span class="badge bg-danger float-right d-none d-md-block">OFFLINE</span>
{{end}}</h4>
2018-06-11 03:41:02 +00:00
2018-10-02 06:21:14 +00:00
<div class="row stats_area mt-5 mb-5">
<div class="col-4">
<span class="lg_number">{{$s.OnlineDaysPercent 1}}%</span>
2018-10-02 06:21:14 +00:00
Online last 24 Hours
</div>
<div class="col-4">
<span class="lg_number">{{$s.AvgTime}}ms</span>
Average Response
2018-06-22 04:02:57 +00:00
</div>
2018-10-02 06:21:14 +00:00
<div class="col-4">
<span class="lg_number">{{$s.TotalUptime}}%</span>
Total Uptime
</div>
</div>
{{if $s.ActiveMessages}}
2018-11-16 16:42:49 +00:00
<div class="col-12 mb-5">
{{range $s.ActiveMessages}}
<div class="alert alert-warning" role="alert">
<h3>{{.Title}}</h3>
<span class="mb-3">{{safe .Description}}</span>
<div class="d-block mt-2 mb-4">
<span class="float-left small">Starts at {{.StartOn}}</span>
<span class="float-right small">Ends on {{.EndOn}}</span>
</div>
2018-11-16 16:42:49 +00:00
</div>
{{end}}
</div>
{{end}}
2018-10-02 06:21:14 +00:00
<div class="service-chart-container">
2019-01-29 12:02:13 +00:00
<div id="service"></div>
2019-02-01 19:57:59 +00:00
<div id="service-bar"></div>
2019-01-29 12:02:13 +00:00
</div>
<div class="service-chart-heatmap">
2019-01-29 12:02:13 +00:00
<div id="service_heatmap"></div>
2018-10-02 06:21:14 +00:00
</div>
<form id="service_date_form" class="col-12 mt-2 mb-3">
<input type="text" class="d-none" name="start" id="service_start" data-input>
<span data-toggle title="toggle" id="start_date" class="text-muted small float-left pointer mt-2">{{.Start}} to {{.End}}</span>
<button type="submit" class="btn btn-light btn-sm mt-2">Set Timeframe</button>
<input type="text" class="d-none" name="end" id="service_end" data-input>
2018-10-02 06:21:14 +00:00
<div id="start_container"></div>
<div id="end_container"></div>
</form>
{{if not $s.Online}}
<div class="col-12 small text-center mt-3 text-muted">{{$s.DowntimeText}}</div>
{{end}}
{{if IsUser}}
<nav class="nav nav-pills flex-column flex-sm-row mt-3" id="service_tabs" role="serviceLists">
{{if $isAdmin}}<a class="flex-sm-fill text-sm-center nav-link active" id="edit-tab" data-toggle="tab" href="#edit" role="tab" aria-controls="edit" aria-selected="false">Edit Service</a>{{end}}
<a class="flex-sm-fill text-sm-center nav-link{{ if not $failures }} disabled{{end}}" id="failures-tab" data-toggle="tab" href="#failures" role="tab" aria-controls="failures" aria-selected="true">Failures</a>
{{if $isAdmin}}<a class="flex-sm-fill text-sm-center nav-link" id="checkins-tab" data-toggle="tab" href="#checkins" role="tab" aria-controls="checkins" aria-selected="false">Checkins</a>{{end}}
<a class="flex-sm-fill text-sm-center nav-link{{if not $isAdmin}} active{{end}}" id="response-tab" data-toggle="tab" href="#response" role="tab" aria-controls="response" aria-selected="false">Response</a>
</nav>
<div class="tab-content" id="myTabContent">
{{if $isAdmin}}
<div class="tab-pane fade" id="failures" role="serviceLists" aria-labelledby="failures-tab">
{{ if $failures }}
<div class="list-group mt-3 mb-4">
{{ range $failures }}
<a href="#" class="list-group-item list-group-item-action flex-column align-items-start">
<div class="d-flex w-100 justify-content-between">
<h5 class="mb-1">{{.ParseError}}</h5>
<small>{{.Ago}}</small>
</div>
<p class="mb-1">{{.Issue}}</p>
</a>
{{ end }}
2018-10-02 06:21:14 +00:00
</div>
{{ end }}
2018-06-23 08:42:50 +00:00
</div>
{{end}}
{{if $isAdmin}}
<div class="tab-pane fade" id="checkins" role="serviceLists" aria-labelledby="checkins-tab">
2018-12-06 19:03:55 +00:00
{{if $s.AllCheckins}}
<table class="table">
<thead>
<tr>
<th scope="col">Checkin</th>
<th scope="col">Report Period<br>Grace Period</th>
<th scope="col">Last Seen</th>
<th scope="col">Expected</th>
<th scope="col"></th>
</tr>
</thead>
<tbody style="font-size: 10pt;">
2018-12-06 19:03:55 +00:00
{{range $s.AllCheckins}}
{{ $ch := . }}
<tr id="checkin_{{$ch.Id}}" class="{{ if lt $ch.Expected 0}}bg-warning text-black{{else}}bg-light{{end}}">
<td>{{$ch.Name}}<br><a href="{{$ch.Link}}" target="_blank">{{$ch.Link}}</a></td>
<td>every {{Duration $ch.Period}}<br>after {{Duration $ch.Grace}}</td>
<td>{{ if $ch.Last.CreatedAt.IsZero}}
Never
{{else}}
2018-10-07 22:38:56 +00:00
{{Ago $ch.Last.CreatedAt}}
{{end}}
</td>
<td>
{{ if $ch.Last.CreatedAt.IsZero}}
-
{{else}}
2018-10-07 22:38:56 +00:00
{{ if lt $ch.Expected 0}}{{Duration $ch.Expected}} ago{{else}}in {{Duration $ch.Expected}}{{end}}
{{end}}
</td>
<td><a href="/api/checkin/{{$ch.ApiKey}}" data-method="DELETE" data-obj="checkin_{{$ch.Id}}" data-id="{{$ch.Id}}" class="ajax_delete btn btn-sm btn-danger">Delete</a></td>
</tr>
2018-10-07 22:38:56 +00:00
{{end}}
</tbody>
</table>
2018-10-06 03:35:53 +00:00
{{end}}
{{if $isAdmin}}
{{template "form_checkin" $s}}
{{end}}
2019-01-04 06:16:44 +00:00
{{ if $checkinFailures }}
<div class="list-group mt-3 mb-4">
2019-01-04 06:16:44 +00:00
{{ range $checkinFailures }}
<a href="#" class="list-group-item list-group-item-action flex-column align-items-start">
<div class="d-flex w-100 justify-content-between">
<h5 class="mb-1">{{.ParseError}}</h5>
<small>{{.Ago}}</small>
</div>
<p class="mb-1">{{.Issue}}</p>
</a>
{{ end }}
</div>
{{ end }}
</div>
{{ end }}
<div class="tab-pane fade{{if not $isAdmin}} show active{{end}}" id="response" role="serviceLists" aria-labelledby="response-tab">
<div class="col-12 mt-4{{if ne $s.Type "http"}} d-none{{end}}">
<h3>Last Response</h3>
<textarea rows="8" class="form-control" readonly>{{ $s.LastResponse }}</textarea>
<div class="form-group row mt-2">
<label for="last_status_code" class="col-sm-3 col-form-label">HTTP Status Code</label>
<div class="col-sm-2">
<input type="text" id="last_status_code" class="form-control" value="{{ $s.LastStatusCode }}" readonly>
</div>
</div>
</div>
</div>
{{if $isAdmin}}
<div class="tab-pane fade show active" id="edit" role="serviceLists" aria-labelledby="edit-tab">
{{template "form_service" $s}}
</div>
{{end}}
</div>
2019-01-04 06:16:44 +00:00
{{else}}
{{if $s.Public.Bool }}
{{ if $failures }}
<div class="list-group mt-3 mb-4">
{{ range $failures }}
<a href="#" class="list-group-item list-group-item-action flex-column align-items-start">
<div class="d-flex w-100 justify-content-between">
<h5 class="mb-1">{{.ParseError}}</h5>
<small>{{.Ago}}</small>
</div>
<p class="mb-1">{{.Issue}}</p>
</a>
{{ end }}
</div>
{{ end }}
{{end}}
2018-06-30 19:30:58 +00:00
{{end}}
2018-06-30 03:40:00 +00:00
</div>
</div>
2018-10-02 06:21:14 +00:00
{{end}}
{{define "extra_css"}}
<link rel="stylesheet" href="/css/flatpickr.min.css">
{{end}}
{{define "extra_scripts"}}
2018-10-02 06:21:14 +00:00
{{$s := .Service}}
<script src="/js/flatpickr.js"></script>
<script src="/js/rangePlugin.js"></script>
2018-09-18 22:02:27 +00:00
<script>
2018-09-21 04:17:24 +00:00
let options = {
chart: {
height: "100%",
width: "100%",
type: "area",
animations: {
enabled: false,
initialAnimation: {
enabled: false
}
},
},
fill: {
colors: ["#48d338"],
opacity: 1,
type: 'solid'
},
stroke: {
show: true,
curve: 'smooth',
lineCap: 'butt',
colors: ["#3aa82d"],
},
2019-02-20 02:11:40 +00:00
series: [{data: [{}]}],
xaxis: {
type: "datetime",
2019-02-01 19:57:59 +00:00
tickAmount: 8,
},
yaxis: {
labels: {
formatter: (value) => {
return (value).toFixed(0) + "ms"
2018-09-21 04:17:24 +00:00
},
2019-01-29 12:02:13 +00:00
},
},
dataLabels: {
enabled: false
},
};
var heat_options = {
chart: {
height: "100%",
width: "100%",
type: 'heatmap',
toolbar: {
show: false
}
},
dataLabels: {
enabled: false,
},
enableShades: true,
shadeIntensity: 0.5,
colors: ["#d53a3b"],
2019-02-20 02:11:40 +00:00
series: [{data: [{}]}],
yaxis: {
labels: {
formatter: (value) => {
return value
},
2019-01-29 12:02:13 +00:00
},
},
tooltip: {
enabled: true,
x: {
show: false,
2019-01-29 12:02:13 +00:00
},
y: {
formatter: function(val, opts) { return val+" Failures" },
title: {
formatter: (seriesName) => seriesName,
2019-01-29 12:02:13 +00:00
},
},
}
};
2018-09-21 04:17:24 +00:00
2019-01-29 12:02:13 +00:00
async function RenderHeatmap() {
let heatChart = new ApexCharts(
document.querySelector("#service_heatmap"),
heat_options
);
let dataArr = [];
let heatmapData = await ChartHeatmap({{$s.Id}});
heatmapData.forEach(function(d) {
var date = new Date(d.date);
dataArr.push({name: date.toLocaleString('en-us', { month: 'long' }), data: d.data});
});
heatChart.render();
heatChart.updateSeries(dataArr);
}
async function RenderChartLatency() {
2019-02-23 22:14:30 +00:00
options.fill.colors = {{if $s.Online}}["#48d338"]{{else}}["#dd3545"]{{end}};
options.stroke.colors = {{if $s.Online}}["#3aa82d"]{{else}}["#c23342"]{{end}};
let chart = new ApexCharts(document.querySelector("#service"), options);
await RenderChart(chart,{{$s.Id}},{{.StartUnix}},{{.EndUnix}},"hour");
}
2018-09-21 04:17:24 +00:00
$(document).ready(async function() {
let startDate = $("#service_start").flatpickr({
enableTime: false,
static: true,
altInput: true,
altFormat: "U",
maxDate: "today",
dateFormat: "F j, Y",
onChange: function(selectedDates, dateStr, instance) {
var one = Math.round((new Date(selectedDates[0])).getTime() / 1000);
var two = Math.round((new Date(selectedDates[1])).getTime() / 1000);
$("#service_start").val(one);
$("#service_end").val(two);
$("#start_date").html(dateStr);
},
"plugins": [new rangePlugin({ input: "#service_end"})]
2018-09-18 22:02:27 +00:00
});
$("#start_date").click(function(e) {
startDate.open()
2018-10-07 22:38:56 +00:00
});
2018-09-18 22:02:27 +00:00
await RenderChartLatency();
await RenderHeatmap();
2019-01-29 12:02:13 +00:00
});
2018-09-18 22:02:27 +00:00
</script>
2018-10-02 06:21:14 +00:00
{{end}}