pull/10/head v0.22
Hunter Long 2018-06-24 04:51:07 -07:00
parent 04e3a4239c
commit 0666ce247a
18 changed files with 134 additions and 35 deletions

View File

@ -18,7 +18,7 @@ services:
env: env:
global: global:
- VERSION=0.21 - VERSION=0.22
matrix: matrix:
allow_failures: allow_failures:

View File

@ -1,6 +1,6 @@
FROM alpine:latest FROM alpine:latest
ENV VERSION=v0.21 ENV VERSION=v0.22
RUN apk --no-cache add ca-certificates RUN apk --no-cache add ca-certificates
RUN wget https://github.com/hunterlong/statup/releases/download/$VERSION/statup-alpine && \ RUN wget https://github.com/hunterlong/statup/releases/download/$VERSION/statup-alpine && \

View File

@ -10,10 +10,12 @@ import (
func CheckServices() { func CheckServices() {
services, _ = SelectAllServices() services, _ = SelectAllServices()
time.Sleep(3 * time.Second)
for _, v := range services { for _, v := range services {
obj := v obj := v
go obj.StartCheckins() go obj.StartCheckins()
go obj.CheckQueue() go obj.CheckQueue()
time.Sleep(1 * time.Second)
} }
} }
@ -23,7 +25,7 @@ func (s *Service) CheckQueue() {
if s.Interval < 1 { if s.Interval < 1 {
s.Interval = 1 s.Interval = 1
} }
fmt.Printf(" Service: %v | Online: %v | Latency: %0.0fms\n", s.Name, s.Online, (s.Latency * 100)) fmt.Printf(" Service: %v | Online: %v | Latency: %0.0fms\n", s.Name, s.Online, (s.Latency * 1000))
time.Sleep(time.Duration(s.Interval) * time.Second) time.Sleep(time.Duration(s.Interval) * time.Second)
} }

View File

@ -47,10 +47,17 @@ func (u *Service) DeleteFailures() {
func (s *Service) LimitedFailures() []*Failure { func (s *Service) LimitedFailures() []*Failure {
var fails []*Failure var fails []*Failure
col := dbSession.Collection("failures").Find("service", s.Id) col := dbSession.Collection("failures").Find("service", s.Id)
col.OrderBy("-id").Limit(10).All(&fails) col.OrderBy("create_at").All(&fails)
return fails return fails
} }
func reverseFailures(input []*Failure) []*Failure {
if len(input) == 0 {
return input
}
return append(reverseFailures(input[1:]), input[0])
}
func (f *Failure) Ago() string { func (f *Failure) Ago() string {
got, _ := timeago.TimeAgoWithTime(time.Now(), f.CreatedAt) got, _ := timeago.TimeAgoWithTime(time.Now(), f.CreatedAt)
return got return got

15
hits.go
View File

@ -36,11 +36,18 @@ func (s *Service) Hits() ([]Hit, error) {
return hits, err return hits, err
} }
func (s *Service) LimitedHits() ([]Hit, error) { func (s *Service) LimitedHits() ([]*Hit, error) {
var hits []Hit var hits []*Hit
col := hitCol().Find("service", s.Id).Limit(1056).OrderBy("-id") col := hitCol().Find("service", s.Id).OrderBy("-id").Limit(1024)
err := col.All(&hits) err := col.All(&hits)
return hits, err return reverseHits(hits), err
}
func reverseHits(input []*Hit) []*Hit {
if len(input) == 0 {
return input
}
return append(reverseHits(input[1:]), input[0])
} }
func (s *Service) SelectHitsGroupBy(group string) ([]Hit, error) { func (s *Service) SelectHitsGroupBy(group string) ([]Hit, error) {

View File

@ -90,10 +90,30 @@ HTML,BODY {
text-decoration: none; text-decoration: none;
} }
.chart-container {
position: relative;
height: 20vh;
width: 60vh;
}
@media (max-width: 767px) { @media (max-width: 767px) {
.sm-container {
margin-top: 40px !important;
padding: 0 !important;
}
.list-group-item H5 {
font-size: 0.9rem;
}
.chart-container {
position: relative;
height:17vh;
width:80vw;
}
.container { .container {
margin-top: 0 !important;
padding: 0 !important; padding: 0 !important;
} }

View File

@ -12,7 +12,7 @@
<body> <body>
<div class="container col-md-7 col-sm-12 mt-2 bg-light"> <div class="container col-md-7 col-sm-12 mt-md-5 bg-light">
{{template "nav"}} {{template "nav"}}

View File

@ -3,6 +3,6 @@
{{ if .Core.Footer }} {{ if .Core.Footer }}
{{ safe .Core.Footer }} {{ safe .Core.Footer }}
{{ end }} {{ end }}
<a href="https://statup.io" target="_blank">Statup made with ❤️ {{ VERSION }}</a> | <a href="/dashboard">Dashboard</a> <a href="https://statup.io" target="_blank">Statup {{ VERSION }} made with ❤️</a> | <a href="/dashboard">Dashboard</a>
</div> </div>
{{ end }} {{ end }}

View File

@ -11,7 +11,7 @@
</head> </head>
<body> <body>
<div class="container col-md-7 col-sm-12 mt-2 bg-light"> <div class="container col-md-7 col-sm-12 mt-md-5 bg-light">
{{if Auth}} {{if Auth}}
{{template "nav"}} {{template "nav"}}

View File

@ -18,7 +18,7 @@
<body> <body>
<div class="container col-md-7 col-sm-12 mt-2"> <div class="container col-md-7 col-sm-12 mt-2 sm-container">
<h1 class="text-center mb-4 mt-sm-3">{{.Core.Name}}</h1> <h1 class="text-center mb-4 mt-sm-3">{{.Core.Name}}</h1>
@ -46,7 +46,7 @@
<div class="col-12"> <div class="col-12">
{{ range .Services }} {{ range .Services }}
<div class="mb-4"> <div class="mt-4">
<div class="card"> <div class="card">
<div class="card-body{{if .Online}}{{else}} offline_bg{{end}}"> <div class="card-body{{if .Online}}{{else}} offline_bg{{end}}">
@ -79,7 +79,9 @@
</div> </div>
</div> </div>
<canvas id="service_{{ .Id }}" width="400" height="120"></canvas> <div class="chart-container">
<canvas id="service_{{ .Id }}"></canvas>
</div>
{{ if .LimitedFailures }} {{ if .LimitedFailures }}
<div class="list-group mt-5"> <div class="list-group mt-5">
@ -130,6 +132,7 @@ var chartdata = new Chart(ctx, {
}] }]
}, },
options: { options: {
maintainAspectRatio: false,
legend: { legend: {
display: false display: false
}, },

View File

@ -12,7 +12,7 @@
<body> <body>
<div class="container col-md-7 col-sm-12 mt-2 bg-light"> <div class="container col-md-7 col-sm-12 mt-md-5 bg-light">
<div class="col-12"> <div class="col-12">

View File

@ -12,7 +12,7 @@
<body> <body>
<div class="container col-md-7 col-sm-12 mt-2 bg-light"> <div class="container col-md-7 col-sm-12 mt-md-5 bg-light">
{{template "nav"}} {{template "nav"}}

View File

@ -12,7 +12,7 @@
</head> </head>
<body> <body>
<div class="container col-md-7 col-sm-12 mt-2 bg-light"> <div class="container col-md-7 col-sm-12 mt-md-5 bg-light">
{{if Auth}} {{if Auth}}
{{template "nav"}} {{template "nav"}}
@ -155,9 +155,11 @@
</div> </div>
</div> </div>
<div class="form-group row"> <div class="form-group row">
<div class="col-sm-10"> <div class="col-sm-6">
<button type="submit" class="btn btn-success">Update Service</button> <button type="submit" class="btn btn-success btn-block">Update Service</button>
<a href="/service/{{ .Id }}/delete_failures" class="btn btn-danger">Delete All Failures</a> </div>
<div class="col-sm-6">
<a href="/service/{{ .Id }}/delete_failures" class="btn btn-danger btn-block">Delete All Failures</a>
</div> </div>
</div> </div>
</form> </form>

View File

@ -12,7 +12,7 @@
<body> <body>
<div class="container col-md-7 col-sm-12 mt-2 bg-light"> <div class="container col-md-7 col-sm-12 mt-md-5 bg-light">
{{template "nav"}} {{template "nav"}}
@ -103,8 +103,8 @@
</div> </div>
</div> </div>
<div class="form-group row"> <div class="form-group row">
<div class="col-sm-10"> <div class="col-sm-12">
<button type="submit" class="btn btn-success btn-block ">Create Service</button> <button type="submit" class="btn btn-success btn-block">Create Service</button>
</div> </div>
</div> </div>
</form> </form>

View File

@ -13,7 +13,7 @@
<body> <body>
<div class="container col-md-7 col-sm-12 mt-2 bg-light"> <div class="container col-md-7 col-sm-12 mt-md-5 bg-light">
{{ if .Error }} {{ if .Error }}
<div class="alert alert-danger" role="alert"> <div class="alert alert-danger" role="alert">

View File

@ -12,7 +12,7 @@
<body> <body>
<div class="container col-md-7 col-sm-12 mt-2 bg-light"> <div class="container col-md-7 col-sm-12 mt-md-5 bg-light">
{{template "nav"}} {{template "nav"}}

View File

@ -102,21 +102,74 @@ type GraphJson struct {
Y float64 `json:"y"` Y float64 `json:"y"`
} }
type DateScan struct {
CreatedAt time.Time `json:"x"`
Value int64 `json:"y"`
}
func (s *Service) GraphData() string { func (s *Service) GraphData() string {
var d []GraphJson var d []DateScan
hits, _ := s.LimitedHits()
for _, h := range hits { since := time.Now().Add(time.Hour * -12 + time.Minute * 0 + time.Second * 0)
val := h.CreatedAt
o := GraphJson{ 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))
X: val.String(),
Y: h.Latency * 1000, fmt.Println(sql)
}
d = append(d, o) dated, err := dbSession.Query(db.Raw(sql))
if err != nil {
panic(err)
} }
for dated.Next() {
var gd DateScan
var ff float64
dated.Scan(&gd.CreatedAt, &ff)
gd.Value = int64(ff)
d = append(d, gd)
}
if err != nil {
panic(err)
}
//
//hits, _ := s.LimitedHits()
//for _, h := range hits {
// val := h.CreatedAt
// o := GraphJson{
// X: val.String(),
// Y: h.Latency * 1000,
// }
// d = append(d, o)
//}
data, _ := json.Marshal(d) data, _ := json.Marshal(d)
return string(data) return string(data)
} }
//func (s *Service) GraphData() string {
// var d []GraphJson
// hits, _ := s.LimitedHits()
// for _, h := range hits {
// val := h.CreatedAt
// o := GraphJson{
// X: val.String(),
// Y: h.Latency * 1000,
// }
// d = append(d, o)
// }
// data, _ := json.Marshal(d)
// return string(data)
//}
func (s *Service) AvgUptime() string { func (s *Service) AvgUptime() string {
failed, _ := s.TotalFailures() failed, _ := s.TotalFailures()
total, _ := s.TotalHits() total, _ := s.TotalHits()

5
web.go
View File

@ -217,6 +217,11 @@ func IndexHandler(w http.ResponseWriter, r *http.Request) {
return return
} }
out := index{*core, services} out := index{*core, services}
first, _ := out.Services[0].LimitedHits()
fmt.Println(out.Services[0].Name, "start:", first[0].Id, "last:", first[len(first)-1].Id)
ExecuteResponse(w, r, "index.html", out) ExecuteResponse(w, r, "index.html", out)
} }