health

package module
v0.1.0 Latest Latest
Warning

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

Go to latest
Published: Feb 29, 2024 License: Apache-2.0 Imports: 4 Imported by: 0

README

Health

This library provides a mechanism for a service to check its health and report it to any type of listener. The most common use case for this library is a service running as a kubernetes pod, but it is useful in any running Go service.

Concepts

Manager

The manager is responsible for managing individual health checks and subsequent reporters. It handles setup and teardown of checkers and reporters. It also manages check frequencies and whether liveness and readiness should be affected

Checker

A checker is anything that implements the Checker interface. For one-off checks, you can use the CheckerFunc type to wrap them (see example below).

Reporter

A reporter is anything that reports the status of health checks. The current reporters are:

httpserver

This reporter runs an HTTP server (default port 8181) that reports liveness at /health/live and readiness at /health/ready. Passing checks will always return an HTTP 200 (OK) response, while failing checks will always return an HTTP 503 (Service Unavailable) response.

stdout

This reporter prints to stdout

test

this reporter can be used for tests

Basic Example

The following is a basic example of how this library can be used

package main

import (
	"context"
	"log"
	"os/signal"
	"syscall"
	"time"

	"github.com/schigh/health"
	"github.com/schigh/health/manager/std"
	healthpb "github.com/schigh/health/pkg/v1"
	"github.com/schigh/health/reporter/stdout"
)

func main() {
	ctx, cancel := signal.NotifyContext(context.Background(), syscall.SIGINT, syscall.SIGTERM)
	defer cancel()

	// create an instance of a health check manager
	mgr := std.Manager{}

	// add a spurious health check that runs at a 5-second interval
	_ = mgr.AddCheck(
		"test_check",
		health.CheckerFunc(func(ctx context.Context) *healthpb.Check {
			log.Print("Running health check")
			return &healthpb.Check{
				Name:             "test_check",
				Healthy:          true,
				AffectsLiveness:  true,
				AffectsReadiness: true,
			}
		}),
		health.WithCheckFrequency(health.CheckAtInterval, 5*time.Second, 0),
		health.WithCheckImpact(true, true),
	)

	// add a reporter
	_ = mgr.AddReporter("stdout", &stdout.Reporter{})

	// run the manager
	// This returns a read-only error channel. You can ignore this if you like.
	errChan := mgr.Run(ctx)

	// this toy example won't pipe any errors, but the handling 
	// is here to demonstrate how that should be done
	for {
		select {
		case err := <-errChan:
			log.Printf("error: %v", err)
		case <-ctx.Done():
			_ = mgr.Stop(ctx) // remember to stop the manager
			return
		}
	}
}

Planned updates

  • currently the http reporter used the chi muxxer. I plan to remove it and just use servemux
  • The documentation was hastily assembled, it's definitely WIP
  • add more examples
  • add more basic checkers

Documentation

Index

Constants

This section is empty.

Variables

View Source
var ErrAddCheckAlreadyRunning = errors.New("health: cannot add a health check to a running health instance")

Functions

This section is empty.

Types

type AddCheckOption

type AddCheckOption func(*AddCheckOptions)

AddCheckOption is a functional option for adding a Checker to a health managers.

func WithCheckFrequency

func WithCheckFrequency(f CheckFrequency, interval, delay time.Duration) AddCheckOption

WithCheckFrequency tells the health instance the CheckFrequency at which it will perform check with the specified Checker instance. If the value for CheckFrequency is CheckOnce, the Interval parameter is ignored. If the value for CheckFrequency is CheckAtInterval, the value of Interval will be used. If the value of Interval is equal to or less than zero, then the default Interval is used. If the value of Delay is equal to or less than zero, it is ignored. This option is not additive, so multiple invocations of this option will result in the last invocation being used to configure the Checker.

func WithCheckImpact

func WithCheckImpact(liveness, readiness bool) AddCheckOption

WithCheckImpact tells the health instance that a healthcheck affects either the liveness or readiness of the application. Liveness and readiness are ways Kubernetes determines the fitness of a pod (https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-startup-probes/). If liveness is affected by the failing health check, then readiness is also affected. By default, application liveness and readiness are not affected by health check.

type AddCheckOptions

type AddCheckOptions struct {
	Frequency        CheckFrequency
	Delay            time.Duration
	Interval         time.Duration
	AffectsLiveness  bool
	AffectsReadiness bool
}

AddCheckOptions contain the options needed to add a new health check to the manager.

type CheckFrequency

type CheckFrequency uint

CheckFrequency is a set of flags to instruct the.

const (
	// CheckOnce instructs the Checker to perform its check one time. If the
	// CheckAfter flag is set, CheckOnce will perform the check after a duration
	// specified by the desired configuration.
	CheckOnce CheckFrequency = 1 << iota

	// CheckAtInterval instructs the Checker to perform its check at a specified
	// Interval. If the CheckAfter flag is set, this check will begin after a
	// lapse of the combined Delay and Interval.
	CheckAtInterval

	// CheckAfter instructs the Checker to wait until after a specified time to
	// perform its check.
	CheckAfter
)

type Checker

type Checker interface {
	// Check runs the health check and returns a check result
	Check(context.Context) *healthpb.Check
}

Checker performs an individual health check and returns the result to the health manager.

type CheckerFunc

type CheckerFunc func(context.Context) *healthpb.Check

CheckerFunc is a functional health checker.

func (CheckerFunc) Check

func (cf CheckerFunc) Check(ctx context.Context) *healthpb.Check

Check satisfies Checker.

type Config

type Config struct {
	HTTPPort          int    `envconfig:"HEALTH_HTTP_PORT" default:"8181"`
	LivenessEndpoint  string `envconfig:"HEALTH_LIVENESS_ENDPOINT" default:"/live"`
	ReadinessEndpoint string `envconfig:"HEALTH_READINESS_ENDPOINT" default:"/ready"`
}

type Logger

type Logger interface {
	Debug(msg string, args ...any)
	Info(msg string, args ...any)
	Warn(msg string, args ...any)
	Error(msg string, args ...any)
}

type Manager

type Manager interface {
	// Run the health check manager. Invoking this will initialize all managed
	// checks and reporters. This function returns a read-only channel of errors.
	// If a non-nil error is propagated across this channel, that means the health
	// check manager has entered an unrecoverable state, and the application
	// should halt.
	Run(context.Context) <-chan error

	// Stop the manager and all included checks and reporters. Should be called
	// when an application is shutting down gracefully.
	Stop(context.Context) error

	// AddCheck will add a named health checker to the manager. By default, an
	// added check will run once immediately upon startup, and not affect
	// liveness or readiness. Options are available to set an initial check delay,
	// a check interval, and any affects on liveness or readiness. All added
	// health checks must be named uniquely.  Adding a check with the same name
	// as an existing health check (case-insensitive), will overwrite the previous
	// check. Attempting to add a check after the manager is running will return
	// an error.
	AddCheck(name string, c Checker, opts ...AddCheckOption) error

	// AddReporter adds a named health reporters to the manager. Every time a
	// health check is reported, the manager will relay the update to the
	// reporters. All added health reporters must be named uniquely.
	// Adding a reporters with the same name as an existing health reporters
	// (case-insensitive), will overwrite the previous reporters. Attempting to
	// add a reporters after the manager is running will return an error.
	AddReporter(name string, r Reporter) error
}

Manager defines a manager of health checks for the application. A Manager is a running daemon that oversees all the health checks added to it. When a Manager has new health check information, it dispatches an update to its Reporter(s).

type NoOpLogger

type NoOpLogger struct{}

func (NoOpLogger) Debug

func (n NoOpLogger) Debug(_ string, _ ...any)

func (NoOpLogger) Error

func (n NoOpLogger) Error(_ string, _ ...any)

func (NoOpLogger) Info

func (n NoOpLogger) Info(_ string, _ ...any)

func (NoOpLogger) Warn

func (n NoOpLogger) Warn(_ string, _ ...any)

type Reporter

type Reporter interface {
	// Run the reporter
	Run(context.Context) error

	// Stop the reporters and release resources
	Stop(context.Context) error

	// SetLiveness instructs the reporters to relay the liveness of the
	// application to an external observer
	SetLiveness(context.Context, bool)

	// SetReadiness instructs the reporters to relay the readiness of the
	// application to an external observer
	SetReadiness(context.Context, bool)

	// UpdateHealthChecks is called from the manager to update the reported health checks. Only new health check invocations
	UpdateHealthChecks(context.Context, map[string]*healthpb.Check)
}

Reporter reports the health status of the application to a receiving output. The mechanism by which the Reporter sends this information is implementation-dependent. Some reporters, such as an HTTP server, are pull-based, while others, such as a stdout reporters, are push-based. Each reporters variant is responsible for managing the health information passed to it from the health Manager. A Manager may have multiple reporters, and a Reporter may have multiple providers. The common dialog between reporters and providers is a map of HealthCheck items keyed by string. It is implied that all health checks within a system are named uniquely. A Reporter must be prepared to receive updates at any time and at any frequency. A Reporter curates the health checks passed to it.

Directories

Path Synopsis
checker
db
examples
manager
std
Code generated by github.com/schigh/carto.
Code generated by github.com/schigh/carto.
pkg
v1
reporter
stdout
Code generated by github.com/schigh/carto.
Code generated by github.com/schigh/carto.

Jump to

Keyboard shortcuts

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