tutorial

Monitoring Snac2 ActivityPub Server with Vigilmon

Snac2 is a minimal, self-hosted ActivityPub server written in C. Learn how to monitor its HTTP server, inbox/outbox, federation delivery, SQLite storage, and webfinger endpoint with Vigilmon.

Snac2 is one of the most minimal ActivityPub implementations available — a single C binary that speaks the Mastodon-compatible fediverse protocol from a tiny footprint. No Node.js runtime, no Ruby gem ecosystem, no JVM: just a C process, a SQLite database, and an HTTP listener on port 8001. That simplicity is its strength, but self-hosting Snac2 means owning the uptime of your fediverse presence. If your Snac2 instance goes down, remote servers stop delivering posts to your followers, your outbox queue backs up, and you silently drop off the fediverse. Vigilmon keeps you connected by monitoring every layer of your Snac2 deployment.

What You'll Set Up

  • HTTP uptime monitor for the Snac2 server (port 8001)
  • ActivityPub inbox endpoint response time monitor
  • Webfinger discovery endpoint health check
  • SQLite database file accessibility heartbeat
  • Outbox delivery queue processing heartbeat
  • Federation delivery retry queue monitor
  • Cron heartbeat for the scheduled cleanup job

Prerequisites

  • Snac2 running on port 8001 (direct or behind a reverse proxy)
  • A reverse proxy (nginx or Caddy) for HTTPS termination
  • A free Vigilmon account

Step 1: Monitor the Snac2 HTTP Server

Snac2's built-in HTTP server handles all ActivityPub traffic, the web UI, and webfinger lookups from a single process on port 8001. Start with a root-level HTTP monitor:

  1. Log in to vigilmon.online and click Add Monitor.
  2. Set Type to HTTP / HTTPS.
  3. Enter the URL: https://yourdomain.com/ (or http://your-host:8001/ for direct access).
  4. Set Check interval to 1 minute.
  5. Set Expected HTTP status to 200.
  6. Click Save.

Snac2 serves an HTML page at the root showing your public profile and recent posts. A 200 response confirms the C process is alive and the HTTP listener is functioning.


Step 2: Monitor the ActivityPub Inbox Endpoint

The ActivityPub inbox is how remote servers deliver posts, follows, likes, and boosts to your account. Snac2 exposes it at:

POST https://yourdomain.com/user/YOUR_USERNAME/inbox

Remote servers retry delivery several times before giving up, but extended downtime means lost federation events. Monitor the inbox endpoint's availability:

  1. Click Add MonitorHTTP / HTTPS.
  2. URL: https://yourdomain.com/user/YOUR_USERNAME/inbox.
  3. Method: GET (for an availability check — a GET returns 405 Method Not Allowed, which is correct behavior for a POST-only endpoint).
  4. Expected status: 405.
  5. Check interval: 2 minutes.
  6. Click Save.

A 405 response confirms the endpoint is reachable and correctly rejecting unauthenticated GET requests. If you get 404 or 502, the process is down or the reverse proxy is misconfigured.


Step 3: Monitor the Webfinger Discovery Endpoint

Webfinger (/.well-known/webfinger) is how other fediverse servers find your account. If webfinger fails, nobody can follow you from a remote instance and existing followers may lose your account resolution.

  1. Click Add MonitorHTTP / HTTPS.
  2. URL: https://yourdomain.com/.well-known/webfinger?resource=acct:YOUR_USERNAME@yourdomain.com.
  3. Check interval: 5 minutes.
  4. Expected status: 200.
  5. Under Response body, add a contains check for "type":"Application" or your account handle to confirm the response content is valid.
  6. Click Save.

A valid webfinger response is JSON-LD. Checking for content — not just the status code — catches cases where nginx returns a 200 with an error page instead of the Snac2 response.


Step 4: Monitor SQLite Database Accessibility

Snac2 stores all posts, follows, and account data in a SQLite file (snac.db in your data directory). SQLite is highly reliable, but filesystem issues, full disks, or permission problems can make the database inaccessible while leaving the HTTP process running — causing mysterious 500 errors on every write operation.

Set up a heartbeat script that attempts a read query:

#!/bin/bash
# /opt/snac2/db-health.sh
SNAC_DB="/var/lib/snac2/snac.db"
sqlite3 "$SNAC_DB" "SELECT COUNT(*) FROM actors;" > /dev/null 2>&1 && \
  curl -s https://vigilmon.online/heartbeat/YOUR_DB_HEARTBEAT_ID

Create a Vigilmon heartbeat monitor (Add MonitorCron Heartbeat, interval 5 minutes) and schedule the script:

*/5 * * * * /opt/snac2/db-health.sh

If the disk fills, the filesystem mounts read-only, or the file becomes corrupted, the heartbeat stops and Vigilmon alerts after 5 minutes of silence.


Step 5: Monitor Outbox Delivery Queue

Snac2 delivers outgoing posts to remote servers by iterating through each follower's inbox. If the delivery process stalls — due to network issues, a crash in the delivery loop, or SQLite contention — your posts stop reaching the fediverse while appearing to send locally.

Snac2 logs delivery activity to stderr/syslog. Monitor delivery health with a heartbeat that parses recent logs:

#!/bin/bash
# /opt/snac2/outbox-health.sh
# Check that Snac2 has logged outbox activity in the last 15 minutes
RECENT=$(journalctl -u snac2 --since "15 minutes ago" | grep -c "queue\|deliver\|POST" || true)
if [ "$RECENT" -gt 0 ] || [ "$(date +%M)" -lt 5 ]; then
  # Either there's been recent activity, or we're in a quiet period (first 5 min of hour)
  curl -s https://vigilmon.online/heartbeat/OUTBOX_HEARTBEAT_ID
fi

For a simpler check, create a dedicated heartbeat monitor with a 30 minute interval that your instance pings after each successful outbox sweep. If outbox processing stops, the heartbeat lapses and Vigilmon alerts.


Step 6: Monitor the Remote Actor Fetch Service

When a new user follows you from a remote server, Snac2 fetches that user's actor document to store their profile information. Failures here cause follow requests to hang or silently fail. Monitor your instance's ability to reach remote fediverse servers:

#!/bin/bash
# /opt/snac2/remote-fetch-check.sh
# Try fetching a well-known public actor document
curl -sf -H "Accept: application/activity+json" \
  "https://mastodon.social/users/Mastodon" -o /dev/null && \
  curl -s https://vigilmon.online/heartbeat/REMOTE_FETCH_HEARTBEAT_ID

Schedule every 10 minutes. If your server loses outbound internet connectivity, this heartbeat lapses and Vigilmon alerts — saving you from discovering the issue when followers complain they can't find your account.


Step 7: Monitor the Scheduled Cleanup Job

Snac2 includes housekeeping routines that purge old cache entries, expired follow requests, and stale remote actor data. These typically run as a cron job or a periodic signal sent to the Snac2 process. If the cleanup job stops running, your SQLite database grows unboundedly.

If you run cleanup via cron:

# Typical cleanup invocation
snac purge /var/lib/snac2
curl -s https://vigilmon.online/heartbeat/CLEANUP_HEARTBEAT_ID

Create a Vigilmon heartbeat monitor with an interval matching your cleanup schedule (e.g. 24 hours if you run cleanup daily). If the cron job is accidentally removed or the snac binary is unavailable, Vigilmon alerts after one missed cycle.


Step 8: Monitor Media Attachment Storage

If you've configured Snac2 to store media attachments (images, files), the storage backend needs to remain accessible. For local filesystem storage, add a heartbeat check:

#!/bin/bash
# /opt/snac2/storage-health.sh
MEDIA_DIR="/var/lib/snac2/media"
# Check directory is writable and has sufficient free space
df "$MEDIA_DIR" | awk 'NR==2 {if ($5+0 < 90) exit 0; exit 1}' && \
  touch "$MEDIA_DIR/.healthcheck" && rm "$MEDIA_DIR/.healthcheck" && \
  curl -s https://vigilmon.online/heartbeat/STORAGE_HEARTBEAT_ID

This script alerts if disk usage exceeds 90% or the media directory becomes read-only — both conditions that cause media upload failures before the HTTP server itself shows errors.


Step 9: Configure Alert Channels

  1. Go to Alert Channels in Vigilmon.
  2. Add email or Slack for outage notifications.
  3. Set Consecutive failures before alert to 2 on HTTP monitors — Snac2 is a C binary and restarts quickly under systemd, but a restart can cause 15–30 seconds of downtime that trips a single probe.
  4. Use Maintenance windows if you rebuild or update Snac2 (which requires a brief process restart):
# Before updating Snac2
curl -X POST https://vigilmon.online/api/maintenance \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -d '{"monitor_id": "abc123", "duration_minutes": 5}'

systemctl restart snac2

Summary

| Monitor | Target | What It Catches | |---|---|---| | HTTP server | https://yourdomain.com/ | Process crash | | ActivityPub inbox (HTTP) | /user/USERNAME/inbox | Federation delivery failure | | Webfinger (HTTP) | /.well-known/webfinger | Account discovery failure | | SQLite database (Heartbeat) | sqlite3 query script | Disk full, file corruption | | Outbox delivery (Heartbeat) | Log-based script | Delivery queue stall | | Remote actor fetch (Heartbeat) | Outbound HTTP test | Connectivity loss | | Cleanup job (Heartbeat) | Cron-based script | Runaway database growth | | Media storage (Heartbeat) | Disk/write check script | Attachment upload failure |

Snac2's minimal architecture is a feature — there's very little to break compared to a Rails or Node.js fediverse server. But that simplicity means there's no built-in health dashboard either. With Vigilmon covering the HTTP layer, the SQLite database, federation delivery, and outbound connectivity, you'll know about any problem before the fediverse delivers the bad news to your timeline.

Monitor your app with Vigilmon

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

Start free →