tutorial

How to Monitor Credo with Vigilmon

Integrate Credo static analysis into your Elixir CI pipeline and use Vigilmon heartbeat monitors to alert your team when code quality checks stop running or start failing.

How to Monitor Credo with Vigilmon

Credo is the code quality guardian for Elixir projects. It checks for consistency issues, anti-patterns, refactoring opportunities, and style violations across your entire codebase — giving every PR a uniform quality gate before it reaches review.

The problem is that static analysis is easy to accidentally skip. A .credo.exs configuration change can silently disable checks. A --ignore flag slips into a script. A CI step is commented out to fix a flaky build and never re-enabled. When Credo stops running, code quality degrades invisibly — and you only notice months later when the codebase has accumulated significant technical debt.

Vigilmon heartbeat monitors alert your team the moment Credo checks go dark.


Why Monitor Credo?

Credo catches issues humans miss in review:

  • Cyclomatic complexity — functions that branch too many ways and become untestable
  • Pipe chain abuse — pipes that break the |> contract by taking multiple arguments mid-chain
  • Unused variables and aliases — dead code accumulation that confuses future readers
  • Inconsistent module naming — conventions that diverge and make the codebase harder to navigate
  • Missing documentation — public modules without @moduledoc or @doc attributes

But those checks only help if they run on every commit. Monitoring Credo's CI integration ensures the quality gate is always active.


Key Metrics to Track

| Metric | What it tells you | |--------|-------------------| | Credo CI step pass rate | Whether quality checks are running and passing | | Issue count trend | Whether technical debt is growing or shrinking over time | | Check categories failing | Which types of issues (consistency, readability, warning) are accumulating | | Time since last Credo run | Whether the check has been silently disabled | | Strict mode pass/fail | Whether stricter enforcement is achievable |


Step 1: Add Credo to Your Project

# mix.exs
defp deps do
  [
    {:credo, "~> 1.7", only: [:dev, :test], runtime: false},
    # rest of your deps
  ]
end
mix deps.get
mix credo gen.config

The generated .credo.exs gives you a starting point you can tune per project. The defaults catch the most impactful issues immediately.


Step 2: Configure Credo for CI

Create a strict CI configuration alongside your development config:

# .credo.ci.exs
%{
  configs: [
    %{
      name: "ci",
      files: %{
        included: ["lib/", "test/"],
        excluded: ["test/support/"]
      },
      strict: true,
      color: false,
      checks: %{
        enabled: [
          {Credo.Check.Consistency.ExceptionNames, []},
          {Credo.Check.Consistency.LineEndings, []},
          {Credo.Check.Consistency.MultiAliasImportRequireUse, []},
          {Credo.Check.Design.AliasUsage, [priority: :low, if_nested_deeper_than: 2]},
          {Credo.Check.Readability.ModuleDoc, []},
          {Credo.Check.Refactor.CyclomaticComplexity, [max_complexity: 9]},
          {Credo.Check.Warning.UnusedEnumOperation, []},
          {Credo.Check.Warning.UnusedKeywordOperation, []},
        ]
      }
    }
  ]
}

Run it in CI:

mix credo --config-file .credo.ci.exs --strict

Step 3: Emit a Heartbeat After Successful Credo Run

The key integration: only ping Vigilmon when Credo passes. No ping means the quality gate failed or didn't run.

#!/bin/bash
# scripts/ci_quality.sh
set -e

echo "Running Credo analysis..."
mix credo --config-file .credo.ci.exs --strict

echo "Credo passed. Pinging Vigilmon..."
if [ -n "$VIGILMON_CREDO_HEARTBEAT_URL" ]; then
  curl -fsS "$VIGILMON_CREDO_HEARTBEAT_URL" > /dev/null
  echo "Heartbeat sent."
fi

GitHub Actions workflow:

# .github/workflows/quality.yml
name: Code Quality

on:
  push:
    branches: [main, develop]
  pull_request:

jobs:
  credo:
    name: Credo Static Analysis
    runs-on: ubuntu-latest
    env:
      VIGILMON_CREDO_HEARTBEAT_URL: ${{ secrets.VIGILMON_CREDO_HEARTBEAT_URL }}
    steps:
      - uses: actions/checkout@v4

      - uses: erlef/setup-beam@v1
        with:
          elixir-version: '1.16'
          otp-version: '26'

      - name: Cache deps
        uses: actions/cache@v3
        with:
          path: deps
          key: ${{ runner.os }}-deps-${{ hashFiles('mix.lock') }}

      - run: mix deps.get

      - name: Run Credo
        run: mix credo --config-file .credo.ci.exs --strict

      - name: Ping Vigilmon heartbeat
        if: success()
        run: curl -fsS "$VIGILMON_CREDO_HEARTBEAT_URL"

Step 4: Create a Heartbeat Monitor in Vigilmon

  1. Sign in at vigilmon.online
  2. Click New Monitor → Heartbeat
  3. Name it Credo — main branch
  4. Set the expected interval to slightly more than your longest CI run, e.g. 2 hours for active teams
  5. Copy the URL and store it as VIGILMON_CREDO_HEARTBEAT_URL in your CI secrets

If Credo fails or CI is broken, the heartbeat misses and Vigilmon alerts you.


Step 5: Track Issue Trends with a Custom Exporter

For teams that want to track Credo issue counts over time, add a step that exports the JSON report:

# lib/mix/tasks/credo_report.ex
defmodule Mix.Tasks.CredoReport do
  use Mix.Task

  @shortdoc "Run Credo and output a summary JSON for CI tracking"

  def run(_args) do
    {output, exit_code} = System.cmd("mix", ["credo", "--format", "json"], stderr_to_stdout: true)

    case Jason.decode(output) do
      {:ok, report} ->
        issues = report["issues"] || []
        summary = %{
          total: length(issues),
          by_category: Enum.group_by(issues, & &1["category"]) |> Map.new(fn {k, v} -> {k, length(v)} end),
          exit_code: exit_code
        }

        IO.puts(Jason.encode!(summary, pretty: true))

        if exit_code != 0, do: exit({:shutdown, exit_code})

      {:error, _} ->
        IO.puts("Failed to parse Credo JSON output")
        exit({:shutdown, 1})
    end
  end
end

Pipe this into a CI artifact or external metrics dashboard to track issue count trends over time.


Step 6: Production Health Check + Alerting

Add an HTTP monitor on your app's /health endpoint to cover production uptime alongside code quality monitoring:

# lib/my_app_web/plugs/health_check.ex
defmodule MyAppWeb.Plugs.HealthCheck do
  import Plug.Conn

  def init(opts), do: opts

  def call(%Plug.Conn{request_path: "/health"} = conn, _opts) do
    checks = %{database: check_db()}
    status = if Enum.all?(checks, fn {_, v} -> v == :ok end), do: 200, else: 503

    conn
    |> put_resp_content_type("application/json")
    |> send_resp(status, Jason.encode!(%{status: if(status == 200, do: "ok", else: "degraded"), checks: checks}))
    |> halt()
  end

  def call(conn, _opts), do: conn

  defp check_db do
    case Ecto.Adapters.SQL.query(MyApp.Repo, "SELECT 1", []) do
      {:ok, _} -> :ok
      _ -> :error
    end
  end
end

In Vigilmon, add:

  • HTTP monitorhttps://yourdomain.com/health for production uptime
  • Heartbeat monitor → Credo CI pipeline health

Step 7: Alerting Configuration

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

🔴 MISSED: Credo — main branch
Last heartbeat: 3 hours ago (expected every 2 hours)
Action: Check CI pipeline for Credo failures or disabled steps

For critical projects, escalate to PagerDuty or email when the Credo heartbeat misses twice in a row.


What You've Built

| What | How | |------|-----| | Credo CI integration | mix credo --strict in dedicated CI job | | Pipeline health monitoring | Vigilmon heartbeat monitor | | Failure alerting | Slack/email notification channel | | Issue trend tracking | Custom Mix task with JSON output | | Production uptime monitoring | Vigilmon HTTP monitor on /health | | Team status page | Vigilmon public status page |

Credo keeps your code quality honest. Vigilmon keeps your Credo honest.


Next Steps

  • Add separate heartbeat monitors for main and your release branches
  • Export Credo JSON reports to a time-series store (InfluxDB, Grafana) to visualize technical debt trends
  • Use Vigilmon's incident history to correlate production incidents with Credo check regressions
  • Configure different .credo.exs strictness per environment (dev permissive, CI strict)

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 →