Documentation
¶
Overview ¶
Package health is a generated GoMock package.
Package health implements liveness and readiness probes for HTTP services.
Probe model ¶
Two probes are provided, following the Kubernetes convention:
Liveness (GET AlivePath) — indicates the process is running and the HTTP server is accepting connections. Always returns 200 OK. Use this as the kubelet liveness probe; a failure restarts the pod.
Readiness (GET ReadyPath) — indicates the service can handle traffic. Runs all registered [Checker]s concurrently and returns 200 OK when all pass, or 503 Service Unavailable when any fail. Use this as the kubelet readiness probe; a failure removes the pod from load-balancer rotation.
Readiness is evaluated live on every request; results are not cached.
Usage ¶
db := &dbChecker{pool: pool} // implements health.Checker
coll := health.New([]health.Checker{db},
health.WithTimeout(5 * time.Second),
health.WithMaxConcurrency(4),
)
handlers := health.NewHandlers(logr, coll)
mux.HandleFunc(health.AlivePath, handlers.AliveHandler)
mux.HandleFunc(health.ReadyPath, handlers.ReadyHandler)
Implementing a Checker ¶
type dbChecker struct{ pool *pgxpool.Pool }
func (c *dbChecker) Name() string { return "postgres" }
func (c *dbChecker) Check(ctx context.Context) error {
return c.pool.Ping(ctx)
}
Concurrency and timeouts ¶
Collector.CheckAll runs checkers concurrently up to WithMaxConcurrency goroutines at a time (default 8). A shared timeout (default 6 s) is applied to the entire CheckAll call, not to individual checkers. Checkers must respect the context they receive to honour this deadline.
Panics inside a checker are recovered and reported as errors so that a single misbehaving checker cannot bring down the health endpoint. The panic value and stack trace are logged via the Collector logger (see WithLogger) but are not included in the HTTP response to avoid leaking internal details.
Index ¶
Constants ¶
const ( // AlivePath is the HTTP path for the liveness probe. // Register it with [Handlers.AliveHandler]. AlivePath = "/health/alive" // ReadyPath is the HTTP path for the readiness probe. // Register it with [Handlers.ReadyHandler]. ReadyPath = "/health/ready" )
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type CheckAllResult ¶
type CheckAllResult struct {
// Results contains one entry per registered checker, in registration order.
// An entry with a non-empty Error field indicates a failed check.
// Checkers that were not started because the shared context expired before
// the semaphore could be acquired are reported with
// Error = "not started: context deadline exceeded", so every entry always
// carries a meaningful Name.
Results []CheckResult
// HasErrors is true if any checker failed or if the shared context expired
// before all checkers could be started.
HasErrors bool
}
CheckAllResult is the aggregated output of Collector.CheckAll.
type CheckResult ¶
type CheckResult struct {
// Name is the value returned by [Checker.Name].
Name string `json:"name"`
// Error is the error message returned by [Checker.Check], or empty if the
// check passed. Omitted from JSON when empty.
Error string `json:"error,omitempty"`
}
CheckResult holds the outcome of a single Checker run. It is included in the JSON body of the readiness response.
type Checker ¶
type Checker interface {
// Name returns a short human-readable identifier for this checker
// (e.g. "postgres", "redis"). Used as the key in readiness responses
// and log output. Must be stable across calls.
//
// Names do not need to be unique, but duplicates make readiness responses
// and log output ambiguous. Prefer distinct names across all checkers.
Name() string
// Check performs the health probe. It should return a non-nil error if the
// dependency is unavailable or degraded. The context carries the deadline
// set by [Collector.CheckAll]; implementations must propagate it to any
// blocking calls (e.g. DB ping, HTTP request).
Check(ctx context.Context) error
}
Checker is the interface that a dependency check must implement. Implementations must be safe for concurrent use and must respect context cancellation to honour the Collector timeout.
type Collector ¶
type Collector struct {
// contains filtered or unexported fields
}
Collector runs a set of [Checker]s concurrently and aggregates their results. Construct one with New; the zero value is not usable.
func New ¶
New creates a Collector with the provided checkers and applies any options. Defaults: maxConcurrency = 8, timeout = 6 s. Passing an empty or nil checkers slice is valid; [CheckAll] will return an empty result immediately.
Returns an error if any element of checkers is nil: a nil Checker cannot provide a name and would panic inside Collector.CheckAll rather than producing a recoverable error result.
Checker names do not have to be unique, but duplicates make readiness responses and log output ambiguous. Prefer distinct names across all checkers.
func (*Collector) CheckAll ¶
func (c *Collector) CheckAll(ctx context.Context) CheckAllResult
CheckAll runs all registered checkers concurrently and returns aggregated results. It is safe to call from multiple goroutines simultaneously.
Execution model:
- A context with [Collector.timeout] is derived from ctx and shared by all checker goroutines. Callers should still pass a meaningful parent context (e.g. the request context) so that an upstream cancellation propagates.
- Up to [Collector.maxConcurrency] checkers run at a time; the rest wait for the semaphore. If the context expires while waiting, the remaining checkers are marked as "not started" and HasErrors is set to true.
- Results are written to pre-allocated index positions so no mutex is needed for the slice itself. HasErrors is updated atomically.
- Panics inside checkers are recovered by [runCheck] and reported as errors.
type Handlers ¶
type Handlers struct {
// contains filtered or unexported fields
}
Handlers exposes the liveness and readiness probes as http.HandlerFunc values. Construct one with NewHandlers.
func NewHandlers ¶
NewHandlers creates a Handlers that delegates readiness checks to coll and logs warnings via logr when any checker fails.
Panics if logr or coll is nil: both are required for correct operation and a nil dereference inside a request handler is harder to diagnose than an early panic at construction time.
func (*Handlers) AliveHandler ¶
func (h *Handlers) AliveHandler(w http.ResponseWriter, _ *http.Request)
AliveHandler is the liveness probe handler. It always returns 200 OK with a static JSON body. No checks are performed: if the HTTP server can route this request, the process is alive.
Response body: {"status":"ok"}.
func (*Handlers) ReadyHandler ¶
func (h *Handlers) ReadyHandler(w http.ResponseWriter, r *http.Request)
ReadyHandler is the readiness probe handler. It runs all registered checkers via Collector.CheckAll and responds based on the outcome:
- 200 OK — all checkers passed; body: {"status":"ok", "checkers":[...]}
- 503 Service Unavail. — one or more checkers failed; body: {"status":"unhealthy", "checkers":[...]}
Only failed checkers are logged at Warn level to keep log volume bounded.
type MockChecker ¶
type MockChecker struct {
// contains filtered or unexported fields
}
MockChecker is a mock of Checker interface.
func NewMockChecker ¶
func NewMockChecker(ctrl *gomock.Controller) *MockChecker
NewMockChecker creates a new mock instance.
func (*MockChecker) Check ¶
func (m *MockChecker) Check(ctx context.Context) error
Check mocks base method.
func (*MockChecker) EXPECT ¶
func (m *MockChecker) EXPECT() *MockCheckerMockRecorder
EXPECT returns an object that allows the caller to indicate expected use.
type MockCheckerMockRecorder ¶
type MockCheckerMockRecorder struct {
// contains filtered or unexported fields
}
MockCheckerMockRecorder is the mock recorder for MockChecker.
func (*MockCheckerMockRecorder) Check ¶
func (mr *MockCheckerMockRecorder) Check(ctx any) *gomock.Call
Check indicates an expected call of Check.
func (*MockCheckerMockRecorder) Name ¶
func (mr *MockCheckerMockRecorder) Name() *gomock.Call
Name indicates an expected call of Name.
type Option ¶
type Option func(*Collector)
Option is a functional option for New.
func WithLogger ¶
WithLogger attaches a logger to the Collector. When set, checker panics are logged at Error level with the panic value and full stack trace before being suppressed in the HTTP response. Without a logger, panics are silently recovered and only reported as "name: panic" in the response body.
func WithMaxConcurrency ¶
WithMaxConcurrency sets the maximum number of [Checker]s that run in parallel during Collector.CheckAll. Values <= 0 are ignored. Default: 8.
func WithTimeout ¶
WithTimeout sets the maximum wall-clock time for a complete Collector.CheckAll call, shared across all checkers. Values <= 0 are ignored. Default: 6 s.
Individual checkers are not given their own deadline; they share this budget. Set the timeout conservatively: it directly affects the latency of the readiness probe endpoint.