# `Macaw.Host.Health`
[🔗](https://github.com/dcoai/macaw_host/blob/v0.1.4/lib/macaw/host/health.ex#L1)

An app's health, in one shape every `<app>-ctl status` reads.

A report runs named checks. Each returns `:ok`, `{:error, detail}` (the
app is unhealthy) or `{:warn, detail}` (worth showing, not a failure):

    Macaw.Host.Health.report([
      database: fn -> Macaw.Host.Health.database(MyApp.Repo) end,
      migrations: fn -> Macaw.Host.Health.migrations(MyApp.Repo) end,
      data_dir: fn -> Macaw.Host.Health.writable(data_dir) end
    ], version: MyApp.Build.version(), build: MyApp.Build.sha())

gives

    %{healthy: true, version: "1.2.0", build: "3f639e84a704",
      checks: %{database: "ok", migrations: "ok", data_dir: "ok"}}

A check that raises is reported as an error naming the exception, never
a crash of the report: the point of a health check is to answer while
something is broken. The whole report answers within its deadline (5 s
unless `:deadline` says otherwise): the checks run side by side, each
given the time left, and one that misses it is reported as timed out.
`Macaw.Host.Health.Plug` serves the report as JSON, `200` when healthy
and `503` when not.

# `check`

```elixir
@type check() :: (-&gt; :ok | {:error, term()} | {:warn, term()})
```

# `database`

```elixir
@spec database(module()) :: :ok | {:error, String.t()}
```

Whether a repo answers `SELECT 1`. Requires `ecto_sql`.

# `migrations`

```elixir
@spec migrations(module()) :: :ok | {:error, String.t()}
```

Whether every migration has run. Requires `ecto_sql`.

# `report`

```elixir
@spec report([{atom(), check()}], keyword(), keyword()) :: map()
```

Runs the checks and builds the report; `extra` is merged in (version,
build), and may not set `:healthy` or `:checks` (an `ArgumentError`, at
the call). Options: `:deadline`, the whole report's, in milliseconds
(default 5000).

# `writable`

```elixir
@spec writable(Path.t()) :: :ok | {:error, String.t()}
```

Whether a directory is writable, by writing and removing a probe file.

---

*Consult [api-reference.md](api-reference.md) for complete listing*
