98 lines
2.9 KiB
Python
98 lines
2.9 KiB
Python
"""Professional health check endpoints."""
|
|
|
|
import time
|
|
import logging
|
|
import sys
|
|
from typing import Optional
|
|
from datetime import datetime
|
|
from fastapi import APIRouter, Request
|
|
from pydantic import BaseModel, Field
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
router = APIRouter(prefix="/api/v1/health", tags=["Health"])
|
|
|
|
start_time = time.time()
|
|
|
|
|
|
class HealthResponse(BaseModel):
|
|
"""Health check response model."""
|
|
status: str = Field(..., description="Service status")
|
|
uptime_seconds: float = Field(..., description="Service uptime in seconds")
|
|
version: str = Field("2.0.0", description="API version")
|
|
timestamp: str = Field(..., description="Health check timestamp (ISO 8601)")
|
|
request_id: Optional[str] = Field(None, description="Request ID for tracing")
|
|
|
|
|
|
@router.get("/", response_model=HealthResponse)
|
|
async def health_check(request: Request):
|
|
"""
|
|
Health check endpoint.
|
|
|
|
Returns the current health status of the API service including:
|
|
- Service status (healthy/unhealthy)
|
|
- Uptime in seconds
|
|
- API version
|
|
- Timestamp
|
|
"""
|
|
try:
|
|
uptime = time.time() - start_time
|
|
request_id = getattr(request.state, "request_id", None)
|
|
|
|
return HealthResponse(
|
|
status="healthy",
|
|
uptime_seconds=round(uptime, 2),
|
|
version="2.0.0",
|
|
timestamp=datetime.utcnow().isoformat() + "Z",
|
|
request_id=request_id
|
|
)
|
|
except Exception as e:
|
|
logger.error(f"Health check failed: {e}", exc_info=True)
|
|
request_id = getattr(request.state, "request_id", None)
|
|
|
|
return HealthResponse(
|
|
status="unhealthy",
|
|
uptime_seconds=0.0,
|
|
version="2.0.0",
|
|
timestamp=datetime.utcnow().isoformat() + "Z",
|
|
request_id=request_id
|
|
)
|
|
|
|
|
|
@router.get("/ready")
|
|
async def readiness_check(request: Request):
|
|
"""
|
|
Readiness check endpoint for load balancers.
|
|
|
|
Returns 200 if the service is ready to accept requests.
|
|
"""
|
|
try:
|
|
# Check if critical services are available
|
|
# Add your service health checks here
|
|
|
|
return {
|
|
"status": "ready",
|
|
"timestamp": datetime.utcnow().isoformat() + "Z",
|
|
"request_id": getattr(request.state, "request_id", None)
|
|
}
|
|
except Exception as e:
|
|
logger.error(f"Readiness check failed: {e}")
|
|
return {
|
|
"status": "not_ready",
|
|
"timestamp": datetime.utcnow().isoformat() + "Z",
|
|
"request_id": getattr(request.state, "request_id", None)
|
|
}
|
|
|
|
|
|
@router.get("/live")
|
|
async def liveness_check(request: Request):
|
|
"""
|
|
Liveness check endpoint for container orchestration.
|
|
|
|
Returns 200 if the service is alive.
|
|
"""
|
|
return {
|
|
"status": "alive",
|
|
"timestamp": datetime.utcnow().isoformat() + "Z",
|
|
"request_id": getattr(request.state, "request_id", None)
|
|
} |