health

package
v0.6.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Apr 24, 2023 License: BSD-3-Clause Imports: 25 Imported by: 0

Documentation

Overview

Package health implements health check clients to return server system statuses.

Index

Constants

View Source
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

View Source
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

func (h *HTTPMonitor) CheckRedirect(req *http.Request, via []*http.Request) error

If the server returns a 301 or 308 then update the monitor's endpoint.

func (*HTTPMonitor) Do

func (h *HTTPMonitor) Do(req *http.Request) (*http.Response, error)

Execute an HTTP request with the monitor client - useful for embeddings.

func (*HTTPMonitor) NewRequest

func (h *HTTPMonitor) NewRequest(ctx context.Context) (req *http.Request, err error)

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

type MonitorOption func(*Options) error

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
const (
	Unknown Status = iota
	Online
	Maintenance
	Stopping
	Degraded
	Unhealthy
	Offline
	Outage
)

func ParseStatus

func ParseStatus(s string) (Status, error)

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.

func (Status) String

func (s Status) String() string

type StatusChange

type StatusChange uint
const (
	NoChange StatusChange = iota
	BackOnline
	Deescalating
	NoLongerHealthy
	Escalating
)

func CompareStatus

func CompareStatus(previous, current Status) StatusChange

type Versioned

type Versioned interface {
	Version() string
}

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL