From c0d76eb8910615bf31d9b284410aae41074c270a Mon Sep 17 00:00:00 2001 From: hunterlong Date: Tue, 25 Feb 2020 05:18:29 -0800 Subject: [PATCH] building --- core/checkin.go | 2 - core/sample.go | 16 +++--- core/services.go | 4 +- database/failures.go | 6 +++ handlers/checkin.go | 21 +++----- handlers/dashboard.go | 47 ++++++++-------- handlers/groups.go | 20 +++---- handlers/prometheus.go | 10 ++-- handlers/routes.go | 3 +- handlers/services.go | 118 ++++++++--------------------------------- handlers/setup.go | 7 +-- handlers/users.go | 6 +-- 12 files changed, 87 insertions(+), 173 deletions(-) diff --git a/core/checkin.go b/core/checkin.go index fe388fa7..c37c5f43 100644 --- a/core/checkin.go +++ b/core/checkin.go @@ -168,8 +168,6 @@ func (c *Checkin) Create() (int64, error) { log.Warnln(err) return 0, err } - service := SelectService(c.ServiceId) - service.Checkins = append(service.Checkins, c) c.Start() go CheckinRoutine(c) return c.Id, err diff --git a/core/sample.go b/core/sample.go index 23445086..715924a1 100644 --- a/core/sample.go +++ b/core/sample.go @@ -195,7 +195,7 @@ func insertSampleGroups() error { func insertSampleCheckins() error { s1 := SelectService(1) checkin1 := &types.Checkin{ - ServiceId: s1.Id, + ServiceId: s1.Model().Id, Interval: 300, GracePeriod: 300, } @@ -206,7 +206,7 @@ func insertSampleCheckins() error { s2 := SelectService(1) checkin2 := &types.Checkin{ - ServiceId: s2.Id, + ServiceId: s2.Model().Id, Interval: 900, GracePeriod: 300, } @@ -240,7 +240,7 @@ func InsertSampleHits() error { sg.Add(1) service := SelectService(i) seed := time.Now().UnixNano() - log.Infoln(fmt.Sprintf("Adding %v sample hit records to service %v", SampleHits, service.Name)) + log.Infoln(fmt.Sprintf("Adding %v sample hit records to service %v", SampleHits, service.Model().Name)) createdAt := sampleStart p := utils.NewPerlin(2., 2., 10, seed) go func() { @@ -249,7 +249,7 @@ func InsertSampleHits() error { latency := p.Noise1D(hi / 500) createdAt = createdAt.Add(60 * time.Second) hit := &types.Hit{ - Service: service.Id, + Service: service.Model().Id, CreatedAt: createdAt, Latency: latency, } @@ -527,14 +527,14 @@ func InsertLargeSampleData() error { func insertFailureRecords(since time.Time, amount int) { for i := int64(14); i <= 15; i++ { service := SelectService(i) - log.Infoln(fmt.Sprintf("Adding %v Failure records to service %v", amount, service.Name)) + log.Infoln(fmt.Sprintf("Adding %v Failure records to service %v", amount, service.Model().Name)) createdAt := since for fi := 1; fi <= amount; fi++ { createdAt = createdAt.Add(2 * time.Minute) failure := &types.Failure{ - Service: service.Id, + Service: service.Model().Id, Issue: "testing right here", CreatedAt: createdAt, } @@ -548,14 +548,14 @@ func insertFailureRecords(since time.Time, amount int) { func insertHitRecords(since time.Time, amount int) { for i := int64(1); i <= 15; i++ { service := SelectService(i) - log.Infoln(fmt.Sprintf("Adding %v hit records to service %v", amount, service.Name)) + log.Infoln(fmt.Sprintf("Adding %v hit records to service %v", amount, service.Model().Name)) createdAt := since p := utils.NewPerlin(2, 2, 5, time.Now().UnixNano()) for hi := 1; hi <= amount; hi++ { latency := p.Noise1D(float64(hi / 10)) createdAt = createdAt.Add(1 * time.Minute) hit := &types.Hit{ - Service: service.Id, + Service: service.Model().Id, CreatedAt: createdAt.UTC(), Latency: latency, } diff --git a/core/services.go b/core/services.go index 52ba8fa0..04df8ac9 100644 --- a/core/services.go +++ b/core/services.go @@ -35,11 +35,11 @@ func Services() []database.Servicer { } // SelectService returns a *core.Service from in memory -func SelectService(id int64) *types.Service { +func SelectService(id int64) database.Servicer { for _, s := range Services() { if s.Model().Id == id { fmt.Println("service: ", s.Model()) - return s.Model() + return s } } return nil diff --git a/database/failures.go b/database/failures.go index 257da83c..31565cbb 100644 --- a/database/failures.go +++ b/database/failures.go @@ -23,6 +23,12 @@ func (f *FailureObj) All() []*types.Failure { return fails } +func AllFailures() int { + var amount int + database.Failures().Count(&amount) + return amount +} + func (f *FailureObj) DeleteAll() error { query := database.Exec(`DELETE FROM failures WHERE service = ?`, f.o.Id) return query.Error() diff --git a/handlers/checkin.go b/handlers/checkin.go index 35babd2c..3ef6fe51 100644 --- a/handlers/checkin.go +++ b/handlers/checkin.go @@ -40,10 +40,7 @@ func apiCheckinHandler(w http.ResponseWriter, r *http.Request) { return } out := checkin.Model() - - out.Hits = checkin.Hits() - out.Failures = checkin.Failures(32) - returnJson(checkin, w, r) + returnJson(out, w, r) } func checkinCreateHandler(w http.ResponseWriter, r *http.Request) { @@ -69,8 +66,8 @@ func checkinCreateHandler(w http.ResponseWriter, r *http.Request) { func checkinHitHandler(w http.ResponseWriter, r *http.Request) { vars := mux.Vars(r) - checkin := core.SelectCheckin(vars["api"]) - if checkin == nil { + checkin, err := database.CheckinByKey(vars["api"]) + if err != nil { sendErrorJson(fmt.Errorf("checkin %v was not found", vars["api"]), w, r) return } @@ -81,20 +78,14 @@ func checkinHitHandler(w http.ResponseWriter, r *http.Request) { From: ip, CreatedAt: utils.Now().UTC(), } - checkinHit := core.ReturnCheckinHit(hit) - if checkin.Last() == nil { - checkin.Start() - go checkin.Routine() - } - _, err := checkinHit.Create() - checkin.Hits = append(checkin.Hits, checkinHit.CheckinHit) + newCheck, err := database.Create(hit) if err != nil { - sendErrorJson(err, w, r) + sendErrorJson(fmt.Errorf("checkin %v was not found", vars["api"]), w, r) return } checkin.Failing = false checkin.LastHit = utils.Timezoner(utils.Now().UTC(), core.CoreApp.Timezone) - sendJsonAction(checkinHit, "update", w, r) + sendJsonAction(newCheck.Id, "update", w, r) } func checkinDeleteHandler(w http.ResponseWriter, r *http.Request) { diff --git a/handlers/dashboard.go b/handlers/dashboard.go index 2572e4d1..b550e918 100644 --- a/handlers/dashboard.go +++ b/handlers/dashboard.go @@ -16,17 +16,14 @@ package handlers import ( - "bytes" "encoding/json" "fmt" "github.com/dgrijalva/jwt-go" "github.com/hunterlong/statping/core" - "github.com/hunterlong/statping/core/notifier" "github.com/hunterlong/statping/source" "github.com/hunterlong/statping/utils" "net/http" "os" - "strconv" "time" ) @@ -149,28 +146,28 @@ func logsLineHandler(w http.ResponseWriter, r *http.Request) { } } -func exportHandler(w http.ResponseWriter, r *http.Request) { - var notifiers []*notifier.Notification - for _, v := range core.CoreApp.Notifications { - notifier := v.(notifier.Notifier) - notifiers = append(notifiers, notifier.Select()) - } - - export, _ := core.ExportSettings() - - mime := http.DetectContentType(export) - fileSize := len(string(export)) - - w.Header().Set("Content-Type", mime) - w.Header().Set("Content-Disposition", "attachment; filename=export.json") - w.Header().Set("Expires", "0") - w.Header().Set("Content-Transfer-Encoding", "binary") - w.Header().Set("Content-Length", strconv.Itoa(fileSize)) - w.Header().Set("Content-Control", "private, no-transform, no-store, must-revalidate") - - http.ServeContent(w, r, "export.json", utils.Now(), bytes.NewReader(export)) - -} +//func exportHandler(w http.ResponseWriter, r *http.Request) { +// var notifiers []*notifier.Notification +// for _, v := range core.CoreApp.Notifications { +// notifier := v.(notifier.Notifier) +// notifiers = append(notifiers, notifier.Select()) +// } +// +// export, _ := core.ExportSettings() +// +// mime := http.DetectContentType(export) +// fileSize := len(string(export)) +// +// w.Header().Set("Content-Type", mime) +// w.Header().Set("Content-Disposition", "attachment; filename=export.json") +// w.Header().Set("Expires", "0") +// w.Header().Set("Content-Transfer-Encoding", "binary") +// w.Header().Set("Content-Length", strconv.Itoa(fileSize)) +// w.Header().Set("Content-Control", "private, no-transform, no-store, must-revalidate") +// +// http.ServeContent(w, r, "export.json", utils.Now(), bytes.NewReader(export)) +// +//} type JwtClaim struct { Username string `json:"username"` diff --git a/handlers/groups.go b/handlers/groups.go index 71d09d36..72219a6b 100644 --- a/handlers/groups.go +++ b/handlers/groups.go @@ -20,7 +20,7 @@ import ( "errors" "github.com/gorilla/mux" "github.com/hunterlong/statping/core" - "github.com/hunterlong/statping/types" + "github.com/hunterlong/statping/database" "github.com/hunterlong/statping/utils" "net/http" ) @@ -29,15 +29,7 @@ import ( func apiAllGroupHandler(r *http.Request) interface{} { auth, admin := IsUser(r), IsAdmin(r) groups := core.SelectGroups(admin, auth) - return joinGroups(groups) -} - -func joinGroups(groups []*core.Group) []*types.Group { - var g []*types.Group - for _, v := range groups { - g = append(g, v.Group) - } - return g + return groups } // apiGroupHandler will show a single group @@ -61,7 +53,7 @@ func apiGroupUpdateHandler(w http.ResponseWriter, r *http.Request) { } decoder := json.NewDecoder(r.Body) decoder.Decode(&group) - _, err := group.Update() + err := database.Update(group) if err != nil { sendErrorJson(err, w, r) return @@ -78,7 +70,7 @@ func apiCreateGroupHandler(w http.ResponseWriter, r *http.Request) { sendErrorJson(err, w, r) return } - _, err = group.Create() + _, err = database.Create(group) if err != nil { sendErrorJson(err, w, r) return @@ -94,7 +86,7 @@ func apiGroupDeleteHandler(w http.ResponseWriter, r *http.Request) { sendErrorJson(errors.New("group not found"), w, r) return } - err := group.Delete() + err := database.Delete(group) if err != nil { sendErrorJson(err, w, r) return @@ -115,7 +107,7 @@ func apiGroupReorderHandler(w http.ResponseWriter, r *http.Request) { for _, g := range newOrder { group := core.SelectGroup(g.Id) group.Order = g.Order - group.Update() + database.Update(group) } returnJson(newOrder, w, r) } diff --git a/handlers/prometheus.go b/handlers/prometheus.go index 63b9c0cb..fd40c8af 100644 --- a/handlers/prometheus.go +++ b/handlers/prometheus.go @@ -18,6 +18,7 @@ package handlers import ( "fmt" "github.com/hunterlong/statping/core" + "github.com/hunterlong/statping/database" "net/http" "strings" ) @@ -34,11 +35,12 @@ import ( func prometheusHandler(w http.ResponseWriter, r *http.Request) { metrics := []string{} - system := fmt.Sprintf("statping_total_failures %v\n", core.CountFailures()) - system += fmt.Sprintf("statping_total_services %v", len(core.CoreApp.Services)) + allFails := database.AllFailures() + system := fmt.Sprintf("statping_total_failures %v\n", allFails) + system += fmt.Sprintf("statping_total_services %v", len(core.Services())) metrics = append(metrics, system) - for _, ser := range core.CoreApp.Services { - v := ser.Select() + for _, ser := range core.Services() { + v := ser.Model() online := 1 if !v.Online { online = 0 diff --git a/handlers/routes.go b/handlers/routes.go index 4f3709b6..79599438 100644 --- a/handlers/routes.go +++ b/handlers/routes.go @@ -115,7 +115,6 @@ func Router() *mux.Router { // API SERVICE Routes api.Handle("/api/services", scoped(apiAllServicesHandler)).Methods("GET") api.Handle("/api/services", authenticated(apiCreateServiceHandler, false)).Methods("POST") - api.Handle("/api/services_test", authenticated(apiTestServiceHandler, false)).Methods("POST") api.Handle("/api/services/{id}", scoped(apiServiceHandler)).Methods("GET") api.Handle("/api/reorder/services", authenticated(reorderServiceHandler, false)).Methods("POST") api.Handle("/api/services/{id}/running", authenticated(apiServiceRunningHandler, false)).Methods("POST") @@ -129,7 +128,7 @@ func Router() *mux.Router { api.Handle("/api/services/{id}/hits_data", cached("30s", "application/json", apiServiceDataHandler)).Methods("GET") api.Handle("/api/services/{id}/failure_data", cached("30s", "application/json", apiServiceFailureDataHandler)).Methods("GET") api.Handle("/api/services/{id}/ping_data", cached("30s", "application/json", apiServicePingDataHandler)).Methods("GET") - api.Handle("/api/services/{id}/heatmap", cached("30s", "application/json", apiServiceHeatmapHandler)).Methods("GET") + //api.Handle("/api/services/{id}/heatmap", cached("30s", "application/json", apiServiceHeatmapHandler)).Methods("GET") // API INCIDENTS Routes api.Handle("/api/incidents", readOnly(apiAllIncidentsHandler, false)).Methods("GET") diff --git a/handlers/services.go b/handlers/services.go index b70834a4..68b65938 100644 --- a/handlers/services.go +++ b/handlers/services.go @@ -18,43 +18,14 @@ package handlers import ( "encoding/json" "errors" - "fmt" "github.com/gorilla/mux" "github.com/hunterlong/statping/core" "github.com/hunterlong/statping/database" "github.com/hunterlong/statping/types" "github.com/hunterlong/statping/utils" "net/http" - "time" ) -func renderServiceChartsHandler(w http.ResponseWriter, r *http.Request) { - services := core.CoreApp.Services - w.Header().Set("Content-Type", "text/javascript") - w.Header().Set("Cache-Control", "max-age=60") - - end := utils.Now().UTC() - start := utils.Now().Add((-24 * 7) * time.Hour).UTC() - var srvs []*core.Service - for _, s := range services { - srvs = append(srvs, s.(*core.Service)) - } - out := struct { - Services []*core.Service - Start int64 - End int64 - }{srvs, start.Unix(), end.Unix()} - - executeJSResponse(w, r, "charts.js", out) -} - -func servicesHandler(w http.ResponseWriter, r *http.Request) { - data := map[string]interface{}{ - "Services": core.CoreApp.Services, - } - ExecuteResponse(w, r, "services.gohtml", data, nil) -} - type serviceOrder struct { Id int64 `json:"service"` Order int `json:"order"` @@ -66,20 +37,20 @@ func reorderServiceHandler(w http.ResponseWriter, r *http.Request) { decoder := json.NewDecoder(r.Body) decoder.Decode(&newOrder) for _, s := range newOrder { - service := core.SelectService(s.Id) + service := core.SelectService(s.Id).Model() service.Order = s.Order - service.Update(false) + database.Update(service) } returnJson(newOrder, w, r) } func apiServiceHandler(r *http.Request) interface{} { vars := mux.Vars(r) - servicer := core.SelectService(utils.ToInt(vars["id"])) + servicer := core.SelectService(utils.ToInt(vars["id"])).Model() if servicer == nil { return errors.New("service not found") } - return *servicer.Select() + return *servicer } func apiCreateServiceHandler(w http.ResponseWriter, r *http.Request) { @@ -90,13 +61,12 @@ func apiCreateServiceHandler(w http.ResponseWriter, r *http.Request) { sendErrorJson(err, w, r) return } - newService := core.ReturnService(service) - _, err = newService.Create(true) + _, err = database.Create(service) if err != nil { sendErrorJson(err, w, r) return } - sendJsonAction(newService, "create", w, r) + sendJsonAction(service, "create", w, r) } func apiTestServiceHandler(w http.ResponseWriter, r *http.Request) { @@ -108,13 +78,12 @@ func apiTestServiceHandler(w http.ResponseWriter, r *http.Request) { return } - newService := core.ReturnService(service) - _, err = newService.Create(true) + _, err = database.Create(service) if err != nil { sendErrorJson(err, w, r) return } - sendJsonAction(newService, "create", w, r) + sendJsonAction(service, "create", w, r) } func apiServiceUpdateHandler(w http.ResponseWriter, r *http.Request) { @@ -126,18 +95,19 @@ func apiServiceUpdateHandler(w http.ResponseWriter, r *http.Request) { } decoder := json.NewDecoder(r.Body) decoder.Decode(&service) - err := service.Update(true) + err := database.Update(service) if err != nil { sendErrorJson(err, w, r) return } - go service.Check(true) + go core.CheckService(service, true) sendJsonAction(service, "update", w, r) } func apiServiceRunningHandler(w http.ResponseWriter, r *http.Request) { vars := mux.Vars(r) - service := core.SelectService(utils.ToInt(vars["id"])) + srv := core.SelectService(utils.ToInt(vars["id"])) + service := srv.Model() if service == nil { sendErrorJson(errors.New("service not found"), w, r) return @@ -200,52 +170,6 @@ type dataXyMonth struct { Data []*dataXy `json:"data"` } -func apiServiceHeatmapHandler(w http.ResponseWriter, r *http.Request) { - vars := mux.Vars(r) - service := core.SelectService(utils.ToInt(vars["id"])) - if service == nil { - sendErrorJson(errors.New("service data not found"), w, r) - return - } - - var monthOutput []*dataXyMonth - - start := service.CreatedAt - //now := utils.Now() - - sY, sM, _ := start.Date() - - var date time.Time - - month := int(sM) - maxMonth := 12 - - for year := int(sY); year <= utils.Now().Year(); year++ { - - if year == utils.Now().Year() { - maxMonth = int(utils.Now().Month()) - } - - for m := month; m <= maxMonth; m++ { - - var output []*dataXy - - for day := 1; day <= 31; day++ { - date = time.Date(year, time.Month(m), day, 0, 0, 0, 0, time.UTC) - failures, _ := service.TotalFailuresOnDate(date) - output = append(output, &dataXy{day, int(failures)}) - } - - thisDate := fmt.Sprintf("%v-%v-01 00:00:00", year, m) - monthOutput = append(monthOutput, &dataXyMonth{thisDate, output}) - } - - month = 1 - - } - returnJson(monthOutput, w, r) -} - func apiServiceDeleteHandler(w http.ResponseWriter, r *http.Request) { vars := mux.Vars(r) service := core.SelectService(utils.ToInt(vars["id"])) @@ -253,7 +177,7 @@ func apiServiceDeleteHandler(w http.ResponseWriter, r *http.Request) { sendErrorJson(errors.New("service not found"), w, r) return } - err := service.Delete() + err := database.Delete(service) if err != nil { sendErrorJson(err, w, r) return @@ -266,23 +190,27 @@ func apiAllServicesHandler(r *http.Request) interface{} { return joinServices(services) } -func joinServices(srvs []types.ServiceInterface) []*types.Service { +func joinServices(srvs []database.Servicer) []*types.Service { var services []*types.Service for _, v := range srvs { - services = append(services, v.Select()) + services = append(services, v.Model()) } return services } func servicesDeleteFailuresHandler(w http.ResponseWriter, r *http.Request) { vars := mux.Vars(r) - service := core.SelectService(utils.ToInt(vars["id"])) - if service == nil { + srv, err := database.Service(utils.ToInt(vars["id"])) + if err != nil { sendErrorJson(errors.New("service not found"), w, r) return } - service.DeleteFailures() - sendJsonAction(service, "delete_failures", w, r) + err = srv.Failures().DeleteAll() + if err != nil { + sendErrorJson(err, w, r) + return + } + sendJsonAction(srv.Model(), "delete_failures", w, r) } func apiServiceFailuresHandler(r *http.Request) interface{} { diff --git a/handlers/setup.go b/handlers/setup.go index 362f1138..a2b05800 100644 --- a/handlers/setup.go +++ b/handlers/setup.go @@ -18,6 +18,7 @@ package handlers import ( "errors" "github.com/hunterlong/statping/core" + "github.com/hunterlong/statping/database" "github.com/hunterlong/statping/types" "github.com/hunterlong/statping/utils" "net/http" @@ -106,13 +107,13 @@ func processSetupHandler(w http.ResponseWriter, r *http.Request) { return } - admin := core.ReturnUser(&types.User{ + admin := &types.User{ Username: config.Username, Password: config.Password, Email: config.Email, Admin: types.NewNullBool(true), - }) - admin.Create() + } + database.Create(admin) if sample { if err = core.SampleData(); err != nil { diff --git a/handlers/users.go b/handlers/users.go index 8666b468..95fae9d9 100644 --- a/handlers/users.go +++ b/handlers/users.go @@ -21,6 +21,7 @@ import ( "fmt" "github.com/gorilla/mux" "github.com/hunterlong/statping/core" + "github.com/hunterlong/statping/database" "github.com/hunterlong/statping/types" "github.com/hunterlong/statping/utils" "net/http" @@ -107,11 +108,10 @@ func apiCreateUsersHandler(w http.ResponseWriter, r *http.Request) { sendErrorJson(err, w, r) return } - newUser := core.ReturnUser(user) - _, err = newUser.Create() + _, err = database.Create(user) if err != nil { sendErrorJson(err, w, r) return } - sendJsonAction(newUser, "create", w, r) + sendJsonAction(user, "create", w, r) }