Configuration Guide
This guide covers all configuration options for Rails Error Dashboard, including advanced features for customization and extensibility.
Table of Contents
- Configuration Defaults Reference
- Opt-in Feature System
- Basic Configuration
- Notification Features
- Performance Features
- Advanced Analytics Features
- Source Code Integration
- Local Variable Capture
- Instance Variable Capture
- Swallowed Exception Detection
- Diagnostic Dump
- Rack Attack Event Tracking
- Process Crash Capture
- Custom Severity Classification
- Ignored Exceptions
- Error Sampling
- Notification Callbacks
- ActiveSupport Notifications
- Backtrace Configuration
- Complete Configuration Example
Configuration Defaults Reference
Complete reference of all 60+ configuration options with defaults, types, and descriptions.
Authentication & Access
| Option | Type | Default | Description |
|---|---|---|---|
dashboard_username |
String | "gandalf" |
Username for HTTP Basic Auth (ENV: ERROR_DASHBOARD_USER) |
dashboard_password |
String | "youshallnotpass" |
Password for HTTP Basic Auth (ENV: ERROR_DASHBOARD_PASSWORD) |
authenticate_with |
Lambda/Proc/Callable | nil |
Custom auth lambda executed in controller context. When set, replaces HTTP Basic Auth. Return truthy to allow, falsy to deny (403). |
user_model |
String | "User" |
Model name for user associations |
Multi-App Support
| Option | Type | Default | Description |
|---|---|---|---|
application_name |
String | Auto-detected | Application identifier (ENV: APPLICATION_NAME) |
database |
Symbol/String | nil |
Database connection name (nil = primary database) |
use_separate_database |
Boolean | false |
Use separate database for errors (ENV: USE_SEPARATE_ERROR_DB) |
Notifications - Slack
| Option | Type | Default | Description |
|---|---|---|---|
enable_slack_notifications |
Boolean | false |
Enable Slack webhooks |
slack_webhook_url |
String | nil |
Slack webhook URL (ENV: SLACK_WEBHOOK_URL) |
Notifications - Email
| Option | Type | Default | Description |
|---|---|---|---|
enable_email_notifications |
Boolean | false |
Enable email notifications |
notification_email_recipients |
Array | [] |
Email recipients (ENV: ERROR_NOTIFICATION_EMAILS, comma-separated) |
notification_email_from |
String | "errors@example.com" |
From address (ENV: ERROR_NOTIFICATION_FROM) |
dashboard_base_url |
String | nil |
Base URL for links in emails (ENV: DASHBOARD_BASE_URL) |
Notifications - Discord
| Option | Type | Default | Description |
|---|---|---|---|
enable_discord_notifications |
Boolean | false |
Enable Discord webhooks |
discord_webhook_url |
String | nil |
Discord webhook URL (ENV: DISCORD_WEBHOOK_URL) |
Notifications - PagerDuty
| Option | Type | Default | Description |
|---|---|---|---|
enable_pagerduty_notifications |
Boolean | false |
Enable PagerDuty (critical errors only) |
pagerduty_integration_key |
String | nil |
PagerDuty integration key (ENV: PAGERDUTY_INTEGRATION_KEY) |
Notifications - Webhooks
| Option | Type | Default | Description |
|---|---|---|---|
enable_webhook_notifications |
Boolean | false |
Enable custom webhooks |
webhook_urls |
Array | [] |
Custom webhook URLs (ENV: WEBHOOK_URLS, comma-separated) |
Core Features
| Option | Type | Default | Description |
|---|---|---|---|
enable_middleware |
Boolean | true |
Enable error catching middleware |
enable_error_subscriber |
Boolean | true |
Enable Rails.error subscriber |
retention_days |
Integer | 90 |
Days to keep errors before auto-deletion |
Error Classification
| Option | Type | Default | Description |
|---|---|---|---|
custom_severity_rules |
Hash | {} |
Custom error type → severity mappings |
ignored_exceptions |
Array | [] |
Exception classes/patterns to ignore |
Performance Optimization
| Option | Type | Default | Description |
|---|---|---|---|
async_logging |
Boolean | false |
Log errors asynchronously in background jobs |
async_adapter |
Symbol | :sidekiq |
Background job adapter (:sidekiq, :solid_queue, :async) |
sampling_rate |
Float | 1.0 |
Percentage of errors to log (0.0-1.0, critical always logged) |
max_backtrace_lines |
Integer | 50 |
Maximum backtrace lines to store |
API & Rate Limiting
| Option | Type | Default | Description |
|---|---|---|---|
enable_rate_limiting |
Boolean | false |
Enable API rate limiting (opt-in) |
rate_limit_per_minute |
Integer | 100 |
Max requests per minute per IP |
Enhanced Metrics
| Option | Type | Default | Description |
|---|---|---|---|
app_version |
String | nil |
Application version (ENV: APP_VERSION) |
git_sha |
String | nil |
Git commit SHA (ENV: GIT_SHA) |
git_repository_url |
String | nil |
Git repository URL for commit links (ENV: GIT_REPOSITORY_URL) |
total_users_for_impact |
Integer | nil |
Total users for impact % calculation (auto-detected if nil) |
Advanced Analytics - Error Analysis
| Option | Type | Default | Description |
|---|---|---|---|
enable_similar_errors |
Boolean | false |
Fuzzy error matching with Jaccard/Levenshtein similarity |
enable_co_occurring_errors |
Boolean | false |
Detect errors happening together |
enable_error_cascades |
Boolean | false |
Detect parent→child error relationships |
enable_error_correlation |
Boolean | false |
Version/user/time correlation analysis |
enable_platform_comparison |
Boolean | false |
iOS vs Android vs Web health comparison |
enable_occurrence_patterns |
Boolean | false |
Cyclical and burst pattern detection |
Advanced Analytics - Baseline Monitoring
| Option | Type | Default | Description |
|---|---|---|---|
enable_baseline_alerts |
Boolean | false |
Statistical anomaly detection and alerts |
baseline_alert_threshold_std_devs |
Float | 2.0 |
Standard deviations to trigger alert (ENV: BASELINE_ALERT_THRESHOLD) |
baseline_alert_severities |
Array | [:critical, :high] |
Severities to alert on |
baseline_alert_cooldown_minutes |
Integer | 120 |
Minutes between alerts for same error (ENV: BASELINE_ALERT_COOLDOWN) |
Source Code Integration (NEW!)
| Option | Type | Default | Description |
|---|---|---|---|
enable_source_code_integration |
Boolean | false |
View source code directly in error details |
source_code_context_lines |
Integer | 5 |
Lines of context before/after error line |
enable_git_blame |
Boolean | false |
Show git blame info (author, commit, timestamp) |
source_code_cache_ttl |
Integer | 3600 |
Cache TTL in seconds (1 hour default) |
only_show_app_code_source |
Boolean | true |
Hide gem/vendor code (security) |
git_branch_strategy |
Symbol | :commit_sha |
Branch strategy (:commit_sha, :current_branch, :main) |
Breadcrumbs — Request Activity Trail (NEW!)
| Option | Type | Default | Description |
|---|---|---|---|
enable_breadcrumbs |
Boolean | false |
Capture request activity trail (SQL, controller, cache, etc.) |
breadcrumb_buffer_size |
Integer | 40 |
Max breadcrumbs per request (ring buffer) |
breadcrumb_categories |
Array/nil | nil |
Categories to capture (nil = all; or [:sql, :controller, :cache, :job, :mailer, :deprecation, :custom]) |
enable_n_plus_one_detection |
Boolean | true |
Detect N+1 query patterns in SQL breadcrumbs (display-time analysis) |
n_plus_one_threshold |
Integer | 3 |
Min repetitions to flag as N+1 (min: 2) |
System Health Snapshot
| Option | Type | Default | Description |
|---|---|---|---|
enable_system_health |
Boolean | false |
Capture GC, memory, threads, connection pool, RubyVM cache, YJIT stats at error time |
Local Variable Capture (v0.4.0)
| Option | Type | Default | Description |
|---|---|---|---|
enable_local_variables |
Boolean | false |
Capture local variables at exception raise point via TracePoint |
local_variable_max_count |
Integer | 15 |
Maximum number of local variables to capture per exception |
local_variable_max_depth |
Integer | 3 |
Maximum object nesting depth for serialization |
local_variable_max_string_length |
Integer | 200 |
Truncate string values beyond this length |
local_variable_max_array_items |
Integer | 10 |
Maximum array items to serialize |
local_variable_max_hash_items |
Integer | 20 |
Maximum hash entries to serialize |
local_variable_filter_patterns |
Array | [] |
Additional sensitive variable name patterns to filter (beyond Rails filter_parameters) |
Instance Variable Capture (v0.4.0)
| Option | Type | Default | Description |
|---|---|---|---|
enable_instance_variables |
Boolean | false |
Capture instance variables from the object that raised the exception |
instance_variable_max_count |
Integer | 20 |
Maximum instance variables to capture per exception |
instance_variable_filter_patterns |
Array | [] |
Additional sensitive instance variable name patterns to filter |
Swallowed Exception Detection (v0.4.0)
| Option | Type | Default | Description |
|---|---|---|---|
detect_swallowed_exceptions |
Boolean | false |
Detect exceptions that are raised but silently rescued. Requires Ruby 3.3+ |
swallowed_exception_max_cache_size |
Integer | 1000 |
Maximum entries per thread-local raise/rescue tracking cache |
swallowed_exception_flush_interval |
Integer | 60 |
Seconds between database flushes of accumulated data |
swallowed_exception_threshold |
Float | 0.95 |
Rescue ratio (0.0-1.0) to flag a location as “swallowed” |
swallowed_exception_ignore_classes |
Array | [] |
Additional exception classes to skip during tracking |
Diagnostic Dump (v0.4.0)
| Option | Type | Default | Description |
|---|---|---|---|
enable_diagnostic_dump |
Boolean | false |
Enable on-demand system state snapshots via dashboard or rake task |
Rack Attack Event Tracking (v0.4.0)
| Option | Type | Default | Description |
|---|---|---|---|
enable_rack_attack_tracking |
Boolean | false |
Track Rack::Attack throttle/blocklist events as breadcrumbs. Requires enable_breadcrumbs = true |
Process Crash Capture (v0.4.0)
| Option | Type | Default | Description |
|---|---|---|---|
enable_crash_capture |
Boolean | false |
Capture unhandled exceptions that crash the Ruby process via at_exit hook |
crash_capture_path |
String | nil |
Directory for crash files. If nil, uses Dir.tmpdir. Directory must exist |
Internal Logging & Debugging
| Option | Type | Default | Description |
|---|---|---|---|
enable_internal_logging |
Boolean | false |
Enable internal gem logging for debugging |
log_level |
Symbol | :silent |
Log level (:debug, :info, :warn, :error, :silent) |
Read-Only Attributes
| Option | Type | Default | Description |
|---|---|---|---|
notification_callbacks |
Hash | See below | Notification callback registry (use helper methods, not direct assignment) |
Environment Variables Quick Reference
All environment variables that can be used instead of or alongside configuration:
# Authentication
ERROR_DASHBOARD_USER=admin
ERROR_DASHBOARD_PASSWORD=secure_password
# Multi-App
APPLICATION_NAME=my-api
# Database
USE_SEPARATE_ERROR_DB=true # "true" or "false"
# Notifications
SLACK_WEBHOOK_URL=https://hooks.slack.com/services/...
ERROR_NOTIFICATION_EMAILS=team@example.com,ops@example.com
ERROR_NOTIFICATION_FROM=errors@myapp.com
DASHBOARD_BASE_URL=https://dashboard.example.com
DISCORD_WEBHOOK_URL=https://discord.com/api/webhooks/...
PAGERDUTY_INTEGRATION_KEY=abc123...
WEBHOOK_URLS=https://hook1.example.com,https://hook2.example.com
# Enhanced Metrics
APP_VERSION=1.2.3
GIT_SHA=abc123def456
GIT_REPOSITORY_URL=https://github.com/user/repo
# Baseline Alerts
BASELINE_ALERT_THRESHOLD=2.0 # Standard deviations
BASELINE_ALERT_COOLDOWN=120 # Minutes
Practical Defaults Guidance
For Development:
config.async_logging = false # Sync for easier debugging
config.sampling_rate = 1.0 # Log all errors
config.enable_internal_logging = true # See what's happening
config.log_level = :debug # Verbose logging
For Production (Low Traffic):
config.async_logging = true # Background jobs
config.async_adapter = :sidekiq # Battle-tested
config.sampling_rate = 1.0 # Log all errors
config.retention_days = 90 # 3 months
config.max_backtrace_lines = 50 # Full context
For Production (High Traffic >1000 errors/day):
config.async_logging = true # REQUIRED
config.async_adapter = :sidekiq # Recommended
config.sampling_rate = 0.1 # 10% (critical always logged)
config.retention_days = 30 # 1 month
config.max_backtrace_lines = 20 # Reduce storage
config.use_separate_database = true # Isolate errors
Opt-in Feature System
Rails Error Dashboard uses an opt-in architecture. Core features are always enabled, while everything else is disabled by default.
Tier 1 Features (Always ON):
- ✅ Error capture (controllers, jobs, middleware)
- ✅ Dashboard UI with search and filtering
- ✅ Real-time updates via Turbo Streams
- ✅ Analytics and trend charts
Optional Features (17 total):
- 📧 5 Notification Channels (Slack, Email, Discord, PagerDuty, Webhooks)
- ⚡ 3 Performance Features (Async Logging, Error Sampling, Separate Database)
- 📊 7 Advanced Analytics (Baseline Alerts, Fuzzy Matching, Co-occurring Errors, Error Cascades, Correlation, Platform Comparison, Occurrence Patterns)
- 🔍 2 Developer Tools (Source Code Integration, Git Blame)
All features can be enabled during installation via the interactive installer, or toggled on/off at any time in the initializer.
Basic Configuration
Create an initializer at config/initializers/rails_error_dashboard.rb:
RailsErrorDashboard.configure do |config|
# Dashboard authentication (always required)
config.dashboard_username = "admin"
config.dashboard_password = ENV.fetch("ERROR_DASHBOARD_PASSWORD", "changeme")
# Data retention (days)
config.retention_days = 90
# User model for error association
config.user_model = "User"
# Enable/disable middleware and error subscriber
config.enable_middleware = true
config.enable_error_subscriber = true
end
Custom Authentication
If you use Devise, Warden, or any other auth system, you can replace HTTP Basic Auth with a lambda that runs in controller context via instance_exec:
RailsErrorDashboard.configure do |config|
# Devise/Warden — use warden directly (recommended)
config.authenticate_with = -> {
if warden.authenticated?
true
else
redirect_to main_app.new_user_session_path, allow_other_host: true
end
}
# Warden with admin scope
config.authenticate_with = -> { warden.authenticated?(:admin) }
# Session-based
config.authenticate_with = -> { session[:dashboard_admin] == true }
end
Important: Engine controller context. The lambda runs inside the engine’s controller, which inherits from
ActionController::Base— not your app’sApplicationController. This means Devise helpers likecurrent_userandauthenticate_user!are not available. Usewarden(the underlying Rack middleware) instead:
Works Doesn’t work warden.authenticated?current_userwarden.userauthenticate_user!warden.authenticate(:scope => :user)user_signed_in?session,cookies,request,paramsDevise helper methods
How it works:
- The lambda has access to
warden,session,request,params,cookies,redirect_to, etc. - Truthy return → access granted
- Falsy return (including
nil) → 403 Forbidden - Lambda raises → rescued, logged, 403 (fail closed)
- Lambda calls
redirect_to→ redirect honored (e.g. to your login page) authenticate_with = nil(default) → falls back to HTTP Basic Auth
Notification Features
Rails Error Dashboard supports 5 notification channels, all disabled by default.
Slack Notifications
Send real-time error notifications to Slack channels.
RailsErrorDashboard.configure do |config|
config.enable_slack_notifications = true
config.slack_webhook_url = ENV['SLACK_WEBHOOK_URL']
end
Email Notifications
Send error alerts via email to your team.
RailsErrorDashboard.configure do |config|
config.enable_email_notifications = true
config.notification_email_recipients = ["dev@yourapp.com", "team@yourapp.com"]
config.notification_email_from = "errors@yourapp.com"
end
Discord Notifications
Push errors to Discord channels via webhooks.
RailsErrorDashboard.configure do |config|
config.enable_discord_notifications = true
config.discord_webhook_url = ENV['DISCORD_WEBHOOK_URL']
end
PagerDuty Integration
Escalate critical errors to PagerDuty for on-call teams. Only triggers for critical errors to avoid alert fatigue.
RailsErrorDashboard.configure do |config|
config.enable_pagerduty_notifications = true
config.pagerduty_integration_key = ENV['PAGERDUTY_INTEGRATION_KEY']
end
Custom Webhooks
Send errors to custom endpoints (Zapier, IFTTT, custom services).
RailsErrorDashboard.configure do |config|
config.enable_webhook_notifications = true
config.webhook_urls = [
'https://yourapp.com/hooks/errors',
'https://zapier.com/hooks/catch/123456/abcdef'
]
end
Dashboard Base URL (for notification links):
config.dashboard_base_url = ENV['DASHBOARD_BASE_URL'] # e.g., "https://yourapp.com"
See Notifications Guide for detailed setup instructions.
Performance Features
Optimize performance and reduce database load with these features.
Async Error Logging
Log errors in background jobs for non-blocking performance.
RailsErrorDashboard.configure do |config|
config.async_logging = true
config.async_adapter = :sidekiq # Options: :sidekiq, :solid_queue, :async
end
Supported Adapters:
:sidekiq- Battle-tested, recommended for production:solid_queue- Rails 8.1+ built-in job backend:async- Rails default (in-process, good for development)
Error Sampling
Reduce database writes by logging only a percentage of non-critical errors. Critical errors are ALWAYS logged regardless of sampling rate.
RailsErrorDashboard.configure do |config|
config.sampling_rate = 0.1 # Log 10% of non-critical errors
end
See Error Sampling section below for details.
Separate Database
Isolate error data in a dedicated database for better performance and separation of concerns.
RailsErrorDashboard.configure do |config|
config.use_separate_database = true
end
Requires additional database configuration. See Database Options Guide for setup instructions.
Advanced Analytics Features
Powerful analytics features for deep error insights, all disabled by default.
Baseline Anomaly Alerts
Automatically detect when error rates exceed normal patterns using statistical analysis.
RailsErrorDashboard.configure do |config|
config.enable_baseline_alerts = true
config.baseline_alert_threshold_std_devs = 2.0 # Alert when >2 std devs above baseline
config.baseline_alert_severities = [:critical, :high] # Alert on these severities only
config.baseline_alert_cooldown_minutes = 120 # 2 hours between alerts for same error
end
See Baseline Monitoring Guide for details.
Fuzzy Error Matching
Find similar errors even with different error_hashes using backtrace signatures and message similarity.
RailsErrorDashboard.configure do |config|
config.enable_similar_errors = true
end
See Advanced Error Grouping Guide for details.
Co-occurring Errors
Detect errors that happen together in time (within 5-minute windows).
RailsErrorDashboard.configure do |config|
config.enable_co_occurring_errors = true
end
See Advanced Error Grouping Guide for details.
Error Cascades
Identify parent→child error relationships (error A causes error B).
RailsErrorDashboard.configure do |config|
config.enable_error_cascades = true
end
See Advanced Error Grouping Guide for details.
Error Correlation
Correlate errors with app versions, users, and time patterns.
RailsErrorDashboard.configure do |config|
config.enable_error_correlation = true
end
See Error Correlation Guide for details.
Platform Comparison
Compare iOS vs Android vs Web health metrics and platform-specific error rates.
RailsErrorDashboard.configure do |config|
config.enable_platform_comparison = true
end
See Platform Comparison Guide for details.
Occurrence Patterns
Detect cyclical patterns (daily/weekly rhythms) and error bursts.
RailsErrorDashboard.configure do |config|
config.enable_occurrence_patterns = true
end
See Occurrence Patterns Guide for details.
Source Code Integration (NEW!)
View source code directly in the error dashboard with git blame information and repository links.
Basic Configuration
RailsErrorDashboard.configure do |config|
# Enable source code viewer
config.enable_source_code_integration = true
# Optional: Enable git blame integration
config.enable_git_blame = true
end
Advanced Configuration
RailsErrorDashboard.configure do |config|
# Enable source code viewer
config.enable_source_code_integration = true
# Enable git blame
config.enable_git_blame = true
# Context lines (±N lines around error)
config.source_code_context_lines = 5 # Default: 5
# Cache TTL in seconds
config.source_code_cache_ttl = 3600 # Default: 1 hour
# Security: only show app code (hide gems/vendor)
config.only_show_app_code_source = true # Default: true
# Branch strategy for repository links
config.git_branch_strategy = :commit_sha # Options: :commit_sha, :current_branch, :main
end
Features
- Source Code Viewer: View actual source code lines around the error
- Git Blame Integration: See who last modified the code and when
- Repository Links: Direct links to GitHub, GitLab, or Bitbucket
- Automatic Detection: Detects repository URL from git remote
- Security: Only reads files within application root directory
Requirements
- Application must be a git repository
- Git must be installed (for git blame functionality)
- Dashboard must have read access to application source files
Use Cases
# Development: Full visibility
config.enable_source_code_integration = true
config.enable_git_blame = true
# Production: Source code only (no git blame for performance)
config.enable_source_code_integration = true
config.enable_git_blame = false
# Staging: Enable both for debugging
if Rails.env.staging?
config.enable_source_code_integration = true
config.enable_git_blame = true
end
Privacy & Security
- Self-hosted: Source code never leaves your infrastructure
- Read-only: Dashboard only reads files, never modifies
- Path validation: Only files within app root can be accessed
- No external calls: All processing happens locally
Breadcrumbs — Request Activity Trail (NEW!)
Breadcrumbs capture a timeline of events (SQL queries, controller actions, cache operations, etc.) during a request, then store them with the error for instant debugging context.
Basic Configuration
RailsErrorDashboard.configure do |config|
# Enable breadcrumbs
config.enable_breadcrumbs = true
end
Advanced Configuration
RailsErrorDashboard.configure do |config|
config.enable_breadcrumbs = true
# Max events per request (default: 40, ring buffer drops oldest when full)
config.breadcrumb_buffer_size = 40
# Limit which categories are captured (default: nil = all)
# Options: :sql, :controller, :cache, :job, :mailer, :deprecation, :custom
config.breadcrumb_categories = [ :sql, :controller ] # Only SQL and controller events
# N+1 query detection (analyzes SQL breadcrumbs at display time)
config.enable_n_plus_one_detection = true # Default: true
config.n_plus_one_threshold = 3 # Min repetitions to flag (default: 3, min: 2)
end
Manual Breadcrumbs
Add custom breadcrumbs from anywhere in your application code:
RailsErrorDashboard.add_breadcrumb("checkout started", { cart_id: 123 })
RailsErrorDashboard.add_breadcrumb("payment processed", { provider: "stripe", amount: 99.99 })
Captured Events
| Event | Category | What’s Captured |
|---|---|---|
sql.active_record |
sql |
SQL query (first 200 chars) + duration. Skips SCHEMA queries and internal gem queries |
process_action.action_controller |
controller |
ControllerName#action + duration |
cache_read.active_support |
cache |
cache read: key |
cache_write.active_support |
cache |
cache write: key |
perform.active_job |
job |
Job class name + duration |
deliver.action_mailer |
mailer |
MailerClass to: [recipients] |
deprecation.rails |
deprecation |
Deprecation warning message + caller location |
N+1 Query Detection
When breadcrumbs and N+1 detection are both enabled, the error detail page automatically analyzes SQL breadcrumbs for repeated query patterns. A yellow warning card appears when the same normalized query shape is repeated above the threshold:
config.enable_n_plus_one_detection = true # ON by default
config.n_plus_one_threshold = 3 # Flag when same pattern appears 3+ times
The detector normalizes SQL by replacing literal values (WHERE id = 42 → WHERE id = ?) and IN lists (IN (1, 2, 3) → IN (?)) while preserving PostgreSQL double-quoted identifiers. Analysis runs at display time only — zero overhead on requests.
Use Cases
# Development: Full breadcrumb visibility
config.enable_breadcrumbs = true
# Production: Enable with conservative buffer
config.enable_breadcrumbs = true
config.breadcrumb_buffer_size = 25
# High-traffic: Only capture SQL and controller events
config.enable_breadcrumbs = true
config.breadcrumb_categories = [ :sql, :controller ]
Safety
- Default OFF — opt-in only
- Fixed-size ring buffer — no unbounded memory growth
- Thread-local — no mutex/lock, each request isolated
- Cleanup in ensure — buffer cleared even on exceptions (Puma thread reuse safe)
- Every subscriber wrapped in rescue — never raises, never blocks
- Sensitive data filtered — passwords, tokens, secrets scrubbed before storage
- < 0.1ms/request overhead — events already fired by Rails
System Health Snapshot (NEW!)
Capture runtime health metrics (GC stats, memory, threads, connection pool, Puma) at the moment of every error. Displayed in the error detail sidebar.
Quick Start
RailsErrorDashboard.configure do |config|
config.enable_system_health = true
end
What Gets Captured
| Metric | Source | Notes |
|---|---|---|
| GC stats | GC.stat |
heap_live_slots, heap_free_slots, major_gc_count, total_allocated_objects |
| Process memory | /proc/self/status |
RSS in MB, Linux only (nil on macOS) |
| Thread count | Thread.list.count |
O(1), safe |
| Connection pool | ActiveRecord::Base.connection_pool.stat |
size, busy, idle, dead, waiting |
| Puma stats | Puma.stats |
running, max_threads, pool_capacity, backlog (when available) |
| RubyVM cache | RubyVM.stat |
constant_cache invalidations, class serial, global state (when available) |
| YJIT stats | RubyVM::YJIT.runtime_stats |
compiled ISEQs, code region size, inline/outlined bytes (when YJIT enabled) |
Safety
- Default OFF — opt-in only
- Sub-millisecond — total snapshot < 1ms
- Every metric individually wrapped in
rescue => nil - Top-level rescue — returns
{ captured_at: ... }if everything fails (never raises) - No ObjectSpace scanning — never calls
each_objectorcount_objects - No Thread backtraces — only
.count, never.map(&:backtrace) - No subprocess — memory via procfs only, no
ps, no fork, no backtick - No global state — no Thread.current, no mutex, no memoization
Local Variable Capture (v0.4.0)
Capture local variables at the exact moment an exception is raised via TracePoint(:raise). The most valuable debugging context possible.
RailsErrorDashboard.configure do |config|
config.enable_local_variables = true
# Serialization limits (all have sensible defaults)
config.local_variable_max_count = 15 # Max variables per exception
config.local_variable_max_depth = 3 # Max object nesting depth
config.local_variable_max_string_length = 200 # Truncate strings beyond this
config.local_variable_max_array_items = 10 # Max array items
config.local_variable_max_hash_items = 20 # Max hash entries
# Additional sensitive patterns (beyond Rails filter_parameters)
config.local_variable_filter_patterns = [ /secret/, /token/ ]
end
Safety
- Never stores Binding objects — values extracted immediately, Binding is GC’d
- Sensitive data auto-filtered — Rails
filter_parametersapplied automatically - Configurable limits — all size limits enforced during serialization
- Opt-in only — disabled by default
Instance Variable Capture (v0.4.0)
Capture instance variables from the object that raised the exception (tp.self on the TracePoint).
RailsErrorDashboard.configure do |config|
config.enable_instance_variables = true
config.instance_variable_max_count = 20 # Max variables (default: 20)
config.instance_variable_filter_patterns = [] # Additional sensitive patterns
end
Shares the same TracePoint handler as local variable capture — minimal overhead when both are enabled. Includes _self_class metadata showing the receiver’s class name.
Swallowed Exception Detection (v0.4.0)
Detect exceptions that are raised but silently rescued — the hardest bugs to find. Requires Ruby 3.3+ (TracePoint :rescue event, Feature #19572).
RailsErrorDashboard.configure do |config|
config.detect_swallowed_exceptions = true
config.swallowed_exception_max_cache_size = 1000 # Thread-local cache size
config.swallowed_exception_flush_interval = 60 # Seconds between DB flushes
config.swallowed_exception_threshold = 0.95 # 95% rescue ratio = "swallowed"
config.swallowed_exception_ignore_classes = [] # Exception classes to skip
end
Dashboard page at /errors/swallowed_exceptions. Auto-disabled on Ruby < 3.3 with a warning (no crash).
Diagnostic Dump (v0.4.0)
On-demand system state snapshots — environment, GC stats, threads, connection pool, memory, job queue health.
RailsErrorDashboard.configure do |config|
config.enable_diagnostic_dump = true
end
Trigger via dashboard button or rails error_dashboard:diagnostic_dump NOTE="deploy check". Dashboard page at /errors/diagnostic_dumps.
Rack Attack Event Tracking (v0.4.0)
Track Rack::Attack throttle, blocklist, and track events as breadcrumbs. Requires breadcrumbs to be enabled.
RailsErrorDashboard.configure do |config|
config.enable_breadcrumbs = true # Required dependency
config.enable_rack_attack_tracking = true
end
Auto-disabled with warning if breadcrumbs are not enabled. Dashboard page at /errors/rack_attack_summary.
Process Crash Capture (v0.4.0)
Capture unhandled exceptions that crash the Ruby process via an at_exit hook.
RailsErrorDashboard.configure do |config|
config.enable_crash_capture = true
config.crash_capture_path = nil # nil = Dir.tmpdir; custom path must exist
end
Writes crash data to JSON on disk (database may be unavailable during shutdown). Imported automatically on next boot. A self-hosted only feature — impossible for SaaS tools.
Custom Severity Classification
Override default severity levels for specific error types. This is useful when you want to treat certain errors differently than the defaults.
Default Severity Levels
- Critical:
SecurityError,NoMemoryError,SystemStackError,ActiveRecord::StatementInvalid - High:
ActiveRecord::RecordNotFound,ArgumentError,TypeError,NoMethodError,NameError - Medium:
ActiveRecord::RecordInvalid,Timeout::Error,Net::ReadTimeout,Net::OpenTimeout - Low: All other errors
Configuration
RailsErrorDashboard.configure do |config|
config.custom_severity_rules = {
# Treat payment errors as critical
"Stripe::CardError" => :critical,
"PaymentProcessingError" => :critical,
# Downgrade validation errors to low
"ActiveRecord::RecordInvalid" => :low,
# Custom application errors
"MyApp::BusinessLogicError" => :medium
}
end
Use Cases
- Payment Errors: Treat as critical to ensure immediate attention
- Validation Errors: Downgrade to low if they’re expected user input errors
- Third-party API Errors: Classify based on business impact
- Custom Application Errors: Set appropriate severity for domain-specific errors
Ignored Exceptions
Prevent certain exceptions from being logged. Useful for reducing noise from expected errors or third-party gems.
Configuration
RailsErrorDashboard.configure do |config|
config.ignored_exceptions = [
# Exact class names
"ActionController::RoutingError",
"ActiveRecord::RecordNotFound",
# Regex patterns for flexible matching
/Rack::Timeout/,
/ActionController::InvalidAuthenticityToken/,
# All errors from a specific namespace
/ThirdPartyGem::.*/
]
end
Features
- Exact Matching: Specify exception class names as strings
- Regex Patterns: Use regular expressions for flexible matching
- Inheritance Support: Ignoring a parent class ignores all subclasses
- Early Exit: Ignored exceptions skip all processing, saving resources
Use Cases
# Production: Ignore bot-related errors
config.ignored_exceptions = [
"ActionController::RoutingError", # Bots scanning for vulnerabilities
/ActionController::InvalidAuthenticityToken/ # CSRF from legitimate crawlers
]
# Development: Ignore known third-party issues
config.ignored_exceptions = [
/Geocoder::.*/, # Geocoding API rate limits
"Redis::CannotConnectError" # Redis disconnects during development
]
Error Sampling
Reduce database load by logging only a percentage of non-critical errors. Critical errors are ALWAYS logged regardless of sampling rate.
Configuration
RailsErrorDashboard.configure do |config|
# Log 100% of errors (default)
config.sampling_rate = 1.0
# Log only 10% of non-critical errors (critical errors always logged)
config.sampling_rate = 0.1
# Disable logging of non-critical errors entirely
config.sampling_rate = 0.0
end
Behavior
- 1.0 (100%): Log all errors - default behavior
- 0.1 (10%): Log 10% of non-critical errors, 100% of critical errors
- 0.0 (0%): Skip all non-critical errors, log only critical errors
- > 1.0: Treated as 100%
- < 0.0: Treated as 0%
Critical Errors (Always Logged)
These errors bypass sampling because they indicate serious system issues:
SecurityErrorNoMemoryErrorSystemStackErrorActiveRecord::StatementInvalid
Use Cases
# High-traffic production: Reduce database writes
config.sampling_rate = 0.1 # 10% sampling
# Load testing: Only log critical issues
config.sampling_rate = 0.0 # Skip non-critical
# Monitoring phase: Full visibility
config.sampling_rate = 1.0 # Log everything
Notification Callbacks
Register custom Ruby blocks that execute when errors are logged or resolved. Perfect for integrating with external services.
Available Callbacks
1. on_error_logged - Any Error Logged
RailsErrorDashboard.on_error_logged do |error_log|
# Called for every NEW error (not recurrences)
# Send to custom logging service
CustomLogger.log(
level: error_log.severity,
message: error_log.message,
metadata: {
error_type: error_log.error_type,
platform: error_log.platform,
environment: error_log.environment
}
)
end
2. on_critical_error - Critical Errors Only
RailsErrorDashboard.on_critical_error do |error_log|
# Called ONLY for critical errors (in addition to on_error_logged)
# Trigger PagerDuty incident
PagerDuty.trigger(
summary: "Critical: #{error_log.error_type}",
severity: "critical",
source: error_log.platform,
custom_details: {
message: error_log.message,
backtrace: error_log.backtrace&.lines&.first(5)
}
)
end
3. on_error_resolved - Error Resolved
RailsErrorDashboard.on_error_resolved do |error_log|
# Called when error is marked as resolved
# Notify team
Slack.post_message(
channel: "#engineering",
text: "✅ Error resolved: #{error_log.error_type}",
attachments: [{
fields: [
{ title: "Resolved By", value: error_log.resolved_by_name },
{ title: "Occurrences", value: error_log.occurrence_count },
{ title: "Resolution", value: error_log.resolution_comment }
]
}]
)
end
Multiple Callbacks
You can register multiple callbacks for the same event:
# Callback 1: Log to external service
RailsErrorDashboard.on_error_logged do |error_log|
Datadog.increment("errors.logged", tags: ["type:#{error_log.error_type}"])
end
# Callback 2: Send to analytics
RailsErrorDashboard.on_error_logged do |error_log|
Analytics.track_error(error_log)
end
# Both callbacks will execute
Error Handling
Callbacks are fail-safe - if one callback raises an error, it won’t break error logging or prevent other callbacks from running:
RailsErrorDashboard.on_error_logged do |error_log|
raise "Callback error" # Logged as warning, other callbacks still run
end
RailsErrorDashboard.on_error_logged do |error_log|
puts "This still executes" # ✓ Runs even if previous callback failed
end
Integration Examples
Datadog
RailsErrorDashboard.on_error_logged do |error_log|
Datadog::Statsd.increment("errors.logged",
tags: [
"severity:#{error_log.severity}",
"platform:#{error_log.platform}",
"environment:#{error_log.environment}"
]
)
end
Sentry (alongside Error Dashboard)
RailsErrorDashboard.on_critical_error do |error_log|
Sentry.capture_message(
"Critical Error: #{error_log.error_type}",
level: :fatal,
extra: {
error_id: error_log.id,
message: error_log.message,
platform: error_log.platform
}
)
end
Custom Metrics
RailsErrorDashboard.on_error_logged do |error_log|
Prometheus.error_counter.increment(
labels: {
type: error_log.error_type,
severity: error_log.severity,
platform: error_log.platform
}
)
end
ActiveSupport Notifications
Rails Error Dashboard emits standard Rails instrumentation events that can be subscribed to using ActiveSupport::Notifications.
Available Events
1. error_logged.rails_error_dashboard
Emitted when any error is logged (new errors only, not recurrences).
ActiveSupport::Notifications.subscribe("error_logged.rails_error_dashboard") do |name, start, finish, id, payload|
# Payload contains:
# - error_log: Full ErrorLog record
# - error_id: Error ID
# - error_type: Exception class name
# - message: Error message
# - severity: Error severity (:critical, :high, :medium, :low)
# - platform: Platform (iOS, Android, API)
# - environment: Rails environment
# - occurred_at: Timestamp
duration = finish - start
StatsD.timing("error_logging.duration", duration)
StatsD.increment("errors.logged", tags: ["type:#{payload[:error_type]}"])
end
2. critical_error.rails_error_dashboard
Emitted when a critical error is logged (in addition to error_logged).
ActiveSupport::Notifications.subscribe("critical_error.rails_error_dashboard") do |name, start, finish, id, payload|
# Same payload as error_logged
# Trigger immediate alert
PagerDuty.trigger_incident(
title: "Critical Error: #{payload[:error_type]}",
severity: "critical",
details: payload[:message]
)
end
3. error_resolved.rails_error_dashboard
Emitted when an error is marked as resolved.
ActiveSupport::Notifications.subscribe("error_resolved.rails_error_dashboard") do |name, start, finish, id, payload|
# Payload contains:
# - error_log: Full ErrorLog record
# - error_id: Error ID
# - error_type: Exception class name
# - resolved_by: Name of person who resolved it
# - resolved_at: Timestamp
Analytics.track_resolution(
error_id: payload[:error_id],
resolved_by: payload[:resolved_by],
resolution_time: payload[:resolved_at] - payload[:error_log].occurred_at
)
end
Using Event Objects
ActiveSupport::Notifications.subscribe("error_logged.rails_error_dashboard") do |*args|
event = ActiveSupport::Notifications::Event.new(*args)
puts "Event: #{event.name}"
puts "Duration: #{event.duration}ms"
puts "Error Type: #{event.payload[:error_type]}"
puts "Severity: #{event.payload[:severity]}"
end
Wildcard Subscriptions
# Subscribe to all Rails Error Dashboard events
ActiveSupport::Notifications.subscribe(/rails_error_dashboard/) do |event|
Rails.logger.info "Error Dashboard Event: #{event.name}"
end
Integration Examples
NewRelic
ActiveSupport::Notifications.subscribe("critical_error.rails_error_dashboard") do |*args|
event = ActiveSupport::Notifications::Event.new(*args)
NewRelic::Agent.notice_error(
StandardError.new(event.payload[:message]),
custom_params: {
error_id: event.payload[:error_id],
platform: event.payload[:platform]
}
)
end
Prometheus
error_counter = Prometheus::Client::Counter.new(
:rails_errors_total,
docstring: "Total number of Rails errors",
labels: [:type, :severity, :platform]
)
ActiveSupport::Notifications.subscribe("error_logged.rails_error_dashboard") do |*args|
event = ActiveSupport::Notifications::Event.new(*args)
error_counter.increment(
labels: {
type: event.payload[:error_type],
severity: event.payload[:severity],
platform: event.payload[:platform]
}
)
end
Elasticsearch
ActiveSupport::Notifications.subscribe("error_logged.rails_error_dashboard") do |*args|
event = ActiveSupport::Notifications::Event.new(*args)
Elasticsearch::Client.new.index(
index: "rails-errors",
body: {
timestamp: event.payload[:occurred_at],
error_type: event.payload[:error_type],
message: event.payload[:message],
severity: event.payload[:severity],
platform: event.payload[:platform],
environment: event.payload[:environment]
}
)
end
Async Error Logging (Revisited)
Async logging is available and fully functional. See the Async Error Logging section above for complete configuration details.
For quick reference:
RailsErrorDashboard.configure do |config|
# Enable async logging
config.async_logging = true
# Choose adapter: :sidekiq (default), :solid_queue, or :async
config.async_adapter = :sidekiq
end
Backtrace Configuration
Control how many lines of backtrace are stored:
RailsErrorDashboard.configure do |config|
# Limit backtrace to 50 lines (default)
config.max_backtrace_lines = 50
# Store more for detailed debugging
config.max_backtrace_lines = 100
# Minimal storage (just the first line)
config.max_backtrace_lines = 1
end
Benefits:
- Reduced database storage
- Faster error logging
- Still captures the most relevant stack frames
Complete Configuration Example
Here’s a production-ready configuration combining multiple features:
# config/initializers/rails_error_dashboard.rb
RailsErrorDashboard.configure do |config|
# ============================================================================
# AUTHENTICATION (Always Required)
# ============================================================================
# Authentication is always required in all environments
config.dashboard_username = ENV.fetch("ERROR_DASHBOARD_USER", "gandalf")
config.dashboard_password = ENV.fetch("ERROR_DASHBOARD_PASSWORD", "youshallnotpass")
# ============================================================================
# CORE FEATURES (Always Enabled)
# ============================================================================
config.enable_middleware = true
config.enable_error_subscriber = true
config.user_model = "User"
config.retention_days = 90
# ============================================================================
# NOTIFICATION SETTINGS
# ============================================================================
# Slack Notifications
config.enable_slack_notifications = true
config.slack_webhook_url = ENV["SLACK_WEBHOOK_URL"]
# Email Notifications
config.enable_email_notifications = true
config.notification_email_recipients = ENV.fetch("ERROR_NOTIFICATION_EMAILS", "").split(",").map(&:strip)
config.notification_email_from = ENV.fetch("ERROR_NOTIFICATION_FROM", "errors@example.com")
# Discord Notifications
config.enable_discord_notifications = true
config.discord_webhook_url = ENV["DISCORD_WEBHOOK_URL"]
# PagerDuty Integration (critical errors only)
config.enable_pagerduty_notifications = true
config.pagerduty_integration_key = ENV["PAGERDUTY_INTEGRATION_KEY"]
# Generic Webhook Notifications
config.enable_webhook_notifications = true
config.webhook_urls = ENV.fetch("WEBHOOK_URLS", "").split(",").map(&:strip).reject(&:empty?)
# Dashboard base URL (used in notification links)
config.dashboard_base_url = ENV["DASHBOARD_BASE_URL"]
# ============================================================================
# PERFORMANCE & SCALABILITY
# ============================================================================
# Async Error Logging
config.async_logging = true
config.async_adapter = :sidekiq # Options: :sidekiq, :solid_queue, :async
# Backtrace size limiting
config.max_backtrace_lines = 50
# Error Sampling (10% - critical errors ALWAYS logged)
config.sampling_rate = 0.1
# Ignored exceptions
config.ignored_exceptions = [
"ActionController::RoutingError",
"ActionController::InvalidAuthenticityToken",
/^ActiveRecord::RecordNotFound/
]
# ============================================================================
# DATABASE CONFIGURATION
# ============================================================================
config.use_separate_database = false
# ============================================================================
# ADVANCED ANALYTICS
# ============================================================================
# Baseline Anomaly Alerts
config.enable_baseline_alerts = true
config.baseline_alert_threshold_std_devs = 2.0
config.baseline_alert_severities = [:critical, :high]
config.baseline_alert_cooldown_minutes = 120
# Fuzzy Error Matching
config.enable_similar_errors = true
# Co-occurring Errors
config.enable_co_occurring_errors = true
# Error Cascade Detection
config.enable_error_cascades = true
# Error Correlation Analysis
config.enable_error_correlation = true
# Platform Comparison
config.enable_platform_comparison = true
# Occurrence Pattern Detection
config.enable_occurrence_patterns = true
# ============================================================================
# SOURCE CODE INTEGRATION (NEW!)
# ============================================================================
# Enable source code viewer
config.enable_source_code_integration = true
# Context lines around error (default: 5)
config.source_code_context_lines = 5
# Enable git blame integration
config.enable_git_blame = true
# Cache TTL in seconds (default: 3600 = 1 hour)
config.source_code_cache_ttl = 3600
# Security: only show app code (default: true)
config.only_show_app_code_source = true
# Branch strategy for repository links (default: :commit_sha)
config.git_branch_strategy = :commit_sha
# ============================================================================
# BREADCRUMBS (NEW!)
# ============================================================================
# Enable breadcrumbs (request activity trail)
config.enable_breadcrumbs = true
# Max events per request (default: 40)
config.breadcrumb_buffer_size = 40
# Capture all categories (default: nil = all)
# config.breadcrumb_categories = [:sql, :controller, :cache, :job, :mailer, :custom]
# ============================================================================
# SYSTEM HEALTH SNAPSHOT (NEW!)
# ============================================================================
# Capture GC, memory, threads, connection pool, RubyVM, YJIT at error time
config.enable_system_health = true
# ============================================================================
# DEEP DEBUGGING (v0.4.0)
# ============================================================================
# Local variable capture via TracePoint(:raise)
config.enable_local_variables = true
config.local_variable_max_count = 15
config.local_variable_max_depth = 3
config.local_variable_max_string_length = 200
# Instance variable capture from raising object
config.enable_instance_variables = true
config.instance_variable_max_count = 20
# Swallowed exception detection (Ruby 3.3+ required)
config.detect_swallowed_exceptions = true
config.swallowed_exception_threshold = 0.95
# On-demand diagnostic dump
config.enable_diagnostic_dump = true
# Rack Attack event tracking (requires breadcrumbs)
config.enable_rack_attack_tracking = true
# Process crash capture via at_exit hook
config.enable_crash_capture = true
# config.crash_capture_path = "/var/log/myapp/crashes" # default: Dir.tmpdir
# ============================================================================
# ADDITIONAL CONFIGURATION
# ============================================================================
# Custom severity rules
config.custom_severity_rules = {
"PaymentError" => :critical,
"ValidationError" => :low
}
# Enhanced metrics
config.app_version = ENV["APP_VERSION"]
config.git_sha = ENV["GIT_SHA"]
# config.total_users_for_impact = 10000 # For user impact % calculation
end
# ============================================================================
# NOTIFICATION CALLBACKS
# ============================================================================
# Alert on critical errors
RailsErrorDashboard.on_critical_error do |error_log|
PagerDuty.trigger(
summary: "Critical: #{error_log.error_type}",
severity: "critical",
source: error_log.platform
)
end
# Track metrics
RailsErrorDashboard.on_error_logged do |error_log|
StatsD.increment("errors.logged",
tags: [
"type:#{error_log.error_type}",
"severity:#{error_log.severity}",
"platform:#{error_log.platform}"
]
)
end
# Notify on resolution
RailsErrorDashboard.on_error_resolved do |error_log|
Slack.post_message(
channel: "#engineering",
text: "✅ #{error_log.error_type} resolved by #{error_log.resolved_by_name}"
)
end
# ============================================================================
# ACTIVESUPPORT NOTIFICATIONS
# ============================================================================
# Send to external logging service
ActiveSupport::Notifications.subscribe("error_logged.rails_error_dashboard") do |*args|
event = ActiveSupport::Notifications::Event.new(*args)
Elasticsearch::Client.new.index(
index: "rails-errors",
body: {
timestamp: event.payload[:occurred_at],
error_type: event.payload[:error_type],
message: event.payload[:message],
severity: event.payload[:severity],
platform: event.payload[:platform]
}
)
end
Environment-Specific Configuration
Configure differently per environment:
RailsErrorDashboard.configure do |config|
# Common configuration
config.user_model = "User"
config.max_backtrace_lines = 50
if Rails.env.production?
# Production: Aggressive sampling, strict filtering
config.sampling_rate = 0.1
config.ignored_exceptions = [
"ActionController::RoutingError",
/ActionController::InvalidAuthenticityToken/
]
elsif Rails.env.staging?
# Staging: Moderate sampling
config.sampling_rate = 0.5
else
# Development/Test: Log everything
config.sampling_rate = 1.0
config.ignored_exceptions = []
end
end
Troubleshooting
Configuration Not Taking Effect
Problem: Changes to config/initializers/rails_error_dashboard.rb don’t seem to work.
Solutions:
- Restart server - Configuration is loaded at startup
rails server - Check file location - Must be in
config/initializers/ls -la config/initializers/rails_error_dashboard.rb - Check for syntax errors
ruby -c config/initializers/rails_error_dashboard.rb - Verify configuration is loaded
# In rails console RailsErrorDashboard.configuration.inspect
Environment Variables Not Working
Problem: ENV['VARIABLE'] returns nil in configuration.
Solutions:
- Load environment variables before Rails
- Use
dotenv-railsgem for development - Use system environment variables in production
- Use
- Check variable is set
echo $SLACK_WEBHOOK_URL - Provide defaults
config.slack_webhook_url = ENV.fetch('SLACK_WEBHOOK_URL', nil)
Notifications Not Sending
Problem: Slack/Discord notifications aren’t working.
Solutions:
- Check notifications are enabled
# In rails console RailsErrorDashboard.configuration.enable_slack_notifications # Should return true - Verify webhook URL is set
RailsErrorDashboard.configuration.slack_webhook_url # Should return your webhook URL - Test webhook manually
curl -X POST YOUR_WEBHOOK_URL \ -H 'Content-Type: application/json' \ -d '{"text": "Test message"}' - Check background jobs are running
# With Sidekiq bundle exec sidekiq # With Solid Queue bin/jobs - Check notification thresholds
# Critical errors only go to PagerDuty config.severity_thresholds[:pagerduty] = :critical
Custom Severity Rules Not Working
Problem: Custom severity rules aren’t being applied.
Solutions:
- Check rule format - Use regex or symbol
# Correct config.custom_severity_rules = { /ActiveRecord::RecordNotFound/ => :low, :timeout_error => :high } # Incorrect (string won't match) config.custom_severity_rules = { "ActiveRecord::RecordNotFound" => :low } - Test regex patterns
# In rails console error_class = "ActiveRecord::RecordNotFound" /ActiveRecord::RecordNotFound/.match?(error_class) # Should return true - Check rule order - First match wins
# More specific rules should come first config.custom_severity_rules = { /ActiveRecord::RecordNotFound.*User/ => :high, # Specific /ActiveRecord::RecordNotFound/ => :low # General }
Background Jobs Not Processing
Problem: Async logging enabled but errors not appearing.
Solutions:
- Check job adapter configuration
# In rails console RailsErrorDashboard.configuration.async_adapter # Should return :sidekiq, :solid_queue, or :async - Verify job processor is running
# Sidekiq ps aux | grep sidekiq # Solid Queue ps aux | grep solid_queue - Check failed jobs
# Sidekiq require 'sidekiq/api' Sidekiq::RetrySet.new.size Sidekiq::DeadSet.new.size # Solid Queue SolidQueue::Job.failed.count - Test with sync logging temporarily
config.async_logging = false # For debugging
Sampling Too Aggressive
Problem: Too many errors being filtered out.
Solutions:
- Check sampling rate
RailsErrorDashboard.configuration.sampling_rate # 0.1 = 10% of errors logged - Critical errors always logged - Check severity
# Critical errors bypass sampling config.severity_thresholds[:critical] - Adjust rate - Start higher, tune down
config.sampling_rate = 0.5 # Start with 50% - Use conditional sampling
config.before_log_callback = lambda do |exception, context| # Always log payment errors return true if exception.message.include?("Stripe") # Sample others based on environment Rails.env.production? ? rand < 0.1 : true end
Database Performance Issues
Problem: Error logging is slow or causing database issues.
Solutions:
- Enable async logging
config.async_logging = true - Use separate database
config.database = :errors -
Add database indexes - Already included in migrations
- Increase backtrace limit
config.max_backtrace_lines = 20 # Default is 50 - Configure retention policy
config.retention_days = 30 # Auto-cleanup old errors
See Database Optimization Guide for more.
Authentication Not Working
Problem: Can’t access dashboard even with correct credentials.
Solutions:
- Check username and password are set
# In rails console RailsErrorDashboard.configuration.dashboard_username RailsErrorDashboard.configuration.dashboard_password - Verify HTTP Basic Auth is configured
config.dashboard_username = "admin" config.dashboard_password = "secure_password" - Test credentials
curl -u admin:password http://localhost:3000/red - Check for proxy/load balancer issues
- Some proxies strip Authorization headers
- May need to configure pass-through
- Clear browser cache - Old credentials may be cached
Multi-App Configuration Issues
Problem: Errors from multiple apps not showing correctly.
Solutions:
- Set APP_NAME environment variable
APP_NAME=my-api rails server - Or configure manually
config.application_name = "my-api" - Verify application is created
# In rails console RailsErrorDashboard::Application.all.pluck(:name) - Check errors are tagged correctly
RailsErrorDashboard::ErrorLog.last.application.name
See Multi-App Support Guide for more.
Resetting Configuration
For testing or dynamic reconfiguration:
# Reset to defaults
RailsErrorDashboard.reset_configuration!
# Reconfigure
RailsErrorDashboard.configure do |config|
config.sampling_rate = 1.0
end
Next Steps
- Testing: Write tests for your custom callbacks and severity rules
- Monitoring: Set up ActiveSupport::Notifications subscribers for your metrics service
- Optimization: Review database optimization and performance tuning guides
For questions or issues, visit: https://github.com/AnjanJ/rails_error_dashboard