90 lines
1.5 KiB
Go
90 lines
1.5 KiB
Go
package health
|
|
|
|
import (
|
|
"context"
|
|
"time"
|
|
)
|
|
|
|
type CheckResult int
|
|
|
|
const (
|
|
CheckResultUnknown CheckResult = iota
|
|
CheckResultSuccess
|
|
CheckResultFailure
|
|
)
|
|
|
|
func (r CheckResult) String() string {
|
|
switch r {
|
|
case CheckResultSuccess:
|
|
return "SUCCESS"
|
|
case CheckResultFailure:
|
|
return "FAILURE"
|
|
default:
|
|
return "UNKNOWN"
|
|
}
|
|
}
|
|
|
|
type Checker interface {
|
|
Check(ctx context.Context) CheckResult
|
|
Name() string
|
|
Type() string
|
|
}
|
|
|
|
type CheckerConfig struct {
|
|
Name string
|
|
Type string
|
|
Interval time.Duration
|
|
Timeout time.Duration
|
|
Rise int
|
|
Fall int
|
|
Config map[string]interface{}
|
|
}
|
|
|
|
type CheckerState struct {
|
|
Name string
|
|
Healthy bool
|
|
LastResult CheckResult
|
|
LastCheckTime time.Time
|
|
SuccessCount int
|
|
FailureCount int
|
|
TotalChecks int
|
|
ConsecutiveOK int
|
|
ConsecutiveFail int
|
|
}
|
|
|
|
func (s *CheckerState) IsHealthy() bool {
|
|
return s.Healthy
|
|
}
|
|
|
|
func (s *CheckerState) Update(result CheckResult, rise, fall int) bool {
|
|
s.LastResult = result
|
|
s.LastCheckTime = time.Now()
|
|
s.TotalChecks++
|
|
|
|
oldHealthy := s.Healthy
|
|
|
|
switch result {
|
|
case CheckResultSuccess:
|
|
s.SuccessCount++
|
|
s.ConsecutiveOK++
|
|
s.ConsecutiveFail = 0
|
|
|
|
if !s.Healthy && s.ConsecutiveOK >= rise {
|
|
s.Healthy = true
|
|
}
|
|
|
|
case CheckResultFailure:
|
|
s.FailureCount++
|
|
s.ConsecutiveFail++
|
|
s.ConsecutiveOK = 0
|
|
|
|
if s.Healthy && s.ConsecutiveFail >= fall {
|
|
s.Healthy = false
|
|
}
|
|
}
|
|
|
|
return s.Healthy != oldHealthy
|
|
}
|
|
|
|
type StateChangeCallback func(name string, oldHealthy, newHealthy bool)
|