pull/429/head
hunterlong 2020-02-03 19:49:17 -08:00
parent cbbee72bd5
commit ad0332e46e
13 changed files with 120 additions and 71 deletions

View File

@ -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,

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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;

View File

@ -7,7 +7,7 @@
Total Services
</div>
<div class="col-4">
<span class="lg_number">48</span>
<span class="lg_number">{{failuresLast24Hours()}}</span>
Failures last 24 Hours
</div>
<div class="col-4">
@ -35,6 +35,11 @@
}
},
methods: {
failuresLast24Hours() {
let total = 0;
this.$store.getters.services.map((s) => { total += s.failures_24_hours })
return total
},
}
}

View File

@ -5,20 +5,20 @@
<div class="col-12">
<h4 class="mt-3">
<router-link :to="`/service/${service.id}`">{{service.name}}</router-link>
<span class="badge bg-success float-right">{{service.online ? "ONLINE" : "OFFLINE"}}</span>
<span class="badge float-right" :class="{'bg-success': service.online, 'bg-danger': !service.online}">{{service.online ? "ONLINE" : "OFFLINE"}}</span>
</h4>
<div class="row stats_area mt-5">
<div class="col-4">
<span class="lg_number">131ms</span>
<span class="lg_number">{{service.avg_response}}ms</span>
Average Response
</div>
<div class="col-4">
<span class="lg_number">100%</span>
<span class="lg_number">{{service.online_24_hours}}%</span>
Uptime last 24 Hours
</div>
<div class="col-4">
<span class="lg_number">100%</span>
<span class="lg_number">{{service.online_7_days}}%</span>
Uptime last 7 Days
</div>
</div>
@ -30,12 +30,15 @@
<ServiceChart :service="service"/>
</div>
<div class="row lower_canvas full-col-12 text-white">
<div class="row lower_canvas full-col-12 text-white" :class="{'bg-success': service.online, 'bg-danger': !service.online}">
<div class="col-10 text-truncate">
<span class="d-none d-md-inline">Online, last Failure was Wednesday 1:16:49PM, Dec 18 2019</span>
<span class="d-none d-md-inline">
{{smallText(service)}}
</span>
</div>
<div class="col-sm-12 col-md-2">
<router-link :to="serviceLink(service)" class="btn btn-success btn-sm float-right dyn-dark btn-block">View Service</router-link>
<router-link :to="serviceLink(service)" class="btn btn-sm float-right dyn-dark btn-block" :class="{'bg-success': service.online, 'bg-danger': !service.online}">
View Service</router-link>
</div>
</div>
@ -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}`
}
}
}
}
</script>

View File

@ -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: [{

View File

@ -147,7 +147,9 @@
</div>
<div class="form-group row">
<div class="col-12">
<button @click.prevent="saveService" type="submit" class="btn btn-success btn-block">Create Service</button>
<button @click.prevent="saveService" type="submit" class="btn btn-success btn-block">
{{service.id ? "Update Service" : "Create Service"}}
</button>
</div>
</div>
<div class="alert alert-danger d-none" id="alerter" role="alert"></div>
@ -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)
}
}
}
</script>

View File

@ -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() {

View File

@ -22,6 +22,8 @@
</template>
<script>
import Api from '../components/API';
const Header = () => import("@/components/Index/Header");
const ServiceBlock = () => import("@/components/Service/ServiceBlock.vue");
const MessageBlock = () => import("@/components/Index/MessageBlock");
@ -40,10 +42,14 @@ export default {
}
},
created() {
async created() {
const core = await Api.core()
context.commit("setCore", core);
if (!core.setup) {
this.$router.push('/setup')
}
},
mounted() {
async mounted() {
},
methods: {
@ -51,7 +57,7 @@ export default {
const start = this.isBetween(new Date(), message.start_on)
const end = this.isBetween(message.end_on, new Date())
return start && end
},
}
}
}
</script>

View File

@ -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()
}

View File

@ -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