mirror of https://github.com/statping/statping
limited fialures for service
parent
b9bf873e22
commit
37303351d5
|
@ -10,6 +10,7 @@
|
|||
- Modified Service chart on index page to show ping data along with latency
|
||||
- Added AWS SNS Notifier
|
||||
- Modified dashboard services UI
|
||||
- Modified service.Failures API to include 32 failures (max)
|
||||
|
||||
# 0.90.63 (08-17-2020)
|
||||
- Modified build process to use xgo for all arch builds
|
||||
|
|
|
@ -8,7 +8,7 @@ const tokenKey = "statping_auth";
|
|||
class Api {
|
||||
constructor() {
|
||||
this.version = "0.90.64";
|
||||
this.commit = "d17a3e2384c18e41cd81109f3ac7b42c18481a6d";
|
||||
this.commit = "b9bf873e22de211c28c9f1432c2f115883adbff0";
|
||||
}
|
||||
|
||||
async oauth() {
|
||||
|
|
|
@ -34,8 +34,14 @@
|
|||
</div>
|
||||
|
||||
<div class="row">
|
||||
<ServiceInfo v-for="(service, index) in services" v-bind:key="index" :service="service" />
|
||||
<ServiceInfo v-for="(service, index) in services_no_group" v-bind:key="index" :service="service" />
|
||||
</div>
|
||||
|
||||
<div class="row" v-for="group in groups">
|
||||
<h4 class="h4 col-12 mb-3 mt-2 text-dim"><font-awesome-icon icon="minus" class="mr-3"/> {{group.name}}</h4>
|
||||
<ServiceInfo v-if="group_services(group.id)" v-for="(service, index) in group_services(group.id)" v-bind:key="index" :service="service" />
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
@ -62,10 +68,18 @@
|
|||
},
|
||||
services() {
|
||||
return this.$store.getters.services
|
||||
}
|
||||
},
|
||||
services_no_group() {
|
||||
return this.$store.getters.servicesNoGroup
|
||||
},
|
||||
groups() {
|
||||
return this.$store.getters.groupsInOrder
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
|
||||
group_services(id) {
|
||||
return this.$store.getters.servicesInGroup(id)
|
||||
},
|
||||
failuresLast24Hours() {
|
||||
let total = 0;
|
||||
this.services.map((s) => {
|
||||
|
|
|
@ -1,29 +1,30 @@
|
|||
<template>
|
||||
<div>
|
||||
<Loading :loading="!loaded"/>
|
||||
<div v-if="loaded && isBefore(nowSubtract(86400), service.last_error)" class="text-danger font-2 p-0 m-0 mb-2">
|
||||
<div v-if="loaded && last_failure && failureBefore" class="text-danger font-2 p-0 m-0 mb-2">
|
||||
<font-awesome-icon icon="exclamation" class="mr-1 text-danger" size="1x"/> Recent Failure<br>
|
||||
<span class="font-italic d-inline-block text-dim" style="max-width: 270px">
|
||||
Last failure was {{ago(service.last_error)}} ago. {{service.failures[0].issue}}
|
||||
Last failure was {{ago(service.last_error)}} ago. {{last_failure.issue}}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
|
||||
<div v-if="loaded" v-for="message in messages" class="font-2 p-0 m-0 mb-2">
|
||||
<font-awesome-icon icon="calendar" class="mr-1" size="1x"/> Upcoming Announcement<br>
|
||||
<span class="font-italic font-weight-light">{{message.description}}</span>
|
||||
<span class="font-0 text-dim float-right font-weight-light">@ <strong>{{niceDate(message.start_on)}}</strong>
|
||||
<span class="font-italic font-weight-light text-dim">{{message.description}}</span>
|
||||
<span class="font-0 text-dim float-right font-weight-light mt-1">@ <strong>{{niceDate(message.start_on)}}</strong>
|
||||
</span>
|
||||
</div>
|
||||
<div v-if="loaded" v-for="incident in incidents" class="font-2 p-0 m-0 mb-2">
|
||||
<font-awesome-icon icon="bullhorn" class="mr-1" size="1x"/>Recent Incident<br>
|
||||
<span class="font-italic d-inline-block text-truncate" style="max-width: 270px">{{incident.title}} - {{incident.description}}</span>
|
||||
<span class="font-0 text-dim float-right font-weight-light">@ <strong>{{niceDate(incident.created_at)}}</strong></span>
|
||||
<span class="font-italic d-inline-block text-dim" style="max-width: 270px">{{incident.title}} - {{incident.description}}</span>
|
||||
<span class="font-0 text-dim float-right font-weight-light mt-1">@ <strong>{{niceDate(incident.created_at)}}</strong></span>
|
||||
</div>
|
||||
|
||||
<div v-if="success_event" class="font-2 p-0 m-0 mt-1 mb-3">
|
||||
<div v-if="success_event && !failureBefore" class="font-2 p-0 m-0 mt-1 mb-3">
|
||||
<span class="text-success"><font-awesome-icon icon="check" class="mr-1" size="1x"/>No New Events</span>
|
||||
<span class="font-italic d-inline-block text-truncate text-dim" style="max-width: 270px">Last failure was {{ago(service.last_error)}} ago.</span>
|
||||
<span class="font-italic d-inline-block text-truncate text-dim" style="max-width: 270px">
|
||||
Last failure was {{ago(service.last_error)}} ago.
|
||||
</span>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
@ -47,7 +48,6 @@ name: "ServiceEvents",
|
|||
data() {
|
||||
return {
|
||||
incidents: null,
|
||||
failure: null,
|
||||
loaded: false,
|
||||
}
|
||||
},
|
||||
|
@ -55,6 +55,15 @@ name: "ServiceEvents",
|
|||
this.load()
|
||||
},
|
||||
computed: {
|
||||
last_failure() {
|
||||
if (!this.service.failures) {
|
||||
return null
|
||||
}
|
||||
return this.service.failures[0]
|
||||
},
|
||||
failureBefore() {
|
||||
return this.isAfter(this.parseISO(this.service.last_error), this.nowSubtract(43200).toISOString())
|
||||
},
|
||||
messages() {
|
||||
return this.$store.getters.serviceMessages(this.service.id)
|
||||
},
|
||||
|
@ -68,9 +77,6 @@ name: "ServiceEvents",
|
|||
methods: {
|
||||
async load() {
|
||||
this.loaded = false
|
||||
if (!this.service.online) {
|
||||
this.failure = this.service.failures[0]
|
||||
}
|
||||
await this.getMessages()
|
||||
await this.getIncidents()
|
||||
this.loaded = true
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import Vue from "vue";
|
||||
const { endOfTomorrow, endOfToday, endOfDay, startOfToday, startOfMonth, lastDayOfMonth, subSeconds, getUnixTime, fromUnixTime, differenceInSeconds, formatDistance, addMonths, addSeconds, isWithinInterval } = require('date-fns')
|
||||
const { startOfDay, startOfWeek, endOfMonth, startOfToday, startOfTomorrow, startOfYesterday, endOfYesterday, endOfTomorrow, endOfToday, endOfDay, startOfMonth, lastDayOfMonth, subSeconds, getUnixTime, fromUnixTime, differenceInSeconds, formatDistance, addMonths, addSeconds, isWithinInterval } = require('date-fns')
|
||||
import formatDistanceToNow from 'date-fns/formatDistanceToNow'
|
||||
import format from 'date-fns/format'
|
||||
import parseISO from 'date-fns/parseISO'
|
||||
|
@ -34,7 +34,7 @@ export default Vue.mixin({
|
|||
return lastDayOfMonth(t1)
|
||||
},
|
||||
nowSubtract(seconds) {
|
||||
return subSeconds(new Date(), seconds)
|
||||
return subSeconds(this.now(), seconds)
|
||||
},
|
||||
isAfter(date, compare) {
|
||||
return isAfter(date, parseISO(compare))
|
||||
|
@ -65,6 +65,27 @@ export default Vue.mixin({
|
|||
return endOfToday()
|
||||
case "tomorrow":
|
||||
return endOfTomorrow()
|
||||
case "yesterday":
|
||||
return endOfYesterday()
|
||||
case "month":
|
||||
return endOfMonth(val)
|
||||
}
|
||||
return roundToNearestMinutes(val)
|
||||
},
|
||||
beginningOf(method, val) {
|
||||
switch (val) {
|
||||
case "day":
|
||||
return startOfDay(val)
|
||||
case "today":
|
||||
return startOfToday()
|
||||
case "tomorrow":
|
||||
return startOfTomorrow()
|
||||
case "yesterday":
|
||||
return startOfYesterday()
|
||||
case "week":
|
||||
return startOfWeek()
|
||||
case "month":
|
||||
return startOfMonth(val)
|
||||
}
|
||||
return roundToNearestMinutes(val)
|
||||
},
|
||||
|
|
|
@ -2275,7 +2275,7 @@ OluFxewsEO0QNDrfFb+0gnjYlnGqOFcZjUMXbDdY5oLSPtXohynuTK1qyQ==
|
|||
</div>
|
||||
|
||||
<div class="text-center small text-dim" v-pre>
|
||||
Automatically generated from Statping's Wiki on 2020-08-21 04:07:11.080469 +0000 UTC
|
||||
Automatically generated from Statping's Wiki on 2020-08-21 21:37:10.928279 +0000 UTC
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
|
||||
<div v-if="!loaded" class="row mt-5 mb-5">
|
||||
<div class="col-12 mt-5 mb-2 text-center">
|
||||
<font-awesome-icon icon="circle-notch" class="text-dim" size="3x" spin/>
|
||||
<font-awesome-icon icon="circle-notch" class="text-dim" size="2x" spin/>
|
||||
</div>
|
||||
<div class="col-12 text-center mt-3 mb-3">
|
||||
<span class="text-dim">{{loading_text}}</span>
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
<template>
|
||||
<div class="offset-md-3 offset-0 col-md-6 mt-5">
|
||||
<div class="offset-md-3 offset-lg-4 offset-0 col-lg-4 col-md-6 mt-5">
|
||||
|
||||
<div class="offset-1 col-10 mb-4 mb-md-3">
|
||||
<img alt="Statping Login" class="embed-responsive" src="banner.png">
|
||||
<div class="offset-1 offset-lg-2 col-lg-8 col-10 mb-4 mb-md-3">
|
||||
<img alt="Statping Login" class="embed-responsive" src="http://0.0.0.0:8585/banner.png">
|
||||
</div>
|
||||
|
||||
<div class="login_container col-12 p-4">
|
||||
|
|
|
@ -159,10 +159,10 @@
|
|||
return this.$store.getters.notifiers
|
||||
},
|
||||
version_below() {
|
||||
if (!this.github) {
|
||||
if (!this.github || !this.core.version) {
|
||||
return false
|
||||
}
|
||||
return semver.gt(semver.coerce(this.github.tag_name), this.core.version)
|
||||
return semver.gt(semver.coerce(this.github.tag_name), semver.coerce(this.core.version))
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
|
|
3
go.mod
3
go.mod
|
@ -13,6 +13,8 @@ require (
|
|||
github.com/fsnotify/fsnotify v1.4.9 // indirect
|
||||
github.com/getsentry/sentry-go v0.5.1
|
||||
github.com/go-mail/mail v2.3.1+incompatible
|
||||
github.com/golang/protobuf v1.4.0
|
||||
github.com/gomarkdown/markdown v0.0.0-20200820230800-3724143f5294 // indirect
|
||||
github.com/gorilla/mux v1.7.4
|
||||
github.com/hako/durafmt v0.0.0-20200605151348-3a43fc422dd9
|
||||
github.com/jinzhu/gorm v1.9.12
|
||||
|
@ -30,6 +32,7 @@ require (
|
|||
github.com/spf13/viper v1.6.3
|
||||
github.com/stretchr/testify v1.5.1
|
||||
github.com/t-tiger/gorm-bulk-insert/v2 v2.0.1
|
||||
github.com/tdewolff/minify/v2 v2.8.0 // indirect
|
||||
github.com/wellington/go-libsass v0.9.2
|
||||
github.com/wellington/sass v0.0.0-20160911051022-cab90b3986d6
|
||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9
|
||||
|
|
12
go.sum
12
go.sum
|
@ -114,6 +114,7 @@ github.com/cenkalti/backoff/v4 v4.0.2/go.mod h1:eEew/i+1Q6OrCDZh3WiXYv3+nJwBASZ8
|
|||
github.com/census-instrumentation/opencensus-proto v0.2.0/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
|
||||
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
|
||||
github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc=
|
||||
github.com/cheekybits/is v0.0.0-20150225183255-68e9c0620927/go.mod h1:h/aW8ynjgkuj+NQRlZcDbAbM1ORAbXjXX77sX7T289U=
|
||||
github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
|
||||
github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
|
||||
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
|
||||
|
@ -253,6 +254,8 @@ github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:W
|
|||
github.com/golang/protobuf v1.4.0 h1:oOuy+ugB+P/kBdUnG5QaMXSIyJ1q38wWSojYCb3z5VQ=
|
||||
github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0=
|
||||
github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
|
||||
github.com/gomarkdown/markdown v0.0.0-20200820230800-3724143f5294 h1:rSb2ZQZ3B1rlWBWamxobyn0jTuGZHbPO5Rmjw48uWRM=
|
||||
github.com/gomarkdown/markdown v0.0.0-20200820230800-3724143f5294/go.mod h1:aii0r/K0ZnHv7G0KF7xy1v0A7s2Ljrb5byB7MO5p6TU=
|
||||
github.com/gomodule/redigo v1.7.1-0.20190724094224-574c33c3df38/go.mod h1:B4C85qUVwatsJoIUNIfCRsp7qO0iAmpGFZ4EELWSbC4=
|
||||
github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
|
||||
github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
|
||||
|
@ -397,6 +400,7 @@ github.com/liquidweb/liquidweb-go v1.6.1/go.mod h1:UDcVnAMDkZxpw4Y7NOHkqoeiGacVL
|
|||
github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
|
||||
github.com/magiconair/properties v1.8.1 h1:ZC2Vc7/ZFkGmsVC9KvOjumD+G5lXy2RtTKyzRKO2BQ4=
|
||||
github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
|
||||
github.com/matryer/try v0.0.0-20161228173917-9ac251b645a2/go.mod h1:0KeJpeMD6o+O4hW7qJOT7vyQPKrWmj26uf5wMc/IiIs=
|
||||
github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
|
||||
github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
|
||||
github.com/mattn/go-isatty v0.0.7/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
|
||||
|
@ -576,6 +580,13 @@ github.com/subosito/gotenv v1.2.0 h1:Slr1R9HxAlEKefgq5jn9U+DnETlIUa6HfgEzj0g5d7s
|
|||
github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw=
|
||||
github.com/t-tiger/gorm-bulk-insert/v2 v2.0.1 h1:HGVkRrwDCbmSP6h1CoBDj6l/mhnvsP5JbYaQ4ss0R6o=
|
||||
github.com/t-tiger/gorm-bulk-insert/v2 v2.0.1/go.mod h1:I3xbaE9ud9/TEXzehwkHx86SyJwqeSNsX2X5oV61jIg=
|
||||
github.com/tdewolff/minify v1.1.0 h1:nxHQi1ML+g3ZbZHffiZ6eC7vMqNvSRfX3KB5Y5y/kfw=
|
||||
github.com/tdewolff/minify v2.3.6+incompatible h1:2hw5/9ZvxhWLvBUnHE06gElGYz+Jv9R4Eys0XUzItYo=
|
||||
github.com/tdewolff/minify/v2 v2.8.0 h1:t3tOPWkTpKhsgxm3IM9Sy8hE2eIt30Oaa+2havJGGIE=
|
||||
github.com/tdewolff/minify/v2 v2.8.0/go.mod h1:6zN8VLhMfFxNrwHROcboYNo2+huPNu4SV8DPh3PUQ8E=
|
||||
github.com/tdewolff/parse/v2 v2.4.4 h1:uMdbQRtYbKR/msP9CbI7li9wK6pionYiH6s7ipltyGY=
|
||||
github.com/tdewolff/parse/v2 v2.4.4/go.mod h1:WzaJpRSbwq++EIQHYIRTpbYKNA3gn9it1Ik++q4zyho=
|
||||
github.com/tdewolff/test v1.0.6/go.mod h1:6DAvZliBAAnD7rhVgwaM7DE5/d9NMOAJ09SqYqeK4QE=
|
||||
github.com/timewasted/linode v0.0.0-20160829202747-37e84520dcf7 h1:CpHxIaZzVy26GqJn8ptRyto8fuoYOd1v0fXm9bG3wQ8=
|
||||
github.com/timewasted/linode v0.0.0-20160829202747-37e84520dcf7/go.mod h1:imsgLplxEC/etjIhdr3dNzV3JeT27LbVu5pYWm0JCBY=
|
||||
github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
|
||||
|
@ -629,6 +640,7 @@ go.uber.org/ratelimit v0.0.0-20180316092928-c15da0234277/go.mod h1:2X8KaoNd1J0lZ
|
|||
go.uber.org/ratelimit v0.1.0 h1:U2AruXqeTb4Eh9sYQSTrMhH8Cb7M0Ian2ibBOnBcnAw=
|
||||
go.uber.org/ratelimit v0.1.0/go.mod h1:2X8KaoNd1J0lZV+PxJk/5+DGbO/tpwLR1m++a7FnB/Y=
|
||||
go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
|
||||
golang.org/dl v0.0.0-20190829154251-82a15e2f2ead/go.mod h1:IUMfjQLJQd4UTqG1Z90tenwKoCX93Gn3MAQJMOSBsDQ=
|
||||
golang.org/x/crypto v0.0.0-20180621125126-a49355c7e3f8/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||
golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// DO NOT EDIT ** This file was generated with go generate on 2020-08-06 20:20:14.476432 +0000 UTC ** DO NOT EDIT //
|
||||
// DO NOT EDIT ** This file was generated with go generate on 2020-08-21 21:37:06.638898 +0000 UTC ** DO NOT EDIT //
|
||||
package notifiers
|
||||
|
||||
const emailSuccess = `<!doctype html><html xmlns=http://www.w3.org/1999/xhtml xmlns:v=urn:schemas-microsoft-com:vml xmlns:o=urn:schemas-microsoft-com:office:office><title>Statping Service Notification</title><meta http-equiv=x-ua-compatible content="IE=edge"><meta charset=utf-8><meta name=viewport content="width=device-width,initial-scale=1"><style type=text/css>
|
||||
|
|
|
@ -7,6 +7,8 @@ import (
|
|||
"time"
|
||||
)
|
||||
|
||||
const limitFailures = 32
|
||||
|
||||
func (s *Service) FailuresColumnID() (string, int64) {
|
||||
return "service", s.Id
|
||||
}
|
||||
|
|
|
@ -6,6 +6,11 @@ import (
|
|||
"github.com/statping/statping/utils"
|
||||
)
|
||||
|
||||
func AddNotifier(n ServiceNotifier) {
|
||||
notif := n.Select()
|
||||
allNotifiers[notif.Method] = n
|
||||
}
|
||||
|
||||
func sendSuccess(s *Service) {
|
||||
if !s.AllowNotifications.Bool {
|
||||
return
|
||||
|
|
|
@ -341,11 +341,6 @@ func RecordSuccess(s *Service) {
|
|||
sendSuccess(s)
|
||||
}
|
||||
|
||||
func AddNotifier(n ServiceNotifier) {
|
||||
notif := n.Select()
|
||||
allNotifiers[notif.Method] = n
|
||||
}
|
||||
|
||||
// RecordFailure will create a new 'Failure' record in the database for a offline service
|
||||
func RecordFailure(s *Service, issue, reason string) {
|
||||
s.LastOffline = utils.Now()
|
||||
|
@ -366,6 +361,14 @@ func RecordFailure(s *Service, issue, reason string) {
|
|||
}
|
||||
s.Online = false
|
||||
s.DownText = s.DowntimeText()
|
||||
|
||||
limitOffset := len(s.Failures)
|
||||
if len(s.Failures) >= limitFailures {
|
||||
limitOffset = limitFailures - 1
|
||||
}
|
||||
|
||||
s.Failures = append([]*failures.Failure{fail}, s.Failures[:limitOffset]...)
|
||||
|
||||
metrics.Gauge("online", 0., s.Name, s.Type)
|
||||
metrics.Inc("failure", s.Name)
|
||||
sendFailure(s, fail)
|
||||
|
|
Loading…
Reference in New Issue