tutorial

Monitoring CircleCI Pipelines with Vigilmon: Catch Silent CI/CD Failures

Use Vigilmon heartbeat monitors to detect silent CircleCI failures — scheduled pipeline drift, stuck jobs, and pipelines that stop running entirely.

Your nightly integration suite stopped running two weeks ago. Nobody noticed until a regression made it to production. CircleCI had no errors to report — the scheduled pipeline simply wasn't being triggered anymore. Build notifications only fire on failures, and you can't fail if you never run.

This is the silent CI/CD failure problem. HTTP monitors can't catch it because there's nothing to ping. The fix is heartbeat monitoring: your pipeline pings a unique URL at the end of every successful run, and if Vigilmon doesn't receive that ping within the expected window, you get alerted.

This tutorial shows you how to instrument CircleCI pipelines with Vigilmon heartbeat monitors to catch failures before your team does.

What You'll Cover

  • Heartbeat monitoring for scheduled CircleCI pipelines
  • Catching pipelines that stop triggering entirely
  • Alerting on long-running or stuck jobs
  • Multi-environment CI monitoring (staging and production)
  • Detecting scheduled pipeline drift

Prerequisites

  • A CircleCI project with at least one pipeline
  • A free account at vigilmon.online

The Problem: What Standard CircleCI Monitoring Misses

CircleCI has built-in email notifications — but they only fire when a job fails. They won't alert you when:

  • A scheduled pipeline trigger is disabled or misconfigured in the CircleCI UI
  • A pipeline is paused or suspended without anyone noticing
  • A workflow runs but silently skips a critical job due to branch filtering
  • A deployment job completes successfully but the actual deploy step is a no-op

Vigilmon's heartbeat pattern closes all of these gaps.


Step 1: Create a Heartbeat Monitor in Vigilmon

A heartbeat monitor expects a ping on a regular interval. No ping → alert.

  1. Log in to Vigilmon and click New Monitor → Heartbeat.
  2. Give it a name like Nightly Tests — main.
  3. Set the Expected interval to match your pipeline schedule. For a nightly cron, use 24 hours. For hourly CI, use 90 minutes (adds a 50% buffer).
  4. Set the Grace period to 30 minutes for short intervals, or 1 hour for daily jobs. This prevents false alerts from slight schedule drift.
  5. Save and copy the Ping URL — it looks like https://vigilmon.online/api/heartbeat/<unique-id>.

Step 2: Add the Heartbeat Ping to a Scheduled Pipeline

Store the heartbeat URL as a CircleCI environment variable first. Go to Project Settings → Environment Variables → Add Variable:

  • Name: VIGILMON_NIGHTLY_HEARTBEAT_URL
  • Value: the ping URL from Step 1

For shared variables across projects, use a CircleCI Context (Organization Settings → Contexts → Create Context) and reference it with context: vigilmon in the pipeline config.

Here's a complete example of a nightly test pipeline with Vigilmon instrumentation:

# .circleci/config.yml
version: 2.1

jobs:
  test:
    docker:
      - image: cimg/node:20.0
    steps:
      - checkout

      - restore_cache:
          keys:
            - v1-deps-{{ checksum "package-lock.json" }}

      - run:
          name: Install dependencies
          command: npm ci

      - save_cache:
          paths:
            - node_modules
          key: v1-deps-{{ checksum "package-lock.json" }}

      - run:
          name: Run tests
          command: npm test

      - run:
          name: Ping Vigilmon heartbeat
          when: on_success
          command: |
            curl -fsS -X POST "$VIGILMON_NIGHTLY_HEARTBEAT_URL" \
              --max-time 10 \
              --retry 3 \
              --retry-delay 2

workflows:
  nightly:
    triggers:
      - schedule:
          cron: "0 2 * * *"  # 02:00 UTC every night
          filters:
            branches:
              only:
                - main
    jobs:
      - test:
          context: vigilmon

Key points about this setup:

  • when: on_success — the heartbeat ping is only sent when all previous steps pass. If tests fail, the job fails, and no ping is sent.
  • --retry 3 — transient network issues won't cause a false "missed heartbeat" alert.
  • --max-time 10 — the ping step won't hang and block the executor.
  • context: vigilmon — pulls the heartbeat URL from the org-level CircleCI context.

Step 3: Monitor Your Deployment Pipeline

Heartbeats are even more valuable for deployment pipelines than for tests — a silently stuck deploy leaves production stale without any error to page you.

# .circleci/config.yml (deployment job)
jobs:
  deploy-production:
    docker:
      - image: cimg/base:stable
    steps:
      - checkout

      - run:
          name: Build
          command: npm run build

      - run:
          name: Deploy
          command: ./scripts/deploy.sh production

      - run:
          name: Run smoke tests
          command: npm run test:smoke

      - run:
          name: Ping Vigilmon deployment heartbeat
          when: on_success
          command: |
            curl -fsS -X POST "$VIGILMON_DEPLOY_PROD_HEARTBEAT_URL" \
              --max-time 10 \
              --retry 3

workflows:
  deploy:
    jobs:
      - deploy-production:
          context: vigilmon
          filters:
            branches:
              only: main

Create a separate heartbeat monitor for this workflow with an interval of 48 hours (or however often you expect to deploy). If no successful deployment reaches production within that window, Vigilmon pages you.


Step 4: Detect Scheduled Pipeline Drift

CircleCI's scheduled pipeline triggers have a known limitation: if a schedule is misconfigured or the project is suspended, triggers silently stop firing. There's no built-in alerting for a pipeline that just... stops running.

Vigilmon's heartbeat monitor catches this automatically — if the cron misses a run for any reason, no ping arrives, and you get alerted.

To make the signal even more reliable, add metadata to the heartbeat payload:

- run:
    name: Ping Vigilmon heartbeat with metadata
    when: on_success
    command: |
      curl -fsS -X POST "$VIGILMON_NIGHTLY_HEARTBEAT_URL" \
        -H "Content-Type: application/json" \
        -d "{\"pipeline\": \"$CIRCLE_PROJECT_REPONAME\", \"build_num\": \"$CIRCLE_BUILD_NUM\", \"branch\": \"$CIRCLE_BRANCH\"}" \
        --max-time 10 \
        --retry 3

Vigilmon accepts the body but doesn't require it — it only cares whether the ping arrived within the grace period.


Step 5: Multi-Environment Monitoring

For teams with staging and production pipelines, create one heartbeat monitor per environment per workflow:

| Workflow | Environment | Monitor name | Interval | |---|---|---|---| | Deploy workflow | Production | Deploy → Production | 48 h | | Deploy workflow | Staging | Deploy → Staging | 24 h | | Nightly tests | main | Nightly Tests — main | 25 h | | Weekly security scan | — | Weekly Security Scan | 8 days |

Use separate environment variables per environment, resolved dynamically:

- run:
    name: Ping heartbeat
    when: on_success
    command: |
      if [ "$CIRCLE_BRANCH" = "main" ]; then
        HEARTBEAT_URL="$VIGILMON_DEPLOY_PROD_HEARTBEAT_URL"
      else
        HEARTBEAT_URL="$VIGILMON_DEPLOY_STAGING_HEARTBEAT_URL"
      fi
      curl -fsS -X POST "$HEARTBEAT_URL" --max-time 10

Step 6: Alert Channels

In Vigilmon, go to Notifications → New Channel and configure:

  • Email — immediate alert when a heartbeat is missed
  • Slack webhook — ping your #alerts or #ci-cd channel

When a pipeline stops pinging:

🔴 MISSED HEARTBEAT: Nightly Tests — main
Last ping: 26 hours ago
Expected interval: 24 hours

When it resumes:

✅ HEARTBEAT RECOVERED: Nightly Tests — main
Gap: 26 hours

Step 7: Protect Against Pipeline Suspension

One more failure mode specific to CircleCI: a project can be suspended or have its free plan credit exhausted, causing all pipelines to silently stop. Since no jobs run, no ping arrives, and Vigilmon alerts you within one interval.

No code change needed — the heartbeat monitor already covers this case.


Complete Step Template

Here's a reusable step you can copy into any CircleCI job:

# Add this step at the end of any job you want heartbeat monitoring on
- run:
    name: Ping Vigilmon heartbeat
    when: on_success
    command: |
      curl -fsS -X POST "$VIGILMON_HEARTBEAT_URL" \
        --max-time 10 \
        --retry 3 \
        --retry-delay 2

Replace VIGILMON_HEARTBEAT_URL with the specific environment variable name for that pipeline's monitor (use one heartbeat monitor per pipeline).


What You're Now Catching

| Silent failure mode | How Vigilmon detects it | |---|---| | Scheduled trigger disabled in CircleCI UI | No ping arrives → alert after grace period | | Project suspended or credit exhausted | No ping arrives → alert after grace period | | Pipeline runs but skips a critical job | No ping on that job → alert | | Job hung on a stuck step | Job timeout → no ping → alert | | Deploy pipeline stopped shipping | Deploy heartbeat missed → alert | | Branch filter change stops triggering builds | No ping on missed runs → alert |


CircleCI is reliable — until it quietly stops working. Vigilmon's heartbeat monitors give you the external signal that CircleCI itself can't provide: a definitive alert when your CI/CD pipeline hasn't run in longer than expected.

Add heartbeat monitoring to your CircleCI pipelines today — register 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 →