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 -> body = PromEx.get_metrics(Microwaveprop.PromEx) conn |> put_resp_content_type("text/plain; version=0.0.4") |> send_resp(200, body) |> halt() :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