Skip to content

A simple, robust, and customizable health check solution written in Elixir

License

Notifications You must be signed in to change notification settings

fishbrain/goodoo

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

19 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

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.

goodoo

Development

Make sure you have Elixir installed.

  1. Fork the project.
  2. Run mix deps.get to fetch dependencies.
  3. Run mix test.

Contributing

If you have any ideas or suggestions, feel free to submit an issue or a pull request.

License

MIT

About

A simple, robust, and customizable health check solution written in Elixir

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages