mirror of https://github.com/statping/statping
integrations
parent
0b93ad4b7a
commit
56353bfa6d
|
@ -257,7 +257,7 @@ func recordSuccess(s *Service) {
|
||||||
Service: s.Id,
|
Service: s.Id,
|
||||||
Latency: s.Latency,
|
Latency: s.Latency,
|
||||||
PingTime: s.PingTime,
|
PingTime: s.PingTime,
|
||||||
CreatedAt: time.Now(),
|
CreatedAt: time.Now().UTC(),
|
||||||
}
|
}
|
||||||
s.CreateHit(hit)
|
s.CreateHit(hit)
|
||||||
log.WithFields(utils.ToFields(hit, s.Select())).Infoln(fmt.Sprintf("Service %v Successful Response: %0.2f ms | Lookup in: %0.2f ms", s.Name, hit.Latency*1000, hit.PingTime*1000))
|
log.WithFields(utils.ToFields(hit, s.Select())).Infoln(fmt.Sprintf("Service %v Successful Response: %0.2f ms | Lookup in: %0.2f ms", s.Name, hit.Latency*1000, hit.PingTime*1000))
|
||||||
|
@ -272,7 +272,7 @@ func recordFailure(s *Service, issue string) {
|
||||||
Service: s.Id,
|
Service: s.Id,
|
||||||
Issue: issue,
|
Issue: issue,
|
||||||
PingTime: s.PingTime,
|
PingTime: s.PingTime,
|
||||||
CreatedAt: time.Now(),
|
CreatedAt: time.Now().UTC(),
|
||||||
ErrorCode: s.LastStatusCode,
|
ErrorCode: s.LastStatusCode,
|
||||||
}
|
}
|
||||||
log.WithFields(utils.ToFields(fail, s.Select())).
|
log.WithFields(utils.ToFields(fail, s.Select())).
|
||||||
|
|
|
@ -104,8 +104,8 @@ func LoadUsingEnv() (*types.DbConfig, error) {
|
||||||
return Configs, nil
|
return Configs, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// DefaultPort accepts a database type and returns its default port
|
// defaultPort accepts a database type and returns its default port
|
||||||
func DefaultPort(db string) int64 {
|
func defaultPort(db string) int64 {
|
||||||
switch db {
|
switch db {
|
||||||
case "mysql":
|
case "mysql":
|
||||||
return 3306
|
return 3306
|
||||||
|
@ -140,7 +140,7 @@ func EnvToConfig() (*types.DbConfig, error) {
|
||||||
}
|
}
|
||||||
port := utils.ToInt(os.Getenv("DB_PORT"))
|
port := utils.ToInt(os.Getenv("DB_PORT"))
|
||||||
if port == 0 {
|
if port == 0 {
|
||||||
port = DefaultPort(os.Getenv("DB_PORT"))
|
port = defaultPort(os.Getenv("DB_PORT"))
|
||||||
}
|
}
|
||||||
name := os.Getenv("NAME")
|
name := os.Getenv("NAME")
|
||||||
if name == "" {
|
if name == "" {
|
||||||
|
@ -185,9 +185,11 @@ func EnvToConfig() (*types.DbConfig, error) {
|
||||||
// SampleData runs all the sample data for a new Statping installation
|
// SampleData runs all the sample data for a new Statping installation
|
||||||
func SampleData() error {
|
func SampleData() error {
|
||||||
if err := InsertSampleData(); err != nil {
|
if err := InsertSampleData(); err != nil {
|
||||||
|
log.Errorln(err)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if err := InsertSampleHits(); err != nil {
|
if err := InsertSampleHits(); err != nil {
|
||||||
|
log.Errorln(err)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
|
|
|
@ -50,7 +50,7 @@ func init() {
|
||||||
// NewCore return a new *core.Core struct
|
// NewCore return a new *core.Core struct
|
||||||
func NewCore() *Core {
|
func NewCore() *Core {
|
||||||
CoreApp = &Core{&types.Core{
|
CoreApp = &Core{&types.Core{
|
||||||
Started: time.Now(),
|
Started: time.Now().UTC(),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
return CoreApp
|
return CoreApp
|
||||||
|
|
115
core/database.go
115
core/database.go
|
@ -38,6 +38,10 @@ var (
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
DbModels = []interface{}{&types.Service{}, &types.User{}, &types.Hit{}, &types.Failure{}, &types.Message{}, &types.Group{}, &types.Checkin{}, &types.CheckinHit{}, ¬ifier.Notification{}, &types.Incident{}, &types.IncidentUpdate{}}
|
DbModels = []interface{}{&types.Service{}, &types.User{}, &types.Hit{}, &types.Failure{}, &types.Message{}, &types.Group{}, &types.Checkin{}, &types.CheckinHit{}, ¬ifier.Notification{}, &types.Incident{}, &types.IncidentUpdate{}}
|
||||||
|
|
||||||
|
gorm.NowFunc = func() time.Time {
|
||||||
|
return time.Now().UTC()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// DbConfig stores the config.yml file for the statup configuration
|
// DbConfig stores the config.yml file for the statup configuration
|
||||||
|
@ -115,60 +119,60 @@ func CloseDB() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// AfterFind for Core will set the timezone
|
//// AfterFind for Core will set the timezone
|
||||||
func (c *Core) AfterFind() (err error) {
|
//func (c *Core) AfterFind() (err error) {
|
||||||
c.CreatedAt = utils.Timezoner(c.CreatedAt, CoreApp.Timezone)
|
// c.CreatedAt = utils.Timezoner(c.CreatedAt, CoreApp.Timezone)
|
||||||
c.UpdatedAt = utils.Timezoner(c.UpdatedAt, CoreApp.Timezone)
|
// c.UpdatedAt = utils.Timezoner(c.UpdatedAt, CoreApp.Timezone)
|
||||||
return
|
// return
|
||||||
}
|
//}
|
||||||
|
//
|
||||||
// AfterFind for Service will set the timezone
|
//// AfterFind for Service will set the timezone
|
||||||
func (s *Service) AfterFind() (err error) {
|
//func (s *Service) AfterFind() (err error) {
|
||||||
s.CreatedAt = utils.Timezoner(s.CreatedAt, CoreApp.Timezone)
|
// s.CreatedAt = utils.Timezoner(s.CreatedAt, CoreApp.Timezone)
|
||||||
s.UpdatedAt = utils.Timezoner(s.UpdatedAt, CoreApp.Timezone)
|
// s.UpdatedAt = utils.Timezoner(s.UpdatedAt, CoreApp.Timezone)
|
||||||
return
|
// return
|
||||||
}
|
//}
|
||||||
|
//
|
||||||
// AfterFind for Hit will set the timezone
|
//// AfterFind for Hit will set the timezone
|
||||||
func (h *Hit) AfterFind() (err error) {
|
//func (h *Hit) AfterFind() (err error) {
|
||||||
h.CreatedAt = utils.Timezoner(h.CreatedAt, CoreApp.Timezone)
|
// h.CreatedAt = utils.Timezoner(h.CreatedAt, CoreApp.Timezone)
|
||||||
return
|
// return
|
||||||
}
|
//}
|
||||||
|
//
|
||||||
// AfterFind for Failure will set the timezone
|
//// AfterFind for Failure will set the timezone
|
||||||
func (f *Failure) AfterFind() (err error) {
|
//func (f *Failure) AfterFind() (err error) {
|
||||||
f.CreatedAt = utils.Timezoner(f.CreatedAt, CoreApp.Timezone)
|
// f.CreatedAt = utils.Timezoner(f.CreatedAt, CoreApp.Timezone)
|
||||||
return
|
// return
|
||||||
}
|
//}
|
||||||
|
//
|
||||||
// AfterFind for USer will set the timezone
|
//// AfterFind for USer will set the timezone
|
||||||
func (u *User) AfterFind() (err error) {
|
//func (u *User) AfterFind() (err error) {
|
||||||
u.CreatedAt = utils.Timezoner(u.CreatedAt, CoreApp.Timezone)
|
// u.CreatedAt = utils.Timezoner(u.CreatedAt, CoreApp.Timezone)
|
||||||
u.UpdatedAt = utils.Timezoner(u.UpdatedAt, CoreApp.Timezone)
|
// u.UpdatedAt = utils.Timezoner(u.UpdatedAt, CoreApp.Timezone)
|
||||||
return
|
// return
|
||||||
}
|
//}
|
||||||
|
//
|
||||||
// AfterFind for Checkin will set the timezone
|
//// AfterFind for Checkin will set the timezone
|
||||||
func (c *Checkin) AfterFind() (err error) {
|
//func (c *Checkin) AfterFind() (err error) {
|
||||||
c.CreatedAt = utils.Timezoner(c.CreatedAt, CoreApp.Timezone)
|
// c.CreatedAt = utils.Timezoner(c.CreatedAt, CoreApp.Timezone)
|
||||||
c.UpdatedAt = utils.Timezoner(c.UpdatedAt, CoreApp.Timezone)
|
// c.UpdatedAt = utils.Timezoner(c.UpdatedAt, CoreApp.Timezone)
|
||||||
return
|
// return
|
||||||
}
|
//}
|
||||||
|
//
|
||||||
// AfterFind for checkinHit will set the timezone
|
//// AfterFind for checkinHit will set the timezone
|
||||||
func (c *CheckinHit) AfterFind() (err error) {
|
//func (c *CheckinHit) AfterFind() (err error) {
|
||||||
c.CreatedAt = utils.Timezoner(c.CreatedAt, CoreApp.Timezone)
|
// c.CreatedAt = utils.Timezoner(c.CreatedAt, CoreApp.Timezone)
|
||||||
return
|
// return
|
||||||
}
|
//}
|
||||||
|
//
|
||||||
// AfterFind for Message will set the timezone
|
//// AfterFind for Message will set the timezone
|
||||||
func (u *Message) AfterFind() (err error) {
|
//func (u *Message) AfterFind() (err error) {
|
||||||
u.CreatedAt = utils.Timezoner(u.CreatedAt, CoreApp.Timezone)
|
// u.CreatedAt = utils.Timezoner(u.CreatedAt, CoreApp.Timezone)
|
||||||
u.UpdatedAt = utils.Timezoner(u.UpdatedAt, CoreApp.Timezone)
|
// u.UpdatedAt = utils.Timezoner(u.UpdatedAt, CoreApp.Timezone)
|
||||||
u.StartOn = utils.Timezoner(u.StartOn.UTC(), CoreApp.Timezone)
|
// u.StartOn = utils.Timezoner(u.StartOn.UTC(), CoreApp.Timezone)
|
||||||
u.EndOn = utils.Timezoner(u.EndOn.UTC(), CoreApp.Timezone)
|
// u.EndOn = utils.Timezoner(u.EndOn.UTC(), CoreApp.Timezone)
|
||||||
return
|
// return
|
||||||
}
|
//}
|
||||||
|
|
||||||
// InsertCore create the single row for the Core settings in Statping
|
// InsertCore create the single row for the Core settings in Statping
|
||||||
func (c *Core) InsertCore(db *types.DbConfig) (*Core, error) {
|
func (c *Core) InsertCore(db *types.DbConfig) (*Core, error) {
|
||||||
|
@ -216,7 +220,7 @@ func (c *Core) Connect(retry bool, location string) error {
|
||||||
var err error
|
var err error
|
||||||
dbType = CoreApp.Config.DbConn
|
dbType = CoreApp.Config.DbConn
|
||||||
if CoreApp.Config.DbPort == 0 {
|
if CoreApp.Config.DbPort == 0 {
|
||||||
CoreApp.Config.DbPort = DefaultPort(dbType)
|
CoreApp.Config.DbPort = defaultPort(dbType)
|
||||||
}
|
}
|
||||||
switch dbType {
|
switch dbType {
|
||||||
case "sqlite":
|
case "sqlite":
|
||||||
|
@ -395,6 +399,7 @@ func (c *Core) MigrateDatabase() error {
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
if tx.Error != nil {
|
if tx.Error != nil {
|
||||||
|
log.Errorln(tx.Error)
|
||||||
return tx.Error
|
return tx.Error
|
||||||
}
|
}
|
||||||
for _, table := range DbModels {
|
for _, table := range DbModels {
|
||||||
|
|
|
@ -86,7 +86,7 @@ func (s *Service) LimitedCheckinFailures(amount int64) []*Failure {
|
||||||
|
|
||||||
// Ago returns a human readable timestamp for a Failure
|
// Ago returns a human readable timestamp for a Failure
|
||||||
func (f *Failure) Ago() string {
|
func (f *Failure) Ago() string {
|
||||||
got, _ := timeago.TimeAgoWithTime(time.Now(), f.CreatedAt)
|
got, _ := timeago.TimeAgoWithTime(time.Now().UTC(), f.CreatedAt)
|
||||||
return got
|
return got
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -135,7 +135,7 @@ func (s *Service) TotalFailuresOnDate(ago time.Time) (uint64, error) {
|
||||||
|
|
||||||
// TotalFailures24 returns the amount of failures for a service within the last 24 hours
|
// TotalFailures24 returns the amount of failures for a service within the last 24 hours
|
||||||
func (s *Service) TotalFailures24() (uint64, error) {
|
func (s *Service) TotalFailures24() (uint64, error) {
|
||||||
ago := time.Now().Add(-24 * time.Hour)
|
ago := time.Now().UTC().Add(-24 * time.Hour)
|
||||||
return s.TotalFailuresSince(ago)
|
return s.TotalFailuresSince(ago)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -149,7 +149,7 @@ func (s *Service) TotalFailures() (uint64, error) {
|
||||||
|
|
||||||
// FailuresDaysAgo returns the amount of failures since days ago
|
// FailuresDaysAgo returns the amount of failures since days ago
|
||||||
func (s *Service) FailuresDaysAgo(days int) uint64 {
|
func (s *Service) FailuresDaysAgo(days int) uint64 {
|
||||||
ago := time.Now().Add((-24 * time.Duration(days)) * time.Hour)
|
ago := time.Now().UTC().Add((-24 * time.Duration(days)) * time.Hour)
|
||||||
count, _ := s.TotalFailuresSince(ago)
|
count, _ := s.TotalFailuresSince(ago)
|
||||||
return count
|
return count
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,14 +22,14 @@ func (g *Group) Delete() error {
|
||||||
|
|
||||||
// Create will create a group and insert it into the database
|
// Create will create a group and insert it into the database
|
||||||
func (g *Group) Create() (int64, error) {
|
func (g *Group) Create() (int64, error) {
|
||||||
g.CreatedAt = time.Now()
|
g.CreatedAt = time.Now().UTC()
|
||||||
db := groupsDb().Create(g)
|
db := groupsDb().Create(g)
|
||||||
return g.Id, db.Error
|
return g.Id, db.Error
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update will update a group
|
// Update will update a group
|
||||||
func (g *Group) Update() (int64, error) {
|
func (g *Group) Update() (int64, error) {
|
||||||
g.UpdatedAt = time.Now()
|
g.UpdatedAt = time.Now().UTC()
|
||||||
db := groupsDb().Update(g)
|
db := groupsDb().Update(g)
|
||||||
return g.Id, db.Error
|
return g.Id, db.Error
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,7 +28,7 @@ type Hit struct {
|
||||||
func (s *Service) CreateHit(h *types.Hit) (int64, error) {
|
func (s *Service) CreateHit(h *types.Hit) (int64, error) {
|
||||||
db := hitsDB().Create(&h)
|
db := hitsDB().Create(&h)
|
||||||
if db.Error != nil {
|
if db.Error != nil {
|
||||||
log.Warnln(db.Error)
|
log.Errorln(db.Error)
|
||||||
return 0, db.Error
|
return 0, db.Error
|
||||||
}
|
}
|
||||||
return h.Id, db.Error
|
return h.Id, db.Error
|
||||||
|
|
|
@ -47,14 +47,14 @@ func (i *Incident) Delete() error {
|
||||||
|
|
||||||
// Create will create a incident and insert it into the database
|
// Create will create a incident and insert it into the database
|
||||||
func (i *Incident) Create() (int64, error) {
|
func (i *Incident) Create() (int64, error) {
|
||||||
i.CreatedAt = time.Now()
|
i.CreatedAt = time.Now().UTC()
|
||||||
db := incidentsDB().Create(i)
|
db := incidentsDB().Create(i)
|
||||||
return i.Id, db.Error
|
return i.Id, db.Error
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update will update a incident
|
// Update will update a incident
|
||||||
func (i *Incident) Update() (int64, error) {
|
func (i *Incident) Update() (int64, error) {
|
||||||
i.UpdatedAt = time.Now()
|
i.UpdatedAt = time.Now().UTC()
|
||||||
db := incidentsDB().Update(i)
|
db := incidentsDB().Update(i)
|
||||||
return i.Id, db.Error
|
return i.Id, db.Error
|
||||||
}
|
}
|
||||||
|
@ -67,7 +67,7 @@ func (i *IncidentUpdate) Delete() error {
|
||||||
|
|
||||||
// Create will create a incident update and insert it into the database
|
// Create will create a incident update and insert it into the database
|
||||||
func (i *IncidentUpdate) Create() (int64, error) {
|
func (i *IncidentUpdate) Create() (int64, error) {
|
||||||
i.CreatedAt = time.Now()
|
i.CreatedAt = time.Now().UTC()
|
||||||
db := incidentsUpdatesDB().Create(i)
|
db := incidentsUpdatesDB().Create(i)
|
||||||
return i.Id, db.Error
|
return i.Id, db.Error
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,12 +16,13 @@
|
||||||
package integrations
|
package integrations
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bytes"
|
||||||
|
"encoding/csv"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/hunterlong/statping/types"
|
"github.com/hunterlong/statping/types"
|
||||||
"github.com/hunterlong/statping/utils"
|
"github.com/hunterlong/statping/utils"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -35,7 +36,7 @@ var csvIntegrator = &csvIntegration{&types.Integration{
|
||||||
ShortName: "csv",
|
ShortName: "csv",
|
||||||
Name: "CSV File",
|
Name: "CSV File",
|
||||||
Icon: "<i class=\"fas fa-file-csv\"></i>",
|
Icon: "<i class=\"fas fa-file-csv\"></i>",
|
||||||
Description: "Import multiple services from a CSV file",
|
Description: "Import multiple services from a CSV file. Please have your CSV file formatted with the correct amount of columns based on the <a href=\"https://raw.githubusercontent.com/hunterlong/statping/master/source/tmpl/bulk_import.csv\">example file on Github</a>.",
|
||||||
Fields: []*types.IntegrationField{
|
Fields: []*types.IntegrationField{
|
||||||
{
|
{
|
||||||
Name: "input",
|
Name: "input",
|
||||||
|
@ -53,16 +54,19 @@ func (t *csvIntegration) Get() *types.Integration {
|
||||||
|
|
||||||
func (t *csvIntegration) List() ([]*types.Service, error) {
|
func (t *csvIntegration) List() ([]*types.Service, error) {
|
||||||
data := Value(t, "input").(string)
|
data := Value(t, "input").(string)
|
||||||
for _, line := range strings.Split(strings.TrimSuffix(data, "\n"), "\n") {
|
buf := bytes.NewReader([]byte(data))
|
||||||
col := strings.Split(line, ",")
|
r := csv.NewReader(buf)
|
||||||
csvData = append(csvData, col)
|
records, err := r.ReadAll()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
var services []*types.Service
|
var services []*types.Service
|
||||||
for _, v := range csvData {
|
for k, v := range records[1:] {
|
||||||
s, err := commaToService(v)
|
s, err := commaToService(v)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
log.Errorf("error on line %v: %v", k, err)
|
||||||
|
continue
|
||||||
}
|
}
|
||||||
services = append(services, s)
|
services = append(services, s)
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,22 +3,30 @@ package integrations
|
||||||
import (
|
import (
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
|
"io/ioutil"
|
||||||
"testing"
|
"testing"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestCsvFileIntegration(t *testing.T) {
|
func TestCsvFileIntegration(t *testing.T) {
|
||||||
|
data, err := ioutil.ReadFile("../../source/tmpl/bulk_import.csv")
|
||||||
|
require.Nil(t, err)
|
||||||
|
|
||||||
csvIntegrator.Fields[0].Value = "test_files/example_services.csv"
|
t.Run("Set Field Value", func(t *testing.T) {
|
||||||
|
formPost := map[string][]string{}
|
||||||
|
formPost["input"] = []string{string(data)}
|
||||||
|
_, err = SetFields(csvIntegrator, formPost)
|
||||||
|
require.Nil(t, err)
|
||||||
|
})
|
||||||
|
|
||||||
t.Run("CSV File", func(t *testing.T) {
|
t.Run("Get Field Value", func(t *testing.T) {
|
||||||
path := csvIntegrator.Fields[0].Value
|
value := Value(csvIntegrator, "input").(string)
|
||||||
assert.Equal(t, "test_files/example_services.csv", path)
|
assert.Equal(t, string(data), value)
|
||||||
})
|
})
|
||||||
|
|
||||||
t.Run("List Services from CSV File", func(t *testing.T) {
|
t.Run("List Services from CSV File", func(t *testing.T) {
|
||||||
services, err := csvIntegrator.List()
|
services, err := csvIntegrator.List()
|
||||||
require.Nil(t, err)
|
require.Nil(t, err)
|
||||||
assert.Equal(t, len(services), 1)
|
assert.Equal(t, 10, len(services))
|
||||||
})
|
})
|
||||||
|
|
||||||
t.Run("Confirm Services from CSV File", func(t *testing.T) {
|
t.Run("Confirm Services from CSV File", func(t *testing.T) {
|
||||||
|
|
|
@ -8,6 +8,21 @@ import (
|
||||||
|
|
||||||
func TestDockerIntegration(t *testing.T) {
|
func TestDockerIntegration(t *testing.T) {
|
||||||
|
|
||||||
|
t.Run("Set Field Value", func(t *testing.T) {
|
||||||
|
formPost := map[string][]string{}
|
||||||
|
formPost["path"] = []string{"unix:///var/run/docker.sock"}
|
||||||
|
formPost["version"] = []string{"1.25"}
|
||||||
|
_, err := SetFields(csvIntegrator, formPost)
|
||||||
|
require.Nil(t, err)
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("Get Field Value", func(t *testing.T) {
|
||||||
|
path := Value(dockerIntegrator, "path").(string)
|
||||||
|
version := Value(dockerIntegrator, "version").(string)
|
||||||
|
assert.Equal(t, "unix:///var/run/docker.sock", path)
|
||||||
|
assert.Equal(t, "1.25", version)
|
||||||
|
})
|
||||||
|
|
||||||
t.Run("List Services from Docker", func(t *testing.T) {
|
t.Run("List Services from Docker", func(t *testing.T) {
|
||||||
services, err := dockerIntegrator.List()
|
services, err := dockerIntegrator.List()
|
||||||
require.Nil(t, err)
|
require.Nil(t, err)
|
||||||
|
|
|
@ -9,7 +9,7 @@ func TestIntegrations(t *testing.T) {
|
||||||
|
|
||||||
t.Run("Collect Integrations", func(t *testing.T) {
|
t.Run("Collect Integrations", func(t *testing.T) {
|
||||||
amount := len(Integrations)
|
amount := len(Integrations)
|
||||||
assert.Equal(t, 2, amount)
|
assert.Equal(t, 3, amount)
|
||||||
})
|
})
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1 +0,0 @@
|
||||||
Bulk Upload,http://google.com,,200,60s,http,get,,,60s,1,TRUE,TRUE,,Authorization=example,bulk_example,false
|
|
|
|
@ -9,12 +9,14 @@ import (
|
||||||
func TestTraefikIntegration(t *testing.T) {
|
func TestTraefikIntegration(t *testing.T) {
|
||||||
|
|
||||||
t.Run("List Services from Traefik", func(t *testing.T) {
|
t.Run("List Services from Traefik", func(t *testing.T) {
|
||||||
|
t.SkipNow()
|
||||||
services, err := traefikIntegrator.List()
|
services, err := traefikIntegrator.List()
|
||||||
require.Nil(t, err)
|
require.Nil(t, err)
|
||||||
assert.NotEqual(t, 0, len(services))
|
assert.NotEqual(t, 0, len(services))
|
||||||
})
|
})
|
||||||
|
|
||||||
t.Run("Confirm Services from Traefik", func(t *testing.T) {
|
t.Run("Confirm Services from Traefik", func(t *testing.T) {
|
||||||
|
t.SkipNow()
|
||||||
services, err := traefikIntegrator.List()
|
services, err := traefikIntegrator.List()
|
||||||
require.Nil(t, err)
|
require.Nil(t, err)
|
||||||
for _, s := range services {
|
for _, s := range services {
|
||||||
|
|
|
@ -20,6 +20,7 @@ import (
|
||||||
"github.com/hunterlong/statping/core/notifier"
|
"github.com/hunterlong/statping/core/notifier"
|
||||||
"github.com/hunterlong/statping/types"
|
"github.com/hunterlong/statping/types"
|
||||||
"github.com/hunterlong/statping/utils"
|
"github.com/hunterlong/statping/utils"
|
||||||
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -191,7 +192,7 @@ func insertSampleCheckins() error {
|
||||||
})
|
})
|
||||||
checkin2.Update()
|
checkin2.Update()
|
||||||
|
|
||||||
checkTime := time.Now().Add(-24 * time.Hour)
|
checkTime := time.Now().UTC().Add(-24 * time.Hour)
|
||||||
for i := 0; i <= 60; i++ {
|
for i := 0; i <= 60; i++ {
|
||||||
checkHit := ReturnCheckinHit(&types.CheckinHit{
|
checkHit := ReturnCheckinHit(&types.CheckinHit{
|
||||||
Checkin: checkin1.Id,
|
Checkin: checkin1.Id,
|
||||||
|
@ -206,32 +207,35 @@ func insertSampleCheckins() error {
|
||||||
|
|
||||||
// InsertSampleHits will create a couple new hits for the sample services
|
// InsertSampleHits will create a couple new hits for the sample services
|
||||||
func InsertSampleHits() error {
|
func InsertSampleHits() error {
|
||||||
|
tx := hitsDB().Begin()
|
||||||
|
sg := new(sync.WaitGroup)
|
||||||
for i := int64(1); i <= 5; i++ {
|
for i := int64(1); i <= 5; i++ {
|
||||||
|
sg.Add(1)
|
||||||
service := SelectService(i)
|
service := SelectService(i)
|
||||||
seed := time.Now().UnixNano()
|
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.Name))
|
||||||
createdAt := sampleStart
|
createdAt := sampleStart
|
||||||
|
|
||||||
p := utils.NewPerlin(2., 2., 10, seed)
|
p := utils.NewPerlin(2., 2., 10, seed)
|
||||||
|
go func() {
|
||||||
for hi := 0.; hi <= float64(SampleHits); hi++ {
|
defer sg.Done()
|
||||||
|
for hi := 0.; hi <= float64(SampleHits); hi++ {
|
||||||
latency := p.Noise1D(hi / 500)
|
latency := p.Noise1D(hi / 500)
|
||||||
createdAt = createdAt.Add(60 * time.Second)
|
createdAt = createdAt.Add(60 * time.Second)
|
||||||
hit := &types.Hit{
|
hit := &types.Hit{
|
||||||
Service: service.Id,
|
Service: service.Id,
|
||||||
CreatedAt: createdAt,
|
CreatedAt: createdAt,
|
||||||
Latency: latency,
|
Latency: latency,
|
||||||
|
}
|
||||||
|
tx = tx.Create(&hit)
|
||||||
}
|
}
|
||||||
service.CreateHit(hit)
|
}()
|
||||||
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
sg.Wait()
|
||||||
return nil
|
err := tx.Commit().Error
|
||||||
|
if err != nil {
|
||||||
|
log.Errorln(err)
|
||||||
|
}
|
||||||
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// insertSampleCore will create a new Core for the seed
|
// insertSampleCore will create a new Core for the seed
|
||||||
|
@ -243,7 +247,7 @@ func insertSampleCore() error {
|
||||||
ApiSecret: "samplesecret",
|
ApiSecret: "samplesecret",
|
||||||
Domain: "http://localhost:8080",
|
Domain: "http://localhost:8080",
|
||||||
Version: "test",
|
Version: "test",
|
||||||
CreatedAt: time.Now(),
|
CreatedAt: time.Now().UTC(),
|
||||||
UseCdn: types.NewNullBool(false),
|
UseCdn: types.NewNullBool(false),
|
||||||
}
|
}
|
||||||
query := coreDB().Create(core)
|
query := coreDB().Create(core)
|
||||||
|
@ -276,8 +280,8 @@ func insertMessages() error {
|
||||||
Title: "Routine Downtime",
|
Title: "Routine Downtime",
|
||||||
Description: "This is an example a upcoming message for a service!",
|
Description: "This is an example a upcoming message for a service!",
|
||||||
ServiceId: 1,
|
ServiceId: 1,
|
||||||
StartOn: time.Now().Add(15 * time.Minute),
|
StartOn: time.Now().UTC().Add(15 * time.Minute),
|
||||||
EndOn: time.Now().Add(2 * time.Hour),
|
EndOn: time.Now().UTC().Add(2 * time.Hour),
|
||||||
})
|
})
|
||||||
if _, err := m1.Create(); err != nil {
|
if _, err := m1.Create(); err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -312,7 +316,7 @@ func InsertLargeSampleData() error {
|
||||||
if err := insertMessages(); err != nil {
|
if err := insertMessages(); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
createdOn := time.Now().Add((-24 * 90) * time.Hour).UTC()
|
createdOn := time.Now().UTC().Add((-24 * 90) * time.Hour)
|
||||||
s6 := ReturnService(&types.Service{
|
s6 := ReturnService(&types.Service{
|
||||||
Name: "JSON Lint",
|
Name: "JSON Lint",
|
||||||
Domain: "https://jsonlint.com",
|
Domain: "https://jsonlint.com",
|
||||||
|
@ -443,7 +447,7 @@ func InsertLargeSampleData() error {
|
||||||
s14.Create(false)
|
s14.Create(false)
|
||||||
s15.Create(false)
|
s15.Create(false)
|
||||||
|
|
||||||
var dayAgo = time.Now().Add((-24 * 90) * time.Hour)
|
var dayAgo = time.Now().UTC().Add((-24 * 90) * time.Hour)
|
||||||
|
|
||||||
insertHitRecords(dayAgo, 5450)
|
insertHitRecords(dayAgo, 5450)
|
||||||
|
|
||||||
|
@ -485,7 +489,7 @@ func insertHitRecords(since time.Time, amount int64) {
|
||||||
createdAt = createdAt.Add(1 * time.Minute)
|
createdAt = createdAt.Add(1 * time.Minute)
|
||||||
hit := &types.Hit{
|
hit := &types.Hit{
|
||||||
Service: service.Id,
|
Service: service.Id,
|
||||||
CreatedAt: createdAt,
|
CreatedAt: createdAt.UTC(),
|
||||||
Latency: latency,
|
Latency: latency,
|
||||||
}
|
}
|
||||||
service.CreateHit(hit)
|
service.CreateHit(hit)
|
||||||
|
|
|
@ -144,7 +144,7 @@ func (s *Service) AvgTime() string {
|
||||||
|
|
||||||
// OnlineDaysPercent returns the service's uptime percent within last 24 hours
|
// OnlineDaysPercent returns the service's uptime percent within last 24 hours
|
||||||
func (s *Service) OnlineDaysPercent(days int) float32 {
|
func (s *Service) OnlineDaysPercent(days int) float32 {
|
||||||
ago := time.Now().Add((-24 * time.Duration(days)) * time.Hour)
|
ago := time.Now().UTC().Add((-24 * time.Duration(days)) * time.Hour)
|
||||||
return s.OnlineSince(ago)
|
return s.OnlineSince(ago)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -207,7 +207,7 @@ func (s *Service) SmallText() string {
|
||||||
}
|
}
|
||||||
if len(last) > 0 {
|
if len(last) > 0 {
|
||||||
lastFailure := s.lastFailure()
|
lastFailure := s.lastFailure()
|
||||||
got, _ := timeago.TimeAgoWithTime(time.Now().Add(s.Downtime()), time.Now())
|
got, _ := timeago.TimeAgoWithTime(time.Now().UTC().Add(s.Downtime()), time.Now().UTC())
|
||||||
return fmt.Sprintf("Reported offline %v, %v", got, lastFailure.ParseError())
|
return fmt.Sprintf("Reported offline %v, %v", got, lastFailure.ParseError())
|
||||||
} else {
|
} else {
|
||||||
return fmt.Sprintf("%v is currently offline", s.Name)
|
return fmt.Sprintf("%v is currently offline", s.Name)
|
||||||
|
@ -309,7 +309,7 @@ func (d *DateScanObj) ToString() string {
|
||||||
|
|
||||||
// AvgUptime24 returns a service's average online status for last 24 hours
|
// AvgUptime24 returns a service's average online status for last 24 hours
|
||||||
func (s *Service) AvgUptime24() string {
|
func (s *Service) AvgUptime24() string {
|
||||||
ago := time.Now().Add(-24 * time.Hour)
|
ago := time.Now().UTC().Add(-24 * time.Hour)
|
||||||
return s.AvgUptime(ago)
|
return s.AvgUptime(ago)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -410,7 +410,7 @@ func (s *Service) Update(restart bool) error {
|
||||||
|
|
||||||
// Create will create a service and insert it into the database
|
// Create will create a service and insert it into the database
|
||||||
func (s *Service) Create(check bool) (int64, error) {
|
func (s *Service) Create(check bool) (int64, error) {
|
||||||
s.CreatedAt = time.Now()
|
s.CreatedAt = time.Now().UTC()
|
||||||
db := servicesDB().Create(s)
|
db := servicesDB().Create(s)
|
||||||
if db.Error != nil {
|
if db.Error != nil {
|
||||||
log.Errorln(fmt.Sprintf("Failed to create service %v #%v: %v", s.Name, s.Id, db.Error))
|
log.Errorln(fmt.Sprintf("Failed to create service %v #%v: %v", s.Name, s.Id, db.Error))
|
||||||
|
|
|
@ -9,7 +9,7 @@ import (
|
||||||
// SparklineDayFailures returns a string array of daily service failures
|
// SparklineDayFailures returns a string array of daily service failures
|
||||||
func (s *Service) SparklineDayFailures(days int) string {
|
func (s *Service) SparklineDayFailures(days int) string {
|
||||||
var arr []string
|
var arr []string
|
||||||
ago := time.Now().Add((time.Duration(days) * -24) * time.Hour)
|
ago := time.Now().UTC().Add((time.Duration(days) * -24) * time.Hour)
|
||||||
for day := 1; day <= days; day++ {
|
for day := 1; day <= days; day++ {
|
||||||
ago = ago.Add(24 * time.Hour)
|
ago = ago.Add(24 * time.Hour)
|
||||||
failures, _ := s.TotalFailuresOnDate(ago)
|
failures, _ := s.TotalFailuresOnDate(ago)
|
||||||
|
|
|
@ -68,7 +68,7 @@ func (u *User) Update() error {
|
||||||
|
|
||||||
// Create will insert a new User into the database
|
// Create will insert a new User into the database
|
||||||
func (u *User) Create() (int64, error) {
|
func (u *User) Create() (int64, error) {
|
||||||
u.CreatedAt = time.Now()
|
u.CreatedAt = time.Now().UTC()
|
||||||
u.Password = utils.HashPassword(u.Password)
|
u.Password = utils.HashPassword(u.Password)
|
||||||
u.ApiKey = utils.NewSHA1Hash(5)
|
u.ApiKey = utils.NewSHA1Hash(5)
|
||||||
u.ApiSecret = utils.NewSHA1Hash(10)
|
u.ApiSecret = utils.NewSHA1Hash(10)
|
||||||
|
|
|
@ -1,5 +1,11 @@
|
||||||
name,domain,expected,expected_status,interval,type,method,post_data,port,timeout,order,allow_notifications,public,group_id,headers,permalink
|
name,domain,expected,expected_status,interval,type,method,post_data,port,timeout,order,allow_notifications,public,group_id,headers,permalink,verify_ssl
|
||||||
Bulk Upload,http://google.com,,200,60s,http,get,,,60s,1,TRUE,TRUE,,Authorization=example,bulk_example
|
Bulk Upload,http://google.com,,200,60s,http,get,,,60s,1,TRUE,TRUE,,Authorization=example,bulk_example,FALSE
|
||||||
JSON Post,https://jsonplaceholder.typicode.com/posts,,200,1m,http,post,"{""id"": 1, ""title"": 'foo', ""body"": 'bar', ""userId"": 1}",,15s,2,TRUE,TRUE,,Content-Type=application/json,json_post_example
|
JSON Post,https://jsonplaceholder.typicode.com/posts,,200,1m,http,post,"{""id"": 1, ""title"": 'foo', ""body"": 'bar', ""userId"": 1}",,15s,2,TRUE,TRUE,,Content-Type=application/json,json_post_example,FALSE
|
||||||
Google DNS,8.8.8.8,,,,tcp,,,53,10s,3,TRUE,TRUE,,,google_dns_example
|
Google DNS,8.8.8.8,,,60s,tcp,,,53,10s,3,TRUE,TRUE,,,google_dns_example,FALSE
|
||||||
Google DNS UDP,8.8.8.8,,,,udp,,,53,10s,4,TRUE,TRUE,,,google_dns_udp_example
|
Google DNS UDP,8.8.8.8,,,60s,udp,,,53,10s,4,TRUE,TRUE,,,google_dns_udp_example,FALSE
|
||||||
|
Statping Demo Page,https://demo.statping.com/health,"(\""online\"": true)",200,30s,http,get,,,10s,5,TRUE,TRUE,,,demo_link,FALSE
|
||||||
|
Statping MySQL Page,https://mysql.statping.com/health,"(\""online\"": true)",200,30s,http,get,,,10s,6,TRUE,TRUE,,,mysql_demo_link,FALSE
|
||||||
|
Statping SQLite Page,https://sqlite.statping.com/health,"(\""online\"": true)",200,30s,http,get,,,10s,7,TRUE,TRUE,,,sqlite_demo_link,FALSE
|
||||||
|
Token Balance,https://status.tokenbalance.com/health,"(\""online\"": true)",200,30s,http,get,,,10s,8,TRUE,TRUE,,,token_balance,FALSE
|
||||||
|
CloudFlare DNS,1.1.1.1,,,60s,tcp,,,53,10s,9,TRUE,TRUE,,,cloudflare_dns_example,FALSE
|
||||||
|
Verisign DNS,64.6.64.4,,,60s,tcp,,,53,10s,10,TRUE,TRUE,,,verisign_dns_example,FALSE
|
||||||
|
|
|
|
@ -1,6 +1,6 @@
|
||||||
// Code generated by go generate; DO NOT EDIT.
|
// Code generated by go generate; DO NOT EDIT.
|
||||||
// This file was generated by robots at
|
// This file was generated by robots at
|
||||||
// 2020-01-03 01:13:42.095152 +0000 UTC
|
// 2020-01-03 23:37:37.365614 +0000 UTC
|
||||||
//
|
//
|
||||||
// This contains the most recently Markdown source for the Statping Wiki.
|
// This contains the most recently Markdown source for the Statping Wiki.
|
||||||
package source
|
package source
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
0.80.67
|
0.80.68
|
||||||
|
|
Loading…
Reference in New Issue