Building Robust Applications with Health Checks in Python
Health checks are crucial for ensuring the reliability and availability of applications, especially in distributed systems. This challenge asks you to implement a Python-based health check endpoint that can be queried to determine the overall health of an application. A well-designed health check allows monitoring systems to quickly identify and react to issues, preventing cascading failures and improving user experience.
Problem Description
You are tasked with creating a Python script that exposes a health check endpoint. This endpoint should return a JSON response indicating the application's health status. The health check should consider the following:
- Database Connection: The application should attempt to connect to a database (simulated for this challenge – see "Notes" below). If the connection is successful, the database is considered healthy. If the connection fails, the database is considered unhealthy.
- External Service Dependency: The application should attempt to make a request to an external service (simulated for this challenge – see "Notes" below). If the request is successful (status code 200-299), the external service is considered healthy. If the request fails, the external service is considered unhealthy.
- Overall Status: Based on the database and external service health, determine the overall application health status.
- If both are healthy, the overall status is "healthy".
- If either is unhealthy, the overall status is "degraded".
- If both are unhealthy, the overall status is "unhealthy".
The health check endpoint should return a JSON response with the following format:
{
"database": "healthy" | "unhealthy",
"external_service": "healthy" | "unhealthy",
"overall_status": "healthy" | "degraded" | "unhealthy"
}
Examples
Example 1:
Input: (Application is healthy - database and external service both respond successfully)
Output:
{
"database": "healthy",
"external_service": "healthy",
"overall_status": "healthy"
}
Explanation: Both the database and external service are functioning correctly, resulting in a "healthy" overall status.
Example 2:
Input: (Application is degraded - database connection fails, external service responds successfully)
Output:
{
"database": "unhealthy",
"external_service": "healthy",
"overall_status": "degraded"
}
Explanation: The database connection failed, but the external service is healthy, leading to a "degraded" overall status.
Example 3:
Input: (Application is unhealthy - both database connection fails and external service request fails)
Output:
{
"database": "unhealthy",
"external_service": "unhealthy",
"overall_status": "unhealthy"
}
Explanation: Both the database and external service are unavailable, resulting in an "unhealthy" overall status.
Constraints
- The script should be runnable using Python 3.7 or higher.
- The simulated database connection and external service request should be implemented using Python's built-in libraries (e.g.,
requests,time). No external database or service is required. - The health check endpoint should be accessible via HTTP GET.
- The response should be a valid JSON string.
- The script should handle potential exceptions gracefully (e.g., network errors, timeouts).
- The simulated database connection attempt should take no longer than 1 second.
- The simulated external service request should take no longer than 2 seconds.
Notes
- Simulated Database Connection: Simulate a database connection attempt using
time.sleep()to represent latency and potentially raise an exception to simulate a connection failure. You don't need to use a real database. - Simulated External Service: Simulate an external service request using
requests.get(). You can use a dummy URL (e.g., "https://httpstat.us/200" for a successful response, "https://httpstat.us/500" for a failure). You can also simulate failures by raising exceptions. - You can use a simple web framework like Flask or FastAPI to create the health check endpoint. If you don't want to use a framework, you can use Python's built-in
http.servermodule, but this is less recommended for production use. - Focus on the logic of the health check and the JSON response format. The specific implementation of the web server is less important.
- Consider adding logging to your script to aid in debugging.