pull/10/head
Hunter Long 2018-06-26 23:45:00 -07:00
parent cf8ec576f6
commit 8e2d131839
6 changed files with 658 additions and 219 deletions

3
.gitignore vendored
View File

@ -5,4 +5,5 @@ statup.db
plugins/*.so plugins/*.so
data data
build build
vendor vendor
html/scss/.sass-cache

View File

@ -1,255 +1,196 @@
HTML,BODY { HTML, BODY {
background-color: #efefef; background-color: #fcfcfc; }
}
.container { .container {
padding-top: 20px; padding-top: 20px;
padding-bottom: 20px; padding-bottom: 20px;
max-width: 860px; max-width: 860px; }
}
.online_list .badge { .online_list .badge {
margin-top: 0.2rem; margin-top: 0.2rem; }
}
.navbar { .navbar {
margin-bottom: 30px; margin-bottom: 30px; }
}
.btn-sm { .btn-sm {
line-height: 1.3; line-height: 1.3;
font-size: 0.75rem; font-size: 0.75rem; }
}
.view_service_btn { .view_service_btn {
position: absolute; position: absolute;
bottom: -40px; bottom: -40px;
right: 40px; right: 40px; }
}
.service_lower_info { .service_lower_info {
position: absolute; position: absolute;
bottom: -40px; bottom: -40px;
left: 40px; left: 40px;
color: #d1ffca; color: #d1ffca;
font-size: 0.85rem; font-size: 0.85rem; }
}
.failing_bg { .failing_bg {
background-color: #ff4e4e !important; background-color: #ff4e4e !important;
font-weight: bold; font-weight: bold; }
}
.lg_number { .lg_number {
font-size: 26pt; font-size: 26pt;
font-weight: bold; font-weight: bold;
display: block; display: block;
color: #3e3e3e; color: #3e3e3e; }
}
.text_perfect { .text_perfect {
color: #33b418; color: #33b418;
text-shadow: 0px 1px 0 #0e6702; text-shadow: 0px 1px 0 #0e6702; }
}
.text_good { .text_good {
color: #33b418; color: #33b418;
text-shadow: 0px 1px 0 #0e6702; text-shadow: 0px 1px 0 #0e6702; }
}
.text_ok { .text_ok {
color: #33b418; color: #33b418;
text-shadow: 0px 1px 0 #0e6702; text-shadow: 0px 1px 0 #0e6702; }
}
.text_bad { .text_bad {
color: #33b418; color: #33b418;
text-shadow: 0px 1px 0 #0e6702; text-shadow: 0px 1px 0 #0e6702; }
}
.stats_area { .stats_area {
text-align: center; text-align: center;
color: #a5a5a5; color: #a5a5a5; }
}
.offline_bg { .offline_bg {
background-color: white !important; background-color: white !important;
padding-bottom: 70px !important; padding-bottom: 70px !important; }
}
.online_list {
}
.lower_canvas { .lower_canvas {
position: absolute; height: 55px;
bottom: -60px; width: 100%;
height: 60px; background-color: #48d338;
left: 15px; padding: 17px 10px; }
width: 800px;
background-color: #48d338;
padding: 17px 10px;
}
.lower_canvas SPAN { .lower_canvas SPAN {
font-size: 0.85rem; font-size: 1rem; }
}
.offline_lower_canvas { .offline_lower_canvas {
position: absolute; position: absolute;
bottom: -120px; bottom: -120px;
height: 60px; height: 60px;
left: -25px; left: -25px;
width: 805px; width: 805px;
padding: 17px 10px; padding: 17px 10px; }
}
.offline_lower_canvas SPAN { .offline_lower_canvas SPAN {
font-weight: bold; font-weight: bold;
font-size: 0.85rem; font-size: 0.85rem; }
}
.offline_lower_canvas A { .offline_lower_canvas A {
background-color: #c51b1a; background-color: #c51b1a;
border: 1px solid #bb1727; border: 1px solid #bb1727; }
}
.footer { .footer {
text-decoration: none; text-decoration: none;
margin-top: 20px; margin-top: 20px; }
}
.footer A { .footer A {
color: #aaaaaa; color: #aaaaaa;
text-decoration: none; text-decoration: none; }
}
.footer A:HOVER { .footer A:HOVER {
color: #6d6d6d; color: #6d6d6d; }
}
.online_badge { .online_badge {
color: #fff; color: #fff;
background-color: #35b317; background-color: #35b317; }
}
.offline_badge { .offline_badge {
color: #fff; color: #fff;
background-color: #c51919; background-color: #c51919; }
}
.progress { .progress {
margin-top: -20px; margin-top: -20px;
margin-left: -20px; margin-left: -20px;
margin-bottom: 15px; margin-bottom: 15px;
width: calc(100% + 40px); width: calc(100% + 40px);
height: 3px; height: 3px;
border-radius: 0; border-radius: 0; }
}
.card-body { .card-body {
overflow: hidden; overflow: hidden; }
}
.card-body H4 A { .card-body H4 A {
color: #239e07; color: #239e07;
text-decoration: none; text-decoration: none; }
}
.chart-container { .chart-container {
position: relative; position: relative;
height: 20vh; height: 170px;
width: 93vh; width: 100%; }
margin-left: -52px;
margin-bottom: -30px;
}
.btn-primary { .btn-primary {
background-color: white; background-color: white;
border: 1px solid #b9b9b9; border: 1px solid #b9b9b9;
color: #353535; color: #353535;
height: 35px; height: 35px;
padding: 5px 15px; padding: 5px 15px; }
}
.card-body {
padding-bottom: 85px;
}
@media (max-width: 767px) { @media (max-width: 767px) {
.sm-container {
margin-top: 40px !important;
padding: 0 !important; }
.sm-container { .list-group-item H5 {
margin-top: 40px !important; font-size: 0.9rem; }
padding: 0 !important;
}
.list-group-item H5 { .container {
font-size: 0.9rem; padding: 0 !important; }
}
.chart-container { .navbar {
position: relative; margin-left: 0px;
height: 20vh; margin-top: 0px;
width: 100vw; width: 100%;
} margin-bottom: 0; }
.container { .card-body {
padding: 0 !important; font-size: 6pt;
} padding: 5px 5px; }
.navbar { .lg_number {
margin-left: 0px; font-size: 1.5rem; }
margin-top: 0px;
width: 100%;
margin-bottom: 0;
}
.card-body { .stats_area {
font-size: 6pt; margin-top: 35px !important;
padding: 5px 10px; margin-bottom: 35px !important; }
height: 350px;
}
.lg_number { .stats_area .col-4 {
font-size: 1.4rem; padding-left: 0;
} padding-right: 0; }
.stats_area { .lower_canvas SPAN {
margin-top: 25px !important; font-size: 0.9rem;
margin-bottom: 20px !important; float: left; }
}
.stats_area .col-4 { .btn-sm {
padding-left: 0; line-height: 0.9rem;
padding-right: 0; font-size: 0.65rem; }
}
.lower_canvas { .full-col-12 {
bottom: -3.65rem; padding-left: 0px;
width: 98vw; padding-right: 0px; }
}
.lower_canvas SPAN { .card {
font-size: 0.75rem; border: 0;
float: left; border-radius: 0; }
}
.btn-sm { .list-group-item {
line-height: 0.75rem; border-top: 1px solid #e4e4e4;
font-size: 0.65rem; border: 0px; }
}
.offline_bg { .list-group-item:first-child {
padding-bottom: 0 !important; border-top-left-radius: 0;
height: 240px !important; border-top-right-radius: 0; }
}
.offline_lower_canvas { .list-group-item:last-child {
width: 100vw; border-bottom-right-radius: 0;
} border-bottom-left-radius: 0; } }
.col-12 {
padding-left: 5px; /*# sourceMappingURL=base.css.map */
padding-right: 5px;
}
}

255
html/scss/base.scss Normal file
View File

@ -0,0 +1,255 @@
$background-color: #262626;
$max-width: 860px;
$card-background: #121212;
$card-stats-color: #dfdfdf;
HTML,BODY {
background-color: $background-color;
}
.container {
padding-top: 20px;
padding-bottom: 20px;
max-width: $max-width;
}
.online_list .badge {
margin-top: 0.2rem;
}
.navbar {
margin-bottom: 30px;
}
.btn-sm {
line-height: 1.3;
font-size: 0.75rem;
}
.view_service_btn {
position: absolute;
bottom: -40px;
right: 40px;
}
.service_lower_info {
position: absolute;
bottom: -40px;
left: 40px;
color: #d1ffca;
font-size: 0.85rem;
}
.failing_bg {
background-color: #ff4e4e !important;
font-weight: bold;
}
.lg_number {
font-size: 26pt;
font-weight: bold;
display: block;
color: $card-stats-color;
}
.text_perfect {
color: #33b418;
text-shadow: 0px 1px 0 #0e6702;
}
.text_good {
color: #33b418;
text-shadow: 0px 1px 0 #0e6702;
}
.text_ok {
color: #33b418;
text-shadow: 0px 1px 0 #0e6702;
}
.text_bad {
color: #33b418;
text-shadow: 0px 1px 0 #0e6702;
}
.stats_area {
text-align: center;
color: #a5a5a5;
}
.offline_bg {
background-color: white !important;
padding-bottom: 70px !important;
}
.online_list {
}
.lower_canvas {
height: 55px;
width: 100%;
background-color: #48d338;
padding: 17px 10px;
}
.lower_canvas SPAN {
font-size: 1rem;
}
.offline_lower_canvas {
position: absolute;
bottom: -120px;
height: 60px;
left: -25px;
width: 805px;
padding: 17px 10px;
}
.offline_lower_canvas SPAN {
font-weight: bold;
font-size: 0.85rem;
}
.offline_lower_canvas A {
background-color: #c51b1a;
border: 1px solid #bb1727;
}
.footer {
text-decoration: none;
margin-top: 20px;
}
.footer A {
color: #aaaaaa;
text-decoration: none;
}
.footer A:HOVER {
color: #6d6d6d;
}
.online_badge {
color: #fff;
background-color: #35b317;
}
.offline_badge {
color: #fff;
background-color: #c51919;
}
.progress {
margin-top: -20px;
margin-left: -20px;
margin-bottom: 15px;
width: calc(100% + 40px);
height: 3px;
border-radius: 0;
}
.card {
background-color: $card-background;
}
.card-body {
overflow: hidden;
}
.card-body H4 A {
color: #239e07;
text-decoration: none;
}
.chart-container {
position: relative;
height: 170px;
width: 100%;
}
.btn-primary {
background-color: white;
border: 1px solid #b9b9b9;
color: #353535;
height: 35px;
padding: 5px 15px;
}
@media (max-width: 767px) {
.sm-container {
margin-top: 40px !important;
padding: 0 !important;
}
.list-group-item H5 {
font-size: 0.9rem;
}
.container {
padding: 0 !important;
}
.navbar {
margin-left: 0px;
margin-top: 0px;
width: 100%;
margin-bottom: 0;
}
.card-body {
font-size: 6pt;
padding: 5px 5px;
}
.lg_number {
font-size: 1.5rem;
}
.stats_area {
margin-top: 35px !important;
margin-bottom: 35px !important;
}
.stats_area .col-4 {
padding-left: 0;
padding-right: 0;
}
.lower_canvas SPAN {
font-size: 0.9rem;
float: left;
}
.btn-sm {
line-height: 0.9rem;
font-size: 0.65rem;
}
.full-col-12 {
padding-left: 0px;
padding-right: 0px;
}
.card {
border: 0;
border-radius: 0;
}
.list-group-item {
border-top: 1px solid #e4e4e4;
border: 0px;
}
.list-group-item:first-child {
border-top-left-radius: 0;
border-top-right-radius: 0;
}
.list-group-item:last-child {
border-bottom-right-radius: 0;
border-bottom-left-radius: 0;
}
}

251
html/scss/light-base.scss Normal file
View File

@ -0,0 +1,251 @@
$background-color: #fcfcfc;
$max-width: 860px;
$primary-color: #333;
$card-background: #fff;
HTML,BODY {
background-color: $background-color;
}
.container {
padding-top: 20px;
padding-bottom: 20px;
max-width: $max-width;
}
.online_list .badge {
margin-top: 0.2rem;
}
.navbar {
margin-bottom: 30px;
}
.btn-sm {
line-height: 1.3;
font-size: 0.75rem;
}
.view_service_btn {
position: absolute;
bottom: -40px;
right: 40px;
}
.service_lower_info {
position: absolute;
bottom: -40px;
left: 40px;
color: #d1ffca;
font-size: 0.85rem;
}
.failing_bg {
background-color: #ff4e4e !important;
font-weight: bold;
}
.lg_number {
font-size: 26pt;
font-weight: bold;
display: block;
color: #3e3e3e;
}
.text_perfect {
color: #33b418;
text-shadow: 0px 1px 0 #0e6702;
}
.text_good {
color: #33b418;
text-shadow: 0px 1px 0 #0e6702;
}
.text_ok {
color: #33b418;
text-shadow: 0px 1px 0 #0e6702;
}
.text_bad {
color: #33b418;
text-shadow: 0px 1px 0 #0e6702;
}
.stats_area {
text-align: center;
color: #a5a5a5;
}
.offline_bg {
background-color: white !important;
padding-bottom: 70px !important;
}
.online_list {
}
.lower_canvas {
height: 55px;
width: 100%;
background-color: #48d338;
padding: 17px 10px;
}
.lower_canvas SPAN {
font-size: 1rem;
}
.offline_lower_canvas {
position: absolute;
bottom: -120px;
height: 60px;
left: -25px;
width: 805px;
padding: 17px 10px;
}
.offline_lower_canvas SPAN {
font-weight: bold;
font-size: 0.85rem;
}
.offline_lower_canvas A {
background-color: #c51b1a;
border: 1px solid #bb1727;
}
.footer {
text-decoration: none;
margin-top: 20px;
}
.footer A {
color: #aaaaaa;
text-decoration: none;
}
.footer A:HOVER {
color: #6d6d6d;
}
.online_badge {
color: #fff;
background-color: #35b317;
}
.offline_badge {
color: #fff;
background-color: #c51919;
}
.progress {
margin-top: -20px;
margin-left: -20px;
margin-bottom: 15px;
width: calc(100% + 40px);
height: 3px;
border-radius: 0;
}
.card-body {
overflow: hidden;
}
.card-body H4 A {
color: #239e07;
text-decoration: none;
}
.chart-container {
position: relative;
height: 170px;
width: 100%;
}
.btn-primary {
background-color: white;
border: 1px solid #b9b9b9;
color: #353535;
height: 35px;
padding: 5px 15px;
}
@media (max-width: 767px) {
.sm-container {
margin-top: 40px !important;
padding: 0 !important;
}
.list-group-item H5 {
font-size: 0.9rem;
}
.container {
padding: 0 !important;
}
.navbar {
margin-left: 0px;
margin-top: 0px;
width: 100%;
margin-bottom: 0;
}
.card-body {
font-size: 6pt;
padding: 5px 5px;
}
.lg_number {
font-size: 1.5rem;
}
.stats_area {
margin-top: 35px !important;
margin-bottom: 35px !important;
}
.stats_area .col-4 {
padding-left: 0;
padding-right: 0;
}
.lower_canvas SPAN {
font-size: 0.9rem;
float: left;
}
.btn-sm {
line-height: 0.9rem;
font-size: 0.65rem;
}
.full-col-12 {
padding-left: 0px;
padding-right: 0px;
}
.card {
border: 0;
border-radius: 0;
}
.list-group-item {
border-top: 1px solid #e4e4e4;
border: 0px;
}
.list-group-item:first-child {
border-top-left-radius: 0;
border-top-right-radius: 0;
}
.list-group-item:last-child {
border-bottom-right-radius: 0;
border-bottom-left-radius: 0;
}
}

View File

@ -26,10 +26,10 @@
<h5 class="col-12 text-center mb-5 text-muted">{{ .Core.Description }}</h5> <h5 class="col-12 text-center mb-5 text-muted">{{ .Core.Description }}</h5>
{{ end }} {{ end }}
<div class="col-12 mb-5"> <div class="col-12 full-col-12 mb-5">
<div class="list-group online_list"> <div class="list-group online_list">
{{ range .Services }} {{ range .Services }}
<a href="#" class="service_li list-group-item list-group-item-action {{if not .Online}}failing_bg text-white{{ end }}" data-id="{{.Id}}"> <a href="#" class="service_li list-group-item list-group-item-action {{if not .Online}}bg-danger text-white{{ end }}" data-id="{{.Id}}">
{{ .Name }} {{ .Name }}
{{if .Online}} {{if .Online}}
<span class="badge online_badge float-right">ONLINE</span> <span class="badge online_badge float-right">ONLINE</span>
@ -42,12 +42,11 @@
</div> </div>
<div class="col-12"> <div class="col-12 full-col-12">
{{ range .Services }} {{ range .Services }}
<div class="mt-4" id="service_id_{{.Id}}"> <div class="mt-4" id="service_id_{{.Id}}">
<div class="card"> <div class="card">
<div class="card-body{{if not .Online}} offline_bg{{end}}"> <div class="card-body">
<div class="col-12"> <div class="col-12">
@ -58,54 +57,42 @@
<span class="badge offline_badge float-right">OFFLINE</span> <span class="badge offline_badge float-right">OFFLINE</span>
{{end}}</h4> {{end}}</h4>
<div class="row stats_area mt-5 mb-5"> <div class="row stats_area mt-5 mb-5">
<div class="col-4"> <div class="col-4">
<span class="lg_number">{{.Online24}}%</span> <span class="lg_number">{{.Online24}}%</span>
Online last 24 Hours Online last 24 Hours
</div> </div>
<div class="col-4"> <div class="col-4">
<span class="lg_number">{{.AvgTime}}ms</span> <span class="lg_number">{{.AvgTime}}ms</span>
Average Response Average Response
</div> </div>
<div class="col-4"> <div class="col-4">
<span class="lg_number">{{.AvgUptime}}%</span> <span class="lg_number">{{.AvgUptime}}%</span>
Total Uptime Total Uptime
</div> </div>
</div> </div>
{{ if .AvgTime }}
<div class="chart-container">
<canvas id="service_{{ .Id }}"></canvas>
<div class="lower_canvas text-white">
<div class="col-12">
<span>No failures within the last 25 days</span>
<a href="/service/{{ .Id }}" class="btn btn-success btn-sm float-right">View Service</a>
</div>
</div>
</div>
{{ else }}
<div class="offline_lower_canvas bg-danger">
<div class="col-12">
<span class="text-white">383 failures in the last 24 hours</span>
<a href="/service/{{ .Id }}" class="btn btn-danger btn-sm float-right">View Failures</a>
</div>
</div>
{{ end }}
{{ if .LimitedFailures }} {{ if .LimitedFailures }}
{{ end }} {{ end }}
</div> </div>
</div> </div>
{{ if .AvgTime }}
<div class="chart-container">
<canvas id="service_{{ .Id }}"></canvas>
</div>
{{ end }}
<div class="lower_canvas full-col-12 text-white{{if not .Online}} bg-danger{{end}}">
<div class="col-12">
<span>No failures within the last 25 days</span>
<a href="/service/{{ .Id }}" class="btn {{if .Online}}btn-success{{else}}btn-danger{{end}} btn-sm float-right">View Service</a>
</div>
</div>
</div> </div>
</div> </div>
{{ end }} {{ end }}
</div> </div>
</div> </div>
{{template "footer"}} {{template "footer"}}
@ -146,8 +133,8 @@ var chartdata = new Chart(ctx, {
}, },
responsiveAnimationDuration: 0, responsiveAnimationDuration: 0,
animation: { animation: {
"duration": 0, duration: 3500,
"onComplete": function() { onComplete: function() {
var chartInstance = this.chart, var chartInstance = this.chart,
ctx = chartInstance.ctx; ctx = chartInstance.ctx;
@ -208,8 +195,11 @@ var chartdata = new Chart(ctx, {
ctx.fillStyle = '#ffa7a2'; ctx.fillStyle = '#ffa7a2';
ctx.fillText(highestNum+"ms", hxH - 40, hyH + 15); ctx.fillText(highestNum+"ms", hxH - 40, hyH + 15);
ctx.fillStyle = '#54944b'; ctx.fillStyle = '#45d642';
ctx.fillText(lowestnum+"ms", hxL, hyL - 5); ctx.fillText(lowestnum+"ms", hxL, hyL + 10);
console.log("done service_id_{{.Id}}")
}); });
} }
}, },
@ -225,7 +215,7 @@ var chartdata = new Chart(ctx, {
ticks: { ticks: {
fontSize: 20, fontSize: 20,
display: false, display: false,
beginAtZero: true beginAtZero: false
}, },
gridLines: { gridLines: {
display:false display:false

View File

@ -107,8 +107,9 @@ type DateScan struct {
func (s *Service) GraphData() string { func (s *Service) GraphData() string {
var d []DateScan var d []DateScan
since := time.Now().Add(time.Hour*-24 + time.Minute*0 + time.Second*0) increment := "minute"
sql := fmt.Sprintf("SELECT date_trunc('minute', created_at), AVG(latency)*1000 AS value FROM hits WHERE service=%v AND created_at > '%v' GROUP BY 1 ORDER BY date_trunc ASC;", s.Id, since.Format(time.RFC3339)) since := time.Now().Add(time.Hour*-12 + time.Minute*0 + time.Second*0)
sql := fmt.Sprintf("SELECT date_trunc('%v', created_at), AVG(latency)*1000 AS value FROM hits WHERE service=%v AND created_at > '%v' GROUP BY 1 ORDER BY date_trunc ASC;", increment, s.Id, since.Format(time.RFC3339))
dated, err := dbSession.Query(db.Raw(sql)) dated, err := dbSession.Query(db.Raw(sql))
if err != nil { if err != nil {
fmt.Println(err) fmt.Println(err)