Igniter is a composable code generation and project patching framework for Elixir, used by Ash Framework and an expanding ecosystem of libraries to scaffold applications, patch configuration files, and perform automated code mods at install time or during upgrades. Unlike traditional Mix tasks that generate files and leave them for developers to reconcile manually, Igniter tracks changes, diffs them, and applies them in a composable pipeline. When Igniter tasks run in CI — for example, as part of an automated upgrade bot, a scaffold workflow, or a code quality enforcement job — silent failures mean your codebase silently diverges from the expected state. Vigilmon gives you heartbeat monitoring, HTTP health checks, and alerting so Igniter-powered pipelines don't fail invisibly.
What You'll Set Up
- HTTP health endpoint for services that invoke Igniter tasks at runtime
- Heartbeat monitor for CI/CD jobs that run Igniter mix tasks on a schedule
- Slack alerts on pipeline failure
- SSL monitoring for the webhook endpoints that trigger Igniter jobs
Prerequisites
- Elixir 1.14+ with
igniterinmix.exs - An application or CI pipeline that runs Igniter tasks (scheduled upgrades, scaffold bots, etc.)
- A free Vigilmon account
Step 1: Understand What to Monitor in an Igniter Pipeline
Igniter itself is a build-time and development tool — it doesn't run as a long-lived service. What you monitor depends on how you use it:
| Usage pattern | What to monitor | |---------------|----------------| | Local dev scaffolding | Nothing — failure is immediate and visible | | CI upgrade bot (scheduled) | Heartbeat per scheduled job | | Webhook-triggered scaffold service | HTTP health + webhook endpoint | | Ash Framework install in CD | CI job status (external to Vigilmon) + heartbeat |
This tutorial focuses on the two production patterns: scheduled CI jobs and webhook-triggered scaffold services.
Step 2: Add a Health Endpoint for Webhook-Triggered Igniter Services
If you run a service that accepts webhook events and invokes Igniter tasks (e.g. a GitHub App that scaffolds code on PR creation), add a health endpoint:
# lib/my_scaffold_app_web/controllers/health_controller.ex
defmodule MyScaffoldAppWeb.HealthController do
use MyScaffoldAppWeb, :controller
def index(conn, _params) do
checks = %{
igniter_available: check_igniter(),
job_queue: check_job_queue(),
git_access: check_git_access()
}
status = if Enum.all?(checks, fn {_, v} -> v == :ok end), do: 200, else: 503
conn
|> put_status(status)
|> json(%{status: if(status == 200, do: "ok", else: "degraded"), checks: checks})
end
defp check_igniter do
# Verify Igniter module is loaded and accessible
case Code.ensure_loaded(Igniter) do
{:module, _} -> :ok
{:error, _} -> :error
end
end
defp check_job_queue do
# Check your queue backend (e.g. Oban) can accept new jobs
case Oban.check_queue(queue: :scaffold) do
%{paused: false} -> :ok
_ -> :error
end
end
defp check_git_access do
# Verify the git credentials needed for Igniter to push patches are valid
case System.cmd("git", ["ls-remote", "--exit-code", "origin"], stderr_to_stdout: true) do
{_, 0} -> :ok
_ -> :error
end
rescue
_ -> :error
end
end
Wire it to a route:
# lib/my_scaffold_app_web/router.ex
scope "/", MyScaffoldAppWeb do
get "/health", HealthController, :index
end
Step 3: Wrap Igniter Tasks with Heartbeat Pings
The most common production use of Igniter is in scheduled CI/CD jobs that run mix igniter.* tasks to keep a codebase up to date. Wrap these in a shell script that pings Vigilmon on success:
#!/bin/bash
# scripts/run_igniter_upgrade.sh
set -e
echo "Running Igniter upgrade pipeline..."
# Run Igniter upgrade tasks
mix igniter.upgrade ash
mix igniter.upgrade ash_phoenix
# Run tests to confirm the patches are valid
mix test --exclude slow
# Only ping heartbeat if everything succeeded
if [ $? -eq 0 ]; then
echo "Upgrade succeeded, pinging Vigilmon heartbeat..."
curl -fsS "$VIGILMON_IGNITER_HEARTBEAT_URL" > /dev/null
echo "Heartbeat sent."
else
echo "Upgrade or tests failed — skipping heartbeat ping."
exit 1
fi
For Elixir-native invocation from an Oban worker:
# lib/my_app/workers/igniter_upgrade_worker.ex
defmodule MyApp.Workers.IgniterUpgradeWorker do
use Oban.Worker, queue: :scaffold, max_attempts: 2
require Logger
@impl Oban.Worker
def perform(%Oban.Job{args: %{"packages" => packages}}) do
with :ok <- run_igniter_upgrades(packages),
:ok <- run_test_suite() do
ping_heartbeat()
:ok
else
{:error, reason} ->
Logger.error("Igniter upgrade failed: #{inspect(reason)}")
{:error, reason}
end
end
defp run_igniter_upgrades(packages) do
Enum.reduce_while(packages, :ok, fn package, :ok ->
case System.cmd("mix", ["igniter.upgrade", package],
stderr_to_stdout: true,
env: [{"MIX_ENV", "prod"}]) do
{output, 0} ->
Logger.info("Upgraded #{package}: #{output}")
{:cont, :ok}
{output, exit_code} ->
Logger.error("Failed to upgrade #{package} (exit #{exit_code}): #{output}")
{:halt, {:error, "upgrade failed for #{package}"}}
end
end)
end
defp run_test_suite do
case System.cmd("mix", ["test", "--no-compile"], stderr_to_stdout: true) do
{_output, 0} -> :ok
{output, _} ->
Logger.error("Tests failed after Igniter upgrade: #{output}")
{:error, "test suite failed"}
end
end
defp ping_heartbeat do
url = Application.get_env(:my_app, :vigilmon)[:igniter_heartbeat_url]
if url do
case Req.get(url, receive_timeout: 5_000) do
{:ok, _} -> :ok
{:error, reason} ->
Logger.warning("Vigilmon heartbeat ping failed: #{inspect(reason)}")
end
end
end
end
Configure the URL:
# config/runtime.exs
config :my_app, :vigilmon,
igniter_heartbeat_url: System.get_env("VIGILMON_IGNITER_HEARTBEAT_URL")
Step 4: Set Up Monitoring in Vigilmon
HTTP health monitor (for webhook services):
- Sign in at vigilmon.online
- New Monitor → HTTP
- URL:
https://your-scaffold-service.com/health - Expected status:
200 - Interval: 1 minute
Heartbeat monitor (for scheduled upgrade jobs):
- New Monitor → Heartbeat
- Name:
igniter-upgrade-pipeline - Expected interval: match your schedule (e.g. 24 hours for nightly upgrades)
- Tolerance: 30 minutes (allow CI variability)
- Copy the ping URL and set it as
VIGILMON_IGNITER_HEARTBEAT_URL
If your upgrade job runs weekly:
- Set expected interval: 7 days
- Set tolerance: 2 hours
Step 5: Monitor Webhook Endpoints for GitHub App Integrations
If Igniter tasks are triggered by GitHub webhooks (e.g. a bot that patches code on PR events), monitor the webhook receiver:
- New Monitor → HTTP
- URL:
https://your-scaffold-service.com/webhooks/github(expect 200 or 204 on GET, or configure a POST check) - Add a keyword check if your endpoint returns a status body
For the GitHub webhook delivery endpoint itself, add an SSL certificate monitor:
- New Monitor → SSL Certificate
- URL:
https://your-scaffold-service.com - Alert: 14 days before expiry
An expired certificate causes GitHub to fail webhook delivery with a TLS error, silently stopping all Igniter automation.
Step 6: Alerts via Slack
- In Vigilmon: Notifications → New Channel → Slack
- Paste your incoming webhook URL
- Enable on all monitors
Example alert when the nightly upgrade job misses its window:
🔴 MISSED: igniter-upgrade-pipeline
Last ping: 26 hours ago (expected: 24 hours)
This tells you immediately that the scheduled upgrade didn't run — before stale dependencies accumulate or a breaking change slips through unpatched.
What You've Built
| What | How |
|------|-----|
| Webhook service health | /health endpoint checking Igniter availability and queue state |
| Scheduled upgrade monitoring | Heartbeat with 24-hour (or weekly) window |
| SSL for webhook endpoint | Certificate expiry alert 14 days ahead |
| Slack alerts | Downtime and missed-heartbeat notifications |
Igniter automates the tedious work of patching and upgrading your Elixir project. Vigilmon makes sure the automation itself doesn't go silent.
Next Steps
- Add a heartbeat per Igniter task category (upgrades, scaffolding, migrations) to isolate failures
- Use Vigilmon's response time history to track how long upgrade jobs take — sudden growth indicates new compile-time overhead
- Add a monitor for the GitHub API endpoint your bot depends on
- If you run multiple environments (staging, prod), add a heartbeat per environment
Get started free at vigilmon.online.