goodoo
goodoo copied to clipboard
A simple, robust, and customizable health check solution written in Elixir
Goodoo
Goodoo is a simple, robust, and highly customizable health check solution written in Elixir.
Installation
Add :goodoo to your Mix project.
def deps() do
[{:goodoo, "~> 0.1"}]
end
Overview
Full documentation can be found on Hex.
Goodoo works by periodically checking the availablity of the sub-systems based on your configuration, and provides a few APIs to retrieves the report.
To start using Goodoo, create a module:
defmodule MyHealthCheck do
use Goodoo
end
After that, add the module with the desired checkers to the supervisor tree. Please see the "Checkers" section for all currently supported checkers.
checkers = %{
"primary" => {Goodoo.Checker.EctoSQL, repo: MyPrimaryRepo},
"replica" => {Goodoo.Checker.EctoSQL, repo: MyReplicaRepo},
"persistent_cache" => {Goodoo.Checker.Redix, connection: MyCache}
}
children = [
MyPrimaryRepo,
MyReplicaRepo,
MyCache,
...,
{MyHealthCheck, checkers},
MyEndpoint
]
Supervisor.start_link(children, strategy: :one_for_one, name: MyApp)
Allez, hop! You are "goodoo" to go. To retrieve the health check report,
list_health_states/1 and get_health_state/2 can be used.
Usually you might want to expose an HTTP endpoint for some uptime checkers e.g. AWS ALB, Pingdom, etc. It can be easily done with Plug or Phoenix controller.
Plug integration
defmodule MyRouter do
use Plug.Router
plug :match
plug :dispatch
get "/health" do
healthy? =
Enum.all?(
Goodoo.list_health_states(MyHealthCheck),
fn {_checker_name, {state, _last_checked_at}} ->
state == :healthy
end
)
if healthy? do
send_resp(conn, 200, "Everything is 200 OK")
else
send_resp(conn, 503, "Something is on fire!")
end
end
get "/health/:checker_name" do
case Goodoo.get_health_state(MyHealthCheck, checker_name) do
nil ->
send_resp(conn, 404, "Not found")
{state, _last_checked_at} ->
if state == :healthy do
send_resp(conn, 200, "Service is doing fine")
else
send_resp(conn, 503, "Service is on fire")
end
end
end
end
Phoenix integration
defmodule HealthController do
use MyWeb, :controller
def index(conn, _params) do
healthy? =
Enum.all?(
Goodoo.list_health_states(MyHealthCheck),
fn {_checker_name, {state, _last_checked_at}} ->
state == :healthy
end
)
conn = put_status(conn, 200)
if healthy? do
text(conn, "Everything is 200 OK")
else
text(conn, "Something is on fire!")
end
end
end
"Goodoo" to know
Goodoo is the local name of Murray Cod in Australia. Here is a picture of it.

Development
Make sure you have Elixir installed.
- Fork the project.
- Run
mix deps.getto fetch dependencies. - Run
mix test.
Contributing
If you have any ideas or suggestions, feel free to submit an issue or a pull request.
License
MIT