integrations

pull/342/head
hunterlong 2020-01-03 18:03:59 -08:00
parent 0b93ad4b7a
commit 56353bfa6d
21 changed files with 167 additions and 122 deletions

View File

@ -257,7 +257,7 @@ func recordSuccess(s *Service) {
Service: s.Id,
Latency: s.Latency,
PingTime: s.PingTime,
CreatedAt: time.Now(),
CreatedAt: time.Now().UTC(),
}
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))
@ -272,7 +272,7 @@ func recordFailure(s *Service, issue string) {
Service: s.Id,
Issue: issue,
PingTime: s.PingTime,
CreatedAt: time.Now(),
CreatedAt: time.Now().UTC(),
ErrorCode: s.LastStatusCode,
}
log.WithFields(utils.ToFields(fail, s.Select())).

View File

@ -104,8 +104,8 @@ func LoadUsingEnv() (*types.DbConfig, error) {
return Configs, nil
}
// DefaultPort accepts a database type and returns its default port
func DefaultPort(db string) int64 {
// defaultPort accepts a database type and returns its default port
func defaultPort(db string) int64 {
switch db {
case "mysql":
return 3306
@ -140,7 +140,7 @@ func EnvToConfig() (*types.DbConfig, error) {
}
port := utils.ToInt(os.Getenv("DB_PORT"))
if port == 0 {
port = DefaultPort(os.Getenv("DB_PORT"))
port = defaultPort(os.Getenv("DB_PORT"))
}
name := os.Getenv("NAME")
if name == "" {
@ -185,9 +185,11 @@ func EnvToConfig() (*types.DbConfig, error) {
// SampleData runs all the sample data for a new Statping installation
func SampleData() error {
if err := InsertSampleData(); err != nil {
log.Errorln(err)
return err
}
if err := InsertSampleHits(); err != nil {
log.Errorln(err)
return err
}
return nil

View File

@ -50,7 +50,7 @@ func init() {
// NewCore return a new *core.Core struct
func NewCore() *Core {
CoreApp = &Core{&types.Core{
Started: time.Now(),
Started: time.Now().UTC(),
},
}
return CoreApp

View File

@ -38,6 +38,10 @@ var (
func init() {
DbModels = []interface{}{&types.Service{}, &types.User{}, &types.Hit{}, &types.Failure{}, &types.Message{}, &types.Group{}, &types.Checkin{}, &types.CheckinHit{}, &notifier.Notification{}, &types.Incident{}, &types.IncidentUpdate{}}
gorm.NowFunc = func() time.Time {
return time.Now().UTC()
}
}
// DbConfig stores the config.yml file for the statup configuration
@ -115,60 +119,60 @@ func CloseDB() {
}
}
// AfterFind for Core will set the timezone
func (c *Core) AfterFind() (err error) {
c.CreatedAt = utils.Timezoner(c.CreatedAt, CoreApp.Timezone)
c.UpdatedAt = utils.Timezoner(c.UpdatedAt, CoreApp.Timezone)
return
}
// AfterFind for Service will set the timezone
func (s *Service) AfterFind() (err error) {
s.CreatedAt = utils.Timezoner(s.CreatedAt, CoreApp.Timezone)
s.UpdatedAt = utils.Timezoner(s.UpdatedAt, CoreApp.Timezone)
return
}
// AfterFind for Hit will set the timezone
func (h *Hit) AfterFind() (err error) {
h.CreatedAt = utils.Timezoner(h.CreatedAt, CoreApp.Timezone)
return
}
// AfterFind for Failure will set the timezone
func (f *Failure) AfterFind() (err error) {
f.CreatedAt = utils.Timezoner(f.CreatedAt, CoreApp.Timezone)
return
}
// AfterFind for USer will set the timezone
func (u *User) AfterFind() (err error) {
u.CreatedAt = utils.Timezoner(u.CreatedAt, CoreApp.Timezone)
u.UpdatedAt = utils.Timezoner(u.UpdatedAt, CoreApp.Timezone)
return
}
// AfterFind for Checkin will set the timezone
func (c *Checkin) AfterFind() (err error) {
c.CreatedAt = utils.Timezoner(c.CreatedAt, CoreApp.Timezone)
c.UpdatedAt = utils.Timezoner(c.UpdatedAt, CoreApp.Timezone)
return
}
// AfterFind for checkinHit will set the timezone
func (c *CheckinHit) AfterFind() (err error) {
c.CreatedAt = utils.Timezoner(c.CreatedAt, CoreApp.Timezone)
return
}
// AfterFind for Message will set the timezone
func (u *Message) AfterFind() (err error) {
u.CreatedAt = utils.Timezoner(u.CreatedAt, CoreApp.Timezone)
u.UpdatedAt = utils.Timezoner(u.UpdatedAt, CoreApp.Timezone)
u.StartOn = utils.Timezoner(u.StartOn.UTC(), CoreApp.Timezone)
u.EndOn = utils.Timezoner(u.EndOn.UTC(), CoreApp.Timezone)
return
}
//// AfterFind for Core will set the timezone
//func (c *Core) AfterFind() (err error) {
// c.CreatedAt = utils.Timezoner(c.CreatedAt, CoreApp.Timezone)
// c.UpdatedAt = utils.Timezoner(c.UpdatedAt, CoreApp.Timezone)
// return
//}
//
//// AfterFind for Service will set the timezone
//func (s *Service) AfterFind() (err error) {
// s.CreatedAt = utils.Timezoner(s.CreatedAt, CoreApp.Timezone)
// s.UpdatedAt = utils.Timezoner(s.UpdatedAt, CoreApp.Timezone)
// return
//}
//
//// AfterFind for Hit will set the timezone
//func (h *Hit) AfterFind() (err error) {
// h.CreatedAt = utils.Timezoner(h.CreatedAt, CoreApp.Timezone)
// return
//}
//
//// AfterFind for Failure will set the timezone
//func (f *Failure) AfterFind() (err error) {
// f.CreatedAt = utils.Timezoner(f.CreatedAt, CoreApp.Timezone)
// return
//}
//
//// AfterFind for USer will set the timezone
//func (u *User) AfterFind() (err error) {
// u.CreatedAt = utils.Timezoner(u.CreatedAt, CoreApp.Timezone)
// u.UpdatedAt = utils.Timezoner(u.UpdatedAt, CoreApp.Timezone)
// return
//}
//
//// AfterFind for Checkin will set the timezone
//func (c *Checkin) AfterFind() (err error) {
// c.CreatedAt = utils.Timezoner(c.CreatedAt, CoreApp.Timezone)
// c.UpdatedAt = utils.Timezoner(c.UpdatedAt, CoreApp.Timezone)
// return
//}
//
//// AfterFind for checkinHit will set the timezone
//func (c *CheckinHit) AfterFind() (err error) {
// c.CreatedAt = utils.Timezoner(c.CreatedAt, CoreApp.Timezone)
// return
//}
//
//// AfterFind for Message will set the timezone
//func (u *Message) AfterFind() (err error) {
// u.CreatedAt = utils.Timezoner(u.CreatedAt, CoreApp.Timezone)
// u.UpdatedAt = utils.Timezoner(u.UpdatedAt, CoreApp.Timezone)
// u.StartOn = utils.Timezoner(u.StartOn.UTC(), CoreApp.Timezone)
// u.EndOn = utils.Timezoner(u.EndOn.UTC(), CoreApp.Timezone)
// return
//}
// InsertCore create the single row for the Core settings in Statping
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
dbType = CoreApp.Config.DbConn
if CoreApp.Config.DbPort == 0 {
CoreApp.Config.DbPort = DefaultPort(dbType)
CoreApp.Config.DbPort = defaultPort(dbType)
}
switch dbType {
case "sqlite":
@ -395,6 +399,7 @@ func (c *Core) MigrateDatabase() error {
}
}()
if tx.Error != nil {
log.Errorln(tx.Error)
return tx.Error
}
for _, table := range DbModels {

View File

@ -86,7 +86,7 @@ func (s *Service) LimitedCheckinFailures(amount int64) []*Failure {
// Ago returns a human readable timestamp for a Failure
func (f *Failure) Ago() string {
got, _ := timeago.TimeAgoWithTime(time.Now(), f.CreatedAt)
got, _ := timeago.TimeAgoWithTime(time.Now().UTC(), f.CreatedAt)
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
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)
}
@ -149,7 +149,7 @@ func (s *Service) TotalFailures() (uint64, error) {
// FailuresDaysAgo returns the amount of failures since days ago
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)
return count
}

View File

@ -22,14 +22,14 @@ func (g *Group) Delete() error {
// Create will create a group and insert it into the database
func (g *Group) Create() (int64, error) {
g.CreatedAt = time.Now()
g.CreatedAt = time.Now().UTC()
db := groupsDb().Create(g)
return g.Id, db.Error
}
// Update will update a group
func (g *Group) Update() (int64, error) {
g.UpdatedAt = time.Now()
g.UpdatedAt = time.Now().UTC()
db := groupsDb().Update(g)
return g.Id, db.Error
}

View File

@ -28,7 +28,7 @@ type Hit struct {
func (s *Service) CreateHit(h *types.Hit) (int64, error) {
db := hitsDB().Create(&h)
if db.Error != nil {
log.Warnln(db.Error)
log.Errorln(db.Error)
return 0, db.Error
}
return h.Id, db.Error

View File

@ -47,14 +47,14 @@ func (i *Incident) Delete() error {
// Create will create a incident and insert it into the database
func (i *Incident) Create() (int64, error) {
i.CreatedAt = time.Now()
i.CreatedAt = time.Now().UTC()
db := incidentsDB().Create(i)
return i.Id, db.Error
}
// Update will update a incident
func (i *Incident) Update() (int64, error) {
i.UpdatedAt = time.Now()
i.UpdatedAt = time.Now().UTC()
db := incidentsDB().Update(i)
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
func (i *IncidentUpdate) Create() (int64, error) {
i.CreatedAt = time.Now()
i.CreatedAt = time.Now().UTC()
db := incidentsUpdatesDB().Create(i)
return i.Id, db.Error
}

View File

@ -16,12 +16,13 @@
package integrations
import (
"bytes"
"encoding/csv"
"errors"
"fmt"
"github.com/hunterlong/statping/types"
"github.com/hunterlong/statping/utils"
"strconv"
"strings"
"time"
)
@ -35,7 +36,7 @@ var csvIntegrator = &csvIntegration{&types.Integration{
ShortName: "csv",
Name: "CSV File",
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{
{
Name: "input",
@ -53,16 +54,19 @@ func (t *csvIntegration) Get() *types.Integration {
func (t *csvIntegration) List() ([]*types.Service, error) {
data := Value(t, "input").(string)
for _, line := range strings.Split(strings.TrimSuffix(data, "\n"), "\n") {
col := strings.Split(line, ",")
csvData = append(csvData, col)
buf := bytes.NewReader([]byte(data))
r := csv.NewReader(buf)
records, err := r.ReadAll()
if err != nil {
return nil, err
}
var services []*types.Service
for _, v := range csvData {
for k, v := range records[1:] {
s, err := commaToService(v)
if err != nil {
return nil, err
log.Errorf("error on line %v: %v", k, err)
continue
}
services = append(services, s)
}

View File

@ -3,22 +3,30 @@ package integrations
import (
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"io/ioutil"
"testing"
)
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) {
path := csvIntegrator.Fields[0].Value
assert.Equal(t, "test_files/example_services.csv", path)
t.Run("Get Field Value", func(t *testing.T) {
value := Value(csvIntegrator, "input").(string)
assert.Equal(t, string(data), value)
})
t.Run("List Services from CSV File", func(t *testing.T) {
services, err := csvIntegrator.List()
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) {

View File

@ -8,6 +8,21 @@ import (
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) {
services, err := dockerIntegrator.List()
require.Nil(t, err)

View File

@ -9,7 +9,7 @@ func TestIntegrations(t *testing.T) {
t.Run("Collect Integrations", func(t *testing.T) {
amount := len(Integrations)
assert.Equal(t, 2, amount)
assert.Equal(t, 3, amount)
})
}

View File

@ -1 +0,0 @@
Bulk Upload,http://google.com,,200,60s,http,get,,,60s,1,TRUE,TRUE,,Authorization=example,bulk_example,false
1 Bulk Upload http://google.com 200 60s http get 60s 1 TRUE TRUE Authorization=example bulk_example false

View File

@ -9,12 +9,14 @@ import (
func TestTraefikIntegration(t *testing.T) {
t.Run("List Services from Traefik", func(t *testing.T) {
t.SkipNow()
services, err := traefikIntegrator.List()
require.Nil(t, err)
assert.NotEqual(t, 0, len(services))
})
t.Run("Confirm Services from Traefik", func(t *testing.T) {
t.SkipNow()
services, err := traefikIntegrator.List()
require.Nil(t, err)
for _, s := range services {

View File

@ -20,6 +20,7 @@ import (
"github.com/hunterlong/statping/core/notifier"
"github.com/hunterlong/statping/types"
"github.com/hunterlong/statping/utils"
"sync"
"time"
)
@ -191,7 +192,7 @@ func insertSampleCheckins() error {
})
checkin2.Update()
checkTime := time.Now().Add(-24 * time.Hour)
checkTime := time.Now().UTC().Add(-24 * time.Hour)
for i := 0; i <= 60; i++ {
checkHit := ReturnCheckinHit(&types.CheckinHit{
Checkin: checkin1.Id,
@ -206,32 +207,35 @@ func insertSampleCheckins() error {
// InsertSampleHits will create a couple new hits for the sample services
func InsertSampleHits() error {
tx := hitsDB().Begin()
sg := new(sync.WaitGroup)
for i := int64(1); i <= 5; i++ {
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))
createdAt := sampleStart
p := utils.NewPerlin(2., 2., 10, seed)
for hi := 0.; hi <= float64(SampleHits); hi++ {
latency := p.Noise1D(hi / 500)
createdAt = createdAt.Add(60 * time.Second)
hit := &types.Hit{
Service: service.Id,
CreatedAt: createdAt,
Latency: latency,
go func() {
defer sg.Done()
for hi := 0.; hi <= float64(SampleHits); hi++ {
latency := p.Noise1D(hi / 500)
createdAt = createdAt.Add(60 * time.Second)
hit := &types.Hit{
Service: service.Id,
CreatedAt: createdAt,
Latency: latency,
}
tx = tx.Create(&hit)
}
service.CreateHit(hit)
}
}()
}
return nil
sg.Wait()
err := tx.Commit().Error
if err != nil {
log.Errorln(err)
}
return err
}
// insertSampleCore will create a new Core for the seed
@ -243,7 +247,7 @@ func insertSampleCore() error {
ApiSecret: "samplesecret",
Domain: "http://localhost:8080",
Version: "test",
CreatedAt: time.Now(),
CreatedAt: time.Now().UTC(),
UseCdn: types.NewNullBool(false),
}
query := coreDB().Create(core)
@ -276,8 +280,8 @@ func insertMessages() error {
Title: "Routine Downtime",
Description: "This is an example a upcoming message for a service!",
ServiceId: 1,
StartOn: time.Now().Add(15 * time.Minute),
EndOn: time.Now().Add(2 * time.Hour),
StartOn: time.Now().UTC().Add(15 * time.Minute),
EndOn: time.Now().UTC().Add(2 * time.Hour),
})
if _, err := m1.Create(); err != nil {
return err
@ -312,7 +316,7 @@ func InsertLargeSampleData() error {
if err := insertMessages(); err != nil {
return err
}
createdOn := time.Now().Add((-24 * 90) * time.Hour).UTC()
createdOn := time.Now().UTC().Add((-24 * 90) * time.Hour)
s6 := ReturnService(&types.Service{
Name: "JSON Lint",
Domain: "https://jsonlint.com",
@ -443,7 +447,7 @@ func InsertLargeSampleData() error {
s14.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)
@ -485,7 +489,7 @@ func insertHitRecords(since time.Time, amount int64) {
createdAt = createdAt.Add(1 * time.Minute)
hit := &types.Hit{
Service: service.Id,
CreatedAt: createdAt,
CreatedAt: createdAt.UTC(),
Latency: latency,
}
service.CreateHit(hit)

View File

@ -144,7 +144,7 @@ func (s *Service) AvgTime() string {
// OnlineDaysPercent returns the service's uptime percent within last 24 hours
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)
}
@ -207,7 +207,7 @@ func (s *Service) SmallText() string {
}
if len(last) > 0 {
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())
} else {
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
func (s *Service) AvgUptime24() string {
ago := time.Now().Add(-24 * time.Hour)
ago := time.Now().UTC().Add(-24 * time.Hour)
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
func (s *Service) Create(check bool) (int64, error) {
s.CreatedAt = time.Now()
s.CreatedAt = time.Now().UTC()
db := servicesDB().Create(s)
if db.Error != nil {
log.Errorln(fmt.Sprintf("Failed to create service %v #%v: %v", s.Name, s.Id, db.Error))

View File

@ -9,7 +9,7 @@ import (
// SparklineDayFailures returns a string array of daily service failures
func (s *Service) SparklineDayFailures(days int) 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++ {
ago = ago.Add(24 * time.Hour)
failures, _ := s.TotalFailuresOnDate(ago)

View File

@ -68,7 +68,7 @@ func (u *User) Update() error {
// Create will insert a new User into the database
func (u *User) Create() (int64, error) {
u.CreatedAt = time.Now()
u.CreatedAt = time.Now().UTC()
u.Password = utils.HashPassword(u.Password)
u.ApiKey = utils.NewSHA1Hash(5)
u.ApiSecret = utils.NewSHA1Hash(10)

View File

@ -1,5 +1,11 @@
name,domain,expected,expected_status,interval,type,method,post_data,port,timeout,order,allow_notifications,public,group_id,headers,permalink
Bulk Upload,http://google.com,,200,60s,http,get,,,60s,1,TRUE,TRUE,,Authorization=example,bulk_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
Google DNS,8.8.8.8,,,,tcp,,,53,10s,3,TRUE,TRUE,,,google_dns_example
Google DNS UDP,8.8.8.8,,,,udp,,,53,10s,4,TRUE,TRUE,,,google_dns_udp_example
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,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,FALSE
Google DNS,8.8.8.8,,,60s,tcp,,,53,10s,3,TRUE,TRUE,,,google_dns_example,FALSE
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 name domain expected expected_status interval type method post_data port timeout order allow_notifications public group_id headers permalink verify_ssl
2 Bulk Upload http://google.com 200 60s http get 60s 1 TRUE TRUE Authorization=example bulk_example FALSE
3 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
4 Google DNS 8.8.8.8 60s tcp 53 10s 3 TRUE TRUE google_dns_example FALSE
5 Google DNS UDP 8.8.8.8 60s udp 53 10s 4 TRUE TRUE google_dns_udp_example FALSE
6 Statping Demo Page https://demo.statping.com/health (\"online\": true) 200 30s http get 10s 5 TRUE TRUE demo_link FALSE
7 Statping MySQL Page https://mysql.statping.com/health (\"online\": true) 200 30s http get 10s 6 TRUE TRUE mysql_demo_link FALSE
8 Statping SQLite Page https://sqlite.statping.com/health (\"online\": true) 200 30s http get 10s 7 TRUE TRUE sqlite_demo_link FALSE
9 Token Balance https://status.tokenbalance.com/health (\"online\": true) 200 30s http get 10s 8 TRUE TRUE token_balance FALSE
10 CloudFlare DNS 1.1.1.1 60s tcp 53 10s 9 TRUE TRUE cloudflare_dns_example FALSE
11 Verisign DNS 64.6.64.4 60s tcp 53 10s 10 TRUE TRUE verisign_dns_example FALSE

View File

@ -1,6 +1,6 @@
// Code generated by go generate; DO NOT EDIT.
// 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.
package source

View File

@ -1 +1 @@
0.80.67
0.80.68