Rails Error Dashboard

Self-hosted error tracking and exception monitoring for Ruby on Rails. Open source, free forever. A Sentry alternative with cause chains, analytics, workflow management, and multi-channel notifications.

Download as .zip Download as .tar.gz View on GitHub

Complete Feature List

This document provides a comprehensive overview of all features in Rails Error Dashboard.

Feature Categories

Rails Error Dashboard uses an opt-in architecture with two categories of features:

Tier 1 Features (Always ON)

Core features that are always enabled - no configuration needed:

Optional Features (Opt-in)

24+ features you can enable during installation or anytime in the initializer (plus separate database via the database mode selector):

πŸ“§ Notifications (5 features)

⚑ Performance (3 features)

πŸ“Š Advanced Analytics (7 features)

πŸ” Developer Tools (6 features)

πŸ”¬ Deep Debugging (6 features) β€” v0.4.0

πŸ†• v0.2 Smart Defaults (Always ON)

πŸ†• v0.2 Configurable

All optional features are disabled by default and can be toggled on/off at any time. See Configuration Guide for setup.


Error Tracking & Capture

Automatic Error Capture

Platform Detection

Error Context


Dashboard & UI

Modern Interface

Real-Time Updates ⚑

Search & Filtering

Pagination

Keyboard Shortcuts


Analytics & Insights

Severity Breakdown

Spike Detection 🚨

Platform Comparison

User Impact Analysis

Smart Priority Scoring

Resolution Tracking

Time-Series Analysis


Notifications & Alerting

βš™οΈ Optional Features - All notification channels are disabled by default. Enable them during installation or in the initializer:

config.enable_slack_notifications = true
config.enable_email_notifications = true
config.enable_discord_notifications = true
config.enable_pagerduty_notifications = true
config.enable_webhook_notifications = true

Slack Integration

Email Notifications

Discord Integration

PagerDuty Integration

Custom Webhooks

Notification Throttling πŸ†•

config.notification_minimum_severity = :medium  # Skip :low severity
config.notification_cooldown_minutes = 10       # 10-minute cooldown per error
config.notification_threshold_alerts = [10, 50, 100, 500, 1000]  # Milestone alerts

Notification Callbacks


Performance & Scalability

βš™οΈ Optional Features - Performance optimizations are disabled by default. Enable as needed:

config.async_logging = true           # Async error logging
config.sampling_rate = 0.1            # Error sampling (10%)
config.use_separate_database = true   # Separate database

Async Error Logging

Backtrace Limiting

Error Sampling

Ignored Exceptions

Database Optimization

Separate Database Support


Error Management

Resolution Workflow

Batch Operations

Error Grouping

Error Details Page


Source Code Integration (NEW!)

βš™οΈ Optional Feature - Source code integration is disabled by default. Enable it to see source code directly in the dashboard:

config.enable_source_code_integration = true
config.enable_git_blame = true  # Optional: Show git blame info

Features

Inline Source Code Viewer

Git Blame Integration

Configuration

# Basic setup
config.enable_source_code_integration = true

# Optional: Enable git blame
config.enable_git_blame = true

# Repository settings (auto-detected from git)
config.repository_url = ENV["REPOSITORY_URL"]  # Optional: Override auto-detection
config.repository_branch = ENV["REPOSITORY_BRANCH"] || "main"  # Default branch

How It Works

  1. Source Code Reader: Reads the actual source file from your filesystem
  2. Git Blame Parser: Parses git blame output to show commit information
  3. Link Generator: Generates repository links based on your git remote configuration
  4. Caching: Source code and blame data are cached per request for performance
  5. Security: Only reads files within your application root directory

Requirements

Benefits

Privacy & Security


βš™οΈ Optional Feature - Breadcrumbs are disabled by default. Enable them to see a timeline of events leading up to each error:

config.enable_breadcrumbs = true
config.breadcrumb_buffer_size = 40  # Max events per request (default: 40)

What Are Breadcrumbs?

When an error occurs, you need to know what happened before the crash. Breadcrumbs capture a timeline of events during the request β€” SQL queries, controller actions, cache operations, background jobs, and mailer deliveries β€” stored alongside the error for instant debugging context.

Unlike Sentry or Honeybadger (which require SDK configuration), Rails Error Dashboard captures breadcrumbs automatically from ActiveSupport::Notifications β€” zero configuration beyond the enable flag.

Captured Event Categories

Category Events Example
sql sql.active_record SELECT * FROM users WHERE id = 42 (2.1ms)
controller process_action.action_controller UsersController#show
cache cache_read.active_support, cache_write.active_support cache read: users/42
job perform.active_job SendWelcomeEmailJob
mailer deliver.action_mailer UserMailer to: [user@example.com]
deprecation deprecation.rails Method #foo is deprecated (with caller location)
custom Manual API checkout started

Timeline Display

Each error’s detail page shows a Breadcrumbs card with:

Deprecation Warnings

When breadcrumbs are enabled, Rails deprecation warnings (deprecation.rails) are automatically captured as breadcrumbs. A dedicated red-bordered summary card appears on the error detail page when deprecations are detected, showing:

This helps you identify deprecated code paths that may be contributing to errors β€” especially useful when upgrading Rails versions.

Deprecation Warnings Aggregate Page

Beyond per-error display, the Deprecations page (/errors/deprecations) provides an app-wide view of all deprecation warnings across errors:

Deprecation Warnings

This page helps prioritize which deprecations to fix first based on frequency and scope across your entire error history.

N+1 Query Detection

The N+1 detector analyzes SQL breadcrumbs at display time (not on every request) to identify repeated query patterns that suggest missing eager loading:

config.enable_n_plus_one_detection = true  # Default: true
config.n_plus_one_threshold = 3            # Min repetitions to flag (default: 3, min: 2)

N+1 Query Patterns Aggregate Page

The N+1 Queries page (/errors/n_plus_one_summary) provides an app-wide view of N+1 patterns across all errors:

N+1 Query Patterns

This page helps identify the most impactful N+1 patterns across your entire application.

Cache Health Analysis

Cache breadcrumbs (cache_read.active_support, cache_write.active_support) are analyzed per-error to show cache performance at the moment of failure:

Cache Health Aggregate Page

The Cache Health page (/errors/cache_health_summary) provides an app-wide view of cache performance across all errors:

Cache Health

This page helps identify errors associated with poor cache performance across your application.

Manual Breadcrumbs API

Add custom breadcrumbs from anywhere in your application code:

RailsErrorDashboard.add_breadcrumb("checkout started", { cart_id: 123, items: 5 })
RailsErrorDashboard.add_breadcrumb("payment processing", { provider: "stripe" })

Configuration

RailsErrorDashboard.configure do |config|
  config.enable_breadcrumbs = true           # Master switch (default: false)
  config.breadcrumb_buffer_size = 40         # Max events per request (default: 40)
  config.breadcrumb_categories = nil         # nil = all; or [:sql, :controller, :cache, :job, :mailer, :deprecation, :custom]
  config.enable_n_plus_one_detection = true  # Detect N+1 query patterns (default: true)
  config.n_plus_one_threshold = 3            # Min repetitions to flag (default: 3)
end

Safety & Performance

Breadcrumbs are designed with host app safety as the top priority:

Async Logging Compatibility

When async logging is enabled, breadcrumbs are harvested from the current thread before the background job is dispatched (since the job runs on a different thread). This ensures breadcrumbs are always captured correctly regardless of logging mode.


System Health Snapshot (NEW!)

βš™οΈ Optional Feature - System health is disabled by default. Enable it to capture runtime metrics at the moment of every error:

config.enable_system_health = true

What Is System Health?

When debugging errors, you need to know what the app’s runtime state was at the moment of failure. Was memory spiking? Was the connection pool exhausted? Was GC thrashing? System health snapshots answer these questions automatically.

Each error’s detail page shows a System Health card with:

Configuration

RailsErrorDashboard.configure do |config|
  config.enable_system_health = true  # Master switch (default: false)
end

Safety Guarantees

System health snapshots are designed with host app safety as the top priority:

Async Logging Compatibility

When async logging is enabled, system health is captured from the current thread before the background job is dispatched (since the job runs on a different thread and may have different runtime state). This ensures the snapshot reflects the actual state at error time.

Job Health Page

The Job Health page (/errors/job_health_summary) provides an aggregate view of background job queue health across all errors:

This page helps identify errors that coincide with job queue problems β€” a failing job queue often causes cascading errors.

Database Health Page

The Database Health page (/errors/database_health_summary) is a lightweight PgHero-style database health panel built into the dashboard. It has two sections:

Section A β€” Live Database Health

Queries PostgreSQL system views at display time (NOT in the capture path):

The DatabaseHealthInspector service is designed with the same safety principles as SystemHealthSnapshot:

Section B β€” Historical Connection Pool at Error Time

Extracts connection_pool data from the system_health JSON column per-error:

This page helps identify errors associated with connection pool exhaustion or database performance issues.


Local Variable Capture (v0.4.0)

βš™οΈ Optional Feature - Local variable capture is disabled by default. Enable it to see the exact values of local variables at the moment an exception was raised:

config.enable_local_variables = true

How It Works

Uses TracePoint(:raise) to capture local variables from the stack frame where the exception originates β€” before the stack unwinds and the values are lost. This is the most valuable debugging context possible: instead of guessing what went wrong from a stack trace, you see exactly what the variables contained.

Variables are displayed on the error detail page in a dedicated β€œLocal Variables” card with:

Configuration

RailsErrorDashboard.configure do |config|
  config.enable_local_variables = true              # Master switch (default: false)
  config.local_variable_max_count = 15              # Max variables per exception (default: 15)
  config.local_variable_max_depth = 3               # Max object nesting depth (default: 3)
  config.local_variable_max_string_length = 200     # Truncate strings beyond this (default: 200)
  config.local_variable_max_array_items = 10        # Max array items to serialize (default: 10)
  config.local_variable_max_hash_items = 20         # Max hash entries to serialize (default: 20)
  config.local_variable_filter_patterns = []        # Additional sensitive name patterns (default: [])
end

Safety & Privacy


Instance Variable Capture (v0.4.0)

βš™οΈ Optional Feature - Instance variable capture is disabled by default. Enable it to see the instance variables of the object that raised the exception:

config.enable_instance_variables = true

How It Works

Uses TracePoint(:raise) to inspect tp.self (the receiver object at the raise point) and capture its instance variables. This shows the internal state of the object that failed β€” for example, the @user, @order, or @connection that was in a bad state when the exception occurred.

The error detail page shows an β€œInstance Variables” card alongside the local variables with:

Configuration

RailsErrorDashboard.configure do |config|
  config.enable_instance_variables = true             # Master switch (default: false)
  config.instance_variable_max_count = 20             # Max variables per exception (default: 20)
  config.instance_variable_filter_patterns = []       # Additional sensitive name patterns (default: [])
end

Safety


Swallowed Exception Detection (v0.4.0)

βš™οΈ Optional Feature - Swallowed exception detection is disabled by default. Requires Ruby 3.3+ (TracePoint :rescue event). Enable it to detect exceptions that are raised but silently rescued:

config.detect_swallowed_exceptions = true

How It Works

Uses two TracePoint events working together:

  1. TracePoint(:raise) β€” Tracks every exception raise with its location
  2. TracePoint(:rescue) β€” Tracks every rescue with its location (Ruby 3.3+ only, Feature #19572)

By comparing raise counts vs rescue counts per location, the system identifies code paths where exceptions are caught but never logged, re-raised, or handled meaningfully. These β€œswallowed” exceptions are the hardest bugs to find β€” they silently corrupt state without any visible error.

Dashboard Page

The dedicated page at /errors/swallowed_exceptions shows:

Configuration

RailsErrorDashboard.configure do |config|
  config.detect_swallowed_exceptions = true           # Master switch (default: false)
  config.swallowed_exception_max_cache_size = 1000    # Max entries per thread-local cache (default: 1000)
  config.swallowed_exception_flush_interval = 60      # Seconds between DB flushes (default: 60)
  config.swallowed_exception_threshold = 0.95         # Rescue ratio to flag as swallowed (default: 0.95)
  config.swallowed_exception_ignore_classes = []      # Exception classes to skip (default: [])
end

Safety & Performance


On-Demand Diagnostic Dump (v0.4.0)

βš™οΈ Optional Feature - Diagnostic dumps are disabled by default. Enable to snapshot your app’s entire system state on demand:

config.enable_diagnostic_dump = true

How It Works

Captures a comprehensive snapshot of your application’s runtime state β€” useful for debugging intermittent production issues without reproducing them. The dump includes:

Triggering a Dump

Two ways to capture a dump:

  1. Dashboard button β€” Click β€œCapture Dump” on the /errors/diagnostic_dumps page
  2. Rake task β€” rails error_dashboard:diagnostic_dump (optionally with NOTE="deploy check")

Dashboard Page

The page at /errors/diagnostic_dumps shows:


Rack Attack Event Tracking (v0.4.0)

βš™οΈ Optional Feature - Rack Attack tracking is disabled by default. Requires breadcrumbs to be enabled. Enable it to track Rack::Attack security events:

config.enable_breadcrumbs = true
config.enable_rack_attack_tracking = true

How It Works

Subscribes to Rack::Attack’s ActiveSupport::Notifications events and records them as breadcrumbs. When an error occurs after a throttle or blocklist event, the breadcrumbs show the security context β€” revealing whether rate limiting or blocking contributed to the error.

Tracked Events

Dashboard Page

The page at /errors/rack_attack_summary shows event breakdown with time range filtering (7, 30, or 90 days).

Safety


Process Crash Capture (v0.4.0)

βš™οΈ Optional Feature - Process crash capture is disabled by default. Enable it to capture unhandled exceptions that crash the Ruby process:

config.enable_crash_capture = true

How It Works

Registers an at_exit hook that fires when the Ruby process exits. If the exit is caused by an unhandled exception ($! is set), the crash data is written to a JSON file on disk β€” because the database may be unavailable during process shutdown.

On the next boot, the gem automatically imports any crash files and creates error log records with platform: "crash_capture" and severity: "fatal".

What Gets Captured

Configuration

RailsErrorDashboard.configure do |config|
  config.enable_crash_capture = true      # Master switch (default: false)
  config.crash_capture_path = nil         # Custom path for crash files (default: Dir.tmpdir)
end

Why This Matters

This is a self-hosted only feature β€” impossible for SaaS error trackers. When a process crashes, SaaS tools lose the connection before they can report. Since this gem runs inside the process, it can write to disk as the last act before exit.


Plugin System

Architecture

Available Events

Built-in Plugins (Examples)

Metrics Plugin

Audit Log Plugin

Jira Integration Plugin

Custom Plugins


Security & Privacy

Authentication

Data Privacy

Separate Database Isolation


πŸ—οΈ Architecture & Code Quality

Design Patterns

Code Quality

Extensibility


πŸ› οΈ Developer Experience

Easy Installation

Configuration

Documentation

Testing Support


Production Ready

Performance

Reliability

Monitoring


Advanced Analytics Features

βš™οΈ Optional Features - All advanced analytics are disabled by default. Enable the ones you need:

config.enable_similar_errors = true          # Fuzzy error matching
config.enable_co_occurring_errors = true     # Co-occurring patterns
config.enable_error_cascades = true          # Cascade detection
config.enable_baseline_alerts = true         # Baseline anomaly alerts
config.enable_occurrence_patterns = true     # Cyclical/burst patterns
config.enable_error_correlation = true       # Version/user correlation
config.enable_platform_comparison = true     # Platform health comparison
config.enable_source_code_integration = true # Source code viewer (NEW!)
config.enable_git_blame = true               # Git blame integration (NEW!)

All code is complete and tested (2,600+ tests passing). These advanced features provide powerful insights for production debugging.

Fuzzy Error Matching

Co-occurring Error Patterns

Error Cascade Detection

Baseline Monitoring & Anomaly Detection

Automated Baseline Alerts

Enhanced Occurrence Patterns

Error Correlation Analysis

Platform-Specific Baselines


v0.2 Quick Wins (NEW!)

All v0.2 features are production-safe and designed around the core principle: never break the host app.

Exception Cause Chain

When exceptions wrap other exceptions (common with network errors, database failures, etc.), the full cause chain is captured:

RuntimeError: Failed to load user profile
  └── caused by: SocketError: Connection refused
        └── caused by: Errno::ECONNREFUSED: Connection refused - connect(2) for 127.0.0.1:6379

Stored as structured JSON in the exception_cause column. Displayed on the error detail page with a collapsible cause chain viewer. No configuration needed.

Custom Fingerprint Lambda

Override the default error grouping with a lambda:

config.custom_fingerprint = ->(exception, context) {
  case exception
  when ActiveRecord::RecordNotFound
    "record-not-found-#{context[:controller]}"
  when ActionController::RoutingError
    "routing-error"  # Group all 404s together
  else
    nil  # Fall back to default fingerprinting
  end
}

CurrentAttributes Integration

Automatically captures all values from your ActiveSupport::CurrentAttributes subclasses:

# Your app defines:
class Current < ActiveSupport::CurrentAttributes
  attribute :user, :account, :request_id
end

# We auto-capture: { user: ..., account: ..., request_id: ... }
# Zero configuration needed

Enriched HTTP Context

Every error from an HTTP request automatically captures:

Field Example Description
http_method GET Request method
hostname api.myapp.com Server hostname
content_type application/json Request content type
request_duration_ms 342 Time elapsed before error

Environment Info

Captured once at error time, so you can see exactly what was running:

{
  "ruby_version": "3.3.0",
  "rails_version": "8.1.1",
  "gem_versions": { "puma": "6.4.0", "sidekiq": "7.2.0" },
  "server": "Puma",
  "database_adapter": "postgresql"
}

Sensitive Data Filtering

Automatically scrubs sensitive data from error context before storage:

# Enabled by default. Configure patterns:
config.filter_sensitive_data = true
config.sensitive_data_patterns = [
  /password/i, /token/i, /secret/i, /api_key/i,
  /authorization/i, /credit_card/i, /ssn/i
]

Values matching these patterns are replaced with [FILTERED].

Auto-Reopen on Recurrence

When a resolved error occurs again, it automatically:

  1. Sets resolved = false and status = "new"
  2. Records reopened_at timestamp
  3. Increments occurrence_count
  4. Shows a β€œReopened” badge in the dashboard

Notification Throttling

Three layers to prevent alert fatigue:

BRIN Indexes

PostgreSQL BRIN index on occurred_at for time-series performance:

Structured Backtrace

Uses backtrace_locations (Ruby 2.0+) when available for richer data:

Reduced Dependencies

Core gem requires 4 runtime gems: rails, pagy, groupdate, and concurrent-ruby. Four previously-required dependencies are now optional:


Metrics & Reporting

Dashboard Metrics

Analytics Page

Developer Insights


πŸŽ‰ That’s every feature! Rails Error Dashboard is a comprehensive, production-ready error tracking solution built specifically for Rails developers who value ownership and privacy.


πŸ”§ How to Enable/Disable Features

During Installation

When you run the installer, you’ll be prompted to select which optional features to enable:

rails generate rails_error_dashboard:install

Interactive Mode (default):

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
  Rails Error Dashboard - Installation
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

[1/23] Slack Notifications
    Send errors to Slack channels instantly
    Enable? (y/N): y
    βœ“ Enabled

[2/23] Email Notifications
    Email error alerts to your team
    Enable? (y/N): n
    βœ— Disabled

... (continues for all features)

Non-Interactive Mode (for automation/CI):

rails generate rails_error_dashboard:install \
  --no-interactive \
  --slack \
  --async_logging \
  --baseline_alerts \
  --platform_comparison

Available CLI Flags:

After Installation

All features can be enabled or disabled at any time by editing your initializer:

Location: config/initializers/rails_error_dashboard.rb

To Enable a Feature

  1. Open the initializer file
  2. Find the feature section (use Cmd/Ctrl+F to search)
  3. Uncomment the configuration lines if needed
  4. Set config.enable_[feature_name] = true
  5. Add any required settings (webhook URLs, etc.)
  6. Restart your Rails server

Example - Enabling Slack notifications:

# Before:
# config.enable_slack_notifications = false
# config.slack_webhook_url = ENV["SLACK_WEBHOOK_URL"]

# After:
config.enable_slack_notifications = true
config.slack_webhook_url = ENV["SLACK_WEBHOOK_URL"]
config.dashboard_base_url = ENV["DASHBOARD_BASE_URL"]  # For clickable links

Example - Enabling baseline alerts:

# Before:
# config.enable_baseline_alerts = false

# After:
config.enable_baseline_alerts = true

# Optional tuning:
config.baseline_alert_threshold_std_devs = 2.0  # Sensitivity (default: 2.0)
config.baseline_alert_severities = [:critical, :high]  # Which severities to alert on
config.baseline_alert_cooldown_minutes = 120  # Minutes between alerts

To Disable a Feature

  1. Open the initializer file
  2. Find the feature section
  3. Set config.enable_[feature_name] = false
  4. Or comment out the entire section
  5. Restart your Rails server

Example - Disabling email notifications:

# Before:
config.enable_email_notifications = true
config.notification_email_recipients = ENV.fetch("ERROR_NOTIFICATION_EMAILS", "").split(",")

# After:
config.enable_email_notifications = false
# config.notification_email_recipients = ENV.fetch("ERROR_NOTIFICATION_EMAILS", "").split(",")

Restart Required

After changing any configuration, you must restart your Rails server:

# Development
rails server

# Production
systemctl restart myapp
# or
touch tmp/restart.txt  # For Passenger

Feature Combinations

You can enable/disable any combination of features. Here are some recommended configurations:

Minimal Setup (Small Apps)

config.enable_slack_notifications = true  # Just one notification channel
# Everything else disabled

Production SaaS

# Notifications
config.enable_slack_notifications = true
config.enable_pagerduty_notifications = true

# Performance
config.async_logging = true

# Analytics
config.enable_baseline_alerts = true
config.enable_platform_comparison = true
config.enable_error_correlation = true

# Debugging
config.enable_breadcrumbs = true
config.enable_system_health = true

Enterprise/High-Scale

# All notifications
config.enable_slack_notifications = true
config.enable_email_notifications = true
config.enable_pagerduty_notifications = true

# All performance features
config.async_logging = true
config.sampling_rate = 0.1  # Sample 10% of non-critical errors
config.use_separate_database = true

# All advanced analytics
config.enable_baseline_alerts = true
config.enable_similar_errors = true
config.enable_co_occurring_errors = true
config.enable_error_cascades = true
config.enable_error_correlation = true
config.enable_platform_comparison = true
config.enable_occurrence_patterns = true

# Developer tools
config.enable_source_code_integration = true
config.enable_breadcrumbs = true
config.enable_system_health = true

Environment-Specific Configuration

You can enable different features per environment:

RailsErrorDashboard.configure do |config|
  # Core settings (all environments)
  config.dashboard_username = ENV.fetch("ERROR_DASHBOARD_USER", "gandalf")
  config.dashboard_password = ENV.fetch("ERROR_DASHBOARD_PASSWORD", "youshallnotpass")

  # Production-only features
  if Rails.env.production?
    config.enable_slack_notifications = true
    config.enable_pagerduty_notifications = true
    config.async_logging = true
    config.enable_baseline_alerts = true
  end

  # Development-only features
  if Rails.env.development?
    # Note: Authentication is always required and cannot be disabled
    config.sampling_rate = 0.5  # Reduce noise in development
  end

  # Staging-specific
  if Rails.env.staging?
    config.enable_slack_notifications = true  # Notify #staging-errors channel
    config.enable_baseline_alerts = true  # Test alert logic
  end
end

Checking Enabled Features

To see which features are currently enabled, you can check in the Rails console:

# Rails console
config = RailsErrorDashboard.configuration

# Check specific features
config.enable_slack_notifications  # => true or false
config.enable_baseline_alerts      # => true or false

# List all advanced analytics features
{
  similar_errors: config.enable_similar_errors,
  co_occurring: config.enable_co_occurring_errors,
  cascades: config.enable_error_cascades,
  baselines: config.enable_baseline_alerts,
  correlation: config.enable_error_correlation,
  platform_comparison: config.enable_platform_comparison,
  patterns: config.enable_occurrence_patterns
}

# v0.2 features
{
  filter_sensitive_data: config.filter_sensitive_data,
  custom_fingerprint: config.custom_fingerprint.present?,
  notification_minimum_severity: config.notification_minimum_severity,
  notification_cooldown_minutes: config.notification_cooldown_minutes,
  notification_threshold_alerts: config.notification_threshold_alerts
}

Feature Documentation

For detailed information about what each feature does and when to use it, see the relevant sections above:


πŸ“š Back to Documentation β†’