mirror of
https://github.com/sstent/AICyclingCoach.git
synced 2026-03-06 13:06:01 +00:00
sync
This commit is contained in:
@@ -1,9 +1,54 @@
|
||||
from fastapi import APIRouter
|
||||
from fastapi.responses import PlainTextResponse, JSONResponse
|
||||
from app.services.health_monitor import HealthMonitor
|
||||
from prometheus_client import generate_latest, CONTENT_TYPE_LATEST, Gauge
|
||||
from pathlib import Path
|
||||
import json
|
||||
|
||||
router = APIRouter()
|
||||
monitor = HealthMonitor()
|
||||
|
||||
# Prometheus metrics
|
||||
SYNC_QUEUE = Gauge('sync_queue_size', 'Current Garmin sync queue size')
|
||||
PENDING_ANALYSES = Gauge('pending_analyses', 'Number of pending workout analyses')
|
||||
|
||||
@router.get("/health")
|
||||
async def get_health():
|
||||
return monitor.check_system_health()
|
||||
return monitor.check_system_health()
|
||||
|
||||
@router.get("/metrics")
|
||||
async def prometheus_metrics():
|
||||
# Update metrics with latest values
|
||||
health_data = monitor.check_system_health()
|
||||
SYNC_QUEUE.set(health_data['services'].get('sync_queue_size', 0))
|
||||
PENDING_ANALYSES.set(health_data['services'].get('pending_analyses', 0))
|
||||
|
||||
return PlainTextResponse(
|
||||
content=generate_latest(),
|
||||
media_type=CONTENT_TYPE_LATEST
|
||||
)
|
||||
|
||||
@router.get("/dashboard/health", response_class=JSONResponse)
|
||||
async def health_dashboard():
|
||||
"""Health dashboard endpoint with aggregated monitoring data"""
|
||||
health_data = monitor.check_system_health()
|
||||
|
||||
# Get recent logs (last 100 lines)
|
||||
log_file = Path("/app/logs/app.log")
|
||||
recent_logs = []
|
||||
try:
|
||||
with log_file.open() as f:
|
||||
lines = f.readlines()[-100:]
|
||||
recent_logs = [json.loads(line.strip()) for line in lines]
|
||||
except FileNotFoundError:
|
||||
pass
|
||||
|
||||
return {
|
||||
"system": health_data,
|
||||
"logs": recent_logs,
|
||||
"statistics": {
|
||||
"log_entries": len(recent_logs),
|
||||
"error_count": sum(1 for log in recent_logs if log.get('level') == 'ERROR'),
|
||||
"warning_count": sum(1 for log in recent_logs if log.get('level') == 'WARNING')
|
||||
}
|
||||
}
|
||||
@@ -8,8 +8,9 @@ from app.models.workout import Workout
|
||||
from app.models.analysis import Analysis
|
||||
from app.models.garmin_sync_log import GarminSyncLog
|
||||
from app.models.plan import Plan
|
||||
from app.schemas.workout import Workout as WorkoutSchema, WorkoutSyncStatus
|
||||
from app.schemas.workout import Workout as WorkoutSchema, WorkoutSyncStatus, WorkoutMetric
|
||||
from app.schemas.analysis import Analysis as AnalysisSchema
|
||||
from app.schemas.plan import Plan as PlanSchema
|
||||
from app.services.workout_sync import WorkoutSyncService
|
||||
from app.services.ai_service import AIService
|
||||
from app.services.plan_evolution import PlanEvolutionService
|
||||
@@ -32,7 +33,7 @@ async def read_workout(workout_id: int, db: AsyncSession = Depends(get_db)):
|
||||
raise HTTPException(status_code=404, detail="Workout not found")
|
||||
return workout
|
||||
|
||||
@router.get("/{workout_id}/metrics", response_model=list[schemas.WorkoutMetric])
|
||||
@router.get("/{workout_id}/metrics", response_model=list[WorkoutMetric])
|
||||
async def get_workout_metrics(
|
||||
workout_id: int,
|
||||
db: AsyncSession = Depends(get_db)
|
||||
@@ -153,7 +154,7 @@ async def approve_analysis(
|
||||
return {"message": "Analysis approved"}
|
||||
|
||||
|
||||
@router.get("/plans/{plan_id}/evolution", response_model=List[schemas.Plan])
|
||||
@router.get("/plans/{plan_id}/evolution", response_model=List[PlanSchema])
|
||||
async def get_plan_evolution(
|
||||
plan_id: int,
|
||||
db: AsyncSession = Depends(get_db)
|
||||
|
||||
Reference in New Issue
Block a user