howdy/health
A health check for load balancers, container platforms and uptime
monitors. Mount it with howdy.health_check:
howdy.new()
|> howdy.controller(pages())
|> howdy.health_check(health.new())
GET /up then answers 200 with {"status":"ok"} while the app is
running. It is answered before routing and before any middleware, so
rate limits, guards, CSRF checks and redirects cannot turn it away, and
the request logger and tracing leave it out, so a probe every few seconds
does not fill the logs.
Add checks for what the app cannot serve without, such as its database.
They run at the same time, and any that fails or runs out of time turns
the answer into a 503:
health.new()
|> health.check("database", database.health_check(db))
Types
Values
pub fn at(health: Health, path path: String) -> Health
Answer at another path, such as /healthz. The path must start with /
and is matched exactly. A route of the app’s own at the same path is
never reached by GET or HEAD.
pub fn check(
health: Health,
named name: String,
run run: fn() -> Result(Nil, String),
) -> Health
Add a check. run returns Ok(Nil) when what it checks is usable, or
an Error with the reason it is not. The reason is logged, at most once
every ten seconds per check, and never sent to the client: the response
only says which checks failed, by name.
A check that crashes counts as failed. One still running after the
timeout is stopped and counts as failed too, so keep checks quick and
cheap, such as a SELECT 1. Names must be unique.
pub fn new() -> Health
A health check at /up with no checks: it answers 200 whenever the
app is running and accepting connections.