The scrape surface, and nothing else.
API doc §2 makes GET /metrics unsigned and bind-address-restricted, and
this router is how the second half of that is enforced: it is mounted on its
own Bandit listener bound to AP_METRICS_BIND (AudioProxy.Application),
rather than added to AudioProxy.Router behind a plug that checks the peer
address. Two reasons, in order of weight.
A bind is a guarantee the kernel makes; a peer check is a guarantee this
code makes, and the difference shows up behind a proxy, where the peer
address is the proxy's and every check that reads one has to decide how much
of X-Forwarded-For to believe. Nothing here has to decide anything: an
interface that is not bound cannot be connected to.
And the surface stays honest. This router serves one route. There is no
ordering between it and the signed route to get wrong, no chance of a future
/metrics/… falling through to the render pipeline, and a request for
anything else on this port is a 404 rather than a path into the API.
Scrapes are requests too
:endpoint_class is assigned, so a scrape appears in the log at debug
alongside the probes, and counts in audio_proxy_http_requests_total under
endpoint="metrics". Counting itself is not circular — the exposition is
rendered before this request's own stop event fires, so a scrape reports the
scrape before it, which is exactly what a monotonically increasing counter
is for. What it buys is that a scraper failing to reach this port is visible
from the last scrape that did.
Summary
Functions
Callback implementation for Plug.call/2.
Callback implementation for Plug.init/1.