Docs › Airflow DAG monitoring with RunVouch
Airflow DAG monitoring with RunVouch
Airflow DAG monitoring for what a green DAG run cannot prove: Airflow is very good at telling you a task failed. A task that succeeds with an empty DataFrame, a DAG that is paused, or a scheduler that stopped scheduling all look like silence.
How it runs on Apache Airflow
Wrap the command of a BashOperator, or use the Python client inside a PythonOperator / @task. One RunVouch agent per DAG (or per critical task) is the usual shape.
Store the key
An Airflow Variable or Connection backed by your secrets backend; pass it into the task environment (env={"RUNVOUCH_KEY": ...}) rather than hardcoding.
Wrap the job
from airflow.decorators import dag, task
from airflow.operators.bash import BashOperator
from airflow.models import Variable
import pendulum, runvouch
@dag(schedule="0 2 * * *", start_date=pendulum.datetime(2026, 1, 1, tz="UTC"), catchup=False)
def nightly_report():
build = BashOperator(task_id="build",
env={"RUNVOUCH_KEY": Variable.get("runvouch_key")},
bash_command="rv run nightly-report --evidence-file /out/report.html -- python /opt/report.py")
@task
def summarise():
with runvouch.vouch("nightly-summary", evidence=lambda: {"rows": n > 0}) as run:
n = summarise_rows(run) # run.tool(...) per LLM call for cost and loop detection
build >> summarise()
nightly_report()rv fails open: if RunVouch is unreachable the job still runs and you get one warning line.
Register the cadence and caps
rv agent nightly-report --cadence 24h --grace 30m --max-runtime 1h --evidence --cap-run-cost 2
Register the agent once, from anywhere with the key. Cadence is what turns a schedule that stopped into an alert; --evidence makes a run without evidence a failure; the caps pause the agent when it overspends.
What goes silent on Apache Airflow
- A paused DAG (or one that failed to import after a bad deploy) schedules nothing; the DAG import error banner is not an alert. MISSED is.
sla_miss_callbackonly fires when the scheduler is healthy enough to notice.- A task with
retries=3around an LLM call is a retry storm with a budget; the per-run cost cap ends it.
What Apache Airflow does not tell you
Airflow's on_failure_callback, e-mail on failure and SLA misses all need a task instance that ran or was scheduled. A DAG that failed to import after a deploy shows a red banner in the UI and creates no task instances; a paused DAG creates none either; a scheduler that is down creates none for any DAG. The scheduler's own health check is an HTTP endpoint you have to poll yourself.
What RunVouch detects
| Alert | What it means here |
|---|---|
| MISSED | cadence plus grace passed and no run started |
| FAILED | non-zero exit or a reported failure, with the stderr excerpt |
| NO_EVIDENCE | the run said ok but the file, URL or assertion you required is missing |
| STALLED | a run started and never ended within max runtime |
| RETRY_STORM | the same tool called with identical input many times in one run |
| BUDGET_RUN / BUDGET_DAY | cost cap crossed; the agent is paused until you resume it |
| DRIFT | duration or output size far off its 7-run baseline |
Set up in two minutes
- Get a free key (3 agents, no card) and store it where this page says.
- wrap the job: copy the snippet above into the scheduled job.
- Register the cadence once:
rv agent nightly-report --cadence 24h --grace 30m --evidence, or let the first run create the agent and set the cadence on the dashboard. - Send one test alert:
curl -X POST https://api.runvouch.com/v1/settings/test-alert -H "X-API-Key: $RUNVOUCH_KEY". The next missed, failed or empty run reaches the same channels.
Also running orchestrators?
Prefect. Dagster. Celery beat. APScheduler (in-process). The full list of runtimes is on integrations, and the same agent can report from several of them: one job, one cadence, wherever it happens to run.
Need a key? Get a free key · Stuck? contact