freeleaps-ops/apps/gitea-webhook-ambassador-python/app/handlers/health.py

145 lines
4.0 KiB
Python

"""
Health check handler
Provides service health status checking
"""
from datetime import datetime
from typing import Dict, Any
from fastapi import APIRouter, Depends
from pydantic import BaseModel
from sqlalchemy.orm import Session
from app.database import get_db
from app.services.jenkins_service import get_jenkins_service
from app.services.queue_service import get_queue_service
from app.config import get_settings
router = APIRouter(prefix="/health", tags=["health"])
class JenkinsStatus(BaseModel):
status: str
message: str = None
class WorkerPoolStatus(BaseModel):
active_workers: int
queue_size: int
total_processed: int
total_failed: int
class HealthResponse(BaseModel):
status: str
service: str
version: str
timestamp: datetime
jenkins: JenkinsStatus
worker_pool: WorkerPoolStatus
database: Dict[str, Any]
@router.get("/", response_model=HealthResponse)
async def health_check(db: Session = Depends(get_db)):
"""
Health check endpoint
Check the status of each service component
"""
settings = get_settings()
# Check Jenkins connection
jenkins_service = get_jenkins_service()
jenkins_status = JenkinsStatus(status="disconnected", message="Unable to connect to Jenkins server")
try:
if await jenkins_service.test_connection():
jenkins_status = JenkinsStatus(status="connected")
except Exception as e:
jenkins_status.message = f"Connection failed: {str(e)}"
# Get worker pool stats
queue_service = get_queue_service()
try:
stats = await queue_service.get_stats()
worker_pool_status = WorkerPoolStatus(
active_workers=stats.get("active_workers", 0),
queue_size=stats.get("queue_size", 0),
total_processed=stats.get("total_processed", 0),
total_failed=stats.get("total_failed", 0)
)
except Exception as e:
worker_pool_status = WorkerPoolStatus(
active_workers=0,
queue_size=0,
total_processed=0,
total_failed=0
)
# Check database connection
database_status = {"status": "disconnected", "message": "Database connection failed"}
try:
# 尝试执行简单查询
db.execute("SELECT 1")
database_status = {"status": "connected"}
except Exception as e:
database_status["message"] = f"Database error: {str(e)}"
# Determine overall status
overall_status = "healthy"
if jenkins_status.status != "connected":
overall_status = "unhealthy"
return HealthResponse(
status=overall_status,
service="Gitea Webhook Ambassador",
version=settings.version,
timestamp=datetime.utcnow(),
jenkins=jenkins_status,
worker_pool=worker_pool_status,
database=database_status
)
@router.get("/simple")
async def simple_health_check():
"""
Simple health check endpoint
For load balancers and monitoring systems
"""
return {
"status": "healthy",
"service": "Gitea Webhook Ambassador",
"version": "1.0.0"
}
@router.get("/ready")
async def readiness_check(db: Session = Depends(get_db)):
"""
Readiness check endpoint
Check if the service is ready to receive requests
"""
try:
# Check database connection
db.execute("SELECT 1")
# Check Jenkins connection
jenkins_service = get_jenkins_service()
jenkins_ready = await jenkins_service.test_connection()
if jenkins_ready:
return {"status": "ready"}
else:
return {"status": "not_ready", "reason": "Jenkins connection failed"}
except Exception as e:
return {"status": "not_ready", "reason": f"Database connection failed: {str(e)}"}
@router.get("/live")
async def liveness_check():
"""
Liveness check endpoint
Check if the service process is running normally
"""
return {"status": "alive"}