Skip to main content

Monitoring System Health

To monitor the status of the application services and ensure the backend API is responsive, you can use the built-in health check endpoint and the corresponding frontend SDK methods.

Infrastructure Monitoring with Docker

The primary way to monitor the backend service health is through the Docker Compose health check configuration. This ensures that the container orchestration layer knows when the service is ready to receive traffic.

In compose.yml, the backend service is configured to perform a health check every 10 seconds:

    healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:8000/api/v1/utils/health-check/"]
interval: 10s
timeout: 5s
retries: 5

This configuration uses curl to hit the /api/v1/utils/health-check/ endpoint. If the endpoint returns a successful response (HTTP 200), the container is marked as healthy.

Programmatic Health Checks

You can check the API connectivity programmatically from the frontend using the UtilsService class. This is useful for displaying connection status indicators in the UI.

import { UtilsService } from './client/sdk.gen';

async function checkSystemStatus() {
try {
const isHealthy = await UtilsService.healthCheck();
if (isHealthy) {
console.log("Backend API is reachable and healthy.");
}
} catch (error) {
console.error("Backend API is unreachable:", error);
}
}

The healthCheck method in frontend/src/client/sdk.gen.ts performs a simple GET request:

public static healthCheck(): CancelablePromise<UtilsHealthCheckResponse> {
return __request(OpenAPI, {
method: 'GET',
url: '/api/v1/utils/health-check/'
});
}

Verifying Email Configuration

Beyond basic connectivity, you can verify that the system's email integration is correctly configured using the testEmail method. This is restricted to superusers.

import { UtilsService } from './client/sdk.gen';

async function verifyEmailSetup(testRecipient: string) {
try {
const response = await UtilsService.testEmail({
emailTo: testRecipient
});
console.log(response.message); // "Test email sent"
} catch (error) {
console.error("Email test failed. Check SMTP settings in .env");
}
}

Backend Implementation

The health check logic is implemented in backend/app/api/routes/utils.py. It is designed to be lightweight to minimize overhead during frequent polling.

@router.get("/health-check/")
async def health_check() -> bool:
return True

The email test route in the same file validates the configuration by attempting to send a real email using the configured SMTP settings:

@router.post(
"/test-email/",
dependencies=[Depends(get_current_active_superuser)],
status_code=201,
)
def test_email(email_to: EmailStr) -> Message:
"""
Test emails.
"""
email_data = generate_test_email(email_to=email_to)
send_email(
email_to=email_to,
subject=email_data.subject,
html_content=email_data.html_content,
)
return Message(message="Test email sent")

Troubleshooting

Shallow Health Checks

The /api/v1/utils/health-check/ endpoint currently returns a hardcoded True. While this confirms the FastAPI application is running and the routing is functional, it does not perform deep checks on downstream dependencies like the PostgreSQL database. For database readiness, the project relies on Docker-level dependencies and the prestart.sh script which runs backend/app/backend_pre_start.py to verify the DB connection before the API starts.

Email Test Permissions

If the testEmail call fails with a 403 Forbidden error, ensure the authenticated user has superuser privileges. The backend enforces this via the get_current_active_superuser dependency.

Connection Timeouts

If the Docker health check fails consistently:

  1. Verify the backend container is running: docker compose ps.
  2. Check the backend logs for startup errors: docker compose logs backend.
  3. Ensure the curl command is available inside the backend container image.