change: log out details about PROMETHEUS_MULTIPROC_DIR

Additionally, respond with a 503 if the var is not set when
/metrics is requested.

Signed-off-by: Kevin Morris <kevr@0cost.org>
This commit is contained in:
Kevin Morris 2022-02-19 11:28:16 -08:00
parent 388e64d0af
commit c83c5cdc42
No known key found for this signature in database
GPG key ID: F7E46DED420788F3
4 changed files with 35 additions and 5 deletions

View file

@ -74,6 +74,10 @@ async def app_startup():
if not session_secret: if not session_secret:
raise Exception("[fastapi] session_secret must not be empty") raise Exception("[fastapi] session_secret must not be empty")
if not os.environ.get("PROMETHEUS_MULTIPROC_DIR", None):
logger.warning("$PROMETHEUS_MULTIPROC_DIR is not set, the /metrics "
"endpoint is disabled.")
app.mount("/static/css", app.mount("/static/css",
StaticFiles(directory="web/html/css"), StaticFiles(directory="web/html/css"),
name="static_css") name="static_css")

View file

@ -13,7 +13,7 @@ from sqlalchemy import and_, case, or_
import aurweb.config import aurweb.config
import aurweb.models.package_request import aurweb.models.package_request
from aurweb import cookies, db, models, time, util from aurweb import cookies, db, logging, models, time, util
from aurweb.cache import db_count_cache from aurweb.cache import db_count_cache
from aurweb.exceptions import handle_form_exceptions from aurweb.exceptions import handle_form_exceptions
from aurweb.models.account_type import TRUSTED_USER_AND_DEV_ID, TRUSTED_USER_ID from aurweb.models.account_type import TRUSTED_USER_AND_DEV_ID, TRUSTED_USER_ID
@ -21,6 +21,7 @@ from aurweb.models.package_request import PENDING_ID
from aurweb.packages.util import query_notified, query_voted, updated_packages from aurweb.packages.util import query_notified, query_voted, updated_packages
from aurweb.templates import make_context, render_template from aurweb.templates import make_context, render_template
logger = logging.get_logger(__name__)
router = APIRouter() router = APIRouter()
@ -230,8 +231,11 @@ async def archive_sha256(request: Request, archive: str):
@router.get("/metrics") @router.get("/metrics")
async def metrics(request: Request): async def metrics(request: Request):
if not os.environ.get("PROMETHEUS_MULTIPROC_DIR", None):
return Response("Prometheus metrics are not enabled.",
status_code=HTTPStatus.SERVICE_UNAVAILABLE)
registry = CollectorRegistry() registry = CollectorRegistry()
if os.environ.get("PROMETHEUS_MULTIPROC_DIR", None): # pragma: no cover
multiprocess.MultiProcessCollector(registry) multiprocess.MultiProcessCollector(registry)
data = generate_latest(registry) data = generate_latest(registry)
headers = { headers = {

View file

@ -104,6 +104,17 @@ async def test_asgi_app_unsupported_backends():
await aurweb.asgi.app_startup() await aurweb.asgi.app_startup()
@pytest.mark.asyncio
async def test_asgi_app_disabled_metrics(caplog: pytest.LogCaptureFixture):
env = {"PROMETHEUS_MULTIPROC_DIR": str()}
with mock.patch.dict(os.environ, env):
await aurweb.asgi.app_startup()
expected = ("$PROMETHEUS_MULTIPROC_DIR is not set, the /metrics "
"endpoint is disabled.")
assert expected in caplog.text
@pytest.fixture @pytest.fixture
def use_traceback(): def use_traceback():
config_getboolean = aurweb.config.getboolean config_getboolean = aurweb.config.getboolean

View file

@ -160,12 +160,23 @@ def test_archive_sig_404(client: TestClient):
def test_metrics(client: TestClient): def test_metrics(client: TestClient):
with tempfile.TemporaryDirectory() as tmpdir:
env = {"PROMETHEUS_MULTIPROC_DIR": tmpdir}
with mock.patch.dict(os.environ, env):
with client as request: with client as request:
resp = request.get("/metrics") resp = request.get("/metrics")
assert resp.status_code == int(HTTPStatus.OK) assert resp.status_code == int(HTTPStatus.OK)
assert resp.headers.get("Content-Type").startswith("text/plain") assert resp.headers.get("Content-Type").startswith("text/plain")
def test_disabled_metrics(client: TestClient):
env = {"PROMETHEUS_MULTIPROC_DIR": str()}
with mock.patch.dict(os.environ, env):
with client as request:
resp = request.get("/metrics")
assert resp.status_code == int(HTTPStatus.SERVICE_UNAVAILABLE)
def test_rtl(client: TestClient): def test_rtl(client: TestClient):
responses = {} responses = {}
expected = [ expected = [