How to Monitor Your Axum Web Service with Vigilmon
Axum is a web application framework for Rust built on top of Tokio and Tower. It's fast, composable, and increasingly popular for building production-grade APIs and web services. Like any production service, it needs monitoring — and this guide shows you how to do that with Vigilmon.
Why Monitor Your Axum Service?
Axum services can fail in several ways:
- OOM kills — Rust is memory-efficient but long-running services can still exhaust memory under load
- Thread pool exhaustion — heavy async workloads can starve the Tokio runtime
- Database connection failures — if your Axum service uses SQLx or Diesel, db issues cause 500s
- Deployment failures — a bad binary gets deployed that panics on startup
- Infrastructure issues — the host, load balancer, or network fails
Vigilmon catches all of these from the outside — if your endpoint stops returning 200, you know within a minute.
Step 1: Add a Health Check Route
Axum makes it simple to add a dedicated health endpoint:
use axum::{
routing::get,
Router,
response::IntoResponse,
http::StatusCode,
};
async fn health_check() -> impl IntoResponse {
StatusCode::OK
}
#[tokio::main]
async fn main() {
let app = Router::new()
.route("/health", get(health_check))
.route("/", get(root))
// ... other routes
;
let listener = tokio::net::TcpListener::bind("0.0.0.0:3000")
.await
.unwrap();
axum::serve(listener, app).await.unwrap();
}
Step 2: Add Database Health Check
For services using SQLx:
use axum::{
extract::State,
response::IntoResponse,
http::StatusCode,
};
use sqlx::PgPool;
async fn health_check(
State(pool): State<PgPool>,
) -> impl IntoResponse {
match sqlx::query("SELECT 1")
.fetch_one(&pool)
.await
{
Ok(_) => StatusCode::OK,
Err(_) => StatusCode::SERVICE_UNAVAILABLE,
}
}
This confirms both the Axum process AND database connectivity — two failure modes in one check.
Step 3: More Detailed Health Response
For richer monitoring, return JSON with component status:
use axum::Json;
use serde::Serialize;
#[derive(Serialize)]
struct HealthResponse {
status: String,
db: String,
version: String,
}
async fn health_check(
State(pool): State<PgPool>,
) -> impl IntoResponse {
let db_status = match sqlx::query("SELECT 1").fetch_one(&pool).await {
Ok(_) => "ok",
Err(_) => "error",
};
let status = if db_status == "ok" { "ok" } else { "degraded" };
let code = if status == "ok" { StatusCode::OK } else { StatusCode::SERVICE_UNAVAILABLE };
(code, Json(HealthResponse {
status: status.to_string(),
db: db_status.to_string(),
version: env!("CARGO_PKG_VERSION").to_string(),
}))
}
Step 4: Set Up Vigilmon
- Go to vigilmon.online
- Click + New Monitor
- Configure:
-
URL:
https://your-axum-service.com/health - Method: GET
- Expected status: 200
-
Expected body contains:
ok(if returning JSON) - Check interval: every 1 minute
-
URL:
- Add your alert channels
- Save
Vigilmon will alert you within 60 seconds of any failure.
Step 5: Monitor Middleware and Critical Routes
Beyond the health endpoint, consider monitoring your most critical business routes with lightweight test payloads. Vigilmon supports POST monitors with custom headers and bodies — useful for checking that authenticated endpoints respond correctly (even if the response is a 401 — that means the route is alive).
For example, monitoring your login endpoint:
- Method: POST
-
URL:
https://your-axum-service.com/api/auth/login - Expected status: 400 or 422 (bad request for missing body — but the route is UP)
Step 6: SSL and Domain Monitoring
Enable SSL certificate monitoring in Vigilmon for your Axum service's domain. Set a 14-day expiry alert. Rust TLS is often handled via rustls or a reverse proxy — either way, Vigilmon checks from the client perspective.
Step 7: Alert Routing
For production Axum services:
-
Slack webhook to
#engineeringor#incidents - Email to the on-call developer
- PagerDuty for 24/7 coverage if needed
Axum services tend to be low-level infrastructure. When they go down, something important breaks. Fast alerts are essential.
Production Tips
Exclude health from access logs: Health checks create noisy logs. In nginx or your load balancer, filter /health requests from access logs.
Load balancer health checks: Many platforms (AWS ALB, GCP Load Balancer) use health checks to route traffic. Use the same endpoint for both external Vigilmon monitoring and internal LB health checks.
Graceful shutdown: Axum supports graceful shutdown. During shutdown, your health endpoint should return 503 so Vigilmon and your LB both stop routing traffic to the instance.
Conclusion
Axum's performance and reliability are excellent — but you still need external monitoring to catch infrastructure failures, bad deploys, and database issues. Vigilmon gives you that safety net with minimal setup.
Monitor your Axum service with Vigilmon →
Vigilmon is a free uptime monitoring tool. Monitor any HTTP endpoint and get instant alerts when it fails.
Top comments (0)