service close channels - ServiceInterface - service check from time.Duration

pull/78/head
Hunter Long 2018-09-08 15:16:26 -07:00
parent 49a264c525
commit 347f2798dd
22 changed files with 242 additions and 240 deletions

View File

@ -149,8 +149,9 @@ func RunOnce() {
if err != nil {
utils.Log(4, err)
}
for _, s := range core.CoreApp.Services() {
out := s.Check(true)
for _, s := range core.CoreApp.Services {
out := s.(*types.Service)
out.Check(true)
fmt.Printf(" Service %v | URL: %v | Latency: %0.0fms | Online: %v\n", out.Name, out.Domain, (out.Latency * 1000), out.Online)
}
}

View File

@ -471,11 +471,11 @@ func RunDeleteService(t *testing.T) {
}
func RunCreateService_Hits(t *testing.T) {
services := core.CoreApp.Services()
services := core.CoreApp.Services
assert.NotNil(t, services)
assert.Equal(t, 19, len(services))
for _, s := range services {
service := s.Check(true)
for _, service := range services {
service.Check(true)
assert.NotNil(t, service)
}
}

View File

@ -30,9 +30,8 @@ import (
)
func CheckServices() {
CoreApp.SelectAllServices()
utils.Log(1, fmt.Sprintf("Starting monitoring process for %v DbServices", len(CoreApp.Services())))
for _, ser := range CoreApp.Services() {
utils.Log(1, fmt.Sprintf("Starting monitoring process for %v Services", len(CoreApp.Services)))
for _, ser := range CoreApp.Services {
//go obj.StartCheckins()
go ser.CheckQueue(true)
}
@ -40,23 +39,24 @@ func CheckServices() {
func (s *Service) CheckQueue(record bool) {
s.Checkpoint = time.Now()
s.SleepDuration = time.Duration((time.Duration(s.Id) * 100) * time.Millisecond)
CheckLoop:
for {
select {
case <-s.Running:
utils.Log(1, fmt.Sprintf("Stopping service: %v", s.Name))
break CheckLoop
default:
utils.Log(1, fmt.Sprintf("Checking service: %v", s.Name))
case <-time.After(s.SleepDuration):
s.Check(record)
// Set next time checkpoint and maybe sleep.
s.Checkpoint = s.Checkpoint.Add(s.duration())
if sleepDuration := s.Checkpoint.Sub(time.Now()); sleepDuration > 0 {
time.Sleep(sleepDuration)
sleep := s.Checkpoint.Sub(time.Now())
if !s.Online {
s.SleepDuration = s.duration()
} else {
s.SleepDuration = sleep
}
continue
}
continue
}
}
@ -119,14 +119,13 @@ func (s *Service) checkTcp(record bool) *Service {
return s
}
func (s *Service) Check(record bool) *Service {
func (s *Service) Check(record bool) {
switch s.Type {
case "http":
s.checkHttp(record)
case "tcp":
s.checkTcp(record)
}
return s
}
func (s *Service) checkHttp(record bool) *Service {

View File

@ -36,8 +36,9 @@ func ReturnCheckin(s *types.Checkin) *Checkin {
}
func FindCheckin(api string) *types.Checkin {
for _, ser := range CoreApp.Services() {
for _, c := range ser.Checkins {
for _, ser := range CoreApp.Services {
service := ser.(*types.Service)
for _, c := range service.Checkins {
if c.Api == api {
return c
}

View File

@ -22,7 +22,6 @@ import (
"github.com/hunterlong/statup/utils"
"github.com/pkg/errors"
"os"
"sort"
"time"
)
@ -113,8 +112,8 @@ func (c Core) MobileSASS() string {
// AllOnline will be true if all services are online
func (c Core) AllOnline() bool {
for _, s := range CoreApp.Services() {
if !s.Online {
for _, s := range CoreApp.Services {
if !s.(*types.Service).Online {
return false
}
}
@ -136,7 +135,6 @@ func SelectCore() (*Core, error) {
}
CoreApp.DbConnection = Configs.DbConn
CoreApp.Version = VERSION
CoreApp.SelectAllServices()
if os.Getenv("USE_CDN") == "true" {
CoreApp.UseCdn = true
}
@ -152,13 +150,13 @@ func (c ServiceOrder) Swap(i, j int) { c[i], c[j] = c[j], c[i] }
func (c ServiceOrder) Less(i, j int) bool { return c[i].Order < c[j].Order }
// Services returns each Service that is attached to this instance
func (c *Core) Services() []*Service {
var services []*Service
servs := CoreApp.GetServices()
sort.Sort(ServiceOrder(servs))
CoreApp.SetServices(servs)
for _, ser := range servs {
services = append(services, ReturnService(ser))
}
return services
}
//func (c *Core) Services() []*Service {
// var services []*Service
// servs := CoreApp.GetServices()
// sort.Sort(ServiceOrder(servs))
// CoreApp.SetServices(servs)
// for _, ser := range servs {
// services = append(services, ReturnService(ser))
// }
// return services
//}

View File

@ -19,6 +19,7 @@ import (
"bytes"
"fmt"
"github.com/hunterlong/statup/source"
"github.com/hunterlong/statup/types"
"github.com/hunterlong/statup/utils"
"html/template"
"io/ioutil"
@ -37,8 +38,9 @@ func ExportIndexHTML() string {
injectDatabase()
CoreApp.SelectAllServices()
CoreApp.UseCdn = true
for _, service := range CoreApp.Services() {
service = service.Check(true)
for _, srv := range CoreApp.Services {
service := srv.(*types.Service)
service.Check(true)
fmt.Println(service.Name, service.Online, service.Latency)
}
nav, _ := source.TmplBox.String("nav.html")
@ -99,7 +101,7 @@ func ExportChartsJs() string {
})
t.Parse(render)
var tpl bytes.Buffer
if err := t.Execute(&tpl, CoreApp.Services()); err != nil {
if err := t.Execute(&tpl, CoreApp.Services); err != nil {
utils.Log(3, err)
}
result := tpl.String()

View File

@ -40,14 +40,17 @@ func (s *Service) CreateFailure(f *types.Failure) (int64, error) {
return f.Id, row.Error
}
func (s *Service) AllFailures() []*types.Failure {
var fails []*types.Failure
func (s *Service) AllFailures() []*Failure {
var fails []*Failure
col := failuresDB().Where("service = ?", s.Id).Order("id desc")
err := col.Find(&fails)
if err.Error != nil {
utils.Log(3, fmt.Sprintf("Issue getting failures for service %v, %v", s.Name, err))
return nil
}
for _, f := range fails {
s.Failures = append(s.Failures, f)
}
return fails
}
@ -76,6 +79,16 @@ func (f *Failure) Delete() error {
return db.Error
}
func (c *Core) Count24HFailures() uint64 {
var count uint64
for _, s := range CoreApp.Services {
service := s.(*Service)
fails, _ := service.TotalFailures24()
count += fails
}
return count
}
func CountFailures() uint64 {
var count uint64
err := failuresDB().Count(&count)

View File

@ -34,29 +34,29 @@ func (s *Service) CreateHit(h *types.Hit) (int64, error) {
return h.Id, db.Error
}
func (s *Service) Hits() ([]*Hit, error) {
var hits []*Hit
func (s *Service) Hits() ([]*types.Hit, error) {
var hits []*types.Hit
col := hitsDB().Where("service = ?", s.Id).Order("id desc")
err := col.Find(&hits)
return hits, err.Error
}
func (s *Service) LimitedHits() ([]*Hit, error) {
var hits []*Hit
func (s *Service) LimitedHits() ([]*types.Hit, error) {
var hits []*types.Hit
col := hitsDB().Where("service = ?", s.Id).Order("id desc").Limit(1024)
err := col.Find(&hits)
return reverseHits(hits), err.Error
}
func reverseHits(input []*Hit) []*Hit {
func reverseHits(input []*types.Hit) []*types.Hit {
if len(input) == 0 {
return input
}
return append(reverseHits(input[1:]), input[0])
}
func (s *Service) SelectHitsGroupBy(group string) ([]*Hit, error) {
var hits []*Hit
func (s *Service) SelectHitsGroupBy(group string) ([]*types.Hit, error) {
var hits []*types.Hit
col := hitsDB().Where("service = ?", s.Id)
err := col.Find(&hits)
return hits, err.Error

View File

@ -33,30 +33,27 @@ func ReturnService(s *types.Service) *Service {
}
func SelectService(id int64) *Service {
for _, s := range CoreApp.Services() {
if s.Service.Id == id {
return s
for _, s := range CoreApp.Services {
if s.(*Service).Id == id {
return s.(*Service)
}
}
return nil
}
func (c *Core) SelectAllServices() ([]*types.Service, error) {
var services []*types.Service
var servs []*types.Service
func (c *Core) SelectAllServices() ([]*Service, error) {
var services []*Service
db := servicesDB().Find(&services).Order("order_id desc")
if db.Error != nil {
utils.Log(3, fmt.Sprintf("service error: %v", db.Error))
return nil, db.Error
}
for _, ser := range services {
single := ReturnService(ser)
single.Start()
single.AllCheckins()
single.AllFailures()
servs = append(servs, single.Service)
for _, service := range services {
service.Start()
service.AllCheckins()
service.AllFailures()
CoreApp.Services = append(CoreApp.Services, service)
}
CoreApp.SetServices(servs)
return services, db.Error
}
@ -190,7 +187,7 @@ func (s *Service) AvgUptime(ago time.Time) string {
}
total, _ := s.TotalHitsSince(ago)
if total == 0 {
return "0"
return "0.00"
}
percent := float64(failed) / float64(total) * 100
percent = 100 - percent
@ -220,8 +217,8 @@ func (s *Service) TotalUptime() string {
}
func (s *Service) index() int {
for k, service := range CoreApp.Services() {
if s.Id == service.Id {
for k, service := range CoreApp.Services {
if s.Id == service.(*Service).Id {
return k
}
}
@ -229,19 +226,20 @@ func (s *Service) index() int {
}
func updateService(service *Service) {
service.Start()
index := service.index()
CoreApp.UpdateService(index, service.Service)
CoreApp.Services[index] = service
}
func (u *Service) Delete() error {
i := u.index()
err := servicesDB().Delete(u)
if err.Error != nil {
utils.Log(3, fmt.Sprintf("Failed to delete service %v. %v", u.Name, err.Error))
return err.Error
}
u.Close()
CoreApp.RemoveService(u.index())
slice := CoreApp.Services
CoreApp.Services = append(slice[:i], slice[i+1:]...)
OnDeletedService(u)
return err.Error
}
@ -251,7 +249,6 @@ func (u *Service) UpdateSingle(attr ...interface{}) error {
}
func (u *Service) Update(restart bool) error {
u.CreatedAt = time.Now()
err := servicesDB().Update(u)
if err.Error != nil {
utils.Log(3, fmt.Sprintf("Failed to update service %v. %v", u.Name, err))
@ -259,11 +256,11 @@ func (u *Service) Update(restart bool) error {
}
if restart {
u.Close()
}
updateService(u)
if restart {
u.Start()
u.SleepDuration = time.Duration(u.Interval) * time.Second
go u.CheckQueue(true)
}
updateService(u)
OnUpdateService(u)
return err.Error
}
@ -276,14 +273,19 @@ func (u *Service) Create() (int64, error) {
return 0, db.Error
}
u.Start()
CoreApp.AddService(u.Service)
go u.CheckQueue(true)
CoreApp.Services = append(CoreApp.Services, u)
return u.Id, nil
}
func CountOnline() int {
func (c *Core) ServicesCount() int {
return len(c.Services)
}
func (c *Core) CountOnline() int {
amount := 0
for _, s := range CoreApp.Services() {
if s.Online {
for _, s := range CoreApp.Services {
if s.(*Service).Online {
amount++
}
}

View File

@ -35,17 +35,18 @@ func TestSelectHTTPService(t *testing.T) {
}
func TestSelectAllServices(t *testing.T) {
services := CoreApp.Services()
services := CoreApp.Services
for _, s := range services {
service := s.Check(true)
service := s.(*Service)
service.Check(true)
assert.True(t, service.IsRunning())
t.Logf("ID: %v %v\n", s.Id, s.Name)
t.Logf("ID: %v %v\n", service.Id, service.Name)
}
assert.Equal(t, 18, len(services))
}
func TestSelectTCPService(t *testing.T) {
services := CoreApp.Services()
services := CoreApp.Services
assert.Equal(t, 18, len(services))
service := SelectService(5)
assert.NotNil(t, service)
@ -72,8 +73,7 @@ func TestUpdateService(t *testing.T) {
func TestUpdateAllServices(t *testing.T) {
services, err := CoreApp.SelectAllServices()
assert.Nil(t, err)
for k, s := range services {
srv := ReturnService(s)
for k, srv := range services {
srv.Name = "Changed " + srv.Name
srv.Interval = k + 3
err := srv.Update(true)
@ -83,9 +83,9 @@ func TestUpdateAllServices(t *testing.T) {
func TestServiceHTTPCheck(t *testing.T) {
service := SelectService(1)
checked := service.Check(true)
assert.Equal(t, "Changed Updated Google", checked.Name)
assert.True(t, checked.Online)
service.Check(true)
assert.Equal(t, "Changed Updated Google", service.Name)
assert.True(t, service.Online)
}
func TestCheckHTTPService(t *testing.T) {
@ -98,9 +98,9 @@ func TestCheckHTTPService(t *testing.T) {
func TestServiceTCPCheck(t *testing.T) {
service := SelectService(5)
checked := service.Check(true)
assert.Equal(t, "Changed Google DNS", checked.Name)
assert.True(t, checked.Online)
service.Check(true)
assert.Equal(t, "Changed Google DNS", service.Name)
assert.True(t, service.Online)
}
func TestCheckTCPService(t *testing.T) {
@ -167,7 +167,7 @@ func TestServiceSum(t *testing.T) {
}
func TestCountOnline(t *testing.T) {
amount := CountOnline()
amount := CoreApp.CountOnline()
assert.Equal(t, 2, amount)
}
@ -216,9 +216,9 @@ func TestCreateFailingHTTPService(t *testing.T) {
func TestServiceFailedCheck(t *testing.T) {
service := SelectService(20)
assert.Equal(t, "Bad URL", service.Name)
checked := service.Check(true)
assert.Equal(t, "Bad URL", checked.Name)
assert.False(t, checked.Online)
service.Check(true)
assert.Equal(t, "Bad URL", service.Name)
assert.False(t, service.Online)
}
func TestCreateFailingTCPService(t *testing.T) {
@ -241,9 +241,9 @@ func TestCreateFailingTCPService(t *testing.T) {
func TestServiceFailedTCPCheck(t *testing.T) {
service := SelectService(21)
checked := service.Check(true)
assert.Equal(t, "Bad TCP", checked.Name)
assert.False(t, checked.Online)
service.Check(true)
assert.Equal(t, "Bad TCP", service.Name)
assert.False(t, service.Online)
}
func TestCreateServiceFailure(t *testing.T) {
@ -267,7 +267,7 @@ func TestDeleteService(t *testing.T) {
err = service.Delete()
assert.Nil(t, err)
services := CoreApp.Services()
services := CoreApp.Services
assert.Equal(t, 20, len(services))
}
@ -282,10 +282,13 @@ func TestServiceCloseRoutine(t *testing.T) {
s.Start()
assert.True(t, s.IsRunning())
t.Log(s.Checkpoint)
t.Log(s.SleepDuration)
go s.CheckQueue(false)
t.Log(s.Checkpoint)
t.Log(s.SleepDuration)
time.Sleep(5 * time.Second)
t.Log(s.Checkpoint)
t.Log(s.SleepDuration)
assert.True(t, s.IsRunning())
s.Close()
assert.False(t, s.IsRunning())

View File

@ -156,7 +156,7 @@ func ApiAllServicesHandler(w http.ResponseWriter, r *http.Request) {
http.Error(w, http.StatusText(http.StatusUnauthorized), http.StatusUnauthorized)
return
}
services := core.CoreApp.Services()
services := core.CoreApp.Services
json.NewEncoder(w).Encode(services)
}

View File

@ -16,26 +16,19 @@
package handlers
import (
"fmt"
"github.com/hunterlong/statup/core"
"github.com/hunterlong/statup/utils"
"net/http"
)
type dashboard struct {
Core *core.Core
CountOnline int
CountServices int
Count24Failures uint64
}
func DashboardHandler(w http.ResponseWriter, r *http.Request) {
fmt.Println()
if !IsAuthenticated(r) {
err := core.ErrorResponse{}
ExecuteResponse(w, r, "login.html", err)
} else {
fails := core.CountFailures()
out := dashboard{core.CoreApp, core.CountOnline(), len(core.CoreApp.Services()), fails}
ExecuteResponse(w, r, "dashboard.html", out)
ExecuteResponse(w, r, "dashboard.html", core.CoreApp)
}
}

View File

@ -17,6 +17,7 @@ package handlers
import (
"fmt"
"github.com/gin-gonic/gin/json"
"github.com/gorilla/sessions"
"github.com/hunterlong/statup/core"
"github.com/hunterlong/statup/source"
@ -25,6 +26,7 @@ import (
"html/template"
"net/http"
"os"
"reflect"
"time"
)
@ -105,9 +107,27 @@ func ExecuteResponse(w http.ResponseWriter, r *http.Request, file string, data i
"CoreApp": func() *core.Core {
return core.CoreApp
},
"Services": func() []types.ServiceInterface {
return core.CoreApp.Services
},
"USE_CDN": func() bool {
return core.CoreApp.UseCdn
},
"Type": func(g interface{}) []string {
fooType := reflect.TypeOf(g)
var methods []string
methods = append(methods, fooType.String())
for i := 0; i < fooType.NumMethod(); i++ {
method := fooType.Method(i)
fmt.Println(method.Name)
methods = append(methods, method.Name)
}
return methods
},
"ToJSON": func(g interface{}) template.HTML {
data, _ := json.Marshal(g)
return template.HTML(string(data))
},
"underscore": func(html string) string {
return utils.UnderScoreString(html)
},

View File

@ -41,10 +41,10 @@ func PrometheusHandler(w http.ResponseWriter, r *http.Request) {
}
metrics := []string{}
system := fmt.Sprintf("statup_total_failures %v\n", core.CountFailures())
system += fmt.Sprintf("statup_total_services %v", len(core.CoreApp.Services()))
system += fmt.Sprintf("statup_total_services %v", len(core.CoreApp.Services))
metrics = append(metrics, system)
for _, ser := range core.CoreApp.Services() {
v := ser
for _, ser := range core.CoreApp.Services {
v := ser.(*core.Service)
online := 1
if !v.Online {
online = 0

View File

@ -31,7 +31,7 @@ type Service struct {
}
func RenderServiceChartsHandler(w http.ResponseWriter, r *http.Request) {
services := core.CoreApp.Services()
services := core.CoreApp.Services
w.Header().Set("Content-Type", "text/javascript")
w.Header().Set("Cache-Control", "max-age=60")
ExecuteJSResponse(w, r, "charts.js", services)
@ -42,7 +42,7 @@ func ServicesHandler(w http.ResponseWriter, r *http.Request) {
http.Redirect(w, r, "/", http.StatusSeeOther)
return
}
ExecuteResponse(w, r, "services.html", core.CoreApp.Services())
ExecuteResponse(w, r, "services.html", core.CoreApp.Services)
}
type serviceOrder struct {
@ -106,10 +106,8 @@ func CreateServiceHandler(w http.ResponseWriter, r *http.Request) {
if err != nil {
utils.Log(3, fmt.Sprintf("Error starting %v check routine. %v", service.Name, err))
}
service = service.Check(true)
go service.CheckQueue(true)
core.OnNewService(service)
ExecuteResponse(w, r, "services.html", core.CoreApp.Services())
core.OnNewService(core.ReturnService(service.Service))
ExecuteResponse(w, r, "services.html", core.CoreApp.Services)
}
func ServicesDeleteHandler(w http.ResponseWriter, r *http.Request) {
@ -118,14 +116,13 @@ func ServicesDeleteHandler(w http.ResponseWriter, r *http.Request) {
return
}
vars := mux.Vars(r)
serv := core.SelectService(utils.StringInt(vars["id"]))
if serv == nil {
service := core.SelectService(utils.StringInt(vars["id"]))
if service == nil {
w.WriteHeader(http.StatusNotFound)
return
}
service := serv
service.Delete()
ExecuteResponse(w, r, "services.html", core.CoreApp.Services())
ExecuteResponse(w, r, "services.html", core.CoreApp.Services)
}
func ServicesViewHandler(w http.ResponseWriter, r *http.Request) {
@ -144,8 +141,7 @@ func ServicesUpdateHandler(w http.ResponseWriter, r *http.Request) {
return
}
vars := mux.Vars(r)
serv := core.SelectService(utils.StringInt(vars["id"]))
service := serv
service := core.SelectService(utils.StringInt(vars["id"]))
r.ParseForm()
name := r.PostForm.Get("name")
domain := r.PostForm.Get("domain")
@ -159,23 +155,21 @@ func ServicesUpdateHandler(w http.ResponseWriter, r *http.Request) {
postData := r.PostForm.Get("post_data")
order, _ := strconv.Atoi(r.PostForm.Get("order"))
serviceUpdate := core.ReturnService(&types.Service{
Id: service.Id,
Name: name,
Domain: domain,
Method: method,
Expected: expected,
ExpectedStatus: status,
Interval: interval,
Type: checkType,
Port: port,
PostData: postData,
Timeout: timeout,
Order: order,
})
serviceUpdate.Update(true)
serviceUpdate = serviceUpdate.Check(true)
ExecuteResponse(w, r, "service.html", serviceUpdate)
service.Name = name
service.Domain = domain
service.Method = method
service.ExpectedStatus = status
service.Expected = expected
service.Interval = interval
service.Type = checkType
service.Port = port
service.PostData = postData
service.Timeout = timeout
service.Order = order
service.Update(true)
service.Check(true)
ExecuteResponse(w, r, "service.html", service)
}
func ServicesDeleteFailuresHandler(w http.ResponseWriter, r *http.Request) {
@ -186,7 +180,7 @@ func ServicesDeleteFailuresHandler(w http.ResponseWriter, r *http.Request) {
vars := mux.Vars(r)
service := core.SelectService(utils.StringInt(vars["id"]))
service.DeleteFailures()
ExecuteResponse(w, r, "services.html", core.CoreApp.Services())
ExecuteResponse(w, r, "services.html", core.CoreApp.Services)
}
func CheckinCreateUpdateHandler(w http.ResponseWriter, r *http.Request) {

View File

@ -39,28 +39,29 @@ func SaveSettingsHandler(w http.ResponseWriter, r *http.Request) {
return
}
r.ParseForm()
app := core.CoreApp
name := r.PostForm.Get("project")
if name != "" {
core.CoreApp.Name = name
app.Name = name
}
description := r.PostForm.Get("description")
if description != core.CoreApp.Description {
core.CoreApp.Description = description
if description != app.Description {
app.Description = description
}
style := r.PostForm.Get("style")
if style != core.CoreApp.Style {
core.CoreApp.Style = style
if style != app.Style {
app.Style = style
}
footer := r.PostForm.Get("footer")
if footer != core.CoreApp.Footer {
core.CoreApp.Footer = footer
if footer != app.Footer {
app.Footer = footer
}
domain := r.PostForm.Get("domain")
if domain != core.CoreApp.Domain {
core.CoreApp.Domain = domain
if domain != app.Domain {
app.Domain = domain
}
core.CoreApp.UseCdn = (r.PostForm.Get("enable_cdn") == "on")
core.CoreApp, _ = core.UpdateCore(core.CoreApp)
app.UseCdn = (r.PostForm.Get("enable_cdn") == "on")
core.CoreApp, _ = core.UpdateCore(app)
core.OnSettingsSaved(core.CoreApp.ToCore())
ExecuteResponse(w, r, "settings.html", core.CoreApp)
}

View File

@ -26,7 +26,7 @@ import (
)
func SetupHandler(w http.ResponseWriter, r *http.Request) {
if core.CoreApp.Services() != nil {
if core.CoreApp.Services != nil {
http.Redirect(w, r, "/", http.StatusSeeOther)
return
}
@ -56,7 +56,7 @@ func SetupHandler(w http.ResponseWriter, r *http.Request) {
func ProcessSetupHandler(w http.ResponseWriter, r *http.Request) {
var err error
if core.CoreApp.Services() != nil {
if core.CoreApp.Services != nil {
http.Redirect(w, r, "/", http.StatusSeeOther)
return
}

View File

@ -25,12 +25,12 @@
<div class="row stats_area mb-5">
<div class="col-4">
<span class="lg_number">{{ .CountServices }}</span>
<span class="lg_number">{{ .ServicesCount }}</span>
Total Services
</div>
<div class="col-4">
<span class="lg_number">{{ .Count24Failures }}</span>
<span class="lg_number">{{ .Count24HFailures }}</span>
Failures last 24 Hours
</div>
@ -47,7 +47,7 @@
<h3>Services</h3>
<div class="list-group mb-5 mt-3">
{{ range .Core.Services }}
{{ range Services }}
<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">{{.Name}}</h5>
@ -58,7 +58,7 @@
{{ end }}
</div>
{{ range .Core.Services }}
{{ range Services }}
{{ if .LimitedFailures }}
<h4 class="text-truncate">{{.Name}} Failures</h4>
<div class="list-group mt-3 mb-4">

View File

@ -17,7 +17,6 @@
</head>
<body>
<div class="container col-md-7 col-sm-12 mt-2 sm-container">
<h1 class="col-12 text-center mb-4 mt-sm-3 header-title">{{.Name}}</h1>
@ -28,7 +27,7 @@
<div class="col-12 full-col-12 mb-5">
<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}}bg-danger text-white{{ end }}" data-id="{{.Id}}">
{{ .Name }}
{{if .Online}}
@ -43,7 +42,7 @@
<div class="col-12 full-col-12">
{{ if not .Services }}
{{ if not Services }}
<div class="alert alert-danger" role="alert">
<h4 class="alert-heading">No Services to Monitor!</h4>
<p>Your Statup Status Page is working correctly, but you don't have any services to monitor. Go to the <b>Dashboard</b> and add a website to begin really using your status page!</p>
@ -51,7 +50,7 @@
<p class="mb-0">If this is a bug, please make an issue in the Statup Github Repo. <a href="https://github.com/hunterlong/statup" class="btn btn-sm btn-outline-danger float-right">Statup Github Repo</a></p>
</div>
{{end}}
{{ range .Services }}
{{ range Services }}
<div class="mt-4" id="service_id_{{.Id}}">
<div class="card">
<div class="card-body">

View File

@ -1,7 +1,6 @@
package types
import (
"sort"
"time"
)
@ -9,26 +8,26 @@ import (
// will be saved into 1 row in the 'core' table. You can use the core.CoreApp
// global variable to interact with the attributes to the application, such as services.
type Core struct {
Name string `gorm:"not null;column:name" json:"name"`
Description string `gorm:"not null;column:description" json:"description,omitempty"`
Config string `gorm:"column:config" json:"-"`
ApiKey string `gorm:"column:api_key" json:"-"`
ApiSecret string `gorm:"column:api_secret" json:"-"`
Style string `gorm:"not null;column:style" json:"style,omitempty"`
Footer string `gorm:"not null;column:footer" json:"footer,omitempty"`
Domain string `gorm:"not null;column:domain" json:"domain,omitempty"`
Version string `gorm:"column:version" json:"version"`
MigrationId int64 `gorm:"column:migration_id" json:"migration_id,omitempty"`
UseCdn bool `gorm:"column:use_cdn;default:false" json:"using_cdn,omitempty"`
CreatedAt time.Time `gorm:"column:created_at" json:"created_at"`
UpdatedAt time.Time `gorm:"column:updated_at" json:"updated_at"`
DbConnection string `gorm:"-" json:"database"`
Started time.Time `gorm:"-" json:"started_on"`
dbServices []*Service `gorm:"-" json:"services,omitempty"`
Plugins []Info `gorm:"-" json:"-"`
Repos []PluginJSON `gorm:"-" json:"-"`
AllPlugins []PluginActions `gorm:"-" json:"-"`
Communications []AllNotifiers `gorm:"-" json:"-"`
Name string `gorm:"not null;column:name" json:"name"`
Description string `gorm:"not null;column:description" json:"description,omitempty"`
Config string `gorm:"column:config" json:"-"`
ApiKey string `gorm:"column:api_key" json:"-"`
ApiSecret string `gorm:"column:api_secret" json:"-"`
Style string `gorm:"not null;column:style" json:"style,omitempty"`
Footer string `gorm:"not null;column:footer" json:"footer,omitempty"`
Domain string `gorm:"not null;column:domain" json:"domain,omitempty"`
Version string `gorm:"column:version" json:"version"`
MigrationId int64 `gorm:"column:migration_id" json:"migration_id,omitempty"`
UseCdn bool `gorm:"column:use_cdn;default:false" json:"using_cdn,omitempty"`
CreatedAt time.Time `gorm:"column:created_at" json:"created_at"`
UpdatedAt time.Time `gorm:"column:updated_at" json:"updated_at"`
DbConnection string `gorm:"-" json:"database"`
Started time.Time `gorm:"-" json:"started_on"`
Services []ServiceInterface `gorm:"-" json:"services,omitempty"`
Plugins []Info `gorm:"-" json:"-"`
Repos []PluginJSON `gorm:"-" json:"-"`
AllPlugins []PluginActions `gorm:"-" json:"-"`
Communications []AllNotifiers `gorm:"-" json:"-"`
CoreInterface `gorm:"-" json:"-"`
}
@ -38,30 +37,9 @@ func (c ServiceOrder) Len() int { return len(c) }
func (c ServiceOrder) Swap(i, j int) { c[i], c[j] = c[j], c[i] }
func (c ServiceOrder) Less(i, j int) bool { return c[i].Order < c[j].Order }
func (c *Core) SetServices(s []*Service) {
sort.Sort(ServiceOrder(c.dbServices))
c.dbServices = s
}
func (c *Core) UpdateService(index int, s *Service) {
c.dbServices[index] = s
}
func (c *Core) AddService(s *Service) {
c.dbServices = append(c.dbServices, s)
}
func (c *Core) RemoveService(s int) []*Service {
slice := c.dbServices
c.dbServices = append(slice[:s], slice[s+1:]...)
return c.dbServices
}
func (c *Core) GetServices() []*Service {
return c.dbServices
}
type CoreInterface interface {
SelectAllServices() ([]*Service, error)
Services() []*Service
Count24HFailures() uint64
ServicesCount() int
CountOnline() int
}

View File

@ -14,8 +14,6 @@ type Failure struct {
}
type FailureInterface interface {
Delete() error
// method functions
Ago() string
ParseError() string
}

View File

@ -20,39 +20,40 @@ import (
)
type Service struct {
Id int64 `gorm:"primary_key;column:id" json:"id"`
Name string `gorm:"column:name" json:"name"`
Domain string `gorm:"column:domain" json:"domain"`
Expected string `gorm:"not null;column:expected" json:"expected"`
ExpectedStatus int `gorm:"default:200;column:expected_status" json:"expected_status"`
Interval int `gorm:"default:30;column:check_interval" json:"check_interval"`
Type string `gorm:"column:check_type" json:"type"`
Method string `gorm:"column:method" json:"method"`
PostData string `gorm:"not null;column:post_data" json:"post_data"`
Port int `gorm:"not null;column:port" json:"port"`
Timeout int `gorm:"default:30;column:timeout" json:"timeout"`
Order int `gorm:"default:0;column:order_id" json:"order_id"`
CreatedAt time.Time `gorm:"column:created_at" json:"created_at"`
UpdatedAt time.Time `gorm:"column:updated_at" json:"updated_at"`
Online bool `gorm:"-" json:"online"`
Latency float64 `gorm:"-" json:"latency"`
Online24Hours float32 `gorm:"-" json:"24_hours_online"`
AvgResponse string `gorm:"-" json:"avg_response"`
Failures []*Failure `gorm:"-" json:"failures"`
Checkins []*Checkin `gorm:"-" json:"checkins"`
Running chan bool `gorm:"-" json:"-"`
Checkpoint time.Time `gorm:"-" json:"-"`
LastResponse string `gorm:"-" json:"-"`
LastStatusCode int `gorm:"-" json:"status_code"`
LastOnline time.Time `gorm:"-" json:"last_online"`
DnsLookup float64 `gorm:"-" json:"dns_lookup_time"`
Id int64 `gorm:"primary_key;column:id" json:"id"`
Name string `gorm:"column:name" json:"name"`
Domain string `gorm:"column:domain" json:"domain"`
Expected string `gorm:"not null;column:expected" json:"expected"`
ExpectedStatus int `gorm:"default:200;column:expected_status" json:"expected_status"`
Interval int `gorm:"default:30;column:check_interval" json:"check_interval"`
Type string `gorm:"column:check_type" json:"type"`
Method string `gorm:"column:method" json:"method"`
PostData string `gorm:"not null;column:post_data" json:"post_data"`
Port int `gorm:"not null;column:port" json:"port"`
Timeout int `gorm:"default:30;column:timeout" json:"timeout"`
Order int `gorm:"default:0;column:order_id" json:"order_id"`
CreatedAt time.Time `gorm:"column:created_at" json:"created_at"`
UpdatedAt time.Time `gorm:"column:updated_at" json:"updated_at"`
Online bool `gorm:"-" json:"online"`
Latency float64 `gorm:"-" json:"latency"`
Online24Hours float32 `gorm:"-" json:"24_hours_online"`
AvgResponse string `gorm:"-" json:"avg_response"`
Failures []interface{} `gorm:"-" json:"failures"`
Checkins []*Checkin `gorm:"-" json:"checkins"`
Running chan bool `gorm:"-" json:"-"`
Checkpoint time.Time `gorm:"-" json:"-"`
SleepDuration time.Duration `gorm:"-" json:"-"`
LastResponse string `gorm:"-" json:"-"`
LastStatusCode int `gorm:"-" json:"status_code"`
LastOnline time.Time `gorm:"-" json:"last_online"`
DnsLookup float64 `gorm:"-" json:"dns_lookup_time"`
ServiceInterface `gorm:"-" json:"-"`
}
type ServiceInterface interface {
// Database functions
Create() (int64, error)
Update() error
Update(bool) error
Delete() error
// Basic Method functions
AvgTime() float64
@ -60,12 +61,13 @@ type ServiceInterface interface {
Online24() float32
SmallText() string
GraphData() string
AvgUptime() string
AvgUptime(time.Time) string
AvgUptime24() string
ToJSON() string
// Failure functions
CreateFailure(*Failure) (int64, error)
LimitedFailures() []*Failure
AllFailures() []*Failure
//LimitedFailures() []interface{}
//AllFailures() []*Failure
TotalFailuresSince(time.Time) (uint64, error)
TotalFailures24() (uint64, error)
TotalFailures() (uint64, error)
@ -80,17 +82,15 @@ type ServiceInterface interface {
SelectHitsGroupBy(string) ([]*Hit, error)
// Go Routines
CheckQueue(bool)
Check(bool) *Service
checkHttp(bool) *Service
checkTcp(bool) *Service
Check(bool)
//checkHttp(bool) *Service
//checkTcp(bool) *Service
// Checkin functions
AllCheckins() []*Checkin
}
func (s *Service) Start() {
if s.Running == nil {
s.Running = make(chan bool)
}
s.Running = make(chan bool)
}
func (s *Service) Close() {