tutorial

How to Monitor Igniter with Vigilmon

Igniter is Elixir's composable code generation and project patching framework. Learn how to monitor automated code mod pipelines, track Igniter task health in CI, and alert on patching failures using Vigilmon.

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 igniter in mix.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):

  1. Sign in at vigilmon.online
  2. New Monitor → HTTP
  3. URL: https://your-scaffold-service.com/health
  4. Expected status: 200
  5. Interval: 1 minute

Heartbeat monitor (for scheduled upgrade jobs):

  1. New Monitor → Heartbeat
  2. Name: igniter-upgrade-pipeline
  3. Expected interval: match your schedule (e.g. 24 hours for nightly upgrades)
  4. Tolerance: 30 minutes (allow CI variability)
  5. Copy the ping URL and set it as VIGILMON_IGNITER_HEARTBEAT_URL

If your upgrade job runs weekly:

  1. Set expected interval: 7 days
  2. 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:

  1. New Monitor → HTTP
  2. URL: https://your-scaffold-service.com/webhooks/github (expect 200 or 204 on GET, or configure a POST check)
  3. Add a keyword check if your endpoint returns a status body

For the GitHub webhook delivery endpoint itself, add an SSL certificate monitor:

  1. New Monitor → SSL Certificate
  2. URL: https://your-scaffold-service.com
  3. 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

  1. In Vigilmon: Notifications → New Channel → Slack
  2. Paste your incoming webhook URL
  3. 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.

Monitor your app with Vigilmon

Free plan — 5 monitors, no credit card required. Up and running in 60 seconds.

Start free →