Current section
Files
Jump to
Current section
Files
lib/report.ex
defmodule Report do
@moduledoc """
Health checks results report.
"""
defstruct http_code: 200, passing: [], failing: [], warning: [], timeout: [], checks: []
@type t :: %__MODULE__{
http_code: 200 | 503,
passing: list(atom()),
failing: list(atom()),
warning: list(atom()),
timeout: list(atom()),
checks: list(atom())
}
@spec build(checks :: list(atom())) :: t
def build(checks \\ []) do
%__MODULE__{checks: checks}
end
@spec report_passing(report :: t, check :: atom(), result :: String.t()) :: t
def report_passing(report, check, result \\ "Healthy!") do
%__MODULE__{report | passing: report.passing ++ [check]}
|> Map.put(check, result)
end
@spec report_failing(report :: t, check :: atom(), result :: String.t()) :: t
def report_failing(report, check, result) do
%__MODULE__{report | failing: report.failing ++ [check], http_code: 503}
|> Map.put(check, result)
end
@spec report_warning(report :: t, check :: atom(), result :: String.t()) :: t
def report_warning(report, check, result) do
%__MODULE__{report | warning: report.warning ++ [check]}
|> Map.put(check, result)
end
@spec report_timeout(report :: t) :: t
def report_timeout(report) do
(report.checks -- (report.passing ++ report.failing ++ report.warning))
|> Enum.reduce(report, &report_timeout_check(&2, &1))
end
defp report_timeout_check(report, check) do
%__MODULE__{report | timeout: report.timeout ++ [check], http_code: 503}
end
@spec generate(report :: t) :: {200, map()} | {503, map()}
def generate(report) do
{
report.http_code,
report
|> Map.drop([:__struct__, :checks, :http_code, :passing, :failing, :warning, :timeout])
|> Map.merge(%{
services: Map.take(report, [:passing, :failing, :warning, :timeout])
})
}
end
end