diff --git a/README.md b/README.md
index 4640bec6..54bd3533 100644
--- a/README.md
+++ b/README.md
@@ -11,12 +11,10 @@ An easy to use Status Page for your websites and applications. Statping will aut
[](https://godoc.org/github.com/statping/statping) [](https://gitter.im/statping/general) [](https://microbadger.com/images/hunterlong/statping) [](https://hub.docker.com/r/hunterlong/statping/builds/)
-## A Future-Proof Status Page
-Statping strives to remain future-proof and remain intact if a failure is created. Your Statping service should not be running on the same instance you're trying to monitor. If your server crashes your Status Page should still remaining online to notify your users of downtime.
+
-
-
-
+A Future-Proof Status Page
+Statping strives to remain future-proof and remain intact if a failure is created. Your Statping service should not be running on the same instance you're trying to monitor. If your server crashes your Status Page should still remaining online to notify your users of downtime.
## Lightweight and Fast
Statping is a very lightweight application and is available for Linux, Mac, and Windows. The Docker image is only ~16Mb so you know that this application won't be filling up your hard drive space.
diff --git a/cmd/main.go b/cmd/main.go
index 7e5231bc..58077b33 100644
--- a/cmd/main.go
+++ b/cmd/main.go
@@ -28,7 +28,6 @@ import (
"github.com/statping/statping/source"
"github.com/pkg/errors"
- "github.com/statping/statping/database"
"github.com/statping/statping/handlers"
"github.com/statping/statping/types/configs"
"github.com/statping/statping/types/core"
@@ -47,6 +46,8 @@ var (
port int
log = utils.Log.WithField("type", "cmd")
httpServer = make(chan bool)
+
+ confgs *configs.DbConfig
)
func init() {
@@ -119,29 +120,29 @@ func main() {
log.Errorln(err)
}
- c, err := configs.LoadConfigs()
+ confgs, err = configs.LoadConfigs()
if err != nil {
if err := SetupMode(); err != nil {
exit(err)
}
}
- if err = configs.ConnectConfigs(c); err != nil {
+ if err = configs.ConnectConfigs(confgs); err != nil {
exit(err)
}
- exists := database.DB().HasTable("core")
+ exists := confgs.Db.HasTable("core")
if !exists {
- if err := c.DropDatabase(); err != nil {
+ if err := confgs.DropDatabase(); err != nil {
exit(errors.Wrap(err, "error dropping database"))
}
- if err := configs.CreateDatabase(); err != nil {
+ if err := confgs.CreateDatabase(); err != nil {
exit(errors.Wrap(err, "error creating database"))
}
- if err := configs.CreateAdminUser(c); err != nil {
+ if err := configs.CreateAdminUser(confgs); err != nil {
exit(errors.Wrap(err, "error creating default admin user"))
}
@@ -151,7 +152,7 @@ func main() {
}
- if err := c.MigrateDatabase(); err != nil {
+ if err := confgs.MigrateDatabase(); err != nil {
exit(err)
}
@@ -170,7 +171,7 @@ func main() {
func Close() {
sentry.Flush(3 * time.Second)
utils.CloseLogs()
- database.Close()
+ confgs.Close()
}
func SetupMode() error {
diff --git a/database/database.go b/database/database.go
index a0ceadd0..36a10819 100644
--- a/database/database.go
+++ b/database/database.go
@@ -18,9 +18,7 @@ const (
TIME_DAY = "2006-01-02"
)
-var (
- database Database
-)
+var database Database
// Database is an interface which DB implements
type Database interface {
@@ -112,39 +110,35 @@ type Database interface {
DbType() string
}
-func DB() Database {
- return database
-}
-
func (it *Db) DbType() string {
return it.Database.Dialect().GetName()
}
-func Close() error {
- if database == nil {
+func Close(db Database) error {
+ if db == nil {
return nil
}
- return database.Close()
+ return db.Close()
}
-func LogMode(b bool) Database {
- return database.LogMode(b)
+func LogMode(db Database, b bool) Database {
+ return db.LogMode(b)
}
-func Begin(model interface{}) Database {
+func Begin(db Database, model interface{}) Database {
if all, ok := model.(string); ok {
if all == "migration" {
- return database.Begin()
+ return db.Begin()
}
}
- return database.Model(model).Begin()
+ return db.Model(model).Begin()
}
-func Available() bool {
- if database == nil {
+func Available(db Database) bool {
+ if db == nil {
return false
}
- if err := database.DB().Ping(); err != nil {
+ if err := db.DB().Ping(); err != nil {
return false
}
return true
@@ -179,11 +173,15 @@ func Openw(dialect string, args ...interface{}) (db Database, err error) {
if err != nil {
return nil, err
}
- db = Wrap(gormdb)
- database = db
+ database = Wrap(gormdb)
return database, err
}
+func OpenTester() (Database, error) {
+ newDb, err := Openw("sqlite3", ":memory:?cache=shared")
+ return newDb, err
+}
+
// Wrap wraps gorm.DB in an interface
func Wrap(db *gorm.DB) Database {
return &Db{
diff --git a/database/grouping.go b/database/grouping.go
index 905a5569..86dbdc00 100644
--- a/database/grouping.go
+++ b/database/grouping.go
@@ -50,11 +50,11 @@ var (
ByAverage = func(column string, multiplier int) By {
switch database.DbType() {
case "mysql":
- return By(fmt.Sprintf("CAST(AVG(%s)*%d as UNSIGNED) as amount", column, multiplier))
+ return By(fmt.Sprintf("CAST(AVG(%s) as UNSIGNED) as amount", column))
case "postgres":
- return By(fmt.Sprintf("cast(AVG(%s)*%d as int) as amount", column, multiplier))
+ return By(fmt.Sprintf("cast(AVG(%s) as int) as amount", column))
default:
- return By(fmt.Sprintf("cast(AVG(%s)*%d as int) as amount", column, multiplier))
+ return By(fmt.Sprintf("cast(AVG(%s) as int) as amount", column))
}
}
)
@@ -157,7 +157,7 @@ func ParseQueries(r *http.Request, o isObject) *GroupQuery {
limit = 10000
}
- db := o.Db()
+ q := o.Db()
if grouping == "" {
grouping = "1h"
@@ -176,7 +176,7 @@ func ParseQueries(r *http.Request, o isObject) *GroupQuery {
Limit: int(limit),
Offset: int(offset),
FillEmpty: fill,
- db: db,
+ db: q,
}
if startField == 0 {
@@ -190,18 +190,18 @@ func ParseQueries(r *http.Request, o isObject) *GroupQuery {
}
if query.Limit != 0 {
- db = db.Limit(query.Limit)
+ q = q.Limit(query.Limit)
}
if query.Offset > 0 {
- db = db.Offset(query.Offset)
+ q = q.Offset(query.Offset)
}
- db = db.Where("created_at BETWEEN ? AND ?", db.FormatTime(query.Start), db.FormatTime(query.End))
+ q = q.Where("created_at BETWEEN ? AND ?", q.FormatTime(query.Start), q.FormatTime(query.End))
if query.Order != "" {
- db = db.Order(query.Order)
+ q = q.Order(query.Order)
}
- query.db = db
+ query.db = q
return query
}
diff --git a/database/routines.go b/database/routines.go
index 00c62faa..872c41cb 100644
--- a/database/routines.go
+++ b/database/routines.go
@@ -59,8 +59,8 @@ func databaseMaintence(dur time.Duration) {
// DeleteAllSince will delete a specific table's records based on a time.
func DeleteAllSince(table string, date time.Time) {
sql := fmt.Sprintf("DELETE FROM %v WHERE created_at < '%v';", table, database.FormatTime(date))
- db := database.Exec(sql)
- if db.Error() != nil {
- log.Warnln(db.Error())
+ q := database.Exec(sql)
+ if q.Error() != nil {
+ log.Warnln(q.Error())
}
}
diff --git a/frontend/src/assets/scss/base.scss b/frontend/src/assets/scss/base.scss
index 97c4883b..8ad831fc 100644
--- a/frontend/src/assets/scss/base.scss
+++ b/frontend/src/assets/scss/base.scss
@@ -5,6 +5,22 @@ HTML,BODY {
background-color: $background-color;
}
+
+.chartmarker {
+ background-color: white;
+ padding: 5px;
+}
+
+.chartmarker SPAN {
+ font-size: 11pt;
+ display: block;
+ color: #8b8b8b;
+}
+
+.apexcharts-tooltip {
+ box-shadow: none;
+}
+
.contain-card {
.card-header {
diff --git a/frontend/src/chart_design.js b/frontend/src/chart_design.js
new file mode 100644
index 00000000..e69de29b
diff --git a/frontend/src/components/Service/ServiceChart.vue b/frontend/src/components/Service/ServiceChart.vue
index e7d204ed..5d84dcce 100644
--- a/frontend/src/components/Service/ServiceChart.vue
+++ b/frontend/src/components/Service/ServiceChart.vue
@@ -4,19 +4,20 @@