diff --git a/core/checker.go b/core/checker.go
index 574051aa..fd27554c 100644
--- a/core/checker.go
+++ b/core/checker.go
@@ -252,7 +252,7 @@ func (s *Service) CheckHttp(record bool) *Service {
// recordSuccess will create a new 'hit' record in the database for a successful/online service
func recordSuccess(s *Service) {
- s.LastOnline = utils.Timezoner(time.Now().UTC(), CoreApp.Timezone)
+ s.LastOnline = time.Now().UTC()
hit := &types.Hit{
Service: s.Id,
Latency: s.Latency,
diff --git a/core/sample.go b/core/sample.go
index 04580a8e..0e8221ea 100644
--- a/core/sample.go
+++ b/core/sample.go
@@ -290,8 +290,8 @@ func insertMessages() error {
Title: "Server Reboot",
Description: "This is another example a upcoming message for a service!",
ServiceId: 3,
- 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 := m2.Create(); err != nil {
return err
diff --git a/core/services.go b/core/services.go
index 103940f7..12f99b65 100644
--- a/core/services.go
+++ b/core/services.go
@@ -49,12 +49,23 @@ func Services() []types.ServiceInterface {
func SelectService(id int64) *Service {
for _, s := range Services() {
if s.Select().Id == id {
- return s.(*Service)
+ service := s.(*Service)
+ service = service.UpdateStats()
+ return service
}
}
return nil
}
+func (s *Service) UpdateStats() *Service {
+ s.Online24Hours = s.OnlineDaysPercent(1)
+ s.Online7Days = s.OnlineDaysPercent(7)
+ s.AvgResponse = s.AvgTime()
+ s.FailuresLast24Hours = s.FailuresDaysAgo(1)
+ s.LastFailure = s.lastFailure()
+ return s
+}
+
func SelectServices(auth bool) []*Service {
var validServices []*Service
for _, sr := range CoreApp.Services {
@@ -120,6 +131,8 @@ func (c *Core) SelectAllServices(start bool) ([]*Service, error) {
c.Hits = c.LimitedHits(limitedHits)
service.Checkins = append(service.Checkins, c)
}
+ // collect initial service stats
+ service = service.UpdateStats()
CoreApp.Services = append(CoreApp.Services, service)
}
reorderServices()
@@ -132,14 +145,14 @@ func reorderServices() {
}
// AvgTime will return the average amount of time for a service to response back successfully
-func (s *Service) AvgTime() string {
+func (s *Service) AvgTime() float64 {
total, _ := s.TotalHits()
if total == 0 {
- return "0"
+ return 0
}
- sum := s.Sum()
- avg := sum / float64(total) * 100
- return fmt.Sprintf("%0.0f", avg*10)
+ avg := s.Sum() / float64(total) * 100
+ f, _ := strconv.ParseFloat(fmt.Sprintf("%0.0f", avg*10), 32)
+ return f
}
// OnlineDaysPercent returns the service's uptime percent within last 24 hours
diff --git a/frontend/src/App.vue b/frontend/src/App.vue
index a1aa4081..818d334c 100644
--- a/frontend/src/App.vue
+++ b/frontend/src/App.vue
@@ -20,9 +20,9 @@
},
async mounted() {
if (this.$route.path !== '/setup') {
- const tk = JSON.parse(localStorage.getItem("statping_user"))
+ // const tk = JSON.parse(localStorage.getItem("statping_user"))
if (!this.$store.getters.hasPublicData) {
- await this.$store.dispatch('loadAdmin')
+ await this.$store.dispatch('loadRequired')
}
}
this.loaded = true
diff --git a/frontend/src/assets/scss/base.scss b/frontend/src/assets/scss/base.scss
index 36878049..c50cddff 100644
--- a/frontend/src/assets/scss/base.scss
+++ b/frontend/src/assets/scss/base.scss
@@ -67,7 +67,6 @@ HTML,BODY {
.lower_canvas {
height: 3.4rem;
width: 100%;
- background-color: #48d338;
padding: 15px 10px;
margin-left: 0px !important;
margin-right: 0px !important;
diff --git a/frontend/src/components/Dashboard/DashboardIndex.vue b/frontend/src/components/Dashboard/DashboardIndex.vue
index f79a1804..dd914842 100644
--- a/frontend/src/components/Dashboard/DashboardIndex.vue
+++ b/frontend/src/components/Dashboard/DashboardIndex.vue
@@ -7,7 +7,7 @@
Total Services
@@ -35,6 +35,11 @@
}
},
methods: {
+ failuresLast24Hours() {
+ let total = 0;
+ this.$store.getters.services.map((s) => { total += s.failures_24_hours })
+ return total
+ },
}
}
diff --git a/frontend/src/components/Service/ServiceBlock.vue b/frontend/src/components/Service/ServiceBlock.vue
index 78711b0d..d2f622ff 100644
--- a/frontend/src/components/Service/ServiceBlock.vue
+++ b/frontend/src/components/Service/ServiceBlock.vue
@@ -5,20 +5,20 @@
{{service.name}}
- {{service.online ? "ONLINE" : "OFFLINE"}}
+ {{service.online ? "ONLINE" : "OFFLINE"}}
- 131ms
+ {{service.avg_response}}ms
Average Response
- 100%
+ {{service.online_24_hours}}%
Uptime last 24 Hours
- 100%
+ {{service.online_7_days}}%
Uptime last 7 Days
@@ -30,12 +30,15 @@
-
+
- Online, last Failure was Wednesday 1:16:49PM, Dec 18 2019
+
+ {{smallText(service)}}
+
- View Service
+
+ View Service
@@ -54,7 +57,16 @@
type: Object,
required: true
},
- }
+ },
+ methods: {
+ smallText(s) {
+ if (s.online) {
+ return `Online, last checked on ${s.last_success}`
+ } else {
+ return `Offline, last error: ${s.last_failure.issue}`
+ }
+ }
+ }
}
diff --git a/frontend/src/components/Service/ServiceChart.vue b/frontend/src/components/Service/ServiceChart.vue
index d03e00bb..a46436d0 100644
--- a/frontend/src/components/Service/ServiceChart.vue
+++ b/frontend/src/components/Service/ServiceChart.vue
@@ -115,7 +115,7 @@
show: false
},
fill: {
- colors: ["#48d338"],
+ colors: [this.service.online ? "#48d338" : "#d3132a"],
opacity: 1,
type: 'solid'
},
@@ -123,7 +123,7 @@
show: true,
curve: 'smooth',
lineCap: 'butt',
- colors: ["#3aa82d"],
+ colors: [this.service.online ? "#3aa82d" : "#a40f21"],
}
},
series: [{
diff --git a/frontend/src/forms/Service.vue b/frontend/src/forms/Service.vue
index 238b6eb8..d45fb7ca 100644
--- a/frontend/src/forms/Service.vue
+++ b/frontend/src/forms/Service.vue
@@ -147,7 +147,9 @@
@@ -210,11 +212,18 @@
delete s.last_success
delete s.latency
delete s.online_24_hours
- await Api.service_create(s)
+ if (s.id) {
+ await this.updateService(s)
+ } else {
+ await this.createService(s)
+ }
},
- async testService(e) {
-
- }
+ async createService(s) {
+ await Api.service_create(s)
+ },
+ async updateService(s) {
+ await Api.service_update(s)
+ }
}
}
diff --git a/frontend/src/forms/Setup.vue b/frontend/src/forms/Setup.vue
index 5e08abf7..6c2d8a75 100644
--- a/frontend/src/forms/Setup.vue
+++ b/frontend/src/forms/Setup.vue
@@ -125,7 +125,10 @@
async created() {
const core = await Api.core()
if (core.setup) {
- this.$router.push(Index)
+ if (!this.$store.getters.hasPublicData) {
+ await this.$store.dispatch('loadRequired')
+ }
+ this.$router.push('/')
}
},
mounted() {
diff --git a/frontend/src/pages/Index.vue b/frontend/src/pages/Index.vue
index ec7c40a6..dd50a02d 100644
--- a/frontend/src/pages/Index.vue
+++ b/frontend/src/pages/Index.vue
@@ -22,6 +22,8 @@
diff --git a/handlers/api.go b/handlers/api.go
index f9d94a77..f3b22b6c 100644
--- a/handlers/api.go
+++ b/handlers/api.go
@@ -37,7 +37,6 @@ type apiResponse struct {
func apiIndexHandler(r *http.Request) interface{} {
coreClone := *core.CoreApp
- coreClone.Started = utils.Timezoner(coreClone.Started, coreClone.Timezone)
return *coreClone.ToCore()
}
diff --git a/types/service.go b/types/service.go
index 2ab977c9..1ff34d86 100644
--- a/types/service.go
+++ b/types/service.go
@@ -21,43 +21,46 @@ import (
// Service is the main struct for Services
type Service struct {
- Id int64 `gorm:"primary_key;column:id" json:"id"`
- Name string `gorm:"column:name" json:"name"`
- Domain string `gorm:"column:domain" json:"domain" private:"true" scope:"user,admin"`
- Expected NullString `gorm:"column:expected" json:"expected" scope:"user,admin"`
- ExpectedStatus int `gorm:"default:200;column:expected_status" json:"expected_status" scope:"user,admin"`
- Interval int `gorm:"default:30;column:check_interval" json:"check_interval" scope:"user,admin"`
- Type string `gorm:"column:check_type" json:"type" scope:"user,admin"`
- Method string `gorm:"column:method" json:"method" scope:"user,admin"`
- PostData NullString `gorm:"column:post_data" json:"post_data" scope:"user,admin"`
- Port int `gorm:"not null;column:port" json:"port" scope:"user,admin"`
- Timeout int `gorm:"default:30;column:timeout" json:"timeout" scope:"user,admin"`
- Order int `gorm:"default:0;column:order_id" json:"order_id"`
- AllowNotifications NullBool `gorm:"default:true;column:allow_notifications" json:"allow_notifications" scope:"user,admin"`
- VerifySSL NullBool `gorm:"default:false;column:verify_ssl" json:"verify_ssl" scope:"user,admin"`
- Public NullBool `gorm:"default:true;column:public" json:"public"`
- GroupId int `gorm:"default:0;column:group_id" json:"group_id"`
- Headers NullString `gorm:"column:headers" json:"headers" scope:"user,admin"`
- Permalink NullString `gorm:"column:permalink" json:"permalink"`
- CreatedAt time.Time `gorm:"column:created_at" json:"created_at"`
- UpdatedAt time.Time `gorm:"column:updated_at" json:"updated_at"`
- Online bool `gorm:"-" json:"online"`
- Latency float64 `gorm:"-" json:"latency"`
- PingTime float64 `gorm:"-" json:"ping_time"`
- Online24Hours float32 `gorm:"-" json:"online_24_hours"`
- AvgResponse string `gorm:"-" json:"avg_response"`
- Running chan bool `gorm:"-" json:"-"`
- Checkpoint time.Time `gorm:"-" json:"-"`
- SleepDuration time.Duration `gorm:"-" json:"-"`
- LastResponse string `gorm:"-" json:"-"`
- UserNotified bool `gorm:"-" json:"-"` // True if the User was already notified about a Downtime
- UpdateNotify bool `gorm:"-" json:"-"` // This Variable is a simple copy of `core.CoreApp.UpdateNotify.Bool`
- DownText string `gorm:"-" json:"-"` // Contains the current generated Downtime Text
- SuccessNotified bool `gorm:"-" json:"-"` // Is 'true' if the user has already be informed that the Services now again available
- LastStatusCode int `gorm:"-" json:"status_code"`
- LastOnline time.Time `gorm:"-" json:"last_success"`
- Failures []FailureInterface `gorm:"-" json:"failures,omitempty" scope:"user,admin"`
- Checkins []CheckinInterface `gorm:"-" json:"checkins,omitempty" scope:"user,admin"`
+ Id int64 `gorm:"primary_key;column:id" json:"id"`
+ Name string `gorm:"column:name" json:"name"`
+ Domain string `gorm:"column:domain" json:"domain" private:"true" scope:"user,admin"`
+ Expected NullString `gorm:"column:expected" json:"expected" scope:"user,admin"`
+ ExpectedStatus int `gorm:"default:200;column:expected_status" json:"expected_status" scope:"user,admin"`
+ Interval int `gorm:"default:30;column:check_interval" json:"check_interval" scope:"user,admin"`
+ Type string `gorm:"column:check_type" json:"type" scope:"user,admin"`
+ Method string `gorm:"column:method" json:"method" scope:"user,admin"`
+ PostData NullString `gorm:"column:post_data" json:"post_data" scope:"user,admin"`
+ Port int `gorm:"not null;column:port" json:"port" scope:"user,admin"`
+ Timeout int `gorm:"default:30;column:timeout" json:"timeout" scope:"user,admin"`
+ Order int `gorm:"default:0;column:order_id" json:"order_id"`
+ AllowNotifications NullBool `gorm:"default:true;column:allow_notifications" json:"allow_notifications" scope:"user,admin"`
+ VerifySSL NullBool `gorm:"default:false;column:verify_ssl" json:"verify_ssl" scope:"user,admin"`
+ Public NullBool `gorm:"default:true;column:public" json:"public"`
+ GroupId int `gorm:"default:0;column:group_id" json:"group_id"`
+ Headers NullString `gorm:"column:headers" json:"headers" scope:"user,admin"`
+ Permalink NullString `gorm:"column:permalink" json:"permalink"`
+ CreatedAt time.Time `gorm:"column:created_at" json:"created_at"`
+ UpdatedAt time.Time `gorm:"column:updated_at" json:"updated_at"`
+ Online bool `gorm:"-" json:"online"`
+ Latency float64 `gorm:"-" json:"latency"`
+ PingTime float64 `gorm:"-" json:"ping_time"`
+ Online24Hours float32 `gorm:"-" json:"online_24_hours"`
+ Online7Days float32 `gorm:"-" json:"online_7_days"`
+ AvgResponse float64 `gorm:"-" json:"avg_response"`
+ FailuresLast24Hours uint64 `gorm:"-" json:"failures_24_hours"`
+ LastFailure FailureInterface `gorm:"-" json:"last_failure,omitempty"`
+ Running chan bool `gorm:"-" json:"-"`
+ Checkpoint time.Time `gorm:"-" json:"-"`
+ SleepDuration time.Duration `gorm:"-" json:"-"`
+ LastResponse string `gorm:"-" json:"-"`
+ UserNotified bool `gorm:"-" json:"-"` // True if the User was already notified about a Downtime
+ UpdateNotify bool `gorm:"-" json:"-"` // This Variable is a simple copy of `core.CoreApp.UpdateNotify.Bool`
+ DownText string `gorm:"-" json:"-"` // Contains the current generated Downtime Text
+ SuccessNotified bool `gorm:"-" json:"-"` // Is 'true' if the user has already be informed that the Services now again available
+ LastStatusCode int `gorm:"-" json:"status_code"`
+ LastOnline time.Time `gorm:"-" json:"last_success"`
+ Failures []FailureInterface `gorm:"-" json:"failures,omitempty" scope:"user,admin"`
+ Checkins []CheckinInterface `gorm:"-" json:"checkins,omitempty" scope:"user,admin"`
}
// BeforeCreate for Service will set CreatedAt to UTC