Dev.to WebDev 🛠 Dev 👁 0 📖 3 min read

How to Monitor Your Ruby on Rails Application with Vigilmon

How to Monitor Your Ruby on Rails Application with Vigilmon Ruby on Rails is an opinionated, batteries-included framework — and that includes health monitoring. Rails 7.1+ ships with built-in health check support. Comb

How to Monitor Your Ruby on Rails Application with Vigilmon

Ruby on Rails is an opinionated, batteries-included framework — and that includes health monitoring. Rails 7.1+ ships with built-in health check support. Combined with Vigilmon, you can have production-grade uptime monitoring running in under 15 minutes.

Rails 7.1+ Built-in Health Check

Rails 7.1 introduced a /up endpoint out of the box. It returns:

  • 200 OK when the application is healthy
  • 500 when it can't connect to the database or other dependencies

This endpoint is already in your config/routes.rb:

Rails.application.routes.draw do
  get "up" => "rails/health#show", as: :rails_health_check
end

Just point Vigilmon at https://yourapp.com/up and you're done for the basics.

Custom Health Controller (Rails 6 / Enhanced Rails 7)

For more granular health checks:

# app/controllers/health_controller.rb
class HealthController < ApplicationController
  skip_before_action :authenticate_user!, only: [:show, :database, :cache, :sidekiq]

  def show
    checks = {
      database: check_database,
      cache: check_cache,
      sidekiq: check_sidekiq
    }

    all_ok = checks.values.all? { |v| v == 'ok' }

    render json: { status: all_ok ? 'ok' : 'degraded', checks: checks },
           status: all_ok ? :ok : :service_unavailable
  end

  def database
    ActiveRecord::Base.connection.execute('SELECT 1')
    render json: { status: 'ok', db: 'connected' }
  rescue => e
    render json: { status: 'error', db: e.message }, status: :service_unavailable
  end

  def cache
    Rails.cache.write('health_check', 'ok', expires_in: 30.seconds)
    value = Rails.cache.read('health_check')
    raise 'Cache read failed' unless value == 'ok'
    render json: { status: 'ok', cache: 'connected' }
  rescue => e
    render json: { status: 'error', cache: e.message }, status: :service_unavailable
  end

  def sidekiq
    stats = Sidekiq::Stats.new
    enqueued = stats.enqueued
    workers = Sidekiq::Workers.new.count

    if workers == 0 && enqueued > 100
      render json: { status: 'warning', workers: 0, enqueued: enqueued }, 
             status: :service_unavailable
    else
      render json: { status: 'ok', workers: workers, enqueued: enqueued }
    end
  rescue => e
    render json: { status: 'error', sidekiq: e.message }, status: :service_unavailable
  end

  private

  def check_database
    ActiveRecord::Base.connection.execute('SELECT 1')
    'ok'
  rescue
    'error'
  end

  def check_cache
    Rails.cache.write('hc', '1', expires_in: 10)
    Rails.cache.read('hc') == '1' ? 'ok' : 'error'
  rescue
    'error'
  end

  def check_sidekiq
    Sidekiq::Workers.new.count >= 0 ? 'ok' : 'error'
  rescue
    'unavailable'
  end
end
# config/routes.rb
Rails.application.routes.draw do
  namespace :health do
    get '/', to: 'health#show'
    get '/db', to: 'health#database'
    get '/cache', to: 'health#cache'
    get '/sidekiq', to: 'health#sidekiq'
  end
end

Setting Up Vigilmon for Rails

  1. Sign up at vigilmon.online (free tier)
  2. Add HTTP Monitor → https://yourapp.com/up (or /health/)
  3. Check interval: 1 minute
  4. Expected status: 200
  5. Response time alert: 1500ms (Rails cold starts can be slow)

Monitoring Sidekiq Background Jobs

Sidekiq failures are invisible to users until queues back up. The /health/sidekiq endpoint above handles this — but you can also use the Sidekiq Web UI's status endpoint:

# config/routes.rb
require 'sidekiq/web'
mount Sidekiq::Web => '/sidekiq'  # Protect this in production!

Alternatively, use the sidekiq_alive gem:

# Gemfile
gem 'sidekiq_alive'

This adds /sidekiq/alive that returns 200 when Sidekiq workers are running.

Rails-Specific Failure Modes

Puma Worker Crashes

When Puma workers OOM-crash, requests start timing out. Vigilmon's response time monitoring catches this — set an alert at 2000ms for production Rails apps.

Database Connection Pool Exhaustion

ActiveRecord has a connection pool (default: 5). When your pool exhausts under load:

# config/database.yml
production:
  pool: <%= ENV.fetch('RAILS_MAX_THREADS') { 5 } %>
  checkout_timeout: 5  # Raises ActiveRecord::ConnectionTimeoutError after 5s

Your health endpoint will return 503 when this happens.

Asset Precompile Failures (Post-Deploy)

After a bad deploy, CSS/JS assets may 404. Add a Vigilmon monitor for your main JS bundle:

https://yourapp.com/assets/application-abc123.js

This catches asset pipeline failures immediately after deploy.

Multi-Environment Setup

# Production monitors (1-minute checks, page on failure)
https://yourapp.com/up
https://yourapp.com/health/db
https://yourapp.com/health/sidekiq

# Staging monitors (5-minute checks, Slack only)
https://staging.yourapp.com/up

SSL and Domain Monitoring

Rails apps with Let's Encrypt certificates need SSL expiry monitoring. Vigilmon checks your certificate expiry and alerts 30 days before it expires — before auto-renewal issues leave your users with browser certificate errors.

Production Checklist

  • [ ] Rails 7.1 /up endpoint or custom HealthController
  • [ ] Database health check with SELECT 1
  • [ ] Cache health check (Redis/Memcache)
  • [ ] Sidekiq health check (if using background jobs)
  • [ ] Vigilmon HTTP monitors for each endpoint
  • [ ] Response time alert at 2000ms
  • [ ] SSL certificate monitoring
  • [ ] Maintenance windows for deployments and migrations

Start monitoring your Rails app for free →

Vigilmon is an uptime monitoring platform for developers. Free tier includes 10 monitors with 1-minute checks from multiple global regions.

📰 Read the original article on Dev.to WebDev

Originally published by Dev.to WebDev. Aggregated on AIWithGhost for educational purposes — full credit and traffic to the original publisher.