Last active
March 9, 2017 07:31
-
-
Save freekrai/4a3bd796a374fc6fd42f7359570372dd to your computer and use it in GitHub Desktop.
status page
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!doctype html> | |
<html lang="en"> | |
<head> | |
<meta charset="utf-8"> | |
<meta http-equiv="X-UA-Compatible" content="IE=edge"> | |
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"> | |
<meta name="description" content="Service status"> | |
<meta name="robots" content="index, follow"> | |
<title>Status</title> | |
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous"> | |
<link rel="stylesheet" href="style.css?v=20170223"> | |
</head> | |
<body> | |
<div class="container"> | |
<header> | |
<h1>Status Page</h1> | |
</header> | |
<div class="panel" id="panel"> | |
<div class="panel-heading"> | |
<h3 class="panel-title" id="paneltitle"></h3> | |
</div> | |
</div> | |
<h4 class="page-header">Systems Status</h4> | |
<div class="list-group" id="services"></div> | |
<h4 class="page-header">Incidents</h4> | |
<div class="timeline-centered" id="incidents"></div> | |
<script src="//code.jquery.com/jquery.min.js"></script> | |
<script src="script.js?v=20170223"></script> | |
</body> | |
</html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
$(document).ready(function() { | |
var config = { | |
uptimerobot: { | |
api_keys: [ | |
"YOUR-UPTIME-ROBOT-API-KEY-1", | |
"YOUR-UPTIME-ROBOT-API-KEY-2" | |
], | |
logs: 1 | |
}, | |
github: { | |
org: 'YOUR-GITHUB-USERNAME', | |
repo: 'YOUR-GITHUB-REPO' | |
} | |
}; | |
var status_text = { | |
'operational': 'operational', | |
'investigating': 'investigating', | |
'major outage': 'outage', | |
'degraded performance': 'degraded', | |
}; | |
var monitors = config.uptimerobot.api_keys; | |
for( var i in monitors ){ | |
var api_key = monitors[i]; | |
$.post('https://api.uptimerobot.com/v2/getMonitors', { | |
"api_key": api_key, | |
"format": "json", | |
"logs": config.uptimerobot.logs, | |
}, function(response) { | |
status( response ); | |
}, 'json'); | |
} | |
function status(data) { | |
data.monitors = data.monitors.map(function(check) { | |
check.class = check.status === 2 ? 'label-success' : 'label-danger'; | |
check.text = check.status === 2 ? 'operational' : 'major outage'; | |
if( check.status !== 2 && !check.lasterrortime ){ | |
check.lasterrortime = Date.now(); | |
} | |
if (check.status === 2 && Date.now() - (check.lasterrortime * 1000) <= 86400000) { | |
check.class = 'label-warning'; | |
check.text = 'degraded performance'; | |
} | |
return check; | |
}); | |
var status = data.monitors.reduce(function(status, check) { | |
return check.status !== 2 ? 'danger' : 'operational'; | |
}, 'operational'); | |
if (!$('#panel').data('incident')) { | |
$('#panel').attr('class', (status === 'operational' ? 'panel-success' : 'panel-warning') ); | |
$('#paneltitle').html(status === 'operational' ? 'All systems are operational.' : 'One or more systems inoperative'); | |
} | |
data.monitors.forEach(function(item) { | |
var name = item.friendly_name; | |
var clas = item.class; | |
var text = item.text; | |
$('#services').append('<div class="list-group-item">'+ | |
'<span class="badge '+ clas + '">' + text + '</span>' + | |
'<h4 class="list-group-item-heading">' + name + '</h4>' + | |
'</div>'); | |
}); | |
}; | |
$.getJSON( 'https://api.github.com/repos/' + config.github.org + '/' + config.github.repo + '/issues?state=all' ).done(message); | |
function message(issues) { | |
issues.forEach(function(issue) { | |
var status = issue.labels.reduce(function(status, label) { | |
if (/^status:/.test(label.name)) { | |
return label.name.replace('status:', ''); | |
} else { | |
return status; | |
} | |
}, 'operational'); | |
var systems = issue.labels.filter(function(label) { | |
return /^system:/.test(label.name); | |
}).map(function(label) { | |
return label.name.replace('system:', '') | |
}); | |
if (issue.state === 'open') { | |
$('#panel').data('incident', 'true'); | |
$('#panel').attr('class', (status === 'operational' ? 'panel-success' : 'panel-warn') ); | |
$('#paneltitle').html('<a href="#incidents">' + issue.title + '</a>'); | |
} | |
var html = '<article class="timeline-entry">\n'; | |
html += '<div class="timeline-entry-inner">\n'; | |
if (issue.state === 'closed') { | |
html += '<div class="timeline-icon bg-success"><i class="entypo-feather"></i></div>'; | |
} else { | |
html += '<div class="timeline-icon bg-secondary"><i class="entypo-feather"></i></div>'; | |
} | |
html += '<div class="timeline-label">\n'; | |
html += '<span class="date">' + datetime(issue.created_at) + '</span>\n'; | |
if (issue.state === 'closed') { | |
html += '<span class="badge label-success pull-right">closed</span>'; | |
} else { | |
html += '<span class="badge ' + (status === 'operational' ? 'label-success' : 'label-warn') + ' pull-right">open</span>\n'; | |
} | |
for (var i = 0; i < systems.length; i++) { | |
html += '<span class="badge system pull-right">' + systems[i] + '</span>'; | |
} | |
html += '<h2>' + issue.title + '</h2>\n'; | |
html += '<hr>\n'; | |
html += '<p>' + issue.body + '</p>\n'; | |
if (issue.state === 'closed') { | |
html += '<p><em>Updated ' + datetime(issue.closed_at) + '<br/>'; | |
html += 'The system is back in normal operation.</p>'; | |
} | |
html += '</div>'; | |
html += '</div>'; | |
html += '</article>'; | |
$('#incidents').append(html); | |
}); | |
function datetime(string) { | |
var datetime = string.split('T'); | |
var date = datetime[0]; | |
var time = datetime[1].replace('Z', ''); | |
return date + ' ' + time; | |
}; | |
}; | |
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@import url("https://fonts.googleapis.com/css?family=Open+Sans:300italic,400italic,700italic,400,300,700"); | |
.timeline-centered .timeline-entry .timeline-entry-inner:after, | |
.timeline-centered .timeline-entry:after, | |
.timeline-centered:after { | |
clear: both | |
} | |
img { | |
vertical-align: middle | |
} | |
.img-responsive { | |
display: block; | |
height: auto; | |
max-width: 100% | |
} | |
.img-rounded { | |
border-radius: 3px | |
} | |
.img-thumbnail { | |
background-color: #fff; | |
border: 1px solid #ededf0; | |
border-radius: 3px; | |
display: inline-block; | |
height: auto; | |
line-height: 1.428571429; | |
max-width: 100%; | |
moz-transition: all .2s ease-in-out; | |
o-transition: all .2s ease-in-out; | |
padding: 2px; | |
transition: all .2s ease-in-out; | |
webkit-transition: all .2s ease-in-out | |
} | |
.img-circle { | |
border-radius: 50% | |
} | |
.timeline-centered { | |
position: relative; | |
margin-bottom: 30px | |
} | |
.timeline-centered:after, | |
.timeline-centered:before { | |
content: " "; | |
display: table | |
} | |
.timeline-centered:before { | |
content: ''; | |
position: absolute; | |
display: block; | |
width: 4px; | |
background: #f5f5f6; | |
top: 20px; | |
bottom: 20px; | |
margin-left: 30px | |
} | |
.timeline-centered .timeline-entry .timeline-entry-inner:after, | |
.timeline-centered .timeline-entry .timeline-entry-inner:before, | |
.timeline-centered .timeline-entry:after, | |
.timeline-centered .timeline-entry:before { | |
content: " "; | |
display: table | |
} | |
.timeline-centered .timeline-entry { | |
position: relative; | |
margin-top: 5px; | |
margin-left: 30px; | |
margin-bottom: 10px; | |
clear: both | |
} | |
.timeline-centered .timeline-entry.begin { | |
margin-bottom: 0 | |
} | |
.timeline-centered .timeline-entry.left-aligned { | |
float: left | |
} | |
.timeline-centered .timeline-entry.left-aligned .timeline-entry-inner { | |
margin-left: 0; | |
margin-right: -18px | |
} | |
.timeline-centered .timeline-entry.left-aligned .timeline-entry-inner .timeline-time { | |
left: auto; | |
right: -100px; | |
text-align: left | |
} | |
.timeline-centered .timeline-entry.left-aligned .timeline-entry-inner .timeline-icon { | |
float: right | |
} | |
.timeline-centered .timeline-entry.left-aligned .timeline-entry-inner .timeline-label { | |
margin-left: 0; | |
margin-right: 70px | |
} | |
.timeline-centered .timeline-entry.left-aligned .timeline-entry-inner .timeline-label:after { | |
left: auto; | |
right: 0; | |
margin-left: 0; | |
margin-right: -9px; | |
-moz-transform: rotate(180deg); | |
-o-transform: rotate(180deg); | |
-webkit-transform: rotate(180deg); | |
-ms-transform: rotate(180deg); | |
transform: rotate(180deg) | |
} | |
.timeline-centered .timeline-entry .timeline-entry-inner { | |
position: relative; | |
margin-left: -20px | |
} | |
.timeline-centered .timeline-entry .timeline-entry-inner .timeline-time { | |
position: absolute; | |
left: -100px; | |
text-align: right; | |
padding: 10px; | |
-webkit-box-sizing: border-box; | |
-moz-box-sizing: border-box; | |
box-sizing: border-box | |
} | |
.timeline-centered .timeline-entry .timeline-entry-inner .timeline-time>span { | |
display: block | |
} | |
.timeline-centered .timeline-entry .timeline-entry-inner .timeline-time>span:first-child { | |
font-size: 15px; | |
font-weight: 700 | |
} | |
.timeline-centered .timeline-entry .timeline-entry-inner .timeline-time>span:last-child { | |
font-size: 12px | |
} | |
.timeline-centered .timeline-entry .timeline-entry-inner .timeline-icon { | |
background: #fff; | |
color: #737881; | |
display: block; | |
width: 40px; | |
height: 40px; | |
-webkit-background-clip: padding-box; | |
-moz-background-clip: padding; | |
background-clip: padding-box; | |
-webkit-border-radius: 20px; | |
-moz-border-radius: 20px; | |
border-radius: 20px; | |
text-align: center; | |
-moz-box-shadow: 0 0 0 5px #f5f5f6; | |
-webkit-box-shadow: 0 0 0 5px #f5f5f6; | |
box-shadow: 0 0 0 5px #f5f5f6; | |
line-height: 40px; | |
font-size: 15px; | |
float: left | |
} | |
.timeline-centered .timeline-entry .timeline-entry-inner .timeline-icon.bg-primary { | |
background-color: #303641; | |
color: #fff | |
} | |
.timeline-centered .timeline-entry .timeline-entry-inner .timeline-icon.bg-secondary { | |
background-color: #ee4749; | |
color: #fff | |
} | |
.timeline-centered .timeline-entry .timeline-entry-inner .timeline-icon.bg-success { | |
background-color: #00a651; | |
color: #fff | |
} | |
.timeline-centered .timeline-entry .timeline-entry-inner .timeline-icon.bg-info { | |
background-color: #21a9e1; | |
color: #fff | |
} | |
.timeline-centered .timeline-entry .timeline-entry-inner .timeline-icon.bg-warning { | |
background-color: #fad839; | |
color: #fff | |
} | |
.timeline-centered .timeline-entry .timeline-entry-inner .timeline-icon.bg-danger { | |
background-color: #cc2424; | |
color: #fff | |
} | |
.timeline-centered .timeline-entry .timeline-entry-inner .timeline-label { | |
position: relative; | |
background: #f5f5f6; | |
padding: 1em; | |
margin-left: 60px; | |
-webkit-background-clip: padding-box; | |
-moz-background-clip: padding; | |
background-clip: padding-box; | |
-webkit-border-radius: 3px; | |
-moz-border-radius: 3px; | |
border-radius: 3px | |
} | |
.timeline-centered .timeline-entry .timeline-entry-inner .timeline-label:after { | |
content: ''; | |
display: block; | |
position: absolute; | |
width: 0; | |
height: 0; | |
border-style: solid; | |
border-width: 9px 9px 9px 0; | |
border-color: transparent #f5f5f6 transparent transparent; | |
left: 0; | |
top: 10px; | |
margin-left: -9px | |
} | |
.timeline-centered .timeline-entry .timeline-entry-inner .timeline-label h2, | |
.timeline-centered .timeline-entry .timeline-entry-inner .timeline-label p { | |
color: #737881; | |
font-family: "Noto Sans", sans-serif; | |
font-size: 12px; | |
margin: 0; | |
line-height: 1.428571429 | |
} | |
.timeline-centered .timeline-entry .timeline-entry-inner .timeline-label p+p { | |
margin-top: 15px | |
} | |
.timeline-centered .timeline-entry .timeline-entry-inner .timeline-label h2 { | |
font-size: 16px; | |
margin-bottom: 10px | |
} | |
.timeline-centered .timeline-entry .timeline-entry-inner .timeline-label h2 a { | |
color: #303641 | |
} | |
.timeline-centered .timeline-entry .timeline-entry-inner .timeline-label h2 span { | |
-webkit-opacity: .6; | |
-moz-opacity: .6; | |
opacity: .6; | |
-ms-filter: alpha(opacity=60); | |
filter: alpha(opacity=60) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment