mirror of https://github.com/statping/statping
parent
87f493bf4e
commit
91daa01825
|
@ -18,7 +18,7 @@ services:
|
|||
|
||||
env:
|
||||
global:
|
||||
- VERSION=0.28.8
|
||||
- VERSION=0.28.9
|
||||
- DB_HOST=localhost
|
||||
- DB_USER=travis
|
||||
- DB_PASS=
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
FROM alpine:latest
|
||||
|
||||
ENV VERSION=v0.28.8
|
||||
ENV VERSION=v0.28.9
|
||||
|
||||
RUN apk --no-cache add libstdc++ ca-certificates
|
||||
RUN wget -q https://github.com/hunterlong/statup/releases/download/$VERSION/statup-linux-alpine.tar.gz && \
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
</p>
|
||||
<p align="center">
|
||||
<b>Statup - Web and App Status Monitoring for Any Type of Project</b><br>
|
||||
<a href="https://github.com/hunterlong/statup/wiki">View Wiki</a> | <a href="https://demo.statup.io">Demo</a> <br> <a href="https://github.com/hunterlong/statup/wiki/Docker">Docker</a> | <a href="https://github.com/hunterlong/statup/wiki/AWS-EC2">EC2</a> | <a href="https://github.com/hunterlong/statup/wiki/Heroku">Heroku</a> | <a href="https://github.com/hunterlong/statup/wiki/Mac">Mac</a> | <a href="https://github.com/hunterlong/statup/wiki/Linux">Linux</a> | <a href="https://github.com/hunterlong/statup/wiki/Windows">Windows</a><br>
|
||||
<a href="https://github.com/hunterlong/statup/wiki">View Wiki</a> | <a href="https://demo.statup.io">Demo</a> <br> <a href="https://github.com/hunterlong/statup/wiki/Docker">Docker</a> | <a href="https://github.com/hunterlong/statup/wiki/AWS-EC2">EC2</a> | <a href="https://github.com/hunterlong/statup/wiki/Heroku">Heroku</a> | <a href="https://github.com/hunterlong/statup/wiki/Mac">Mac</a> | <a href="https://github.com/hunterlong/statup/wiki/Linux">Linux</a> | <a href="https://github.com/hunterlong/statup/wiki/Windows">Windows</a> | <a href="https://github.com/hunterlong/statup/wiki/Statup-Plugins">Plugins</a>
|
||||
</p>
|
||||
|
||||
# Statup - Status Page & Monitoring Server
|
||||
|
|
27
core/core.go
27
core/core.go
|
@ -10,19 +10,19 @@ type PluginJSON types.PluginJSON
|
|||
type PluginRepos types.PluginRepos
|
||||
|
||||
type Core struct {
|
||||
Name string `db:"name" json:"name"`
|
||||
Description string `db:"description" json:"name"`
|
||||
Config string `db:"config" json:"-"`
|
||||
ApiKey string `db:"api_key" json:"-"`
|
||||
ApiSecret string `db:"api_secret" json:"-"`
|
||||
Style string `db:"style" json:"-"`
|
||||
Footer string `db:"footer" json:"-"`
|
||||
Domain string `db:"domain" json:"domain,omitempty"`
|
||||
Version string `db:"version" json:"version,omitempty"`
|
||||
Services []*Service `json:"services,omitempty"`
|
||||
Plugins []plugin.Info
|
||||
Repos []PluginJSON
|
||||
//PluginFields []PluginSelect
|
||||
Name string `db:"name" json:"name"`
|
||||
Description string `db:"description" json:"name"`
|
||||
Config string `db:"config" json:"-"`
|
||||
ApiKey string `db:"api_key" json:"-"`
|
||||
ApiSecret string `db:"api_secret" json:"-"`
|
||||
Style string `db:"style" json:"-"`
|
||||
Footer string `db:"footer" json:"-"`
|
||||
Domain string `db:"domain" json:"domain,omitempty"`
|
||||
Version string `db:"version" json:"version,omitempty"`
|
||||
Services []*Service `json:"services,omitempty"`
|
||||
Plugins []plugin.Info
|
||||
Repos []PluginJSON
|
||||
AllPlugins []plugin.PluginActions
|
||||
Communications []*types.Communication
|
||||
OfflineAssets bool
|
||||
}
|
||||
|
@ -37,7 +37,6 @@ var (
|
|||
TmplBox *rice.Box
|
||||
EmailBox *rice.Box
|
||||
SetupMode bool
|
||||
AllPlugins []plugin.PluginActions
|
||||
UsingAssets bool
|
||||
)
|
||||
|
||||
|
|
|
@ -39,11 +39,13 @@ func DbConnection(dbType string) error {
|
|||
if Configs.Port == "" {
|
||||
Configs.Port = "3306"
|
||||
}
|
||||
|
||||
mysqlSettings = mysql.ConnectionURL{
|
||||
Database: Configs.Database,
|
||||
Host: Configs.Host,
|
||||
User: Configs.User,
|
||||
Password: Configs.Password,
|
||||
Options: map[string]string{"parseTime": "true", "charset": "utf8"},
|
||||
}
|
||||
DbSession, err = mysql.Open(mysqlSettings)
|
||||
if err != nil {
|
||||
|
@ -67,7 +69,6 @@ func DbConnection(dbType string) error {
|
|||
}
|
||||
//dbSession.SetLogging(true)
|
||||
dbServer = dbType
|
||||
OnLoad(DbSession)
|
||||
return err
|
||||
}
|
||||
|
||||
|
|
|
@ -10,19 +10,19 @@ import (
|
|||
)
|
||||
|
||||
func OnLoad(db sqlbuilder.Database) {
|
||||
for _, p := range AllPlugins {
|
||||
for _, p := range CoreApp.AllPlugins {
|
||||
p.OnLoad(db)
|
||||
}
|
||||
}
|
||||
|
||||
func OnSuccess(s *Service) {
|
||||
for _, p := range AllPlugins {
|
||||
for _, p := range CoreApp.AllPlugins {
|
||||
p.OnSuccess(structs.Map(s))
|
||||
}
|
||||
}
|
||||
|
||||
func OnFailure(s *Service, f FailureData) {
|
||||
for _, p := range AllPlugins {
|
||||
for _, p := range CoreApp.AllPlugins {
|
||||
p.OnFailure(structs.Map(s))
|
||||
}
|
||||
|
||||
|
@ -61,37 +61,37 @@ func onFailureEmail(s *Service, f FailureData) {
|
|||
}
|
||||
|
||||
func OnSettingsSaved(c *Core) {
|
||||
for _, p := range AllPlugins {
|
||||
for _, p := range CoreApp.AllPlugins {
|
||||
p.OnSettingsSaved(structs.Map(c))
|
||||
}
|
||||
}
|
||||
|
||||
func OnNewUser(u *User) {
|
||||
for _, p := range AllPlugins {
|
||||
for _, p := range CoreApp.AllPlugins {
|
||||
p.OnNewUser(structs.Map(u))
|
||||
}
|
||||
}
|
||||
|
||||
func OnNewService(s *Service) {
|
||||
for _, p := range AllPlugins {
|
||||
for _, p := range CoreApp.AllPlugins {
|
||||
p.OnNewService(structs.Map(s))
|
||||
}
|
||||
}
|
||||
|
||||
func OnDeletedService(s *Service) {
|
||||
for _, p := range AllPlugins {
|
||||
for _, p := range CoreApp.AllPlugins {
|
||||
p.OnDeletedService(structs.Map(s))
|
||||
}
|
||||
}
|
||||
|
||||
func OnUpdateService(s *Service) {
|
||||
for _, p := range AllPlugins {
|
||||
for _, p := range CoreApp.AllPlugins {
|
||||
p.OnUpdatedService(structs.Map(s))
|
||||
}
|
||||
}
|
||||
|
||||
func SelectPlugin(name string) plugin.PluginActions {
|
||||
for _, p := range AllPlugins {
|
||||
for _, p := range CoreApp.AllPlugins {
|
||||
if p.GetInfo().Name == name {
|
||||
return p
|
||||
}
|
||||
|
|
|
@ -17,6 +17,9 @@ func (s *Service) CreateFailure(data FailureData) (int64, error) {
|
|||
s.Failures = append(s.Failures, fail)
|
||||
col := DbSession.Collection("failures")
|
||||
uuid, err := col.Insert(fail)
|
||||
if err != nil {
|
||||
utils.Log(3, err)
|
||||
}
|
||||
if uuid == nil {
|
||||
return 0, err
|
||||
}
|
||||
|
@ -26,7 +29,10 @@ func (s *Service) CreateFailure(data FailureData) (int64, error) {
|
|||
func (s *Service) SelectAllFailures() []*Failure {
|
||||
var fails []*Failure
|
||||
col := DbSession.Collection("failures").Find("service", s.Id).OrderBy("-id")
|
||||
col.All(&fails)
|
||||
err := col.All(&fails)
|
||||
if err != nil {
|
||||
utils.Log(3, fmt.Sprintf("Issue getting failures for service %v, %v", s.Name, err))
|
||||
}
|
||||
return fails
|
||||
}
|
||||
|
||||
|
|
|
@ -125,28 +125,33 @@ func (s *Service) SmallText() string {
|
|||
}
|
||||
|
||||
func (s *Service) GraphData() string {
|
||||
var d []DateScan
|
||||
var d []*DateScan
|
||||
increment := "minute"
|
||||
since := time.Now().Add(time.Hour*-12 + time.Minute*0 + time.Second*0)
|
||||
|
||||
since := time.Now().Add(time.Hour*-24 + time.Minute*0 + time.Second*0)
|
||||
// group by interval sql query for postgres, mysql and sqlite
|
||||
sql := fmt.Sprintf("SELECT date_trunc('%v', created_at), AVG(latency)*1000 AS value FROM hits WHERE service=%v AND created_at > '%v' GROUP BY 1 ORDER BY date_trunc ASC;", increment, s.Id, since.Format(time.RFC3339))
|
||||
if dbServer == "mysql" {
|
||||
sql = fmt.Sprintf("SELECT CONCAT(DATE(created_at), ' ', %v(created_at)) AS created_at, AVG(latency)*1000 AS value FROM hits WHERE service=%v AND DATE_FORMAT(created_at, 'Y-m-d H:i:s') BETWEEN DATE_FORMAT(NOW() - INTERVAL 12 HOUR, 'Y-m-d H:i:s') AND DATE_FORMAT(NOW(), 'Y-m-d H:i:s') GROUP BY created_at", increment, s.Id)
|
||||
sql = fmt.Sprintf("SELECT CONCAT(date_format(created_at, '%%Y-%%m-%%dT%%TZ')) AS created_at, AVG(latency)*1000 AS value FROM hits WHERE service=%v AND DATE_FORMAT(created_at, '%%Y-%%m-%%dT%%TZ') BETWEEN DATE_FORMAT(NOW() - INTERVAL 12 HOUR, '%%Y-%%m-%%dT%%TZ') AND DATE_FORMAT(NOW(), '%%Y-%%m-%%dT%%TZ') GROUP BY created_at", s.Id)
|
||||
} else if dbServer == "sqlite" {
|
||||
sql = fmt.Sprintf("SELECT created_at, AVG(latency)*1000 as value FROM hits WHERE service=%v AND created_at >= '%v' GROUP BY strftime('%%m', created_at)", s.Id, since.Format(time.RFC3339))
|
||||
fmt.Println(sql)
|
||||
sql = fmt.Sprintf("SELECT strftime('%%Y-%%m-%%dT%%H:%%M:%%SZ', created_at), AVG(latency)*1000 as value FROM hits WHERE service=%v AND created_at >= '%v' GROUP BY strftime('%%m', created_at)", s.Id, since.Format(time.RFC3339))
|
||||
}
|
||||
|
||||
dated, err := DbSession.Query(db.Raw(sql))
|
||||
if err != nil {
|
||||
utils.Log(2, err)
|
||||
return ""
|
||||
}
|
||||
for dated.Next() {
|
||||
var gd DateScan
|
||||
gd := new(DateScan)
|
||||
var tt string
|
||||
var ff float64
|
||||
dated.Scan(&gd.CreatedAt, &ff)
|
||||
err := dated.Scan(&tt, &ff)
|
||||
if err != nil {
|
||||
utils.Log(2, fmt.Sprintf("Issue loading chart data for service %v, %v", s.Name, err))
|
||||
}
|
||||
gd.CreatedAt, err = time.Parse(time.RFC3339, tt)
|
||||
if err != nil {
|
||||
utils.Log(2, fmt.Sprintf("Issue parsing time %v", err))
|
||||
}
|
||||
gd.Value = int64(ff)
|
||||
d = append(d, gd)
|
||||
}
|
||||
|
|
23
main.go
23
main.go
|
@ -82,11 +82,12 @@ func ForEachPlugin() {
|
|||
}
|
||||
|
||||
func LoadPlugins() {
|
||||
utils.Log(1, fmt.Sprintf("Loading any available Plugins from /plugins directory"))
|
||||
if _, err := os.Stat("./plugins"); os.IsNotExist(err) {
|
||||
os.Mkdir("./plugins", os.ModePerm)
|
||||
}
|
||||
|
||||
ForEachPlugin()
|
||||
//ForEachPlugin()
|
||||
|
||||
files, err := ioutil.ReadDir("./plugins")
|
||||
if err != nil {
|
||||
|
@ -94,33 +95,39 @@ func LoadPlugins() {
|
|||
return
|
||||
}
|
||||
for _, f := range files {
|
||||
utils.Log(1, fmt.Sprintf("Attempting to load plugin '%v'", f.Name()))
|
||||
ext := strings.Split(f.Name(), ".")
|
||||
if len(ext) != 2 {
|
||||
utils.Log(3, fmt.Sprintf("Plugin '%v' must end in .so extension", f.Name()))
|
||||
continue
|
||||
}
|
||||
if ext[1] != "so" {
|
||||
utils.Log(3, fmt.Sprintf("Plugin '%v' must end in .so extension", f.Name()))
|
||||
continue
|
||||
}
|
||||
plug, err := plg.Open("plugins/" + f.Name())
|
||||
if err != nil {
|
||||
utils.Log(2, fmt.Sprintf("Plugin '%v' could not load correctly.\n", f.Name()))
|
||||
utils.Log(3, fmt.Sprintf("Plugin '%v' could not load correctly. %v", f.Name(), err))
|
||||
continue
|
||||
}
|
||||
symPlugin, err := plug.Lookup("Plugin")
|
||||
if err != nil {
|
||||
utils.Log(3, fmt.Sprintf("Plugin '%v' could not load correctly. %v", f.Name(), err))
|
||||
continue
|
||||
}
|
||||
|
||||
var plugActions plugin.PluginActions
|
||||
plugActions, ok := symPlugin.(plugin.PluginActions)
|
||||
if !ok {
|
||||
utils.Log(2, fmt.Sprintf("Plugin '%v' could not load correctly, error: %v\n", f.Name(), "unexpected type from module symbol"))
|
||||
utils.Log(3, fmt.Sprintf("Plugin '%v' could not load correctly, error: %v", f.Name(), err))
|
||||
continue
|
||||
}
|
||||
|
||||
//allPlugins = append(allPlugins, plugActions)
|
||||
plugActions.OnLoad(core.DbSession)
|
||||
|
||||
core.CoreApp.Plugins = append(core.CoreApp.Plugins, plugActions.GetInfo())
|
||||
core.CoreApp.AllPlugins = append(core.CoreApp.AllPlugins, plugActions)
|
||||
}
|
||||
|
||||
core.OnLoad(core.DbSession)
|
||||
|
||||
//utils.Log(1, fmt.Sprintf("Loaded %v Plugins\n", len(allPlugins)))
|
||||
ForEachPlugin()
|
||||
utils.Log(1, fmt.Sprintf("Loaded %v Plugins\n", len(core.CoreApp.Plugins)))
|
||||
}
|
||||
|
|
76
main_test.go
76
main_test.go
|
@ -13,6 +13,7 @@ import (
|
|||
"os"
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
||||
var (
|
||||
|
@ -24,19 +25,13 @@ func RunInit(t *testing.T) {
|
|||
RenderBoxes()
|
||||
os.Remove("./statup.db")
|
||||
os.Remove("./config.yml")
|
||||
os.Remove("./index.html")
|
||||
route = handlers.Router()
|
||||
LoadDotEnvs()
|
||||
}
|
||||
|
||||
var forceSequential chan bool = make(chan bool, 1)
|
||||
|
||||
type databaseTest struct {
|
||||
in string
|
||||
out string
|
||||
}
|
||||
|
||||
var dbTests []databaseTest
|
||||
|
||||
func TestRunAll(t *testing.T) {
|
||||
|
||||
databases := []string{"mysql", "sqlite", "postgres"}
|
||||
|
@ -63,9 +58,12 @@ func TestRunAll(t *testing.T) {
|
|||
t.Run(dbt+" Select Comms", func(t *testing.T) {
|
||||
RunSelectAllMysqlCommunications(t)
|
||||
})
|
||||
t.Run(dbt+" Create User", func(t *testing.T) {
|
||||
t.Run(dbt+" Create Users", func(t *testing.T) {
|
||||
RunUser_Create(t)
|
||||
})
|
||||
t.Run(dbt+" Select Users", func(t *testing.T) {
|
||||
RunUser_SelectAll(t)
|
||||
})
|
||||
t.Run(dbt+" Select Services", func(t *testing.T) {
|
||||
RunSelectAllServices(t)
|
||||
})
|
||||
|
@ -87,7 +85,7 @@ func TestRunAll(t *testing.T) {
|
|||
t.Run(dbt+" Chart Data", func(t *testing.T) {
|
||||
RunService_GraphData(t)
|
||||
})
|
||||
t.Run(dbt+" Create Service", func(t *testing.T) {
|
||||
t.Run(dbt+" Create Failing Service", func(t *testing.T) {
|
||||
RunBadService_Create(t)
|
||||
})
|
||||
t.Run(dbt+" Check Service", func(t *testing.T) {
|
||||
|
@ -96,9 +94,18 @@ func TestRunAll(t *testing.T) {
|
|||
t.Run(dbt+" Select Hits", func(t *testing.T) {
|
||||
RunService_Hits(t)
|
||||
})
|
||||
t.Run(dbt+" Select Failures", func(t *testing.T) {
|
||||
RunService_Failures(t)
|
||||
})
|
||||
t.Run(dbt+" Select Limited Hits", func(t *testing.T) {
|
||||
RunService_LimitedHits(t)
|
||||
})
|
||||
t.Run(dbt+" Delete Service", func(t *testing.T) {
|
||||
RunDeleteService(t)
|
||||
})
|
||||
t.Run(dbt+" Delete User", func(t *testing.T) {
|
||||
RunUser_Delete(t)
|
||||
})
|
||||
t.Run(dbt+" HTTP /", func(t *testing.T) {
|
||||
RunIndexHandler(t)
|
||||
})
|
||||
|
@ -211,6 +218,8 @@ func RunSelectCoreMYQL(t *testing.T, db string) {
|
|||
core.CoreApp, err = core.SelectCore()
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, "Testing "+db, core.CoreApp.Name)
|
||||
assert.NotEmpty(t, core.CoreApp.ApiKey)
|
||||
assert.NotEmpty(t, core.CoreApp.ApiSecret)
|
||||
assert.Equal(t, VERSION, core.CoreApp.Version)
|
||||
}
|
||||
|
||||
|
@ -228,6 +237,12 @@ func RunSelectAllMysqlCommunications(t *testing.T) {
|
|||
assert.Equal(t, 2, len(comms))
|
||||
}
|
||||
|
||||
func RunUser_SelectAll(t *testing.T) {
|
||||
users, err := core.SelectAllUsers()
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, 2, len(users))
|
||||
}
|
||||
|
||||
func RunUser_Create(t *testing.T) {
|
||||
user := &core.User{
|
||||
Username: "admin",
|
||||
|
@ -236,7 +251,24 @@ func RunUser_Create(t *testing.T) {
|
|||
}
|
||||
id, err := user.Create()
|
||||
assert.Nil(t, err)
|
||||
assert.NotZero(t, id)
|
||||
assert.Equal(t, int64(1), id)
|
||||
user2 := &core.User{
|
||||
Username: "superadmin",
|
||||
Password: "admin",
|
||||
Email: "info@adminer.com",
|
||||
Admin: true,
|
||||
}
|
||||
id, err = user2.Create()
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, int64(2), id)
|
||||
}
|
||||
|
||||
func RunUser_Delete(t *testing.T) {
|
||||
user, err := core.SelectUser(2)
|
||||
assert.Nil(t, err)
|
||||
assert.NotNil(t, user)
|
||||
err = user.Delete()
|
||||
assert.Nil(t, err)
|
||||
}
|
||||
|
||||
func RunSelectAllServices(t *testing.T) {
|
||||
|
@ -266,6 +298,7 @@ func RunService_Create(t *testing.T) {
|
|||
id, err := service.Create()
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, int64(5), id)
|
||||
t.Log(service)
|
||||
}
|
||||
|
||||
func RunService_AvgTime(t *testing.T) {
|
||||
|
@ -286,6 +319,9 @@ func RunService_GraphData(t *testing.T) {
|
|||
service := core.SelectService(1)
|
||||
assert.NotNil(t, service)
|
||||
data := service.GraphData()
|
||||
t.Log(data)
|
||||
assert.NotEqual(t, "null", data)
|
||||
assert.False(t, strings.Contains(data, "0001-01-01T00:00:00Z"))
|
||||
assert.NotEmpty(t, data)
|
||||
}
|
||||
|
||||
|
@ -310,15 +346,24 @@ func RunBadService_Check(t *testing.T) {
|
|||
assert.Equal(t, "JSON API Tester", service.Name)
|
||||
}
|
||||
|
||||
func RunDeleteService(t *testing.T) {
|
||||
service := core.SelectService(4)
|
||||
assert.NotNil(t, service)
|
||||
assert.Equal(t, "JSON API Tester", service.Name)
|
||||
err := service.Delete()
|
||||
assert.Nil(t, err)
|
||||
}
|
||||
|
||||
func RunCreateService_Hits(t *testing.T) {
|
||||
services, err := core.SelectAllServices()
|
||||
assert.Nil(t, err)
|
||||
assert.NotNil(t, services)
|
||||
for i := 0; i <= 2; i++ {
|
||||
for i := 0; i <= 10; i++ {
|
||||
for _, s := range services {
|
||||
service := s.Check()
|
||||
assert.NotNil(t, service)
|
||||
}
|
||||
time.Sleep(1 * time.Second)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -330,6 +375,13 @@ func RunService_Hits(t *testing.T) {
|
|||
assert.NotZero(t, len(hits))
|
||||
}
|
||||
|
||||
func RunService_Failures(t *testing.T) {
|
||||
t.SkipNow()
|
||||
service := core.SelectService(6)
|
||||
assert.NotNil(t, service)
|
||||
assert.NotEmpty(t, service.Failures)
|
||||
}
|
||||
|
||||
func RunService_LimitedHits(t *testing.T) {
|
||||
service := core.SelectService(1)
|
||||
assert.NotNil(t, service)
|
||||
|
@ -363,7 +415,7 @@ func RunPrometheusHandler(t *testing.T) {
|
|||
rr := httptest.NewRecorder()
|
||||
route.ServeHTTP(rr, req)
|
||||
t.Log(rr.Body.String())
|
||||
assert.True(t, strings.Contains(rr.Body.String(), "statup_total_services 6"))
|
||||
assert.True(t, strings.Contains(rr.Body.String(), "statup_total_services 5"))
|
||||
}
|
||||
|
||||
func RunFailingPrometheusHandler(t *testing.T) {
|
||||
|
|
|
@ -17,7 +17,7 @@ CREATE TABLE users (
|
|||
api_key VARCHAR(50),
|
||||
api_secret VARCHAR(50),
|
||||
administrator BOOL NOT NULL DEFAULT '0',
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
|
||||
INDEX (id)
|
||||
);
|
||||
CREATE TABLE services (
|
||||
|
@ -32,34 +32,34 @@ CREATE TABLE services (
|
|||
check_interval int(11),
|
||||
post_data text,
|
||||
order_id integer,
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
|
||||
INDEX (id)
|
||||
);
|
||||
CREATE TABLE hits (
|
||||
id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
|
||||
service INTEGER NOT NULL,
|
||||
latency float,
|
||||
created_at TIMESTAMP,
|
||||
created_at DATETIME,
|
||||
INDEX (id, service),
|
||||
FOREIGN KEY (service) REFERENCES services(id)
|
||||
FOREIGN KEY (service) REFERENCES services(id) ON DELETE CASCADE
|
||||
);
|
||||
CREATE TABLE failures (
|
||||
id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
|
||||
issue text,
|
||||
method text,
|
||||
service INTEGER NOT NULL,
|
||||
created_at TIMESTAMP,
|
||||
created_at DATETIME,
|
||||
INDEX (id, service),
|
||||
FOREIGN KEY (service) REFERENCES services(id)
|
||||
FOREIGN KEY (service) REFERENCES services(id) ON DELETE CASCADE
|
||||
);
|
||||
CREATE TABLE checkins (
|
||||
id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
|
||||
service INTEGER NOT NULL,
|
||||
check_interval integer,
|
||||
api text,
|
||||
created_at TIMESTAMP,
|
||||
created_at DATETIME,
|
||||
INDEX (id, service),
|
||||
FOREIGN KEY (service) REFERENCES services(id)
|
||||
FOREIGN KEY (service) REFERENCES services(id) ON DELETE CASCADE
|
||||
);
|
||||
CREATE TABLE communication (
|
||||
id SERIAL PRIMARY KEY,
|
||||
|
@ -75,5 +75,5 @@ CREATE TABLE communication (
|
|||
enabled BOOL NOT NULL DEFAULT '0',
|
||||
removable BOOL NOT NULL DEFAULT '0',
|
||||
limits integer,
|
||||
created_at TIMESTAMP
|
||||
created_at DATETIME
|
||||
);
|
|
@ -18,7 +18,7 @@ CREATE TABLE users (
|
|||
api_key text,
|
||||
api_secret text,
|
||||
administrator bool,
|
||||
created_at TIMESTAMP
|
||||
created_at DATETIME
|
||||
);
|
||||
|
||||
CREATE TABLE services (
|
||||
|
@ -33,14 +33,14 @@ CREATE TABLE services (
|
|||
check_interval integer,
|
||||
post_data text,
|
||||
order_id integer,
|
||||
created_at TIMESTAMP
|
||||
created_at DATETIME
|
||||
);
|
||||
|
||||
CREATE TABLE hits (
|
||||
id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
|
||||
service INTEGER NOT NULL REFERENCES services(id) ON DELETE CASCADE ON UPDATE CASCADE,
|
||||
latency float,
|
||||
created_at TIMESTAMP
|
||||
created_at DATETIME
|
||||
);
|
||||
|
||||
CREATE TABLE failures (
|
||||
|
@ -48,7 +48,7 @@ CREATE TABLE failures (
|
|||
issue text,
|
||||
method text,
|
||||
service INTEGER NOT NULL REFERENCES services(id) ON DELETE CASCADE ON UPDATE CASCADE,
|
||||
created_at TIMESTAMP
|
||||
created_at DATETIME
|
||||
);
|
||||
|
||||
CREATE TABLE checkins (
|
||||
|
@ -56,7 +56,7 @@ CREATE TABLE checkins (
|
|||
service INTEGER NOT NULL REFERENCES services(id) ON DELETE CASCADE ON UPDATE CASCADE,
|
||||
check_interval integer,
|
||||
api text,
|
||||
created_at TIMESTAMP
|
||||
created_at DATETIME
|
||||
);
|
||||
|
||||
CREATE TABLE communication (
|
||||
|
@ -73,7 +73,7 @@ CREATE TABLE communication (
|
|||
enabled boolean,
|
||||
removable boolean,
|
||||
limits integer,
|
||||
created_at TIMESTAMP
|
||||
created_at DATETIME
|
||||
);
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue