tutorial

Monitoring Misago with Vigilmon

Misago is a self-hosted modern Python forum built on Django. Learn how to monitor web availability, Celery workers, Redis, PostgreSQL, search indexing, and email delivery with Vigilmon.

Misago is a modern, self-hosted forum platform built on Django — fast, feature-rich, and entirely under your control. But a forum is only as useful as its uptime: a crashed Celery worker silently breaks notifications, a stale search index frustrates users looking for past threads, and a full Redis cache drops sessions without any visible error page. Vigilmon gives you real-time visibility into every layer of your Misago deployment so you catch problems before your community does.

What You'll Set Up

  • HTTP uptime monitor for the Misago web server
  • Django application health endpoint check
  • Celery async task worker heartbeat
  • Redis connectivity monitor
  • PostgreSQL connection pool heartbeat
  • Search index health check
  • Email notification service heartbeat
  • User session management monitor

Prerequisites

  • Misago running on Django (Python 3.10+), port 8000 or behind a reverse proxy
  • Celery worker configured with a broker (Redis or RabbitMQ)
  • Redis instance for caching and session storage
  • PostgreSQL database
  • A free Vigilmon account

Step 1: Monitor the Misago Web Server

Start with a basic availability check on the Misago interface.

  1. Log in to vigilmon.online and click Add Monitor.
  2. Set Type to HTTP / HTTPS.
  3. Enter your Misago URL: https://forum.yourdomain.com.
  4. Set Check interval to 1 minute.
  5. Set Expected HTTP status to 200.
  6. Under Keyword match, enter Misago or the name of your forum to confirm the page is rendering rather than showing an error template.
  7. Click Save.

Enable Monitor SSL certificate if you serve Misago over HTTPS and set the alert threshold to 21 days.


Step 2: Add a Django Health Endpoint

Django doesn't ship a health endpoint by default, but adding one is straightforward. It gives Vigilmon a reliable probe point that exercises the application stack without serving a full page render.

In your Misago project, add a view:

# misago/health.py
from django.http import JsonResponse
from django.db import connection


def health_check(request):
    try:
        connection.ensure_connection()
        db_ok = True
    except Exception:
        db_ok = False

    status = 200 if db_ok else 503
    return JsonResponse({"status": "ok" if db_ok else "degraded", "db": db_ok}, status=status)

Wire it up in your URL config:

# urls.py
from django.urls import path
from misago.health import health_check

urlpatterns = [
    path("health/", health_check),
    # ... rest of your urls
]

Add a Vigilmon monitor:

  1. Add MonitorHTTP / HTTPS.
  2. URL: https://forum.yourdomain.com/health/.
  3. Expected HTTP status: 200.
  4. Keyword match: "status": "ok".
  5. Check interval: 1 minute.

This endpoint checks both the Django process and PostgreSQL connectivity in a single probe.


Step 3: Heartbeat for Celery Workers

Celery handles Misago's async tasks: sending email notifications, processing attachments, and running periodic cleanup jobs. A dead worker means users never get notified of replies.

Add a periodic Celery task that pings Vigilmon:

# misago/tasks.py
from celery import shared_task
import requests


@shared_task
def vigilmon_heartbeat():
    try:
        requests.get(
            "https://vigilmon.online/heartbeat/CELERY_HEARTBEAT_ID",
            timeout=5
        )
    except Exception:
        pass

Register it in your Celery beat schedule:

# settings.py
from celery.schedules import crontab

CELERY_BEAT_SCHEDULE = {
    "vigilmon-heartbeat": {
        "task": "misago.tasks.vigilmon_heartbeat",
        "schedule": 60.0,  # every 60 seconds
    },
    # ... your other tasks
}

In Vigilmon:

  1. Add MonitorCron Heartbeat.
  2. Expected ping interval: 2 minutes.
  3. Use the heartbeat URL in vigilmon_heartbeat().

If the Celery worker crashes or loses broker connectivity, no ping arrives and Vigilmon alerts you.


Step 4: Monitor Redis Connectivity

Misago uses Redis for caching and session storage. A Redis outage drops active user sessions and disables the cache layer.

Add a Redis connectivity script on your server:

#!/bin/bash
PONG=$(redis-cli -h 127.0.0.1 -p 6379 ping 2>/dev/null)
if [ "$PONG" = "PONG" ]; then
  curl -s https://vigilmon.online/heartbeat/REDIS_HEARTBEAT_ID
fi

Save it to /usr/local/bin/check-redis.sh, make it executable, and add a cron entry:

* * * * * /usr/local/bin/check-redis.sh

In Vigilmon:

  1. Add MonitorCron Heartbeat.
  2. Expected ping interval: 2 minutes.

Additionally, add a TCP port monitor if Redis is on a dedicated host:

  1. Add MonitorTCP Port.
  2. Host: your Redis server IP.
  3. Port: 6379.
  4. Check interval: 1 minute.

Step 5: Monitor PostgreSQL Connection Pool

Misago's Django ORM uses a PostgreSQL connection pool. If the pool is exhausted or the database is down, all forum reads and writes fail.

Extend your health check script or add a standalone one:

#!/bin/bash
RESULT=$(psql -U misago_user -h 127.0.0.1 -d misago_db \
  -c "SELECT 1;" 2>/dev/null | grep -c "1 row")
if [ "$RESULT" -eq 1 ]; then
  curl -s https://vigilmon.online/heartbeat/POSTGRES_HEARTBEAT_ID
fi

Run it every minute via cron. In Vigilmon, set the heartbeat interval to 2 minutes.

For an additional TCP-level check:

  1. Add MonitorTCP Port.
  2. Host: your PostgreSQL server IP.
  3. Port: 5432.
  4. Check interval: 1 minute.

Step 6: Search Index Health Check

Misago uses Django's search framework (often backed by PostgreSQL full-text search or an external engine). A broken search index doesn't take the site down but frustrates users.

Add a search probe to your health endpoint or create a dedicated one:

# misago/health.py (extended)
from misago.threads.models import Thread


def search_health_check(request):
    try:
        # Try a simple search query to verify the index is responding
        results = Thread.objects.filter(title__search="test").count()
        search_ok = True
    except Exception:
        search_ok = False

    return JsonResponse({"search": search_ok}, status=200 if search_ok else 503)

Add the URL and a Vigilmon monitor:

  1. Add MonitorHTTP / HTTPS.
  2. URL: https://forum.yourdomain.com/health/search/.
  3. Expected HTTP status: 200.
  4. Keyword match: "search": true.
  5. Check interval: 5 minutes.

Step 7: Email Notification Service Heartbeat

Misago sends email notifications when users receive replies, mentions, or private messages. A broken SMTP configuration silently breaks engagement without any visible forum error.

Monitor email delivery with a heartbeat that fires after each batch of notifications is processed:

# misago/tasks.py
from celery import shared_task
from django.core.mail import send_mail
import requests


@shared_task
def email_delivery_check():
    try:
        send_mail(
            subject="Misago health check",
            message="ok",
            from_email="noreply@yourdomain.com",
            recipient_list=["monitor@yourdomain.com"],
            fail_silently=False,
        )
        requests.get(
            "https://vigilmon.online/heartbeat/EMAIL_HEARTBEAT_ID",
            timeout=5
        )
    except Exception:
        pass  # Alert fires naturally when heartbeat stops arriving

Schedule it in Celery beat every 30 minutes. Set the Vigilmon heartbeat interval to 35 minutes.

Alternatively, monitor your SMTP relay's TCP port directly:

  1. Add MonitorTCP Port.
  2. Host: your SMTP server.
  3. Port: 587 (or 465 for SMTPS).
  4. Check interval: 1 minute.

Step 8: User Session Management Monitor

Active Misago sessions are stored in Redis (or the database). If sessions expire unexpectedly or the session backend is misconfigured, users are silently logged out.

Add a session health endpoint:

# misago/health.py (extended)
from django.contrib.sessions.backends.cache import SessionStore


def session_health_check(request):
    try:
        store = SessionStore()
        store["health"] = "ok"
        store.save()
        session_key = store.session_key
        loaded = SessionStore(session_key)
        session_ok = loaded.get("health") == "ok"
        store.delete()
    except Exception:
        session_ok = False

    return JsonResponse({"sessions": session_ok}, status=200 if session_ok else 503)

Add a Vigilmon monitor:

  1. Add MonitorHTTP / HTTPS.
  2. URL: https://forum.yourdomain.com/health/sessions/.
  3. Expected HTTP status: 200.
  4. Keyword match: "sessions": true.
  5. Check interval: 5 minutes.

Step 9: Configure Alert Channels

  1. Go to Alert Channels in Vigilmon and add Slack, email, or a webhook.
  2. Set Consecutive failures before alert to 2 for the web and API monitors to avoid noise from transient network blips.
  3. Set it to 1 for the Celery heartbeat — a dead worker is always urgent.
  4. Create a Maintenance window in Vigilmon during Django migrations or dependency upgrades.

Summary

| Monitor | Target | What It Catches | |---|---|---| | Web server | https://forum.yourdomain.com | Gunicorn/uWSGI down, app crash | | Django health | /health/ | DB disconnect, import errors | | Celery heartbeat | Periodic task ping | Worker crash, broker disconnect | | Redis TCP | :6379 | Redis server unreachable | | Redis heartbeat | Cron ping script | AUTH failure, memory full | | PostgreSQL TCP | :5432 | DB server unreachable | | PostgreSQL heartbeat | Cron ping script | Pool exhaustion, disk full | | Search health | /health/search/ | Broken search index | | Email heartbeat | Celery email task | SMTP relay failure | | Session health | /health/sessions/ | Redis session backend failure |

Misago gives your community a modern, self-hosted home — but keeping it reliable means watching every async worker, cache layer, and database connection that keeps forum interactions flowing. Vigilmon closes that loop so you hear about problems before your members do.

Monitor your app with Vigilmon

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

Start free →