tutorial

Monitoring Your Matterbridge Chat Bridge with Vigilmon

Add uptime monitoring, process health checks, and alerts to your self-hosted Matterbridge multi-protocol chat bridge — covering bridge process health, per-gateway connection status (Slack/Discord/Matrix/IRC/Telegram), message relay throughput, and reconnection event monitoring.

Monitoring Your Matterbridge Chat Bridge with Vigilmon

Matterbridge is a single Go binary that bridges chat messages across Slack, Discord, Matrix, IRC, Telegram, Mattermost, Rocket.Chat, and a dozen more protocols — all at once, with routing rules you define in a TOML config file.

When Matterbridge goes down, message bridging stops silently. People on Slack think people on Matrix aren't responding. Discord users don't see IRC messages. Nobody gets an error — they just stop hearing from each other. By the time someone files a complaint, the bridge may have been down for hours.

This tutorial adds external monitoring to your Matterbridge deployment:

  • Process health check via HTTP API
  • HTTP uptime monitoring with Vigilmon
  • Per-gateway connection status monitoring (Slack, Discord, Matrix, IRC, Telegram)
  • Heartbeat monitoring for message relay throughput
  • Slack/Discord alerts and a public status page

Architecture overview

Matterbridge is intentionally minimal — it runs as a single process with no built-in HTTP server. Monitoring it requires a lightweight sidecar or log-based approach:

| What to monitor | How | |-----------------|-----| | Bridge process health | PID file + HTTP sidecar | | Slack gateway connection | WebSocket reconnect events in logs | | Discord gateway connection | WebSocket reconnect events in logs | | Matrix homeserver connectivity | Direct HTTP check on homeserver | | IRC server connection | Log-based + TCP port check | | Telegram Bot API | Direct HTTP check | | Message relay throughput | Heartbeat based on log line count | | Reconnection frequency | Log error rate check | | Config file integrity | Heartbeat after config validation | | Webhook receiver | HTTP monitor if enabled |


Step 1: Add a health check sidecar

Matterbridge doesn't expose an HTTP server, so you need a lightweight health sidecar that reports bridge process status. The simplest approach is a small systemd service that wraps a health check script:

#!/bin/bash
# /usr/local/bin/matterbridge-health
# Simple HTTP health server for Matterbridge process monitoring

MATTERBRIDGE_PID_FILE="${MATTERBRIDGE_PID_FILE:-/var/run/matterbridge.pid}"
PORT="${HEALTH_PORT:-8765}"

check_health() {
  # Check if PID file exists and process is running
  if [ ! -f "$MATTERBRIDGE_PID_FILE" ]; then
    echo '{"status":"error","reason":"pid_file_missing"}'
    return 1
  fi

  pid=$(cat "$MATTERBRIDGE_PID_FILE")
  if ! kill -0 "$pid" 2>/dev/null; then
    echo '{"status":"error","reason":"process_not_running","pid":'"$pid"'}'
    return 1
  fi

  # Check log file for recent errors (last 60 seconds)
  log_file="${MATTERBRIDGE_LOG:-/var/log/matterbridge/matterbridge.log}"
  if [ -f "$log_file" ]; then
    recent_errors=$(awk -v d="$(date -d '60 seconds ago' '+%Y/%m/%d %H:%M')" '$0 >= d' "$log_file" | grep -c '"level":"error"' || true)
    echo "{\"status\":\"ok\",\"pid\":${pid},\"recent_errors\":${recent_errors}}"
  else
    echo "{\"status\":\"ok\",\"pid\":${pid}}"
  fi
  return 0
}

# Serve HTTP responses
while true; do
  response=$(check_health)
  exit_code=$?

  if [ $exit_code -eq 0 ]; then
    http_status="200 OK"
  else
    http_status="503 Service Unavailable"
  fi

  printf "HTTP/1.1 %s\r\nContent-Type: application/json\r\nContent-Length: %d\r\n\r\n%s" \
    "$http_status" "${#response}" "$response" | nc -l -p "$PORT" -q 1 2>/dev/null
done

Run Matterbridge with a PID file:

# /etc/systemd/system/matterbridge.service
[Unit]
Description=Matterbridge chat bridge
After=network.target

[Service]
Type=simple
User=matterbridge
ExecStart=/usr/local/bin/matterbridge -conf /etc/matterbridge/matterbridge.toml
PIDFile=/var/run/matterbridge.pid
Restart=on-failure
RestartSec=10
StandardOutput=append:/var/log/matterbridge/matterbridge.log
StandardError=append:/var/log/matterbridge/matterbridge.log

[Install]
WantedBy=multi-user.target
# /etc/systemd/system/matterbridge-health.service
[Unit]
Description=Matterbridge health check sidecar
After=matterbridge.service

[Service]
Type=simple
User=matterbridge
ExecStart=/usr/local/bin/matterbridge-health
Environment=MATTERBRIDGE_PID_FILE=/var/run/matterbridge.pid
Environment=HEALTH_PORT=8765
Restart=always

[Install]
WantedBy=multi-user.target

Test it:

curl http://localhost:8765
# {"status":"ok","pid":12345,"recent_errors":0}

Put this behind your reverse proxy at /health and Vigilmon can monitor it:

location /health {
    proxy_pass http://localhost:8765;
    proxy_connect_timeout 5s;
    proxy_read_timeout 10s;
}

Step 2: Set up HTTP monitoring in Vigilmon

Point Vigilmon at your health endpoint:

  1. Sign up at vigilmon.online
  2. Click New Monitor → HTTP
  3. Enter https://matterbridge.yourdomain.com/health
  4. Set check interval: 1 minute (paid) or 5 minutes (free)
  5. Add keyword check for "status":"ok" in response body
  6. Save

This detects the most common failure mode: the systemd service crashed, the process exited, or the binary panicked. A 503 means the bridge is down; anything else means the sidecar itself is broken.


Step 3: Monitor per-gateway connections

Each protocol gateway has its own connectivity requirements. Add direct health monitors where possible:

Matrix homeserver:

https://matrix.yourdomain.com/_matrix/client/versions

In Vigilmon:

  • Add keyword check for "versions" in response body
  • This verifies the Matrix homeserver is accepting connections

Telegram Bot API:

https://api.telegram.org/botYOUR_BOT_TOKEN/getMe

In Vigilmon:

  • Add keyword check for "ok":true in response body
  • A 401 indicates the bot token is invalid or revoked

Discord gateway:

https://discord.com/api/v10/gateway
  • Keyword check for "url" — the returned gateway URL indicates Discord's API is operational

Slack API:

https://slack.com/api/api.test
  • Keyword check for "ok":true

IRC server TCP check:

For IRC, use Vigilmon's TCP monitor:

  1. Click New Monitor → TCP
  2. Enter your IRC server hostname and port (usually 6667 or 6697 for SSL)
  3. This verifies the IRC server accepts TCP connections

These per-protocol monitors tell you when a gateway failure is the external service's fault, not Matterbridge's. When Discord has an incident, your Discord monitor goes red — and you immediately know why Matterbridge isn't bridging Discord messages.


Step 4: Alerts via Slack or Discord

Slack alerts:

In Vigilmon, go to Notifications → New Channel → Slack and paste your incoming webhook URL.

  1. api.slack.com/appsCreate New App
  2. Enable Incoming Webhooks → copy URL

Discord alerts (recommended since you're bridging Discord):

In Vigilmon, go to Notifications → New Channel → Webhook:

  1. Pick a monitoring-specific Discord channel (not one that Matterbridge bridges)
  2. Channel settings → Integrations → Webhooks → New Webhook → copy URL
  3. Append /slack to use the Slack-compatible format: https://discord.com/api/webhooks/...TOKEN.../slack

Use a dedicated monitoring channel that is NOT part of any bridge — if Matterbridge goes down, you don't want your alerts to also go through Matterbridge.


Step 5: Heartbeat monitoring for message relay throughput

A running Matterbridge process doesn't guarantee messages are flowing. The bridge can be up while all gateways have silently disconnected. Add a throughput heartbeat:

#!/bin/bash
# /usr/local/bin/matterbridge-throughput-check
# Run every 5 minutes via cron

VIGILMON_HEARTBEAT_URL="${VIGILMON_HEARTBEAT_URL}"
LOG_FILE="${MATTERBRIDGE_LOG:-/var/log/matterbridge/matterbridge.log}"
CHECK_WINDOW_SECONDS=300  # 5 minutes

# Count relayed messages in the last 5 minutes
recent_relayed=$(awk \
  -v d="$(date -d "${CHECK_WINDOW_SECONDS} seconds ago" '+%Y/%m/%d %H:%M')" \
  '$0 >= d && /msg relay/ {count++} END {print count+0}' \
  "$LOG_FILE" 2>/dev/null)

# Count reconnection events in the same window
reconnects=$(awk \
  -v d="$(date -d "${CHECK_WINDOW_SECONDS} seconds ago" '+%Y/%m/%d %H:%M')" \
  '$0 >= d && /reconnect/ {count++} END {print count+0}' \
  "$LOG_FILE" 2>/dev/null)

echo "Recent relayed: ${recent_relayed}, Reconnects: ${reconnects}"

# Alert on excessive reconnections even if messages are flowing
if [ "$reconnects" -gt 10 ]; then
  echo "Too many reconnections (${reconnects}) — skipping heartbeat ping"
  exit 1
fi

# Ping heartbeat if bridge appears healthy
# Note: we ping even with 0 messages — low traffic is normal
# The PID check in the health endpoint handles actual process failures
curl -sf "${VIGILMON_HEARTBEAT_URL}" > /dev/null

Add to crontab:

*/5 * * * * /usr/local/bin/matterbridge-throughput-check

In Vigilmon, create a Heartbeat Monitor:

  1. Click New Monitor → Heartbeat
  2. Set expected interval: 10 minutes (2× cron interval)
  3. Copy the ping URL → set as VIGILMON_HEARTBEAT_URL
  4. Enable Discord/Slack alerts

Step 6: Monitor reconnection frequency

Frequent reconnections indicate gateway instability — a flaky IRC server, a rate-limited Telegram connection, or a Discord WebSocket that keeps dropping. Add a log-based monitor:

#!/bin/bash
# /usr/local/bin/matterbridge-reconnect-monitor
# Run every hour via cron

VIGILMON_HEARTBEAT_STABILITY="${VIGILMON_HEARTBEAT_STABILITY}"
LOG_FILE="${MATTERBRIDGE_LOG:-/var/log/matterbridge/matterbridge.log}"

# Count reconnections in the last hour
reconnects=$(awk \
  -v d="$(date -d '1 hour ago' '+%Y/%m/%d %H:%M')" \
  '$0 >= d && /reconnect/ {count++} END {print count+0}' \
  "$LOG_FILE" 2>/dev/null)

echo "Reconnections in last hour: ${reconnects}"

# Only ping if reconnection count is within acceptable range
# Occasional reconnects are normal; >20/hour suggests a problem
if [ "$reconnects" -lt 20 ]; then
  curl -sf "${VIGILMON_HEARTBEAT_STABILITY}" > /dev/null
  echo "Stability heartbeat sent"
else
  echo "Reconnection rate too high (${reconnects}/hr) — skipping heartbeat"
fi
5 * * * * /usr/local/bin/matterbridge-reconnect-monitor

In Vigilmon, create a Heartbeat Monitor with expected interval 2 hours and enable alerts. A missed heartbeat means reconnections exceeded 20/hour in the last interval — worth investigating before the gateway starts dropping messages entirely.


Step 7: Configuration file integrity check

Matterbridge reads its config at startup. A broken TOML file causes a silent failure on restart. Add a validation heartbeat to your deployment pipeline:

#!/bin/bash
# /usr/local/bin/matterbridge-config-validate
# Run after any config change

CONFIG_FILE="${MATTERBRIDGE_CONFIG:-/etc/matterbridge/matterbridge.toml}"
VIGILMON_HEARTBEAT_CONFIG="${VIGILMON_HEARTBEAT_CONFIG}"

# Validate config by doing a dry run (check if matterbridge can parse it)
if /usr/local/bin/matterbridge -conf "$CONFIG_FILE" -debug 2>&1 | grep -q "Starting bridge"; then
  # Config is valid — but this would actually start the bridge
  # Instead, use a config linter or basic TOML validation
  echo "Config appears valid"
else
  echo "Config validation check skipped (use toml-test or similar)"
fi

# Simple TOML syntax check using Python (usually available)
if python3 -c "
import sys
try:
    import tomllib
    with open('${CONFIG_FILE}', 'rb') as f:
        tomllib.load(f)
    print('valid')
except Exception as e:
    print(f'error: {e}', file=sys.stderr)
    sys.exit(1)
" 2>/dev/null; then
  curl -sf "${VIGILMON_HEARTBEAT_CONFIG}" > /dev/null
  echo "Config heartbeat sent"
fi

Run this as a git pre-commit hook or a post-deploy step. Set the Vigilmon heartbeat window to 24 hours — a missed daily heartbeat means the last config change or deployment didn't validate cleanly.


Step 8: Status page and badge

Status page:

  1. Go to Status Pages → New Status Page in Vigilmon
  2. Add all monitors in groups:
    • Bridge Core: process health, throughput heartbeat
    • Protocol Gateways: Matrix, Telegram, Discord, Slack, IRC
    • Stability: reconnection rate heartbeat, config heartbeat
  3. Copy the public URL

Share the status page URL with your bridged communities. When users in one platform stop seeing messages from another, they can check the status page first before pinging an admin.

README badge:

[![Bridge Status](https://vigilmon.online/badge/your-monitor-slug)](https://status.yourdomain.com)

What you've built

| What | How | |------|-----| | Bridge process health | PID-based sidecar HTTP endpoint | | Matrix homeserver | HTTP monitor on /_matrix/client/versions | | Telegram Bot API | HTTP monitor on /getMe | | Discord API | HTTP monitor on /gateway | | Slack API | HTTP monitor on /api.test | | IRC server | TCP port monitor | | Message throughput | Log-based cron heartbeat every 5 min | | Reconnection stability | Hourly log-based heartbeat | | Config integrity | Deployment-triggered TOML validation heartbeat | | Discord/Slack alerts | Vigilmon notification channel | | Status page | Vigilmon public status page |

Matterbridge bridges your communities. Vigilmon makes sure the bridge itself doesn't silently collapse.


Next steps

  • Add log rotation monitoring — a growing unbounded log file can eventually exhaust disk and crash the bridge
  • Use Vigilmon response time history to detect when Matrix federation latency spikes before messages start dropping
  • If you run multiple Matterbridge instances for redundancy, add separate heartbeat monitors per instance
  • Consider adding a test message bot that sends a known message and verifies it appears on the other side — the ultimate end-to-end bridge health check

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 →