tutorial

Monitoring Self-Hosted Sentry with Vigilmon

Self-hosting Sentry gives you full control over your error tracking data — but the stack runs nine services that can fail independently. Here's how to monitor Sentry's web UI, Relay ingest proxy, Snuba query engine, Celery workers, Redis, ClickHouse, PostgreSQL, Kafka, and MinIO with Vigilmon.

Self-hosted Sentry is one of the most complex open-source stacks you can run. A single production deployment includes a Django web server, Relay event ingest proxy, Snuba query service, Celery async workers, Redis, ClickHouse, PostgreSQL, Kafka, and MinIO — each of which can fail independently and silently degrade your error tracking without any obvious UI error. Vigilmon lets you monitor all nine layers from a single dashboard so you know the moment any component goes down, before your developers notice that errors have stopped flowing.

What You'll Set Up

  • HTTP uptime monitor for the Sentry web UI (port 9000)
  • TCP monitor for the Relay ingest proxy (port 3000)
  • Health endpoint monitors for Snuba and the Sentry API
  • Cron heartbeat for Celery async task workers
  • TCP monitors for Redis, ClickHouse, PostgreSQL, and Kafka
  • TCP monitor for MinIO blob storage
  • Cron heartbeat for scheduled cleanup and digest jobs

Prerequisites

  • Self-hosted Sentry installed via the official getsentry/self-hosted Docker Compose stack
  • Sentry web UI accessible at http://your-server:9000 (or behind a reverse proxy)
  • A free Vigilmon account

Step 1: Monitor the Sentry Web UI

The Sentry web interface is your primary interaction point. If the Django/uwsgi layer crashes, your team loses access to all error data.

  1. Log in to vigilmon.online and click Add Monitor.
  2. Set Type to HTTP / HTTPS.
  3. Enter your Sentry URL: https://sentry.yourdomain.com (or http://your-server:9000).
  4. Set Check interval to 1 minute.
  5. Set Expected HTTP status to 200.
  6. Enable Monitor SSL certificate if you use HTTPS, with a 21-day expiry alert.
  7. Click Save.

Sentry's root path returns a 200 when the app is up. If you have SSO configured, use the API health endpoint instead to avoid redirect loops:

https://sentry.yourdomain.com/api/0/

The API health endpoint returns {"version": "..."} regardless of authentication state, making it the most reliable probe target.


Step 2: Monitor the Relay Ingest Proxy

Relay is the edge proxy that receives events from your SDKs before forwarding them to Kafka. If Relay goes down, events are dropped even if the Sentry web UI looks healthy — a particularly dangerous silent failure.

  1. Click Add MonitorTCP Port.
  2. Set Host to your Relay server (usually the same host as Sentry).
  3. Set Port to 3000 (Relay's default ingest port).
  4. Set Check interval to 1 minute.
  5. Click Save.

For deeper health checking, Relay exposes a health endpoint:

GET http://your-server:3000/api/relay/healthcheck/ready/

Add an HTTP monitor targeting this URL. A 200 response with {"is_healthy": true} confirms Relay is authenticated to Sentry and ready to accept events.

# Verify manually
curl http://your-server:3000/api/relay/healthcheck/ready/
# {"is_healthy": true}

Step 3: Monitor the Snuba Query Service

Snuba is the query layer that sits between Sentry's Django app and ClickHouse. When Snuba is down, issue searches, performance queries, and the Discover module stop working — errors may still be ingested, but nothing is queryable.

Add an HTTP monitor for Snuba's health endpoint:

  1. Click Add MonitorHTTP / HTTPS.
  2. Set URL to http://your-server:1218/health (Snuba's default port).
  3. Set Expected HTTP status to 200.
  4. Set Check interval to 1 minute.
  5. Click Save.
# Verify Snuba health manually
curl http://your-server:1218/health
# {"status": "ok"}

If Snuba is running in Docker Compose, this port must be exposed in your docker-compose.yml or accessed from within the Docker network via the service name snuba:1218.


Step 4: Monitor Celery Async Task Workers

Sentry uses Celery for async processing: sending alert emails, processing performance data, running digests, and cleanup jobs. If Celery workers go down, none of this background work runs — you won't get alert emails, and your project's issue counts will stop updating.

Celery doesn't expose an HTTP health endpoint by default, so use a cron heartbeat to confirm workers are processing tasks.

Add this Celery health check task to your Sentry configuration (sentry.conf.py or a custom task file):

from celery import shared_task
import requests

@shared_task
def vigilmon_heartbeat():
    """Ping Vigilmon to confirm Celery workers are alive."""
    try:
        requests.get(
            'https://vigilmon.online/heartbeat/YOUR_HEARTBEAT_ID',
            timeout=5
        )
    except Exception:
        pass

Schedule it in your Celery beat configuration:

from celery.schedules import crontab

CELERY_BEAT_SCHEDULE = {
    'vigilmon-heartbeat': {
        'task': 'myapp.tasks.vigilmon_heartbeat',
        'schedule': crontab(minute='*/5'),  # every 5 minutes
    },
}

In Vigilmon:

  1. Click Add MonitorCron Heartbeat.
  2. Set Expected ping interval to 5 minutes (or 10 minutes with a 2× grace period).
  3. Copy the heartbeat URL and paste it into the task above.
  4. Click Save.

If the workers crash or the beat scheduler stops, Vigilmon alerts you after one missed interval.


Step 5: Monitor Redis

Sentry uses Redis as a cache, session store, and Celery message broker. A Redis failure causes Celery to stop processing jobs and breaks user sessions.

  1. Click Add MonitorTCP Port.
  2. Set Host to your Redis server.
  3. Set Port to 6379.
  4. Set Check interval to 1 minute.
  5. Click Save.

If Redis is exposed only inside the Docker network (which is the default for getsentry/self-hosted), monitor it from the host itself using a simple shell ping:

# Add to a cron on the Sentry host
* * * * * redis-cli -h 127.0.0.1 ping | grep -q PONG && \
  curl -s https://vigilmon.online/heartbeat/REDIS_HEARTBEAT_ID

Create a matching cron heartbeat in Vigilmon with a 1 minute expected interval to catch Redis failures within 60 seconds.


Step 6: Monitor ClickHouse

ClickHouse stores all your Sentry events, transactions, and performance profiles. It is the largest and most resource-intensive component in the stack. If ClickHouse goes down or becomes read-only, event ingestion backs up in Kafka and queries return errors.

  1. Click Add MonitorTCP Port.
  2. Set Host to your ClickHouse server.
  3. Set Port to 9000 (ClickHouse native protocol) or 8123 (HTTP interface).
  4. Set Check interval to 1 minute.
  5. Click Save.

For a health-aware check, use ClickHouse's HTTP ping endpoint:

curl http://your-server:8123/ping
# Ok.

Add an HTTP monitor targeting http://your-server:8123/ping with an expected response body containing Ok..


Step 7: Monitor PostgreSQL

PostgreSQL stores Sentry's metadata: projects, users, teams, alert rules, and integrations. It is smaller than ClickHouse but equally critical — without it, the Django app cannot start.

  1. Click Add MonitorTCP Port.
  2. Set Host to your PostgreSQL server.
  3. Set Port to 5432.
  4. Set Check interval to 1 minute.
  5. Click Save.

Pair this with a cron heartbeat using pg_isready on the host:

# Add to cron on the database host
* * * * * pg_isready -h localhost -U sentry -d sentry && \
  curl -s https://vigilmon.online/heartbeat/PG_HEARTBEAT_ID

Step 8: Monitor Kafka

Kafka is the event streaming backbone between Relay and the Sentry consumer workers. If Kafka's brokers go down, events pile up at Relay and are eventually dropped once the buffer fills.

  1. Click Add MonitorTCP Port.
  2. Set Host to your Kafka broker.
  3. Set Port to 9092.
  4. Set Check interval to 1 minute.
  5. Click Save.

For multi-broker setups, add one TCP monitor per broker. You can also monitor the consumer lag via a heartbeat cron that uses kafka-consumer-groups.sh:

#!/bin/bash
LAG=$(kafka-consumer-groups.sh --bootstrap-server localhost:9092 \
  --describe --group sentry-consumer 2>/dev/null | \
  awk 'NR>1 {sum += $5} END {print sum}')

if [ "$LAG" -lt 10000 ]; then
  curl -s https://vigilmon.online/heartbeat/KAFKA_HEARTBEAT_ID
fi

Step 9: Monitor MinIO

MinIO provides blob storage for Sentry's source maps, attachments, and release artifacts. If MinIO is down, source map uploads fail silently and stack traces lose their unmapped frames.

  1. Click Add MonitorHTTP / HTTPS.
  2. Set URL to http://your-server:9000/minio/health/live (MinIO's built-in health endpoint).
  3. Set Expected HTTP status to 200.
  4. Set Check interval to 1 minute.
  5. Click Save.
# Verify MinIO health manually
curl http://your-server:9000/minio/health/live
# (200 OK, empty body means healthy)

Note: MinIO and Sentry both default to port 9000. In production setups, MinIO is typically moved to a different port or a separate host to avoid the conflict.


Step 10: Heartbeat for Scheduled Cleanup and Digest Jobs

Sentry runs scheduled maintenance tasks via sentry cleanup (event deletion) and sentry send_beacon (digest emails). These run via the Celery beat scheduler and are captured by the Celery heartbeat in Step 4 — but you can add dedicated heartbeats for each critical scheduled task.

Add these entries to your custom Celery task (from Step 4), one per critical job:

@shared_task
def cleanup_heartbeat():
    """Confirm cleanup job ran successfully."""
    requests.get('https://vigilmon.online/heartbeat/CLEANUP_HEARTBEAT_ID', timeout=5)

Schedule it to run immediately after sentry cleanup:

# In your maintenance cron
0 3 * * * docker compose run --rm web sentry cleanup --days 90 && \
  curl -s https://vigilmon.online/heartbeat/CLEANUP_HEARTBEAT_ID

Set the expected interval in Vigilmon to 24 hours with a 2 hour grace period.


Step 11: Configure Alert Channels

  1. Go to Alert Channels in Vigilmon and add Slack, email, or a PagerDuty webhook.
  2. Set Consecutive failures before alert to 2 for TCP monitors (brief network blips are normal).
  3. Set it to 1 for the Relay ingest proxy — even a single missed check means events may be dropping.
  4. Create an on-call escalation policy: Slack immediately, email after 5 minutes, PagerDuty after 10 minutes.

Summary

| Monitor | Target | What It Catches | |---|---|---| | Sentry web UI | https://sentry.domain.com/api/0/ | Django/uwsgi crash, app errors | | Relay proxy TCP | :3000 | SDK events being silently dropped | | Relay health HTTP | /api/relay/healthcheck/ready/ | Relay not authenticated to Sentry | | Snuba health | :1218/health | Queries/search broken | | Celery heartbeat | Heartbeat URL | Async jobs not processing | | Redis TCP | :6379 | Sessions broken, Celery down | | ClickHouse TCP | :8123 or :9000 | Event storage unavailable | | PostgreSQL TCP | :5432 | Metadata database down | | Kafka TCP | :9092 | Event pipeline backed up | | MinIO HTTP | :9000/minio/health/live | Source maps not uploading | | Cleanup heartbeat | Heartbeat URL | Event retention jobs not running |

Self-hosted Sentry gives you complete ownership of your error tracking data, but that ownership means you're responsible for monitoring nine independent services. With Vigilmon watching each layer, you'll know the moment any part of the pipeline fails — before your developers notice that their stack traces have stopped arriving.

Monitor your app with Vigilmon

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

Start free →