Packages

HTTP absence check, with its dashboard panel bundled in the same package as a separate module (Integrations.HttpAbsent.Display) — one install, both halves; a release without raven_web simply runs the monitor headless.

Current section

Files

Jump to
raven_integration_http_absent lib integrations http_absent.ex
Raw

lib/integrations/http_absent.ex

defmodule Integrations.HttpAbsent do
@moduledoc """
HTTP absence check.
The inverse of the HTTP integration: healthy when the URL is *not* reachable,
down when it is. Useful for verifying a decommissioned service is gone, a
firewall rule is blocking a destination, or a site is intentionally offline.
Collection only — see `Integrations.HttpAbsent.Display` (same package) for
the dashboard panel. `Display.BundledDefault` auto-hooks it whenever this
monitor starts, same as a single-module package would; a release without
`raven_web` simply never compiles the display half and runs this monitor
headless.
## Params
* `:url` — The URL to check. Required.
* `:timeout_ms` — Request timeout in milliseconds. Defaults to `10_000`.
## Example config
%CodeNameRaven.Monitor.Config{
id: "old-api-gone",
name: "Old API Decommissioned",
module: Integrations.HttpAbsent,
params: %{url: "https://old-api.example.com"},
interval_ms: 300_000,
enabled: true,
tags: ["infra"]
}
## Health signal
* `:up` — Connection failed or timed out (site is unreachable — expected)
* `:down` — Site responded with any HTTP status (site is reachable — unexpected)
"""
use CodeNameRaven.Monitor
@default_timeout_ms 10_000
@impl true
def params_template, do: %{url: "https://"}
@impl true
def params_schema do
[
url: [type: :string, required: true, doc: "URL that should be unreachable (healthy when 4xx/5xx or no response)"],
timeout_ms: [type: :non_neg_integer, default: 10_000, doc: "Request timeout in milliseconds"]
]
end
@impl true
def target_uri(%{url: url}) when is_binary(url), do: {:ok, url}
def target_uri(_params), do: :none
@impl true
def collect(%{url: _} = params, state), do: do_collect(params, state)
def collect(params, state),
do: {:error, "missing required param :url — got: #{inspect(params)}", state}
defp do_collect(%{url: url} = params, state) do
timeout_ms = Map.get(params, :timeout_ms, @default_timeout_ms)
result =
case Req.get(url, receive_timeout: timeout_ms, max_retries: 1) do
{:ok, %{status: code}} -> %{url: url, reachable: true, status_code: code}
{:error, _reason} -> %{url: url, reachable: false, status_code: nil}
end
{:ok, result, state}
end
@impl true
def healthy?(%{reachable: false}), do: :up
def healthy?(%{reachable: true}), do: :down
end