Documentation
¶
Index ¶
- Constants
- Variables
- func AddStatus(err error, status Status) error
- func DefaultHealthResponseCoder(s Status) int
- type Definition
- type Handler
- type HandlerOption
- type HealthResponseCoder
- type Metadata
- type Monitor
- type MonitorOption
- type MonitorState
- type Name
- type Probe
- type ProbeFunc
- type SelfBooler
- type SelfStatuser
- type Status
- type Subsystem
- type Subsystems
- type Updater
Constants ¶
const ( // DefaultProbeInterval is the interval a Monitor will invoke a Probe on // when no interval is set. A Monitor may have its own default, which can // be set via WithDefaultProbeInterval. DefaultProbeInterval time.Duration = 2 * time.Minute )
Variables ¶
var ( // ErrMonitorStarted is returned by Monitor.Start to indicate that the Monitor // has already been started. ErrMonitorStarted = errors.New("the monitor has been started") // ErrMonitorShutdown is returned by Monitor.Shutdown to indicate that the // Monitor has not yet been started or has already been Shutdown. ErrMonitorShutdown = errors.New("the monitor has been shutdown") )
Functions ¶
func AddStatus ¶
AddStatus associates a health Status with the given error. The returned error will wrap err and implement SelfStatuser.
If err already has a status associated with it, it will be replaced with the given status.
func DefaultHealthResponseCoder ¶
DefaultHealthResponseCoder is the default HealthResponseCoder used when no strategy is supplied.
This function returns a 200 for StatusGood, 429 for StatusWarn (consul's convention), and a 500 for any other status.
Types ¶
type Definition ¶
type Definition struct {
// Name is the unique identifier for this subsystem within the Monitor.
Name Name
// Status is the initial status for this subsystem. By default, a subsystem's
// initial state is StatusGood. Use this field to set a different Status that
// will have effect until the first time an update occurs.
Status Status
// NonCritical indicates how this subsystem affects the overall Monitor status. By
// default, this field is false, which means that a subsystem is critical.
//
// A critical subsystem directly affects a Monitor's overall status. If any critical
// subsystems are StatusWarn, the overall status will be StatusWarn. If any critical
// subsystems are StatusBad, the overall status will be StatusBad.
//
// A noncritcal subsystem will never cause a Monitor to be StatusBad. If any noncritical
// subsystem is NOT StatusGood, the overall status will be StatusWarn.
NonCritical bool
// Probe is an optional closure that interrogates this subsystem's state. A probe will be
// called only if both (1) the Monitor has been started, and (2) the subsystem is not paused.
//
// If no Probe is specified, the only way to update a subsystem's state is via its Updater.
Probe Probe
// ProbeInterval is the time interval on which any Probe is invoked. If no Probe is set,
// this field is ignored.
ProbeInterval time.Duration
// Metadata are optional name/value pairs to associate with this subsystem. A caller may
// specify any values in this map to act as metadata for the subsystem.
Metadata Metadata
}
Definition holds the information necessary to create a logical subsystem within a Monitor.
type Handler ¶
type Handler struct {
// contains filtered or unexported fields
}
Handler is an HTTP handler that exposes health status. A Handler uses a Monitor's State to render HTTP responses.
func NewHandler ¶
func NewHandler(opts ...HandlerOption) (*Handler, error)
NewHandler constructs a new health Handler using the supplied set of options.
type HandlerOption ¶
type HandlerOption interface {
// contains filtered or unexported methods
}
HandlerOption is a configurable option for customizing a health Handler.
func WithHealthResponseCoder ¶
func WithHealthResponseCoder(f HealthResponseCoder) HandlerOption
WithHealthResponseCoder sets a custom strategy for determining the HTTP response code for a given health Status.
If this option isn't used or is set to nil, DefaultHealthResponseCoder is used.
func WithMonitor ¶
func WithMonitor(m *Monitor) HandlerOption
WithMonitor sets the health Monitor the Handler uses when presenting status.
type HealthResponseCoder ¶
HealthResponseCoder is a strategy for turning a health Status into an HTTP response code.
type Metadata ¶
type Metadata struct {
// contains filtered or unexported fields
}
Metadata represents an immutable set of name/value pairs. Metadata may be associated with subsystems to expose client-specific metadata.
The zero value of this type is a usable, empty set.
func Map ¶
Map returns an immutable Metadata with the same name/value pairs as the src map. The returned Attributes is a shallow copy of the src.
Values will be of type any in the returned Metadata. This function is genericized to make it easier to turn any map with string keys into Metadata.
func Values ¶
Values returns an immutable Metadata given a sequence of values. The values must occur in a series of pairs, e.g. name1, value1, name2, value2, etc. Thus, even index elements are names and odd index elements are the corresponding values. If there is an odd number of elements passed to this function, the last name is mapped to untyped nil in the returned attributes.
If a name is not a string and does not implement fmt.Stringer, fmt.Sprintf is used to convert it into a string to use as a Metadata key.
func (Metadata) MarshalJSON ¶
MarshalJSON writes this Metadata as a JSON object.
type Monitor ¶
type Monitor struct {
// contains filtered or unexported fields
}
Monitor is a health status monitor for application subsystems. All methods on a Monitor are atomic.
Each subsystem in a Monitor can be updated in one of two ways:
(1) After construction, Get can be used to obtain an Updater for a subsystem. This Updater can be used at any time to update the status of a subsystem, which will cause the overall status of the Monitor to be recomputed.
(2) A subsystem can be defined with a Probe. This Probe is a callback that will be invoked on the configured interval. Each time a Probe returns a result, that Probe's subsystem is update and the overall status of the Monitor is recomputed.
func NewMonitor ¶
func NewMonitor(opts ...MonitorOption) (*Monitor, error)
NewMonitor constructs a health Monitor using the supplied set of options. The returned Monitor will not be running and must be started in order to receive Probe updates.
The set of subsystems is fixed and immutable after construction. The initial value returned by the Monitor from the State method will be computed from the initial states of the subsystems. If no subsystems are configured in the options, the returned Monitor will always report StatusGood as its overall status.
func (*Monitor) Get ¶
Get returns the Updater for a Subsystem. If no such Subsystem exists, this method returns (nil, false).
This method always returns the same Updater instance for a given subsystem. The returned Updater may be used at any time, including when the Monitor has not been started or has been shutdown.
func (*Monitor) Shutdown ¶
Shutdown stops any running tasks. The status of subsystems are preserved. After this method has been called, Probes are no longer run but any Updaters may still be used to update subsystem states.
This method is idempotent. If this Monitor is not running, this method does nothing and returns ErrMonitorShutdown.
func (*Monitor) Start ¶
Start computes the initial, overall state based on the status of the subystems and then starts any background tasks to monitor subsystem Probes. A Monitor may receive updates from subsystems at any time, even before Start is called.
This method is idempotent. If this Monitor has already been started, this method does nothing and returns ErrMonitorStarted.
Start will update the overall timestamp for the State, but will not modify any LastUpdate fields for subsystems.
func (*Monitor) State ¶
func (m *Monitor) State() MonitorState
State returns the last computed state for this Monitor.
type MonitorOption ¶
type MonitorOption interface {
// contains filtered or unexported methods
}
MonitorOption is a configurable option for tailoring a Monitor.
func WithDefaultProbeInterval ¶
func WithDefaultProbeInterval(i time.Duration) MonitorOption
WithDefaultProbeInterval sets the default interval for invoking any registered probes for this Monitor. If unset or nonpositive, the Monitor will use DefaultProbeInterval.
func WithSubsystems ¶
func WithSubsystems(defs ...Definition) MonitorOption
WithSubsystems defines several subsystems for the monitor.
type MonitorState ¶
type MonitorState struct {
// Status is the new overall status of the Monitor.
Status Status `json:"status" yaml:"status"`
// LastUpdate is the timestamp of the monitor's last update to any subsystem.
// This will include updates that may not have changed the status.
//
// This timestamp will always be in UTC.
LastUpdate time.Time `json:"lastUpdate" yaml:"lastUpdate"`
// Subsystems is a snapshot of the state of each subsystem within
// the Monitor.
Subsystems Subsystems `json:"subsystems" yaml:"subsystems"`
}
MonitorState holds a snapshot of the state of a Monitor.
type Name ¶
type Name string
Name is the human-readable identifier for a subsystem. Names must be unique within a Monitor.
type Probe ¶
Probe is a callback type to interrogate a subsystem for its health status. A Probe may consult information out-of-process, so it's passed a context.Context that gets canceled when a Monitor is shutdown.
type ProbeFunc ¶
type ProbeFunc interface {
~func() bool |
~func(context.Context) bool |
~func() error |
~func(context.Context) error |
~func() Status |
~func(context.Context) Status |
~func() (Status, error) |
~func(context.Context) (Status, error)
}
ProbeFunc describes the various closure types that are convertible to Probes. Calling code can convert any closure that satisfies this type via AsProbe.
type SelfBooler ¶
type SelfBooler interface {
// Status indicates the health status for this error. If this method returns false,
// StatusBad is assumed. If this method returns true, StatusGood is assumed.
// Note that this allows errors to indicate a healthy status.
Status() bool
}
SelfBooler is an alternative to SelfStatuser that lets an error simply indicate good or bad health.
type SelfStatuser ¶
type SelfStatuser interface {
// Status returns the health status for this error. Note that this allows
// errors to indicate a healthy status.
Status() Status
}
SelfStatuser is an optional interface that an error can implement to indicate its health status.
type Status ¶
type Status uint8
Status indicates the health status of a single subsystem or the overall application.
const ( // StatusGood indicates a healthy application or subsystem. StatusGood Status = iota // good // StatusWarn indicates an application or subsystem that is usable, but is having problems. StatusWarn // warn // StatusBad indicates an application or subystem that is completely unusable. StatusBad // bad )
func ErrorStatus ¶
ErrorStatus examines an error to determine what health Status to associated with it.
If err is nil, this function returns StatusGood.
If err implements SelfStatuser, then the result of SelfStatuser.Status() is returned.
If err implements SelfBooler, then StatusGood or StatusBad is returned based on the return value of SelfBooler.Status().
For a non-nil error that does not implement one of the optional interfaces in this package, this function returns StatusBad.
func (Status) MarshalText ¶
MarshalText produces the string value of this Status.
type Subsystem ¶
type Subsystem struct {
// Name is the unique identifier for this subsystem.
Name Name `json:"name" yaml:"name"`
// Status is the current status of this subsystem. When creating a
// Monitor, this is the initial status.
Status Status `json:"status" yaml:"status"`
// LastUpdate is the UTC timestamp of the last status update to this subsystem.
// This field is set to the current time upon creation. Only status updates
// affect this timestamp. Pausing or disabling a subsystem does not update
// this field.
LastUpdate time.Time `json:"lastUpdate,omitempty" yaml:"lastUpdate"`
// LastError is the error that occurred with the most recent status update, if any.
// This field is ignored when creating a Monitor.
LastError error `json:"lastError,omitempty" yaml:"lastError"`
// NonCritical indicates whether this subsystem is noncritical, i.e. how it affects
// the overall Monitor status.
NonCritical bool `json:"nonCritical" yaml:"nonCritical"`
// Metadata is the optional set of name/value pairs that were supplied when the
// subsystem was defined.
Metadata Metadata `json:"metadata,omitempty" yaml:"metadata,omitempty"`
}
Subsystem is a snapshot of the current state of a logical subsystem within a monitor.
type Subsystems ¶
type Subsystems struct {
// contains filtered or unexported fields
}
Subsystems is an immutable, iterable sequence of Subsystem snapshots.
func AsSubsystems ¶
func AsSubsystems(subs ...Subsystem) (s Subsystems)
AsSubsystems creates an immutable Subsystems sequence from a slice of individual Subsystem instances. The returned Subsystems will be a shallow copy of the given slice.
If the subs slice is empty, the returned Subsystems will be an immutable, empty sequence.
func (Subsystems) All ¶
func (s Subsystems) All() iter.Seq[Subsystem]
All provides an iterator over this immutable sequence.
func (Subsystems) Get ¶
func (s Subsystems) Get(i int) Subsystem
Get returns the Subsystem at the given 0-based index. If i is negative or not less than Len(), this function panics.
func (Subsystems) Len ¶
func (s Subsystems) Len() int
Len returns the count of Subsystem snapshots in this sequence.
func (Subsystems) MarshalJSON ¶
func (s Subsystems) MarshalJSON() ([]byte, error)
MarshalJSON marshals this sequence as a slice of Subsystems.
type Updater ¶
type Updater interface {
// Update supplies a possibly new status and an optional error that
// occurred while checking the status or otherwise using the subsystem.
Update(Status, error)
}
Updater is a interface that can be used to update a subsystem's health Status as well as pause and resume monitoring.