diff --git a/7project/backend/app/app.py b/7project/backend/app/app.py index af85d4f..30578b1 100644 --- a/7project/backend/app/app.py +++ b/7project/backend/app/app.py @@ -4,6 +4,7 @@ from datetime import datetime from fastapi import Depends, FastAPI from fastapi.middleware.cors import CORSMiddleware +from prometheus_fastapi_instrumentator import Instrumentator, metrics from starlette.requests import Request from app.services import bank_scraper @@ -15,11 +16,11 @@ from app.api.auth import router as auth_router from app.api.csas import router as csas_router from app.api.categories import router as categories_router from app.api.transactions import router as transactions_router -from app.services.user_service import auth_backend, current_active_verified_user, fastapi_users, get_oauth_provider, UserManager, get_jwt_strategy +from app.services.user_service import auth_backend, current_active_verified_user, fastapi_users, get_oauth_provider, \ + UserManager, get_jwt_strategy from app.core.security import extract_bearer_token, is_token_revoked, decode_and_verify_jwt from app.services.user_service import SECRET - from fastapi import FastAPI import sentry_sdk from fastapi_users.db import SQLAlchemyUserDatabase @@ -31,7 +32,6 @@ sentry_sdk.init( ) fastApi = FastAPI() -app = fastApi # CORS for frontend dev server fastApi.add_middleware( @@ -46,11 +46,21 @@ fastApi.add_middleware( allow_headers=["*"], ) +prometheus = Instrumentator().instrument(fastApi) + +prometheus.expose( + fastApi, + endpoint="/metrics", + include_in_schema=True, +) + fastApi.include_router(auth_router) fastApi.include_router(categories_router) fastApi.include_router(transactions_router) logging.basicConfig(filename='app.log', level=logging.INFO, format='%(asctime)s %(message)s') + + @fastApi.middleware("http") async def auth_guard(request: Request, call_next): # Enforce revoked/expired JWTs are rejected globally @@ -88,6 +98,7 @@ async def log_traffic(request: Request, call_next): logging.info(str(log_params)) return response + fastApi.include_router( fastapi_users.get_oauth_router( get_oauth_provider("MojeID"), @@ -114,6 +125,7 @@ fastApi.include_router( fastApi.include_router(csas_router) + # Liveness/root endpoint @fastApi.get("/", include_in_schema=False) async def root(): @@ -132,8 +144,9 @@ async def debug_scrape_csas_all(): return {"status": "queued", "action": "csas_scrape_all", "task_id": getattr(task, 'id', None)} -@fastApi.post("/debug/scrape/csas/{user_id}", tags=["debug"]) +@fastApi.post("/debug/scrape/csas/{user_id}", tags=["debug"]) async def debug_scrape_csas_user(user_id: str, user: User = Depends(current_active_verified_user)): logging.info("[Debug] Queueing CSAS scrape for single user via HTTP endpoint (Celery) | user_id=%s", user_id) task = load_transactions.delay(user_id) - return {"status": "queued", "action": "csas_scrape_single", "user_id": user_id, "task_id": getattr(task, 'id', None)} + return {"status": "queued", "action": "csas_scrape_single", "user_id": user_id, + "task_id": getattr(task, 'id', None)} diff --git a/7project/backend/requirements.txt b/7project/backend/requirements.txt index d0699ef..d7f5316 100644 --- a/7project/backend/requirements.txt +++ b/7project/backend/requirements.txt @@ -38,6 +38,8 @@ MarkupSafe==3.0.2 multidict==6.6.4 packaging==25.0 pamqp==3.3.0 +prometheus-fastapi-instrumentator==7.1.0 +prometheus_client==0.23.1 prompt_toolkit==3.0.52 propcache==0.3.2 pwdlib==0.2.1 diff --git a/7project/charts/myapp-chart/templates/monitoring.yaml b/7project/charts/myapp-chart/templates/monitoring.yaml new file mode 100644 index 0000000..804d804 --- /dev/null +++ b/7project/charts/myapp-chart/templates/monitoring.yaml @@ -0,0 +1,14 @@ +apiVersion: monitoring.coreos.com/v1 +kind: ServiceMonitor +metadata: + name: fastapi-servicemonitor + labels: + release: prometheus +spec: + selector: + matchLabels: + app: {{ .Values.app.name }} + endpoints: + - port: 8000 + path: /metrics + interval: 15s \ No newline at end of file