Burrito packages your Elixir application as a self-extracting executable that bundles the Erlang runtime — no Elixir or Erlang installation required on the target machine. You ship one binary to macOS, Linux, or Windows and it runs anywhere. But that distribution freedom also means you're running Elixir processes outside of traditional container orchestration, often on bare metal or edge machines where you have no native process supervisor watching them. Vigilmon closes that visibility gap with heartbeat monitoring, so you know when a Burrito-packaged process stops running, regardless of where it's deployed.
What You'll Set Up
- Cron heartbeat monitoring for long-running Burrito processes
- HTTP health endpoint within Burrito-packaged server applications
- Alerting for missed heartbeats across distributed deployments
- Per-platform binary health tracking
Prerequisites
- Elixir 1.14+ with Burrito configured in your
mix.exs - At least one Burrito target producing a deployable executable
- A free Vigilmon account
Step 1: Add a Heartbeat Ping to Your Burrito Application
Burrito applications are often long-running services or scheduled tasks. Add a periodic Vigilmon ping so you know the process is alive:
- In Vigilmon, click Add Monitor → Cron Heartbeat.
- Set Expected ping interval to your process's expected run cycle (e.g.
5minutes for a polling daemon,60for an hourly task). - Copy the heartbeat URL (e.g.
https://vigilmon.online/heartbeat/abc123).
Add the ping inside your application's main loop or GenServer callback:
defmodule MyApp.Monitor do
use GenServer
require Logger
@heartbeat_url System.get_env("VIGILMON_HEARTBEAT_URL")
@ping_interval :timer.minutes(5)
def start_link(_), do: GenServer.start_link(__MODULE__, [], name: __MODULE__)
def init(_) do
schedule_ping()
{:ok, %{}}
end
def handle_info(:ping, state) do
ping_vigilmon()
schedule_ping()
{:noreply, state}
end
defp schedule_ping, do: Process.send_after(self(), :ping, @ping_interval)
defp ping_vigilmon do
:httpc.request(:get, {String.to_charlist(@heartbeat_url), []}, [{:timeout, 5000}], [])
rescue
e -> Logger.warning("Vigilmon ping failed: #{inspect(e)}")
end
end
Add MyApp.Monitor to your supervision tree so it starts with the application and restarts on crash.
Step 2: Configure Burrito to Include the Monitor
Make sure Burrito packages your full supervision tree, including the heartbeat monitor, in your release:
# mix.exs
defmodule MyApp.MixProject do
use Mix.Project
def project do
[
app: :my_app,
version: "0.1.0",
releases: releases()
]
end
defp releases do
[
my_app: [
steps: [:assemble, &Burrito.wrap/1],
burrito: [
targets: [
linux: [os: :linux, cpu: :x86_64],
macos: [os: :darwin, cpu: :aarch64],
windows: [os: :windows, cpu: :x86_64]
]
]
]
]
end
end
Build your binaries:
MIX_ENV=prod mix release
# Produces:
# burrito_out/my_app_linux
# burrito_out/my_app_macos
# burrito_out/my_app_windows.exe
Each binary self-extracts and runs the full OTP supervision tree, including your heartbeat monitor.
Step 3: Add an HTTP Health Endpoint for Server Applications
If your Burrito binary runs a web server (Phoenix, Bandit, or a plain Plug), expose a health route for Vigilmon to probe:
defmodule MyApp.HealthPlug do
import Plug.Conn
def init(opts), do: opts
def call(conn, _opts) do
conn
|> put_resp_content_type("application/json")
|> send_resp(200, ~s({"status":"ok","runtime":"burrito"}))
|> halt()
end
end
# In your router
plug MyApp.HealthPlug, at: "/health"
Once deployed, add an HTTP monitor in Vigilmon:
- Click Add Monitor → HTTP / HTTPS.
- Enter
https://your-burrito-app.example.com/health. - Set Check interval to
1 minute. - Set Expected HTTP status to
200. - Click Save.
Step 4: Track Multiple Burrito Deployments
Burrito is commonly used for edge or multi-site deployments where the same binary runs on many machines. Create one Vigilmon heartbeat monitor per deployment:
- For each deployment (e.g.
edge-node-us-east,edge-node-eu-west), create a separate Cron Heartbeat monitor in Vigilmon. - Name each monitor clearly:
Burrito — US East,Burrito — EU West. - Set each binary's
VIGILMON_HEARTBEAT_URLenvironment variable to the URL for that specific monitor.
Pass the heartbeat URL at launch time:
# On the US East machine
VIGILMON_HEARTBEAT_URL=https://vigilmon.online/heartbeat/us123 ./my_app_linux start
# On the EU West machine
VIGILMON_HEARTBEAT_URL=https://vigilmon.online/heartbeat/eu456 ./my_app_linux start
This gives you a per-node liveness view — if the EU West binary crashes and stops pinging, Vigilmon alerts only for that deployment, not the entire fleet.
Step 5: Handle Graceful Shutdown and One-Shot Tasks
Burrito applications can also be one-shot CLIs that run, complete work, and exit. For these, send the heartbeat at the end of a successful run rather than on an interval:
defmodule MyApp.CLI do
def main(_args) do
run_task()
ping_success()
end
defp run_task do
# Do the work
:ok
end
defp ping_success do
url = System.get_env("VIGILMON_HEARTBEAT_URL")
:httpc.request(:get, {String.to_charlist(url), []}, [], [])
end
end
In Vigilmon, set the heartbeat interval to match your cron schedule. If the job fails mid-run and never pings, Vigilmon alerts after the interval expires.
Step 6: Configure Alert Channels
- Go to Alert Channels in Vigilmon and add Slack, email, or PagerDuty.
- For long-running daemon processes, set Consecutive failures before alert to
2to absorb transient network interruptions during the ping. - For one-shot scheduled tasks, set it to
1— a single missed ping means the job didn't run.
Use the Vigilmon API to set maintenance windows when deploying updated binaries:
curl -X POST https://vigilmon.online/api/maintenance \
-H "Authorization: Bearer YOUR_API_KEY" \
-d '{"monitor_id": "abc123", "duration_minutes": 10}'
Summary
| Monitor | Target | What It Catches |
|---|---|---|
| Cron heartbeat (daemon) | Heartbeat URL | Process crash, OOM kill, missing node |
| Cron heartbeat (one-shot) | Heartbeat URL | Job failure, missed cron trigger |
| HTTP health check | /health on server app | App up but unresponsive |
| Per-node heartbeat | Node-specific URL | Individual deployment failures |
Burrito frees you from managing Elixir runtime dependencies on target machines — Vigilmon frees you from worrying about whether those binaries are still running. Together they give you the deployment simplicity of a static binary with the operational confidence of a monitored service.