Fermyon Spin is the fastest way to build and deploy WebAssembly microservices. Spin apps start in milliseconds, run in an isolated Wasm sandbox, and can be hosted on Fermyon Cloud or self-hosted with Spin's built-in server. But the same isolation that makes Wasm safe also makes failures invisible: a component that panics returns a 500, a misconfigured key-value store silently drops writes, and a Redis trigger that falls behind never surfaces in your logs. Vigilmon provides the external vantage point that catches these issues before your users do.
This tutorial shows how to add production-grade monitoring to a Fermyon Spin application.
What You'll Build
- A
/healthroute in your Spin component that checks real dependencies - A Vigilmon HTTP monitor targeting your Spin app's health endpoint
- Heartbeat monitoring for scheduled Spin triggers
- Alert channels (email + webhook) configured in Vigilmon
Prerequisites
- Spin CLI v2+ installed and a working Spin app (
spin newor existing project) - A free account at vigilmon.online
- (Optional) A key-value store or Redis binding in your
spin.toml
Step 1: Add a Health Handler to Your Spin Component
Spin routes HTTP requests to components via spin.toml. Add a dedicated /health route and a corresponding handler that exercises your real dependencies.
spin.toml
[[component]]
id = "api"
source = "target/wasm32-wasi/release/api.wasm"
[component.trigger]
route = "/..."
[component.key_value_stores]
default = { label = "default" }
Rust health handler
use anyhow::Result;
use spin_sdk::{
http::{IntoResponse, Request, Response},
http_component,
key_value::Store,
};
#[http_component]
fn handle_request(req: Request) -> Result<impl IntoResponse> {
if req.uri().path() == "/health" {
return handle_health();
}
// ... rest of routing
Ok(Response::builder()
.status(404)
.body("Not found")
.build())
}
fn handle_health() -> Result<impl IntoResponse> {
let mut checks = std::collections::HashMap::new();
let mut ok = true;
// Key-value store probe
match Store::open_default() {
Ok(store) => {
match store.set("__health_probe__", b"1") {
Ok(_) => match store.get("__health_probe__") {
Ok(Some(val)) if val == b"1" => {
checks.insert("kv", "ok");
}
_ => {
checks.insert("kv", "read_mismatch");
ok = false;
}
},
Err(e) => {
checks.insert("kv", "write_error");
ok = false;
}
}
}
Err(_) => {
checks.insert("kv", "open_error");
ok = false;
}
}
let status = if ok { "ok" } else { "degraded" };
let body = serde_json::json!({ "status": status, "checks": checks });
Ok(Response::builder()
.status(if ok { 200 } else { 503 })
.header("content-type", "application/json")
.body(body.to_string())
.build())
}
Build and run locally to verify:
spin build
spin up
curl http://localhost:3000/health
# {"status":"ok","checks":{"kv":"ok"}}
Step 2: Add a Vigilmon HTTP Monitor
- Log in to Vigilmon and click Add Monitor → HTTP.
- Set URL to
https://<your-spin-app>.fermyon.app/health(or your self-hosted domain). - Set Check interval to 60 seconds.
- Set Expected status code to
200. - Under Advanced, enable JSON body assertion:
- Path:
status - Expected value:
ok
- Path:
- Save. Vigilmon will alert you whenever the health check fails or returns
degraded.
Alert channels
Go to Alerts → Add channel:
- Email — your on-call address for immediate notifications
- Webhook — Slack incoming webhook or PagerDuty endpoint
Step 3: Heartbeat Monitoring for Spin Triggers
Spin supports Redis and HTTP triggers for event-driven components. If your app uses a Redis trigger to process messages, a silent consumer stall won't appear in HTTP logs. Use Vigilmon heartbeats to detect it.
At the end of each successful trigger invocation, ping Vigilmon's heartbeat URL:
use spin_sdk::outbound_http;
fn notify_vigilmon_heartbeat() -> Result<()> {
let req = http::Request::builder()
.method("POST")
.uri("https://vigilmon.online/api/heartbeat/<your-heartbeat-id>")
.body(None)?;
let _ = outbound_http::send_request(req)?;
Ok(())
}
Call notify_vigilmon_heartbeat() at the end of your trigger handler (only on success — on failure, do not ping so Vigilmon fires an alert).
In Vigilmon, create a Heartbeat monitor and set the grace period to 1.5× your expected trigger interval. If the heartbeat goes missing, you get an immediate alert.
Step 4: Monitoring Fermyon Cloud Deployments
When deploying to Fermyon Cloud, your app URL follows the pattern https://<app>-<hash>.fermyon.app. After each spin deploy, verify the health endpoint responds before removing monitoring for the old URL:
spin deploy
NEW_URL=$(spin cloud app info --output json | jq -r '.url')
echo "New URL: $NEW_URL/health"
curl "$NEW_URL/health"
Update your Vigilmon monitor URL to the new deployment URL from the Vigilmon dashboard, or use a custom domain with spin cloud custom-domain add to keep the monitor URL stable across deployments.
Step 5: Key Metrics to Alert On
| Metric | What it signals | Vigilmon check |
|---|---|---|
| /health returns 5xx | Component panic or crash | HTTP status assertion |
| /health returns degraded | KV or upstream dependency failure | JSON body assertion |
| Response time > 500 ms | Wasm JIT warm-up or I/O timeout | Response time threshold |
| Heartbeat missing | Trigger consumer stalled | Heartbeat grace period |
| Repeated 503 from Fermyon Cloud | App resource limit hit | HTTP status + alert |
Step 6: Status Page
Add a public status page so your users can check availability without contacting support. In Vigilmon, go to Status Pages → Create, add your Spin health monitor, and copy the badge:
<img src="https://vigilmon.online/badge/<monitor-id>.svg" alt="API Status" />
Embed this badge in your README or documentation site.
What You Get
| Scenario | How Vigilmon catches it |
|---|---|
| Wasm component panics | HTTP monitor sees 5xx, fires alert |
| Key-value store becomes unavailable | /health returns degraded |
| Redis trigger consumer stalls | Heartbeat not received in grace period |
| Fermyon Cloud deployment fails | New URL health check fails |
| Upstream service outage | Dependency check in /health fails |
Fermyon Spin makes deploying WebAssembly services simple — but simple deploys still need external monitoring. Vigilmon gives you the independent health signal that tells you when something is wrong before your users report it.
Start monitoring your Spin app today — register free at vigilmon.online.