defmodule MicrowavepropWeb.MetricsPlug do @moduledoc """ Serves PromEx metrics at `/metrics`. Optionally gated by a bearer token via `config :microwaveprop, :prometheus_auth_token`, sourced from the `PROMETHEUS_AUTH_TOKEN` env var in `runtime.exs`. """ @behaviour Plug import Plug.Conn @impl true def init(opts), do: opts @impl true def call(conn, _opts) do case authorized?(conn) do :ok -> PromEx.Plug.call(conn, prom_ex_module: Microwaveprop.PromEx, path: "/metrics") :denied -> conn |> put_resp_header("www-authenticate", ~s(Bearer realm="metrics")) |> send_resp(401, "unauthorized") |> halt() end end defp authorized?(conn) do case Application.get_env(:microwaveprop, :prometheus_auth_token) do token when is_binary(token) and token != "" -> check_token(conn, token) _ -> :ok end end defp check_token(conn, expected) do conn |> get_req_header("authorization") |> List.first() |> case do "Bearer " <> token -> if Plug.Crypto.secure_compare(token, expected), do: :ok, else: :denied _ -> :denied end end end