tutorial

Monitoring Retrospring with Vigilmon

Retrospring is a self-hosted anonymous Q&A platform built on Ruby on Rails. Here's how to monitor its Puma server, PostgreSQL database, Redis/Sidekiq workers, and real-time WebSocket notifications with Vigilmon.

Retrospring is a self-hosted anonymous Q&A platform — think Curious Cat or Formspring, but running entirely on your own server. Built on Ruby on Rails with Puma, PostgreSQL, Redis, and Sidekiq, it has several interdependent services that must all be healthy for anonymous questions to flow, notifications to arrive, and media to upload. Vigilmon watches the whole stack externally so you know the moment any layer breaks.

What You'll Set Up

  • HTTP uptime monitor for the Puma/Rails application
  • Health check endpoint covering PostgreSQL, Redis, and Sidekiq
  • Anonymous submission endpoint response time monitoring
  • Sidekiq background job worker heartbeat
  • WebSocket notification endpoint check
  • SSL certificate expiry alerts
  • Scheduled analytics/cleanup job heartbeat

Prerequisites

  • Retrospring deployed on a VPS (Rails + Puma, port 3000 typically proxied via nginx)
  • PostgreSQL database
  • Redis + Sidekiq for background jobs
  • A free Vigilmon account

Step 1: Monitor Web Server Availability

Retrospring's Puma server runs on port 3000, typically behind an nginx reverse proxy that handles SSL termination. Monitor the public-facing URL:

  1. Log in to vigilmon.online and click Add Monitor.
  2. Set Type to HTTP / HTTPS.
  3. Enter your instance URL: https://retrospring.yourdomain.com
  4. Set Check interval to 1 minute.
  5. Set Expected HTTP status to 200.
  6. Enable Monitor SSL certificate with a 21 day expiry alert.
  7. Click Save.

Add a keyword check that verifies the Retrospring UI loads correctly:

  • Under Keyword check, enter retrospring or a string from your site's HTML title tag.

This catches the case where nginx returns 200 with an error page because Puma is down.


Step 2: Add a Rails Health Check Endpoint

Rails 7.1+ includes a built-in health check at /up. If you're running an older version, or want a more detailed check, add a custom health endpoint.

For Rails 7.1+, the /up endpoint is available by default:

https://retrospring.yourdomain.com/up

Add a Vigilmon monitor for /up with a 1-minute interval and expected status 200.

For a detailed health check covering all dependencies, add a custom controller. In config/routes.rb:

get '/health', to: 'health#show'

Create app/controllers/health_controller.rb:

class HealthController < ApplicationController
  skip_before_action :authenticate_user!, raise: false
  skip_before_action :verify_authenticity_token

  def show
    checks = {
      database: check_database,
      redis:    check_redis,
      sidekiq:  check_sidekiq,
    }

    status = checks.values.all? { |v| v == 'ok' } ? :ok : :service_unavailable

    render json: { status: status, checks: checks }, status: status
  end

  private

  def check_database
    ActiveRecord::Base.connection.execute('SELECT 1')
    'ok'
  rescue => e
    Rails.logger.error("Health check DB failed: #{e.message}")
    'error'
  end

  def check_redis
    Redis.new.ping == 'PONG' ? 'ok' : 'error'
  rescue => e
    Rails.logger.error("Health check Redis failed: #{e.message}")
    'error'
  end

  def check_sidekiq
    stats = Sidekiq::Stats.new
    # Alert if the dead queue is growing or retry queue is large
    stats.dead_size < 100 ? 'ok' : 'warn'
  rescue => e
    'error'
  end
end

Deploy and add a Vigilmon HTTP monitor for https://retrospring.yourdomain.com/health.


Step 3: Monitor the Anonymous Submission Endpoint

The anonymous question submission form is Retrospring's core feature. Monitor it explicitly so you know if the submission endpoint stops accepting requests:

  1. In Vigilmon, click Add MonitorHTTP / HTTPS.
  2. Enter: https://retrospring.yourdomain.com/ajax/ask
  3. Set Expected HTTP status to 401 or 422 — unauthenticated GET requests to a POST endpoint return an error code, which still confirms the endpoint is alive.
  4. Set Check interval to 5 minutes.
  5. Click Save.

Alternatively, add a response time threshold: if submission response time exceeds 2 seconds, something is wrong with the database or job queue backing the endpoint.


Step 4: Heartbeat Monitoring for Sidekiq Workers

Sidekiq processes email notifications, question inbox delivery, and other background tasks. If Sidekiq stops, your users won't receive notifications even though the web app appears healthy.

Add a Sidekiq middleware that pings a Vigilmon heartbeat after each successful job batch.

Create config/initializers/vigilmon_heartbeat.rb:

# Ping Vigilmon after every Sidekiq queue drain cycle
class VigilmonSidekiqMiddleware
  HEARTBEAT_URL = ENV['VIGILMON_SIDEKIQ_HEARTBEAT_URL']
  PING_INTERVAL = 5.minutes

  def call(worker, job, queue)
    result = yield

    if HEARTBEAT_URL.present? && should_ping?
      Net::HTTP.get(URI(HEARTBEAT_URL)) rescue nil
    end

    result
  end

  private

  def should_ping?
    now = Time.now.to_i
    last = Rails.cache.read('vigilmon_last_ping').to_i
    if now - last > PING_INTERVAL
      Rails.cache.write('vigilmon_last_ping', now, expires_in: 10.minutes)
      true
    else
      false
    end
  end
end

Sidekiq.configure_server do |config|
  config.server_middleware do |chain|
    chain.add VigilmonSidekiqMiddleware
  end
end

Add VIGILMON_SIDEKIQ_HEARTBEAT_URL to your .env or Rails credentials.

In Vigilmon, create a Cron Heartbeat monitor with a 10 minute expected interval. If Sidekiq crashes or the queue stops draining, the heartbeat stops and Vigilmon alerts.


Step 5: Monitor WebSocket Notifications

Retrospring uses WebSocket connections for real-time question notifications. The WebSocket endpoint is typically at /cable. Monitor it so you catch nginx/Puma misconfiguration that breaks real-time features post-deploy:

  1. In Vigilmon, add an HTTP monitor for https://retrospring.yourdomain.com/cable.
  2. Set Expected HTTP status to 101 (WebSocket upgrade) or 400 (bad WebSocket request) — either confirms the endpoint is routing correctly.
  3. Set Check interval to 5 minutes.

If your nginx configuration strips the Upgrade header, this check returns 400 rather than 101, and both are acceptable to confirm the endpoint is alive.


Step 6: Heartbeat for Scheduled Analytics and Cleanup Jobs

Retrospring runs scheduled tasks for analytics aggregation and old data cleanup. Use Sidekiq-Cron or whenever for scheduling; wrap each critical job in a heartbeat ping.

If using whenever (config/schedule.rb):

every 1.day, at: '2:00 AM' do
  rake 'retrospring:cleanup_old_questions'
end

Modify the rake task to ping after completion:

# lib/tasks/retrospring.rake
namespace :retrospring do
  desc 'Clean up expired questions and analytics data'
  task cleanup_old_questions: :environment do
    # ... cleanup logic ...

    heartbeat_url = ENV['VIGILMON_CLEANUP_HEARTBEAT_URL']
    Net::HTTP.get(URI(heartbeat_url)) if heartbeat_url.present?
  end
end

Create a Vigilmon Cron Heartbeat with a 25 hour expected interval for daily jobs.


Step 7: Configure Alert Channels

  1. Go to Alert Channels in Vigilmon and add your email or Slack webhook.
  2. On the main web monitor and health endpoint, set Consecutive failures before alert to 2.
  3. On the Sidekiq heartbeat, set Consecutive failures before alert to 1 — a stopped worker queue deserves immediate attention.
  4. Enable Maintenance windows in Vigilmon and automate them in your deployment script to suppress alerts during deploys:
# Before deploy
curl -X POST https://vigilmon.online/api/maintenance \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -d '{"monitor_id": "MONITOR_ID", "duration_minutes": 10}'

bundle exec cap production deploy

# Window expires automatically

Summary

| Monitor | Target | What It Catches | |---|---|---| | Web availability | https://retrospring.yourdomain.com | Puma crash, nginx misconfiguration | | Health endpoint | /health or /up | DB down, Redis down, Sidekiq dead queue growing | | Submission endpoint | /ajax/ask | Anonymous Q&A intake broken | | Sidekiq heartbeat | Vigilmon heartbeat URL | Background job worker stopped | | WebSocket endpoint | /cable | Real-time notifications broken | | Cleanup job heartbeat | Vigilmon heartbeat URL | Scheduled maintenance failed | | SSL certificate | Main domain | TLS certificate expired |

Retrospring's anonymous Q&A experience depends on fast submissions, reliable notifications, and background jobs that run on schedule. With Vigilmon monitoring every layer — from the Puma process to Sidekiq workers to WebSocket connectivity — you'll catch failures before users notice the silence.

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 →