diff --git a/.github/workflows/deploy-pr.yaml b/.github/workflows/deploy-pr.yaml index fdcff10..5a488a1 100644 --- a/.github/workflows/deploy-pr.yaml +++ b/.github/workflows/deploy-pr.yaml @@ -101,7 +101,8 @@ jobs: --set image.digest="$DIGEST" \ --set-string rabbitmq.password="$RABBITMQ_PASSWORD" \ --set-string database.password="$DB_PASSWORD" \ - --set-string database.encryptionSecret="$PR" + --set-string database.encryptionSecret="$PR" \ + --set-string app.name="finance-tracker-pr-$PR" - name: Post preview URLs as PR comment uses: actions/github-script@v7 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/app-deployment.yaml b/7project/charts/myapp-chart/templates/app-deployment.yaml index 02afbfb..876e6f9 100644 --- a/7project/charts/myapp-chart/templates/app-deployment.yaml +++ b/7project/charts/myapp-chart/templates/app-deployment.yaml @@ -8,10 +8,12 @@ spec: selector: matchLabels: app: {{ .Values.app.name }} + endpoint: metrics template: metadata: labels: app: {{ .Values.app.name }} + endpoint: metrics spec: containers: - name: {{ .Values.app.name }} diff --git a/7project/charts/myapp-chart/templates/monitoring.yaml b/7project/charts/myapp-chart/templates/monitoring.yaml new file mode 100644 index 0000000..059fed9 --- /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: kube-prometheus-stack +spec: + selector: + matchLabels: + app: {{ .Values.app.name }} + endpoints: + - port: http + path: /metrics + interval: 15s \ No newline at end of file diff --git a/7project/charts/myapp-chart/templates/service.yaml b/7project/charts/myapp-chart/templates/service.yaml index fee4e3c..76974ea 100644 --- a/7project/charts/myapp-chart/templates/service.yaml +++ b/7project/charts/myapp-chart/templates/service.yaml @@ -2,9 +2,12 @@ apiVersion: v1 kind: Service metadata: name: {{ .Values.app.name }} + labels: + app: {{ .Values.app.name }} spec: ports: - - port: {{ .Values.service.port }} + - name: http + port: {{ .Values.service.port }} targetPort: {{ .Values.app.port }} selector: app: {{ .Values.app.name }}