How to Monitor NervesHub with Vigilmon
NervesHub is the OTA (over-the-air) firmware update platform for Nerves-based embedded Linux devices. It handles deployment pipelines, firmware signing, device health reporting, and audit trails for your entire fleet. When NervesHub goes down — or when your self-hosted instance develops a fault — firmware updates stall silently, devices fall behind on patches, and you may not know for hours.
Vigilmon closes that gap with HTTP uptime checks, heartbeat monitoring, and instant alerts so your OTA pipeline stays healthy and your fleet stays current.
This tutorial covers:
- HTTP monitoring for NervesHub's public API
- Heartbeat monitoring from within Nerves firmware
- Monitoring your self-hosted NervesHub instance
- Alerts for deployment failures and device connectivity drops
What to Monitor in a NervesHub Deployment
NervesHub has two layers worth monitoring:
| Layer | What it is | How to monitor | |---|---|---| | NervesHub server | The web app / API that manages devices and deployments | HTTP uptime check | | Device connectivity | Individual devices' ability to reach NervesHub | Heartbeat from firmware | | Deployment pipeline | Whether new firmware is actually reaching devices | Custom heartbeat after deployment |
Step 1: Monitor the NervesHub API endpoint
If you use the hosted NervesHub service (nerveshub.org), monitor their API:
- Sign in at vigilmon.online and click Add Monitor.
- Choose HTTP monitor type.
- Use
https://nerveshub.orgas the URL (or your self-hosted domain). - Set check interval to 60 seconds.
- Expected status:
200.
For self-hosted NervesHub, monitor your own domain plus the internal health endpoint if one is exposed.
Step 2: Monitor a self-hosted NervesHub instance
NervesHub is an open-source Phoenix application. Add a lightweight health plug:
# In your self-hosted NervesHub fork, add to router.ex
scope "/health", NervesHubWeb do
pipe_through :api
get "/", HealthController, :index
end
# lib/nerves_hub_web/controllers/health_controller.ex
defmodule NervesHubWeb.HealthController do
use NervesHubWeb, :controller
def index(conn, _params) do
checks = %{
database: check_db(),
ssl_certs: :ok # extend with actual cert expiry logic
}
status = if Enum.all?(checks, fn {_, v} -> v == :ok end), do: 200, else: 503
conn
|> put_status(status)
|> json(%{status: status_text(status), checks: checks})
end
defp check_db do
case NervesHub.Repo.query("SELECT 1", []) do
{:ok, _} -> :ok
_ -> :error
end
end
defp status_text(200), do: "ok"
defp status_text(_), do: "degraded"
end
Point your Vigilmon HTTP monitor at https://your-nerveshub.example.com/health.
Step 3: Add heartbeat monitoring from Nerves firmware
Devices that can reach NervesHub can also reach Vigilmon's heartbeat endpoint. Add a GenServer to your Nerves firmware that pings Vigilmon on each successful NervesHub connection:
# lib/my_firmware/heartbeat.ex
defmodule MyFirmware.Heartbeat do
use GenServer
require Logger
@interval_ms 60_000
def start_link(_opts), do: GenServer.start_link(__MODULE__, %{}, name: __MODULE__)
@impl true
def init(state) do
schedule_ping()
{:ok, state}
end
@impl true
def handle_info(:ping, state) do
ping_vigilmon()
schedule_ping()
{:noreply, state}
end
defp ping_vigilmon do
case System.get_env("VIGILMON_HEARTBEAT_URL") do
nil ->
Logger.debug("VIGILMON_HEARTBEAT_URL not set, skipping heartbeat")
url ->
case :httpc.request(:get, {String.to_charlist(url), []}, [{:timeout, 5000}], []) do
{:ok, _} -> Logger.debug("Vigilmon heartbeat sent")
{:error, reason} -> Logger.warning("Vigilmon heartbeat failed: #{inspect(reason)}")
end
end
end
defp schedule_ping, do: Process.send_after(self(), :ping, @interval_ms)
end
Add to your firmware supervision tree:
# lib/my_firmware/application.ex
children = [
# ... existing children
MyFirmware.Heartbeat
]
Set the heartbeat URL in your Nerves firmware config or via NervesHub's device environment variables:
# config/prod.exs
config :my_firmware, heartbeat_url: System.get_env("VIGILMON_HEARTBEAT_URL")
In Vigilmon:
- Open your monitor → Heartbeat tab.
- Copy the heartbeat URL.
- Set it as a NervesHub deployment variable so all devices in the deployment receive it.
- Set grace period to 3 minutes (three missed 1-minute pings = alert).
Step 4: Monitor deployment health with a post-deploy heartbeat
Wire a heartbeat ping into your CI/CD pipeline to confirm firmware actually deployed:
#!/bin/bash
# scripts/deploy.sh
# Push firmware to NervesHub
mix nerves_hub.firmware publish --product MyProduct --tag ${FIRMWARE_TAG}
# Start deployment
mix nerves_hub.deployment update --name production --tag ${FIRMWARE_TAG}
# Ping Vigilmon to confirm deploy was initiated
curl -s "${VIGILMON_DEPLOY_HEARTBEAT_URL}" > /dev/null
echo "Deployment started, Vigilmon heartbeat sent"
Create a separate Vigilmon heartbeat monitor for your deployment pipeline with a longer grace period (e.g., 24 hours) to catch cases where your CI/CD stops running entirely.
Step 5: Configure alerts
In Vigilmon go to Alerts and configure notification channels:
- Slack (#ops or #firmware-deploys) — good for deployment events
- Email — on-call engineer
- PagerDuty — for fleets where stale firmware is a safety issue
Recommended alert policies for NervesHub:
| Monitor | Condition | Action | |---|---|---| | NervesHub API | HTTP non-200 or timeout | Alert on-call immediately | | Device heartbeat | Missed ≥ 3× | Alert device owner | | Deploy pipeline heartbeat | Missed ≥ 1× | Alert CI/CD team | | Response latency | > 3 s | Warning — possible DB slowdown |
Step 6: Status page for your fleet team
Create a Vigilmon Status Page that your firmware team and field teams can bookmark:
- Go to Status Pages → New Page.
- Add: NervesHub API monitor, any device fleet heartbeat monitors.
- Set visibility to Team (internal) or Public for partner visibility.
Key Metrics to Watch
| Metric | Threshold | Meaning | |---|---|---| | NervesHub API HTTP status | Must be 200 | Server reachable | | Device heartbeat | < 3 missed | Device connected to network | | Deploy heartbeat | < 1 missed per 24 h | CI/CD pipeline running | | API response time | < 2 s | No DB or backend bottleneck | | Self-hosted DB check | Must be ok | Postgres/Ecto healthy |
Why Monitor NervesHub?
NervesHub is infrastructure. When it's unhealthy:
- Devices can't receive firmware updates — security patches, bug fixes, and new features stall
- Device health reporting breaks — you lose visibility into your fleet
- Deployment audit trails stop — compliance and debugging suffer
A 5-minute Vigilmon setup gives you early warning for all of these scenarios.
Conclusion
NervesHub keeps your Nerves fleet patched and healthy — and Vigilmon keeps NervesHub itself under watch. With HTTP monitoring on the NervesHub API, heartbeat checks from each device, and a deploy-pipeline heartbeat in your CI/CD, you have end-to-end observability from firmware build to device in the field.
Get started free at vigilmon.online.