mirror of https://github.com/statping/statping
service close channels - ServiceInterface - service check from time.Duration
parent
49a264c525
commit
347f2798dd
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
26
core/core.go
26
core/core.go
|
@ -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
|
||||
//}
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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)
|
||||
|
|
14
core/hits.go
14
core/hits.go
|
@ -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
|
||||
|
|
|
@ -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++
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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())
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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)
|
||||
},
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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">
|
||||
|
|
|
@ -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">
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -14,8 +14,6 @@ type Failure struct {
|
|||
}
|
||||
|
||||
type FailureInterface interface {
|
||||
Delete() error
|
||||
// method functions
|
||||
Ago() string
|
||||
ParseError() string
|
||||
}
|
||||
|
|
|
@ -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() {
|
||||
|
|
Loading…
Reference in New Issue