Spaces:
Running
Running
Saurabh Kumar Bajpai commited on
Commit Β·
9fe37a6
1
Parent(s): 234979c
feat: expose Prometheus metrics endpoint
Browse files- backend/app/main.py +3 -0
- backend/app/observability.py +46 -0
- backend/requirements.txt +1 -0
- backend/tests/test_observability.py +13 -0
backend/app/main.py
CHANGED
|
@@ -19,6 +19,7 @@ from slowapi.middleware import SlowAPIMiddleware
|
|
| 19 |
from app.config import get_settings
|
| 20 |
from app.rate_limit import limiter
|
| 21 |
from app.database import init_db, get_db
|
|
|
|
| 22 |
from app.rag.vectorstore import get_chroma_client
|
| 23 |
from app.scheduler import start_scheduler, stop_scheduler
|
| 24 |
|
|
@@ -170,6 +171,8 @@ app.include_router(chat_router, prefix="/api/v1")
|
|
| 170 |
app.include_router(github_router, prefix="/api/v1")
|
| 171 |
app.include_router(admin_router, prefix="/api/v1")
|
| 172 |
|
|
|
|
|
|
|
| 173 |
|
| 174 |
# ββ Health Check βββββββββββββββββββββββββββββββββββββ
|
| 175 |
@app.get("/api/health")
|
|
|
|
| 19 |
from app.config import get_settings
|
| 20 |
from app.rate_limit import limiter
|
| 21 |
from app.database import init_db, get_db
|
| 22 |
+
from app.observability import setup_prometheus_metrics
|
| 23 |
from app.rag.vectorstore import get_chroma_client
|
| 24 |
from app.scheduler import start_scheduler, stop_scheduler
|
| 25 |
|
|
|
|
| 171 |
app.include_router(github_router, prefix="/api/v1")
|
| 172 |
app.include_router(admin_router, prefix="/api/v1")
|
| 173 |
|
| 174 |
+
setup_prometheus_metrics(app)
|
| 175 |
+
|
| 176 |
|
| 177 |
# ββ Health Check βββββββββββββββββββββββββββββββββββββ
|
| 178 |
@app.get("/api/health")
|
backend/app/observability.py
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"""Prometheus instrumentation for the FastAPI application."""
|
| 2 |
+
|
| 3 |
+
import sys
|
| 4 |
+
|
| 5 |
+
try:
|
| 6 |
+
import resource
|
| 7 |
+
except ImportError: # pragma: no cover - resource is unavailable on some platforms.
|
| 8 |
+
resource = None
|
| 9 |
+
|
| 10 |
+
from fastapi import FastAPI
|
| 11 |
+
from prometheus_client import Gauge
|
| 12 |
+
from prometheus_fastapi_instrumentator import Instrumentator
|
| 13 |
+
|
| 14 |
+
APP_PROCESS_RSS_BYTES = Gauge(
|
| 15 |
+
"app_process_resident_memory_bytes",
|
| 16 |
+
"Resident memory used by the backend process in bytes.",
|
| 17 |
+
)
|
| 18 |
+
|
| 19 |
+
|
| 20 |
+
def _get_process_rss_bytes() -> float:
|
| 21 |
+
if resource is None:
|
| 22 |
+
return 0.0
|
| 23 |
+
|
| 24 |
+
usage = resource.getrusage(resource.RUSAGE_SELF).ru_maxrss
|
| 25 |
+
if sys.platform == "darwin":
|
| 26 |
+
return float(usage)
|
| 27 |
+
return float(usage * 1024)
|
| 28 |
+
|
| 29 |
+
|
| 30 |
+
APP_PROCESS_RSS_BYTES.set_function(_get_process_rss_bytes)
|
| 31 |
+
|
| 32 |
+
|
| 33 |
+
def setup_prometheus_metrics(app: FastAPI) -> Instrumentator:
|
| 34 |
+
"""Expose process and HTTP metrics on ``/metrics`` for Prometheus."""
|
| 35 |
+
instrumentator = Instrumentator(
|
| 36 |
+
should_group_status_codes=True,
|
| 37 |
+
should_ignore_untemplated=True,
|
| 38 |
+
excluded_handlers=["/metrics"],
|
| 39 |
+
)
|
| 40 |
+
instrumentator.instrument(app).expose(
|
| 41 |
+
app,
|
| 42 |
+
endpoint="/metrics",
|
| 43 |
+
include_in_schema=False,
|
| 44 |
+
)
|
| 45 |
+
app.state.prometheus_instrumentator = instrumentator
|
| 46 |
+
return instrumentator
|
backend/requirements.txt
CHANGED
|
@@ -55,6 +55,7 @@ huggingface-hub
|
|
| 55 |
# Production
|
| 56 |
gunicorn
|
| 57 |
slowapi
|
|
|
|
| 58 |
|
| 59 |
# File Validation
|
| 60 |
#sudo apt-get install libmagic1 // for Debian/Ubuntu
|
|
|
|
| 55 |
# Production
|
| 56 |
gunicorn
|
| 57 |
slowapi
|
| 58 |
+
prometheus-fastapi-instrumentator
|
| 59 |
|
| 60 |
# File Validation
|
| 61 |
#sudo apt-get install libmagic1 // for Debian/Ubuntu
|
backend/tests/test_observability.py
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
def test_metrics_endpoint_exposes_prometheus_payload(client):
|
| 2 |
+
client.get("/api/health")
|
| 3 |
+
|
| 4 |
+
response = client.get("/metrics")
|
| 5 |
+
|
| 6 |
+
assert response.status_code == 200
|
| 7 |
+
assert response.headers["content-type"].startswith("text/plain")
|
| 8 |
+
|
| 9 |
+
body = response.text
|
| 10 |
+
assert "python_info" in body
|
| 11 |
+
assert "app_process_resident_memory_bytes" in body
|
| 12 |
+
assert "http_requests_total" in body
|
| 13 |
+
assert "/api/health" in body
|