gecko/api/health/checks.go

75 lines
2.2 KiB
Go

// (c) 2020, Ava Labs, Inc. All rights reserved.
// See the file LICENSE for licensing terms.
package health
import (
"errors"
"time"
)
var (
// ErrHeartbeatNotDetected is returned from a HeartbeatCheckFn when the
// heartbeat has not been detected recently enough
ErrHeartbeatNotDetected = errors.New("heartbeat not detected")
)
// CheckFn returns optional status information and an error indicating health or
// non-health
type CheckFn func() (interface{}, error)
// Check defines a single health check that we want to monitor and consider as
// part of our wider healthiness
type Check struct {
// Name is the identifier for this check and must be unique among all Checks
Name string
// CheckFn is the function to call to perform the the health check
CheckFn CheckFn
// ExecutionPeriod is the duration to wait between executions of this Check
ExecutionPeriod time.Duration
// InitialDelay is the duration to wait before executing the first time
InitialDelay time.Duration
// InitiallyPassing is whether or not to consider the Check healthy before the
// initial execution
InitiallyPassing bool
}
// gosundheitCheck implements the health.Check interface backed by a CheckFn
type gosundheitCheck struct {
name string
checkFn CheckFn
}
// Name implements the health.Check interface by returning a unique name
func (c gosundheitCheck) Name() string { return c.name }
// Execute implements the health.Check interface by executing the checkFn and
// returning the results
func (c gosundheitCheck) Execute() (interface{}, error) { return c.checkFn() }
// Heartbeater provides a getter to the most recently observed heartbeat
type Heartbeater interface {
GetHeartbeat() int64
}
// HeartbeatCheckFn returns a CheckFn that checks the given heartbeater has
// pulsed within the given duration
func HeartbeatCheckFn(hb Heartbeater, max time.Duration) CheckFn {
return func() (data interface{}, err error) {
// Get the heartbeat and create a data set to return to the caller
hb := hb.GetHeartbeat()
data = map[string]int64{"heartbeat": hb}
// If the current time is after the last known heartbeat + the limit then
// mark our check as failed
if time.Unix(hb, 0).Add(max).Before(time.Now()) {
err = ErrHeartbeatNotDetected
}
return data, err
}
}