pull/78/head
Hunter Long 2018-10-06 22:04:06 -07:00
parent 9061a97955
commit 2f3c9a2884
10 changed files with 97 additions and 94 deletions

View File

@ -31,9 +31,10 @@ var (
// VERSION stores the current version of Statup // VERSION stores the current version of Statup
VERSION string VERSION string
// COMMIT stores the git commit hash for this version of Statup // COMMIT stores the git commit hash for this version of Statup
COMMIT string COMMIT string
ipAddress string ipAddress string
port int UsingDotEnv bool
port int
) )
func init() { func init() {
@ -87,7 +88,7 @@ func LoadDotEnvs() error {
err := godotenv.Load() err := godotenv.Load()
if err == nil { if err == nil {
utils.Log(1, "Environment file '.env' Loaded") utils.Log(1, "Environment file '.env' Loaded")
usingEnv = true UsingDotEnv = true
} }
return err return err
} }

View File

@ -37,13 +37,13 @@ func (c *checkin) String() string {
} }
// ReturnCheckin converts *types.Checking to *core.checkin // ReturnCheckin converts *types.Checking to *core.checkin
func ReturnCheckin(s *types.Checkin) *checkin { func ReturnCheckin(c *types.Checkin) *checkin {
return &checkin{Checkin: s} return &checkin{Checkin: c}
} }
// ReturnCheckinHit converts *types.checkinHit to *core.checkinHit // ReturnCheckinHit converts *types.checkinHit to *core.checkinHit
func ReturnCheckinHit(h *types.CheckinHit) *checkinHit { func ReturnCheckinHit(c *types.CheckinHit) *checkinHit {
return &checkinHit{CheckinHit: h} return &checkinHit{CheckinHit: c}
} }
// SelectCheckin will find a checkin based on the API supplied // SelectCheckin will find a checkin based on the API supplied
@ -100,31 +100,31 @@ func (c *checkin) Create() (int64, error) {
} }
// Update will update a checkin // Update will update a checkin
func (u *checkin) Update() (int64, error) { func (c *checkin) Update() (int64, error) {
row := checkinDB().Update(&u) row := checkinDB().Update(&c)
if row.Error != nil { if row.Error != nil {
utils.Log(2, row.Error) utils.Log(2, row.Error)
return 0, row.Error return 0, row.Error
} }
return u.Id, row.Error return c.Id, row.Error
} }
// Create will create a new successful checkinHit // Create will create a new successful checkinHit
func (u *checkinHit) Create() (int64, error) { func (c *checkinHit) Create() (int64, error) {
if u.CreatedAt.IsZero() { if c.CreatedAt.IsZero() {
u.CreatedAt = time.Now() c.CreatedAt = time.Now()
} }
row := checkinHitsDB().Create(u) row := checkinHitsDB().Create(c)
if row.Error != nil { if row.Error != nil {
utils.Log(2, row.Error) utils.Log(2, row.Error)
return 0, row.Error return 0, row.Error
} }
return u.Id, row.Error return c.Id, row.Error
} }
// Ago returns the duration of time between now and the last successful checkinHit // Ago returns the duration of time between now and the last successful checkinHit
func (f *checkinHit) Ago() string { func (c *checkinHit) Ago() string {
got, _ := timeago.TimeAgoWithTime(time.Now(), f.CreatedAt) got, _ := timeago.TimeAgoWithTime(time.Now(), c.CreatedAt)
return got return got
} }

View File

@ -31,9 +31,11 @@ import (
) )
var ( var (
// DbSession stores the Statup database session
DbSession *gorm.DB DbSession *gorm.DB
) )
// DbConfig stores the config.yml file for the statup configuration
type DbConfig types.DbConfig type DbConfig types.DbConfig
// failuresDB returns the 'failures' database column // failuresDB returns the 'failures' database column
@ -96,8 +98,8 @@ func (s *Service) AfterFind() (err error) {
} }
// AfterFind for Hit will set the timezone // AfterFind for Hit will set the timezone
func (s *Hit) AfterFind() (err error) { func (h *Hit) AfterFind() (err error) {
s.CreatedAt = utils.Timezoner(s.CreatedAt, CoreApp.Timezone) h.CreatedAt = utils.Timezoner(h.CreatedAt, CoreApp.Timezone)
return return
} }
@ -114,29 +116,29 @@ func (u *user) AfterFind() (err error) {
} }
// AfterFind for checkin will set the timezone // AfterFind for checkin will set the timezone
func (s *checkin) AfterFind() (err error) { func (c *checkin) AfterFind() (err error) {
s.CreatedAt = utils.Timezoner(s.CreatedAt, CoreApp.Timezone) c.CreatedAt = utils.Timezoner(c.CreatedAt, CoreApp.Timezone)
return return
} }
// AfterFind for checkinHit will set the timezone // AfterFind for checkinHit will set the timezone
func (s *checkinHit) AfterFind() (err error) { func (c *checkinHit) AfterFind() (err error) {
s.CreatedAt = utils.Timezoner(s.CreatedAt, CoreApp.Timezone) c.CreatedAt = utils.Timezoner(c.CreatedAt, CoreApp.Timezone)
return return
} }
// BeforeCreate for Hit will set CreatedAt to UTC // BeforeCreate for Hit will set CreatedAt to UTC
func (u *Hit) BeforeCreate() (err error) { func (h *Hit) BeforeCreate() (err error) {
if u.CreatedAt.IsZero() { if h.CreatedAt.IsZero() {
u.CreatedAt = time.Now().UTC() h.CreatedAt = time.Now().UTC()
} }
return return
} }
// BeforeCreate for failure will set CreatedAt to UTC // BeforeCreate for failure will set CreatedAt to UTC
func (u *failure) BeforeCreate() (err error) { func (f *failure) BeforeCreate() (err error) {
if u.CreatedAt.IsZero() { if f.CreatedAt.IsZero() {
u.CreatedAt = time.Now().UTC() f.CreatedAt = time.Now().UTC()
} }
return return
} }
@ -150,25 +152,25 @@ func (u *user) BeforeCreate() (err error) {
} }
// BeforeCreate for Service will set CreatedAt to UTC // BeforeCreate for Service will set CreatedAt to UTC
func (u *Service) BeforeCreate() (err error) { func (s *Service) BeforeCreate() (err error) {
if u.CreatedAt.IsZero() { if s.CreatedAt.IsZero() {
u.CreatedAt = time.Now().UTC() s.CreatedAt = time.Now().UTC()
} }
return return
} }
// BeforeCreate for checkin will set CreatedAt to UTC // BeforeCreate for checkin will set CreatedAt to UTC
func (u *checkin) BeforeCreate() (err error) { func (c *checkin) BeforeCreate() (err error) {
if u.CreatedAt.IsZero() { if c.CreatedAt.IsZero() {
u.CreatedAt = time.Now().UTC() c.CreatedAt = time.Now().UTC()
} }
return return
} }
// BeforeCreate for checkinHit will set CreatedAt to UTC // BeforeCreate for checkinHit will set CreatedAt to UTC
func (u *checkinHit) BeforeCreate() (err error) { func (c *checkinHit) BeforeCreate() (err error) {
if u.CreatedAt.IsZero() { if c.CreatedAt.IsZero() {
u.CreatedAt = time.Now().UTC() c.CreatedAt = time.Now().UTC()
} }
return return
} }
@ -263,14 +265,14 @@ func DeleteAllSince(table string, date time.Time) {
} }
// Update will save the config.yml file // Update will save the config.yml file
func (c *DbConfig) Update() error { func (db *DbConfig) Update() error {
var err error var err error
config, err := os.Create(utils.Directory + "/config.yml") config, err := os.Create(utils.Directory + "/config.yml")
if err != nil { if err != nil {
utils.Log(4, err) utils.Log(4, err)
return err return err
} }
data, err := yaml.Marshal(c) data, err := yaml.Marshal(db)
if err != nil { if err != nil {
utils.Log(3, err) utils.Log(3, err)
return err return err
@ -281,23 +283,23 @@ func (c *DbConfig) Update() error {
} }
// Save will initially create the config.yml file // Save will initially create the config.yml file
func (c *DbConfig) Save() (*DbConfig, error) { func (db *DbConfig) Save() (*DbConfig, error) {
var err error var err error
config, err := os.Create(utils.Directory + "/config.yml") config, err := os.Create(utils.Directory + "/config.yml")
if err != nil { if err != nil {
utils.Log(4, err) utils.Log(4, err)
return nil, err return nil, err
} }
c.ApiKey = utils.NewSHA1Hash(16) db.ApiKey = utils.NewSHA1Hash(16)
c.ApiSecret = utils.NewSHA1Hash(16) db.ApiSecret = utils.NewSHA1Hash(16)
data, err := yaml.Marshal(c) data, err := yaml.Marshal(db)
if err != nil { if err != nil {
utils.Log(3, err) utils.Log(3, err)
return nil, err return nil, err
} }
config.WriteString(string(data)) config.WriteString(string(data))
defer config.Close() defer config.Close()
return c, err return db, err
} }
// CreateCore will initialize the global variable 'CoreApp". This global variable contains most of Statup app. // CreateCore will initialize the global variable 'CoreApp". This global variable contains most of Statup app.

View File

@ -16,7 +16,6 @@
package notifier package notifier
import ( import (
"errors"
"fmt" "fmt"
"strings" "strings"
) )
@ -30,7 +29,7 @@ func checkNotifierForm(n Notifier) error {
for _, f := range notifier.Form { for _, f := range notifier.Form {
contains := contains(f.DbField, allowedVars) contains := contains(f.DbField, allowedVars)
if !contains { if !contains {
return errors.New(fmt.Sprintf("the DbField '%v' is not allowed, allowed vars: %v", f.DbField, allowedVars)) return fmt.Errorf("the DbField '%v' is not allowed, allowed vars: %v", f.DbField, allowedVars)
} }
} }
return nil return nil

View File

@ -1,4 +1,4 @@
// Package Notifier contains the main functionality for the Statup Notification system // Package notifier contains the main functionality for the Statup Notification system
// //
// More info on: https://github.com/hunterlong/statup/wiki/Notifiers // More info on: https://github.com/hunterlong/statup/wiki/Notifiers
package notifier package notifier

View File

@ -318,59 +318,59 @@ func updateService(service *Service) {
} }
// Delete will remove a service from the database, it will also end the service checking go routine // Delete will remove a service from the database, it will also end the service checking go routine
func (u *Service) Delete() error { func (s *Service) Delete() error {
i := u.index() i := s.index()
err := servicesDB().Delete(u) err := servicesDB().Delete(s)
if err.Error != nil { if err.Error != nil {
utils.Log(3, fmt.Sprintf("Failed to delete service %v. %v", u.Name, err.Error)) utils.Log(3, fmt.Sprintf("Failed to delete service %v. %v", s.Name, err.Error))
return err.Error return err.Error
} }
u.Close() s.Close()
slice := CoreApp.Services slice := CoreApp.Services
CoreApp.Services = append(slice[:i], slice[i+1:]...) CoreApp.Services = append(slice[:i], slice[i+1:]...)
reorderServices() reorderServices()
notifier.OnDeletedService(u.Service) notifier.OnDeletedService(s.Service)
return err.Error return err.Error
} }
// UpdateSingle will update a single column for a service // UpdateSingle will update a single column for a service
func (u *Service) UpdateSingle(attr ...interface{}) error { func (s *Service) UpdateSingle(attr ...interface{}) error {
return servicesDB().Model(u).Update(attr).Error return servicesDB().Model(s).Update(attr).Error
} }
// Update will update a service in the database, the service's checking routine can be restarted by passing true // Update will update a service in the database, the service's checking routine can be restarted by passing true
func (u *Service) Update(restart bool) error { func (s *Service) Update(restart bool) error {
err := servicesDB().Update(u) err := servicesDB().Update(s)
if err.Error != nil { if err.Error != nil {
utils.Log(3, fmt.Sprintf("Failed to update service %v. %v", u.Name, err)) utils.Log(3, fmt.Sprintf("Failed to update service %v. %v", s.Name, err))
return err.Error return err.Error
} }
if restart { if restart {
u.Close() s.Close()
u.Start() s.Start()
u.SleepDuration = time.Duration(u.Interval) * time.Second s.SleepDuration = time.Duration(s.Interval) * time.Second
go u.CheckQueue(true) go s.CheckQueue(true)
} }
reorderServices() reorderServices()
updateService(u) updateService(s)
notifier.OnUpdatedService(u.Service) notifier.OnUpdatedService(s.Service)
return err.Error return err.Error
} }
// Create will create a service and insert it into the database // Create will create a service and insert it into the database
func (u *Service) Create(check bool) (int64, error) { func (s *Service) Create(check bool) (int64, error) {
u.CreatedAt = time.Now() s.CreatedAt = time.Now()
db := servicesDB().Create(u) db := servicesDB().Create(s)
if db.Error != nil { if db.Error != nil {
utils.Log(3, fmt.Sprintf("Failed to create service %v #%v: %v", u.Name, u.Id, db.Error)) utils.Log(3, fmt.Sprintf("Failed to create service %v #%v: %v", s.Name, s.Id, db.Error))
return 0, db.Error return 0, db.Error
} }
u.Start() s.Start()
go u.CheckQueue(check) go s.CheckQueue(check)
CoreApp.Services = append(CoreApp.Services, u) CoreApp.Services = append(CoreApp.Services, s)
reorderServices() reorderServices()
notifier.OnNewService(u.Service) notifier.OnNewService(s.Service)
return u.Id, nil return s.Id, nil
} }
// ServicesCount returns the amount of services inside the []*core.Services slice // ServicesCount returns the amount of services inside the []*core.Services slice

View File

@ -19,6 +19,7 @@ import (
"time" "time"
) )
// Checkin struct will allow an application to send a recurring HTTP GET to confirm a service is online
type Checkin struct { type Checkin struct {
Id int64 `gorm:"primary_key;column:id"` Id int64 `gorm:"primary_key;column:id"`
Service int64 `gorm:"index;column:service"` Service int64 `gorm:"index;column:service"`
@ -29,6 +30,7 @@ type Checkin struct {
UpdatedAt time.Time `gorm:"column:updated_at" json:"updated_at"` UpdatedAt time.Time `gorm:"column:updated_at" json:"updated_at"`
} }
// CheckinHit is a successful response from a Checkin
type CheckinHit struct { type CheckinHit struct {
Id int64 `gorm:"primary_key;column:id"` Id int64 `gorm:"primary_key;column:id"`
Checkin int64 `gorm:"index;column:checkin"` Checkin int64 `gorm:"index;column:checkin"`

View File

@ -19,6 +19,7 @@ import (
"time" "time"
) )
// AllNotifiers contains all the Notifiers loaded
type AllNotifiers interface{} type AllNotifiers interface{}
// Core struct contains all the required fields for Statup. All application settings // Core struct contains all the required fields for Statup. All application settings
@ -46,12 +47,11 @@ type Core struct {
Repos []PluginJSON `gorm:"-" json:"-"` Repos []PluginJSON `gorm:"-" json:"-"`
AllPlugins []PluginActions `gorm:"-" json:"-"` AllPlugins []PluginActions `gorm:"-" json:"-"`
Notifications []AllNotifiers `gorm:"-" json:"-"` Notifications []AllNotifiers `gorm:"-" json:"-"`
CoreInterface `gorm:"-" json:"-"`
} }
type CoreInterface interface { //type CoreInterface interface {
SelectAllServices() ([]*Service, error) // SelectAllServices() ([]*Service, error)
Count24HFailures() uint64 // Count24HFailures() uint64
ServicesCount() int // ServicesCount() int
CountOnline() int // CountOnline() int
} //}

View File

@ -20,18 +20,17 @@ import (
) )
const ( const (
TIME_NANOZ = "2006-01-02 15:04:05.999999-0700 MST" TIME_NANO = "2006-01-02T15:04:05Z"
TIME_NANO = "2006-01-02T15:04:05Z" TIME = "2006-01-02 15:04:05"
TIME = "2006-01-02 15:04:05" TIME_DAY = "2006-01-02"
TIME_DAY = "2006-01-02"
) )
var ( var (
NOW = func() time.Time { return time.Now() }() NOW = func() time.Time { return time.Now() }()
HOUR_1_AGO = time.Now().Add(-1 * time.Hour) //HOUR_1_AGO = time.Now().Add(-1 * time.Hour)
HOUR_24_AGO = time.Now().Add(-24 * time.Hour) //HOUR_24_AGO = time.Now().Add(-24 * time.Hour)
HOUR_72_AGO = time.Now().Add(-72 * time.Hour) //HOUR_72_AGO = time.Now().Add(-72 * time.Hour)
DAY_7_AGO = NOW.AddDate(0, 0, -7) //DAY_7_AGO = NOW.AddDate(0, 0, -7)
MONTH_1_AGO = NOW.AddDate(0, -1, 0) //MONTH_1_AGO = NOW.AddDate(0, -1, 0)
YEAR_1_AGO = NOW.AddDate(-1, 0, 0) //YEAR_1_AGO = NOW.AddDate(-1, 0, 0)
) )

View File

@ -70,8 +70,8 @@ func FormatDuration(d time.Duration) string {
if rev(d.Seconds()) >= 2 { if rev(d.Seconds()) >= 2 {
out += "s" out += "s"
} }
return out
} }
return out
} }
func rev(f float64) float64 { func rev(f float64) float64 {