Documentation ¶
Overview ¶
Package health implements health check clients to return server system statuses.
Index ¶
- Constants
- Variables
- func Equal(first, second ServiceStatus) bool
- func VersionChanged(first, second ServiceStatus) bool
- type APIMonitor
- type APIServiceStatus
- func (h *APIServiceStatus) Hash() []byte
- func (h *APIServiceStatus) Marshal() ([]byte, error)
- func (h *APIServiceStatus) ParseStatus() (Status, error)
- func (h *APIServiceStatus) Prev() (_ ServiceStatus, err error)
- func (h *APIServiceStatus) Status() Status
- func (h *APIServiceStatus) Unmarshal(data []byte) error
- func (h *APIServiceStatus) Version() string
- type BaseStatus
- type EnsignMonitor
- type EnsignStatus
- type HTTPMonitor
- func (h *HTTPMonitor) CheckError(err error) Status
- func (h *HTTPMonitor) CheckRedirect(req *http.Request, via []*http.Request) error
- func (h *HTTPMonitor) Do(req *http.Request) (*http.Response, error)
- func (h *HTTPMonitor) NewRequest(ctx context.Context) (req *http.Request, err error)
- func (h *HTTPMonitor) Status(ctx context.Context) (_ ServiceStatus, err error)
- type HTTPServiceStatus
- type Monitor
- type MonitorOption
- type Options
- type ServiceStatus
- type Status
- type StatusChange
- type Versioned
Constants ¶
const ( DegradedThreshold = 1 * time.Minute UnhealthyThreshold = 2 * time.Minute OfflineThreshold = 5 * time.Minute )
If the time between relative statuses is greater than this threshold then the status should be escalated; e.g. degraded to unhealthy or offline to outage.
Variables ¶
var ( ErrTooManyRedirects = errors.New("too many redirects, reporting unhealthy server") ErrNoContent = errors.New("api response did not contain any content") ErrNoStatusResponse = errors.New("api response did not contain a status") ErrUnparsableStatus = errors.New("api response status is unparsable") ErrNoServiceID = errors.New("service id must be specified before status can be saved to db") ErrNoTimestamp = errors.New("the service status does not have a checked at timestamp") )
Functions ¶
func Equal ¶
func Equal(first, second ServiceStatus) bool
Equal compares the statuses to determine if they're the same without taking into account variable data between checks such as timestamps.
func VersionChanged ¶
func VersionChanged(first, second ServiceStatus) bool
Checks if the service statuses are versioned, and if so, if the version has changed.
Types ¶
type APIMonitor ¶
type APIMonitor struct {
HTTPMonitor
}
APIMonitor extends the HTTPMonitor to read JSON responses from the request to detect version and uptime information as well as to read the service state directly from the response of the server. Standard Rotational services generally provide more details at their status endpoints that can be parsed into this struct.
The API monitor will parse the response body from any status code so long as the response contains a
func NewAPIMonitor ¶
func NewAPIMonitor(endpoint string, opts ...MonitorOption) (mon *APIMonitor, err error)
func (*APIMonitor) Status ¶
func (h *APIMonitor) Status(ctx context.Context) (_ ServiceStatus, err error)
Executes an HTTP request to the wrapped endpoint and creates an APIServiceStatus with the status code and parsed API response body or a client error. This method does not return request errors (e.g. on timeout or could not connect) since this is a state signal. If an error is returned it is because the status check could not be executed at all. If the response body cannot be parsed then the status code is used to determine the service status.
type APIServiceStatus ¶
type APIServiceStatus struct { HTTPServiceStatus Content map[string]interface{} `msgpack:"content"` }
func (*APIServiceStatus) Hash ¶
func (h *APIServiceStatus) Hash() []byte
Hashes the status code, parsed status, version, error, and error type for comparison purposes.
func (*APIServiceStatus) Marshal ¶
func (h *APIServiceStatus) Marshal() ([]byte, error)
Marshal to msgpack binary data for storage.
func (*APIServiceStatus) ParseStatus ¶
func (h *APIServiceStatus) ParseStatus() (Status, error)
ParseStatus from the API response, returning an error if the response did not contain a status value or if the status in the response could not be parsed.
func (*APIServiceStatus) Prev ¶
func (h *APIServiceStatus) Prev() (_ ServiceStatus, err error)
Return the previous HTTPServiceStatus
func (*APIServiceStatus) Status ¶
func (h *APIServiceStatus) Status() Status
func (*APIServiceStatus) Unmarshal ¶
func (h *APIServiceStatus) Unmarshal(data []byte) error
Unmarshal from msgpack binary data.
func (*APIServiceStatus) Version ¶
func (h *APIServiceStatus) Version() string
Version attempts to get version information from the API response.
type BaseStatus ¶
type BaseStatus struct { ID []byte `msgpack:"id"` Timestamp time.Time `msgpack:"timestamp"` // contains filtered or unexported fields }
func (*BaseStatus) CheckedAt ¶
func (h *BaseStatus) CheckedAt() time.Time
func (*BaseStatus) GetServiceID ¶
func (h *BaseStatus) GetServiceID() (uuid.UUID, error)
func (*BaseStatus) Key ¶
func (h *BaseStatus) Key() ([]byte, error)
Key returns the service status ID as the key and error if no key is set.
func (*BaseStatus) SetServiceID ¶
func (h *BaseStatus) SetServiceID(sid uuid.UUID)
type EnsignMonitor ¶
type EnsignMonitor struct {
// contains filtered or unexported fields
}
EnsignMonitor wraps a gRPC Ensign client to perform health checks.
func NewEnsignMonitor ¶
func NewEnsignMonitor(endpoint string, opts ...MonitorOption) (mon *EnsignMonitor, err error)
func (*EnsignMonitor) Status ¶
func (h *EnsignMonitor) Status(ctx context.Context) (_ ServiceStatus, err error)
type EnsignStatus ¶
type EnsignStatus struct { BaseStatus Code codes.Code `msgpack:"code"` Error string `msgpack:"error"` ErrorType Status `msgpack:"error_type"` EnsignState api.ServiceState_Status `msgpack:"ensign_state"` EnsignUptime time.Duration `msgpack:"uptime"` EnsignVersion string `msgpack:"version"` }
EnsignStatus determines the health of the status by its status response.
func (*EnsignStatus) Hash ¶
func (h *EnsignStatus) Hash() []byte
Hashes the status code, error, and error type for comparison purposes.
func (*EnsignStatus) Marshal ¶
func (h *EnsignStatus) Marshal() ([]byte, error)
Marshal to msgpack binary data for storage.
func (*EnsignStatus) Prev ¶
func (h *EnsignStatus) Prev() (_ ServiceStatus, err error)
Return the previous EnsignStatus
func (*EnsignStatus) Status ¶
func (h *EnsignStatus) Status() Status
func (*EnsignStatus) Unmarshal ¶
func (h *EnsignStatus) Unmarshal(data []byte) error
Unmarshal from msgpack binary data.
func (*EnsignStatus) Version ¶
func (h *EnsignStatus) Version() string
Version attempts to get version information from the API response.
type HTTPMonitor ¶
type HTTPMonitor struct {
// contains filtered or unexported fields
}
HTTPMonitor is a simple status check that uses the status code to determine the state that the endpoint is in. All that is compared is the status code from the response -- no data in the response is parsed. This check can be used to embed more detailed status checks, however.
func NewHTTPMonitor ¶
func NewHTTPMonitor(endpoint string, opts ...MonitorOption) (mon *HTTPMonitor, err error)
func (*HTTPMonitor) CheckError ¶
func (h *HTTPMonitor) CheckError(err error) Status
CheckError attempts to determine the status of a service based on the error returned by executing the request without a successful response.
func (*HTTPMonitor) CheckRedirect ¶
If the server returns a 301 or 308 then update the monitor's endpoint.
func (*HTTPMonitor) NewRequest ¶
Create a new HTTP request with the specified headers
func (*HTTPMonitor) Status ¶
func (h *HTTPMonitor) Status(ctx context.Context) (_ ServiceStatus, err error)
Executes an HTTP request to the wrapped endpoint and creates an HTTPServiceStatus with the resulting status code or error. This method does not return request errors, e.g. if the client request fails or times out (since this is a state signal). If an error is returned from this method it is because the status check could not be made at all, e.g. the request could not be created to even execute a request.
type HTTPServiceStatus ¶
type HTTPServiceStatus struct { BaseStatus Endpoint string `msgpack:"endpoint"` StatusCode int `msgpack:"status_code"` Error string `msgpack:"error"` ErrorType Status `msgpack:"error_type"` }
HTTPServiceStatus determines the health of a service by only its status code or by the presence of an error if it is returned by the client (e.g. could not connect).
func (*HTTPServiceStatus) Hash ¶
func (h *HTTPServiceStatus) Hash() []byte
Hashes the status code, error, and error type for comparison purposes.
func (*HTTPServiceStatus) Marshal ¶
func (h *HTTPServiceStatus) Marshal() ([]byte, error)
Marshal to msgpack binary data for storage.
func (*HTTPServiceStatus) Prev ¶
func (h *HTTPServiceStatus) Prev() (_ ServiceStatus, err error)
Return the previous HTTPServiceStatus
func (*HTTPServiceStatus) Status ¶
func (h *HTTPServiceStatus) Status() Status
func (*HTTPServiceStatus) Unmarshal ¶
func (h *HTTPServiceStatus) Unmarshal(data []byte) error
Unmarshal from msgpack binary data.
type Monitor ¶
type Monitor interface {
Status(ctx context.Context) (ServiceStatus, error)
}
Monitor is meant to wrap a service endpoint and return a service status. These checks can be http or gRPC based or some other network connection. They can also generically check if a service is online or parse a specific service's expected response to generate incident reports.
type MonitorOption ¶
MonitorOption are used to configure monitors to make correct requests. MonitorOptions are used across different monitors and not all options are applicable. See the docstring of the monitor to determine which options are available for it.
func WithEnsignInsecure ¶
func WithEnsignInsecure() MonitorOption
Connect to Ensign without TLS credentials
func WithHTTPClient ¶
func WithHTTPClient(client *http.Client) MonitorOption
Use the specified http client instead of the default http client.
func WithHTTPMethod ¶
func WithHTTPMethod(method string) MonitorOption
Use the specified http method instead of GET
type Options ¶
type Options struct { HTTPClient *http.Client // Used to specify an HTTP client to the HTTP monitor. HTTPMethod string // Used to specify the method to make status requests with. EnsignInsecure bool // If specified, will connect to Ensign without TLS }
Options are configurations provided to Monitors.
func NewOptions ¶
func NewOptions(opts ...MonitorOption) (*Options, error)
type ServiceStatus ¶
type ServiceStatus interface { db.Model // In order to support quick comparisons between service statuses of the same type, // the data should be hashed uniquely into bytes so that it can be compared with // another hash in a deterministic fashion. This is used by the // ComparableServiceStatus embedding to implement the Equal() method. The data to // be hashed should only include data that users are interested in changes for, e.g. // the readiness state, the version number, etc. It should exclude variable or // continuous data such as uptime, number of requests, etc. // // If computing the hash errors then the method should panic or return a nil hash // depending on the severity of possible errors. Hash() []byte // Status should return the current service status as determined by the health check. Status() Status // CheckedAt should return the time that the check was conducted. CheckedAt() time.Time // SetServiceID allows external users to specify an ID prefix for the Key. SetServiceID(sid uuid.UUID) // Prev returns the previous status from the database Prev() (ServiceStatus, error) }
type Status ¶
type Status uint
func ParseStatus ¶
Parse Status attempts to parse a status message from a string.
func RelativeStatus ¶
func RelativeStatus(previous, current ServiceStatus) Status
Relative status computes the status between two consecutive service statuses. For example, if the previous status was unhealthy and the current status is also unhealthy but the time between statuses is greater than 5 minutes then return outage.
type StatusChange ¶
type StatusChange uint
const ( NoChange StatusChange = iota BackOnline Deescalating NoLongerHealthy Escalating )
func CompareStatus ¶
func CompareStatus(previous, current Status) StatusChange