mirror of https://github.com/statping/statping
Merge branch 'master' into feature/custom-dialer
commit
a9e9c36510
2
Makefile
2
Makefile
|
@ -232,7 +232,7 @@ dev-deps:
|
||||||
$(GOGET) github.com/ararog/timeago
|
$(GOGET) github.com/ararog/timeago
|
||||||
$(GOGET) gopkg.in/natefinch/lumberjack.v2
|
$(GOGET) gopkg.in/natefinch/lumberjack.v2
|
||||||
$(GOGET) golang.org/x/crypto/bcrypt
|
$(GOGET) golang.org/x/crypto/bcrypt
|
||||||
$(GOGET) github.com/99designs/gqlgen
|
$(GOGET) github.com/99designs/gqlgen/...
|
||||||
|
|
||||||
# remove files for a clean compile/build
|
# remove files for a clean compile/build
|
||||||
clean:
|
clean:
|
||||||
|
|
|
@ -263,6 +263,7 @@ func recordSuccess(s *Service) {
|
||||||
s.CreateHit(hit)
|
s.CreateHit(hit)
|
||||||
s.Online = true
|
s.Online = true
|
||||||
notifier.OnSuccess(s.Service)
|
notifier.OnSuccess(s.Service)
|
||||||
|
s.SuccessNotified = true
|
||||||
}
|
}
|
||||||
|
|
||||||
// recordFailure will create a new 'Failure' record in the database for a offline service
|
// recordFailure will create a new 'Failure' record in the database for a offline service
|
||||||
|
@ -277,5 +278,8 @@ func recordFailure(s *Service, issue string) {
|
||||||
utils.Log(2, fmt.Sprintf("Service %v Failing: %v | Lookup in: %0.2f ms", s.Name, issue, fail.PingTime*1000))
|
utils.Log(2, fmt.Sprintf("Service %v Failing: %v | Lookup in: %0.2f ms", s.Name, issue, fail.PingTime*1000))
|
||||||
s.CreateFailure(fail)
|
s.CreateFailure(fail)
|
||||||
s.Online = false
|
s.Online = false
|
||||||
|
s.SuccessNotified = false
|
||||||
|
s.UpdateNotify = CoreApp.UpdateNotify.Bool
|
||||||
|
s.DownText = s.DowntimeText()
|
||||||
notifier.OnFailure(s.Service, fail.Failure)
|
notifier.OnFailure(s.Service, fail.Failure)
|
||||||
}
|
}
|
||||||
|
|
|
@ -38,6 +38,19 @@ func OnFailure(s *types.Service, f *types.Failure) {
|
||||||
if !s.AllowNotifications.Bool {
|
if !s.AllowNotifications.Bool {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// check if User wants to receive every Status Change
|
||||||
|
if s.UpdateNotify {
|
||||||
|
// send only if User hasn't been already notified about the Downtime
|
||||||
|
if !s.UserNotified {
|
||||||
|
s.UserNotified = true
|
||||||
|
goto sendMessages
|
||||||
|
} else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sendMessages:
|
||||||
for _, comm := range AllCommunications {
|
for _, comm := range AllCommunications {
|
||||||
if isType(comm, new(BasicEvents)) && isEnabled(comm) && inLimits(comm) {
|
if isType(comm, new(BasicEvents)) && isEnabled(comm) && inLimits(comm) {
|
||||||
notifier := comm.(Notifier).Select()
|
notifier := comm.(Notifier).Select()
|
||||||
|
@ -45,7 +58,6 @@ func OnFailure(s *types.Service, f *types.Failure) {
|
||||||
comm.(BasicEvents).OnFailure(s, f)
|
comm.(BasicEvents).OnFailure(s, f)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// OnSuccess will be triggered when a service is successful - BasicEvents interface
|
// OnSuccess will be triggered when a service is successful - BasicEvents interface
|
||||||
|
@ -53,6 +65,12 @@ func OnSuccess(s *types.Service) {
|
||||||
if !s.AllowNotifications.Bool {
|
if !s.AllowNotifications.Bool {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// check if User wants to receive every Status Change
|
||||||
|
if s.UpdateNotify && s.UserNotified {
|
||||||
|
s.UserNotified = false
|
||||||
|
}
|
||||||
|
|
||||||
for _, comm := range AllCommunications {
|
for _, comm := range AllCommunications {
|
||||||
if isType(comm, new(BasicEvents)) && isEnabled(comm) && inLimits(comm) {
|
if isType(comm, new(BasicEvents)) && isEnabled(comm) && inLimits(comm) {
|
||||||
notifier := comm.(Notifier).Select()
|
notifier := comm.(Notifier).Select()
|
||||||
|
@ -60,7 +78,6 @@ func OnSuccess(s *types.Service) {
|
||||||
comm.(BasicEvents).OnSuccess(s)
|
comm.(BasicEvents).OnSuccess(s)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// OnNewService is triggered when a new service is created - ServiceEvents interface
|
// OnNewService is triggered when a new service is created - ServiceEvents interface
|
||||||
|
|
|
@ -63,6 +63,9 @@ var handlerFuncs = func(w http.ResponseWriter, r *http.Request) template.FuncMap
|
||||||
"USE_CDN": func() bool {
|
"USE_CDN": func() bool {
|
||||||
return core.CoreApp.UseCdn.Bool
|
return core.CoreApp.UseCdn.Bool
|
||||||
},
|
},
|
||||||
|
"UPDATENOTIFY": func() bool {
|
||||||
|
return core.CoreApp.UpdateNotify.Bool
|
||||||
|
},
|
||||||
"QrAuth": func() string {
|
"QrAuth": func() string {
|
||||||
return fmt.Sprintf("statping://setup?domain=%v&api=%v", core.CoreApp.Domain, core.CoreApp.ApiSecret)
|
return fmt.Sprintf("statping://setup?domain=%v&api=%v", core.CoreApp.Domain, core.CoreApp.ApiSecret)
|
||||||
},
|
},
|
||||||
|
|
|
@ -62,11 +62,15 @@ func saveSettingsHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
timeFloat, _ := strconv.ParseFloat(timezone, 10)
|
timeFloat, _ := strconv.ParseFloat(timezone, 10)
|
||||||
app.Timezone = float32(timeFloat)
|
app.Timezone = float32(timeFloat)
|
||||||
|
|
||||||
|
app.UpdateNotify = types.NewNullBool(form.Get("update_notify") == "true")
|
||||||
|
|
||||||
app.UseCdn = types.NewNullBool(form.Get("enable_cdn") == "on")
|
app.UseCdn = types.NewNullBool(form.Get("enable_cdn") == "on")
|
||||||
core.CoreApp, err = core.UpdateCore(app)
|
core.CoreApp, err = core.UpdateCore(app)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
utils.Log(3, fmt.Sprintf("issue updating Core: %v", err.Error()))
|
utils.Log(3, fmt.Sprintf("issue updating Core: %v", err.Error()))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//notifiers.OnSettingsSaved(core.CoreApp.ToCore())
|
//notifiers.OnSettingsSaved(core.CoreApp.ToCore())
|
||||||
ExecuteResponse(w, r, "settings.gohtml", core.CoreApp, "/settings")
|
ExecuteResponse(w, r, "settings.gohtml", core.CoreApp, "/settings")
|
||||||
}
|
}
|
||||||
|
@ -144,7 +148,7 @@ func bulkImportHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
// commaToService will convert a CSV comma delimited string slice to a Service type
|
// commaToService will convert a CSV comma delimited string slice to a Service type
|
||||||
// this function is used for the bulk import services feature
|
// this function is used for the bulk import services feature
|
||||||
func commaToService(s []string) (*types.Service, error) {
|
func commaToService(s []string) (*types.Service, error) {
|
||||||
if len(s) != 16 {
|
if len(s) != 17 {
|
||||||
err := fmt.Errorf("does not have the expected amount of %v columns for a service", 16)
|
err := fmt.Errorf("does not have the expected amount of %v columns for a service", 16)
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -169,6 +173,11 @@ func commaToService(s []string) (*types.Service, error) {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
verifySsl, err := strconv.ParseBool(s[16])
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
newService := &types.Service{
|
newService := &types.Service{
|
||||||
Name: s[0],
|
Name: s[0],
|
||||||
Domain: s[1],
|
Domain: s[1],
|
||||||
|
@ -185,6 +194,7 @@ func commaToService(s []string) (*types.Service, error) {
|
||||||
GroupId: int(utils.ToInt(s[13])),
|
GroupId: int(utils.ToInt(s[13])),
|
||||||
Headers: types.NewNullString(s[14]),
|
Headers: types.NewNullString(s[14]),
|
||||||
Permalink: types.NewNullString(s[15]),
|
Permalink: types.NewNullString(s[15]),
|
||||||
|
VerifySSL: types.NewNullBool(verifySsl),
|
||||||
}
|
}
|
||||||
|
|
||||||
return newService, nil
|
return newService, nil
|
||||||
|
|
|
@ -75,9 +75,14 @@ func (u *discord) OnFailure(s *types.Service, f *types.Failure) {
|
||||||
|
|
||||||
// OnSuccess will trigger successful service
|
// OnSuccess will trigger successful service
|
||||||
func (u *discord) OnSuccess(s *types.Service) {
|
func (u *discord) OnSuccess(s *types.Service) {
|
||||||
if !s.Online {
|
if !s.Online || !s.SuccessNotified {
|
||||||
u.ResetUniqueQueue(fmt.Sprintf("service_%v", s.Id))
|
u.ResetUniqueQueue(fmt.Sprintf("service_%v", s.Id))
|
||||||
msg := fmt.Sprintf(`{"content": "Your service '%v' is back online!"}`, s.Name)
|
var msg interface{}
|
||||||
|
if s.UpdateNotify {
|
||||||
|
s.UpdateNotify = false
|
||||||
|
}
|
||||||
|
msg = s.DownText
|
||||||
|
|
||||||
u.AddQueue(fmt.Sprintf("service_%v", s.Id), msg)
|
u.AddQueue(fmt.Sprintf("service_%v", s.Id), msg)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -198,11 +198,17 @@ func (u *email) OnFailure(s *types.Service, f *types.Failure) {
|
||||||
|
|
||||||
// OnSuccess will trigger successful service
|
// OnSuccess will trigger successful service
|
||||||
func (u *email) OnSuccess(s *types.Service) {
|
func (u *email) OnSuccess(s *types.Service) {
|
||||||
if !s.Online {
|
if !s.Online || !s.SuccessNotified {
|
||||||
|
var msg string
|
||||||
|
if s.UpdateNotify {
|
||||||
|
s.UpdateNotify = false
|
||||||
|
}
|
||||||
|
msg = s.DownText
|
||||||
|
|
||||||
u.ResetUniqueQueue(fmt.Sprintf("service_%v", s.Id))
|
u.ResetUniqueQueue(fmt.Sprintf("service_%v", s.Id))
|
||||||
email := &emailOutgoing{
|
email := &emailOutgoing{
|
||||||
To: u.Var2,
|
To: u.Var2,
|
||||||
Subject: fmt.Sprintf("Service %v is Back Online", s.Name),
|
Subject: msg,
|
||||||
Template: mainEmailTemplate,
|
Template: mainEmailTemplate,
|
||||||
Data: interface{}(s),
|
Data: interface{}(s),
|
||||||
From: u.Var1,
|
From: u.Var1,
|
||||||
|
|
|
@ -78,16 +78,22 @@ func (u *lineNotifier) OnFailure(s *types.Service, f *types.Failure) {
|
||||||
|
|
||||||
// OnSuccess will trigger successful service
|
// OnSuccess will trigger successful service
|
||||||
func (u *lineNotifier) OnSuccess(s *types.Service) {
|
func (u *lineNotifier) OnSuccess(s *types.Service) {
|
||||||
if !s.Online {
|
if !s.Online || !s.SuccessNotified {
|
||||||
|
var msg string
|
||||||
|
if s.UpdateNotify {
|
||||||
|
s.UpdateNotify = false
|
||||||
|
}
|
||||||
|
msg = s.DownText
|
||||||
|
|
||||||
u.ResetUniqueQueue(fmt.Sprintf("service_%v", s.Id))
|
u.ResetUniqueQueue(fmt.Sprintf("service_%v", s.Id))
|
||||||
msg := fmt.Sprintf("Your service '%v' is back online!", s.Name)
|
|
||||||
u.AddQueue(fmt.Sprintf("service_%v", s.Id), msg)
|
u.AddQueue(fmt.Sprintf("service_%v", s.Id), msg)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// OnSave triggers when this notifier has been saved
|
// OnSave triggers when this notifier has been saved
|
||||||
func (u *lineNotifier) OnSave() error {
|
func (u *lineNotifier) OnSave() error {
|
||||||
utils.Log(1, fmt.Sprintf("Notification %v is receiving updated information.", u.Method))
|
msg := fmt.Sprintf("Notification %v is receiving updated information.", u.Method)
|
||||||
// Do updating stuff here
|
utils.Log(1, msg)
|
||||||
|
u.AddQueue("saved", message)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -105,10 +105,16 @@ func (u *mobilePush) OnFailure(s *types.Service, f *types.Failure) {
|
||||||
// OnSuccess will trigger successful service
|
// OnSuccess will trigger successful service
|
||||||
func (u *mobilePush) OnSuccess(s *types.Service) {
|
func (u *mobilePush) OnSuccess(s *types.Service) {
|
||||||
data := dataJson(s, nil)
|
data := dataJson(s, nil)
|
||||||
if !s.Online {
|
if !s.Online || !s.SuccessNotified {
|
||||||
|
var msgStr string
|
||||||
|
if s.UpdateNotify {
|
||||||
|
s.UpdateNotify = false
|
||||||
|
}
|
||||||
|
msgStr = s.DownText
|
||||||
|
|
||||||
u.ResetUniqueQueue(fmt.Sprintf("service_%v", s.Id))
|
u.ResetUniqueQueue(fmt.Sprintf("service_%v", s.Id))
|
||||||
msg := &pushArray{
|
msg := &pushArray{
|
||||||
Message: fmt.Sprintf("Your service '%v' is back online!", s.Name),
|
Message: msgStr,
|
||||||
Title: "Service Online",
|
Title: "Service Online",
|
||||||
Topic: mobileIdentifier,
|
Topic: mobileIdentifier,
|
||||||
Data: data,
|
Data: data,
|
||||||
|
|
|
@ -97,9 +97,14 @@ func (u *telegram) OnFailure(s *types.Service, f *types.Failure) {
|
||||||
|
|
||||||
// OnSuccess will trigger successful service
|
// OnSuccess will trigger successful service
|
||||||
func (u *telegram) OnSuccess(s *types.Service) {
|
func (u *telegram) OnSuccess(s *types.Service) {
|
||||||
if !s.Online {
|
if !s.Online || !s.SuccessNotified {
|
||||||
u.ResetUniqueQueue(fmt.Sprintf("service_%v", s.Id))
|
u.ResetUniqueQueue(fmt.Sprintf("service_%v", s.Id))
|
||||||
msg := fmt.Sprintf("Your service '%v' is back online!", s.Name)
|
var msg interface{}
|
||||||
|
if s.UpdateNotify {
|
||||||
|
s.UpdateNotify = false
|
||||||
|
}
|
||||||
|
msg = s.DownText
|
||||||
|
|
||||||
u.AddQueue(fmt.Sprintf("service_%v", s.Id), msg)
|
u.AddQueue(fmt.Sprintf("service_%v", s.Id), msg)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -107,9 +107,14 @@ func (u *twilio) OnFailure(s *types.Service, f *types.Failure) {
|
||||||
|
|
||||||
// OnSuccess will trigger successful service
|
// OnSuccess will trigger successful service
|
||||||
func (u *twilio) OnSuccess(s *types.Service) {
|
func (u *twilio) OnSuccess(s *types.Service) {
|
||||||
if !s.Online {
|
if !s.Online || !s.SuccessNotified {
|
||||||
u.ResetUniqueQueue(fmt.Sprintf("service_%v", s.Id))
|
u.ResetUniqueQueue(fmt.Sprintf("service_%v", s.Id))
|
||||||
msg := fmt.Sprintf("Your service '%v' is back online!", s.Name)
|
var msg string
|
||||||
|
if s.UpdateNotify {
|
||||||
|
s.UpdateNotify = false
|
||||||
|
}
|
||||||
|
msg = s.DownText
|
||||||
|
|
||||||
u.AddQueue(fmt.Sprintf("service_%v", s.Id), msg)
|
u.AddQueue(fmt.Sprintf("service_%v", s.Id), msg)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -90,7 +90,7 @@ $('.toggle-service').on('click',function(e) {
|
||||||
let obj = $(this);
|
let obj = $(this);
|
||||||
let serviceId = obj.attr("data-id");
|
let serviceId = obj.attr("data-id");
|
||||||
let online = obj.attr("data-online");
|
let online = obj.attr("data-online");
|
||||||
let d = confirm("Do you want to "+(online ? "stop" : "start")+" checking this service?");
|
let d = confirm("Do you want to "+(eval(online) ? "stop" : "start")+" checking this service?");
|
||||||
if (d) {
|
if (d) {
|
||||||
$.ajax({
|
$.ajax({
|
||||||
url: "/api/services/" + serviceId + "/running",
|
url: "/api/services/" + serviceId + "/running",
|
||||||
|
|
|
@ -37,6 +37,20 @@
|
||||||
<input type="text" name="description" class="form-control" value="{{ .Description }}" id="description" placeholder="Great Uptime">
|
<input type="text" name="description" class="form-control" value="{{ .Description }}" id="description" placeholder="Great Uptime">
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="form-group">
|
||||||
|
<div class="col-4 col-sm-4 mt-sm-1 mt-0">
|
||||||
|
<label for="update_notify" class="d-inline d-sm-none">Send Updates only</label>
|
||||||
|
<label for="update_notify" class="d-none d-sm-block">Send Updates only</label>
|
||||||
|
|
||||||
|
<span class="switch">
|
||||||
|
<input type="checkbox" name="update_notify-option" class="switch" id="switch-update_notify"{{if UPDATENOTIFY}} checked{{end}}>
|
||||||
|
<label for="switch-update_notify" class="mt-2 mt-sm-0"></label>
|
||||||
|
</span>
|
||||||
|
|
||||||
|
<input type="hidden" name="update_notify" id="switch-update_notify-value" value="{{if UPDATENOTIFY}}true{{else}}false{{end}}">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="form-group row">
|
<div class="form-group row">
|
||||||
<div class="col-8 col-sm-9">
|
<div class="col-8 col-sm-9">
|
||||||
<label for="domain">Domain</label>
|
<label for="domain">Domain</label>
|
||||||
|
|
|
@ -37,6 +37,7 @@ type Core struct {
|
||||||
Version string `gorm:"column:version" json:"version"`
|
Version string `gorm:"column:version" json:"version"`
|
||||||
MigrationId int64 `gorm:"column:migration_id" json:"migration_id,omitempty"`
|
MigrationId int64 `gorm:"column:migration_id" json:"migration_id,omitempty"`
|
||||||
UseCdn NullBool `gorm:"column:use_cdn;default:false" json:"using_cdn,omitempty"`
|
UseCdn NullBool `gorm:"column:use_cdn;default:false" json:"using_cdn,omitempty"`
|
||||||
|
UpdateNotify NullBool `gorm:"column:update_notify;default:false" json:"update_notify,omitempty"`
|
||||||
Timezone float32 `gorm:"column:timezone;default:-8.0" json:"timezone,omitempty"`
|
Timezone float32 `gorm:"column:timezone;default:-8.0" json:"timezone,omitempty"`
|
||||||
CreatedAt time.Time `gorm:"column:created_at" json:"created_at"`
|
CreatedAt time.Time `gorm:"column:created_at" json:"created_at"`
|
||||||
UpdatedAt time.Time `gorm:"column:updated_at" json:"updated_at"`
|
UpdatedAt time.Time `gorm:"column:updated_at" json:"updated_at"`
|
||||||
|
|
|
@ -50,6 +50,10 @@ type Service struct {
|
||||||
Checkpoint time.Time `gorm:"-" json:"-"`
|
Checkpoint time.Time `gorm:"-" json:"-"`
|
||||||
SleepDuration time.Duration `gorm:"-" json:"-"`
|
SleepDuration time.Duration `gorm:"-" json:"-"`
|
||||||
LastResponse string `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"`
|
LastStatusCode int `gorm:"-" json:"status_code"`
|
||||||
LastOnline time.Time `gorm:"-" json:"last_success"`
|
LastOnline time.Time `gorm:"-" json:"last_success"`
|
||||||
Failures []FailureInterface `gorm:"-" json:"failures,omitempty"`
|
Failures []FailureInterface `gorm:"-" json:"failures,omitempty"`
|
||||||
|
|
Loading…
Reference in New Issue