Customization Guide
Learn how to customize Rails Error Dashboard to fit your applicationβs specific needs.
Table of Contents
- Custom Severity Rules
- Custom Error Context
- Sampling and Filtering
- Custom Notifications
- UI Customization
- Database Customization
Custom Severity Rules
Override the default severity classification for specific error types.
Basic Usage
# config/initializers/rails_error_dashboard.rb
RailsErrorDashboard.configure do |config|
config.custom_severity_rules = {
'PaymentError' => :critical,
'SecurityError' => :critical,
'DataLossError' => :critical,
'ThirdPartyAPIError' => :high,
'CacheError' => :medium,
'ValidationError' => :low,
'DeprecationWarning' => :low
}
end
Available Severity Levels
:critical- Immediate action required (payment failures, security issues):high- Should be fixed soon (data integrity, important features):medium- Should be fixed eventually (non-critical features):low- Nice to fix (deprecations, minor issues)
Pattern Matching
Use string matching for flexibility:
config.custom_severity_rules = {
# Exact match
'ActiveRecord::RecordNotFound' => :low,
# Your custom errors
'MyApp::PaymentProcessingError' => :critical,
'MyApp::EmailDeliveryError' => :medium,
# Third-party gems
'Stripe::CardError' => :high,
'AWS::S3::Errors::ServiceError' => :medium
}
Dynamic Severity
For more complex logic, use a proc:
# Advanced: Not yet implemented, but planned for future
config.severity_calculator = ->(error) do
return :critical if error.message.include?('payment')
return :high if error.backtrace.any? { |line| line.include?('critical_path') }
:medium
end
Custom Error Context
Add custom data to every error for better debugging.
Basic Context
RailsErrorDashboard.configure do |config|
config.add_error_context do |context|
# Add custom fields
context[:environment] = Rails.env
context[:server_name] = ENV['SERVER_NAME']
context[:deploy_version] = ENV['DEPLOY_VERSION']
context
end
end
Request-Specific Context
Add data from the current request:
config.add_error_context do |context|
# Available in context: request, user, etc.
if context[:request]
context[:user_agent] = context[:request].user_agent
context[:referer] = context[:request].referer
context[:request_id] = context[:request].request_id
end
if context[:user]
context[:user_email] = context[:user].email
context[:user_role] = context[:user].role
context[:subscription_plan] = context[:user].subscription&.plan
end
context
end
Performance Context
Track performance metrics:
config.add_error_context do |context|
context[:memory_usage] = `ps -o rss= -p #{Process.pid}`.to_i / 1024
context[:load_average] = File.read('/proc/loadavg').split.first rescue nil
context[:active_connections] = ActiveRecord::Base.connection_pool.stat[:busy]
context
end
Custom Breadcrumbs
Add manual breadcrumbs at key points in your application to capture domain-specific context:
# In a controller
def checkout
RailsErrorDashboard.add_breadcrumb("checkout started", { cart_id: @cart.id, items: @cart.items.count })
process_payment(@cart)
RailsErrorDashboard.add_breadcrumb("payment processed", { provider: "stripe", amount: @cart.total })
rescue => e
# Breadcrumbs captured automatically β shows the trail leading to the error
raise
end
Custom breadcrumbs appear alongside automatically-captured events (SQL, controller, cache) in the error detail page. Requires config.enable_breadcrumbs = true.
Sampling and Filtering
Control which errors are logged to reduce noise and storage.
Sampling Rate
Log only a percentage of errors (useful for high-traffic apps):
RailsErrorDashboard.configure do |config|
# Log 10% of errors
config.sampling_rate = 0.1
# Log 50% of errors
config.sampling_rate = 0.5
# Log all errors (default)
config.sampling_rate = 1.0
end
Ignore Specific Exceptions
Completely ignore certain error types:
config.ignored_exceptions = [
'ActionController::RoutingError',
'ActiveRecord::RecordNotFound',
'ActionController::InvalidAuthenticityToken'
]
Conditional Logging
Use a proc for complex filtering:
config.should_log_error = ->(exception, context) do
# Don't log in test environment
return false if Rails.env.test?
# Don't log bot requests
return false if context[:user_agent]&.match?(/bot|crawler|spider/i)
# Don't log known third-party errors
return false if exception.is_a?(Faraday::TimeoutError)
# Log everything else
true
end
Custom Notifications
Custom Notification Channels
Add your own notification logic:
RailsErrorDashboard.configure do |config|
config.on_error_logged do |error_log|
# Custom notification logic
if error_log.critical?
CustomNotifier.alert(
message: "Critical error: #{error_log.error_type}",
error_id: error_log.id
)
end
end
end
Conditional Notifications
Only notify for certain errors:
config.on_error_logged do |error_log|
# Only notify for payment errors
if error_log.error_type.include?('Payment')
PaymentTeam.notify(error_log)
end
# Only notify during business hours
if Time.current.hour.between?(9, 17)
SlackNotifier.send(error_log)
end
end
Custom Slack Format
Customize Slack message format:
# Override in your own job
class CustomSlackNotification < RailsErrorDashboard::SlackErrorNotificationJob
def build_payload(error_log)
{
text: "π¨ #{error_log.error_type}",
blocks: [
{
type: "section",
text: {
type: "mrkdwn",
text: "*Error*: #{error_log.error_type}\n*Message*: #{error_log.message}"
}
},
# Your custom blocks
]
}
end
end
# Use your custom job
config.on_error_logged do |error_log|
CustomSlackNotification.perform_later(error_log.id)
end
UI Customization
Custom Styles
Override the dashboard CSS:
/* app/assets/stylesheets/rails_error_dashboard_custom.css */
.rails-error-dashboard {
--primary-color: #FF6B6B;
--success-color: #51CF66;
--danger-color: #FF6B6B;
}
.error-card {
border-left: 4px solid var(--primary-color);
}
Include in your application:
# config/initializers/assets.rb
Rails.application.config.assets.precompile += %w[rails_error_dashboard_custom.css]
Custom Views
Override dashboard views by creating files in your app:
app/
βββ views/
βββ rails_error_dashboard/
βββ errors/
βββ index.html.erb # Override error list
βββ show.html.erb # Override error detail
βββ _error_card.html.erb # Override error card partial
Example custom index:
<!-- app/views/rails_error_dashboard/errors/index.html.erb -->
<h1>My Custom Error Dashboard</h1>
<% @errors.each do |error| %>
<div class="custom-error-card">
<%= link_to error.error_type, error_path(error) %>
<span class="badge"><%= error.platform %></span>
</div>
<% end %>
Custom Helper Methods
Add your own helpers:
# app/helpers/rails_error_dashboard/application_helper.rb
module RailsErrorDashboard
module ApplicationHelper
def custom_error_badge(error)
color = error.critical? ? 'red' : 'yellow'
content_tag(:span, error.severity, class: "badge-#{color}")
end
def formatted_backtrace(error)
error.backtrace.first(5).join("\n")
end
end
end
Database Customization
Use Separate Database
For large applications, use a separate database for error logs:
# config/database.yml
production:
primary:
<<: *default
database: my_app_production
error_logs:
<<: *default
database: my_app_errors_production
migrations_paths: db/error_logs_migrate
Enable in configuration:
RailsErrorDashboard.configure do |config|
config.use_separate_database = true
end
See Database Options Guide for details.
Custom Retention Policy
Automatically delete old errors:
# lib/tasks/error_cleanup.rake
namespace :errors do
desc 'Delete errors older than 90 days'
task cleanup: :environment do
cutoff = 90.days.ago
RailsErrorDashboard::ErrorLog.where('occurred_at < ?', cutoff).delete_all
puts "Deleted errors older than #{cutoff}"
end
end
Schedule with cron:
# config/schedule.rb (with whenever gem)
every 1.day, at: '3:00 am' do
rake 'errors:cleanup'
end
Custom Indexes
Add indexes for your query patterns:
# db/migrate/XXXXXX_add_custom_error_indexes.rb
class AddCustomErrorIndexes < ActiveRecord::Migration[7.0]
def change
add_index :rails_error_dashboard_error_logs, [:app_version, :occurred_at]
add_index :rails_error_dashboard_error_logs, [:user_id, :resolved]
end
end
Advanced Customization
Custom Error Reporter
Replace the default error reporter:
class CustomErrorReporter
def self.report(exception, context = {})
# Your custom error reporting logic
RailsErrorDashboard::Commands::LogError.call(
error_type: exception.class.name,
message: exception.message,
backtrace: exception.backtrace,
**context
)
# Also send to external service
Sentry.capture_exception(exception)
end
end
# Use it in your application
begin
# risky code
rescue => e
CustomErrorReporter.report(e, user_id: current_user.id)
end
Custom Middleware
Add custom error catching middleware:
class CustomErrorCatcher
def initialize(app)
@app = app
end
def call(env)
@app.call(env)
rescue => exception
# Custom error handling
context = {
path: env['PATH_INFO'],
method: env['REQUEST_METHOD'],
custom_field: extract_custom_data(env)
}
RailsErrorDashboard::ErrorReporter.report(exception, context)
raise # Re-raise to let Rails handle it
end
private
def extract_custom_data(env)
# Your custom logic
end
end
# Add to middleware stack
config.middleware.use CustomErrorCatcher
Plugin Development
Create custom plugins for integrations:
# lib/rails_error_dashboard/plugins/jira_plugin.rb
module RailsErrorDashboard
module Plugins
class JiraPlugin < Plugin
on :error_logged do |error_log|
create_jira_ticket(error_log) if error_log.critical?
end
def create_jira_ticket(error_log)
JIRA::Client.new.Issue.create(
summary: error_log.error_type,
description: error_log.message,
priority: 'High'
)
end
end
end
end
See Plugin System Guide for details.
Configuration Reference
All Configuration Options
RailsErrorDashboard.configure do |config|
# Authentication
config.username = "admin"
config.password = "secure_password"
# Performance
config.async_logging = true
config.async_adapter = :sidekiq
config.max_backtrace_lines = 50
config.sampling_rate = 1.0
# Filtering
config.ignored_exceptions = []
# Severity
config.custom_severity_rules = {}
# Notifications
config.enable_slack_notifications = false
config.slack_webhook_url = nil
config.enable_email_notifications = false
config.notification_email = nil
config.enable_discord_notifications = false
config.discord_webhook_url = nil
config.enable_pagerduty_notifications = false
config.pagerduty_integration_key = nil
config.enable_webhook_notifications = false
config.webhook_urls = []
# Baseline Alerts (Advanced)
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
# Database
config.use_separate_database = false
config.user_model = "User"
# UI
config.dashboard_base_url = "http://localhost:3000"
# Developer Tools (v0.3+)
config.enable_breadcrumbs = false
config.enable_system_health = false
config.enable_source_code_integration = false
config.enable_git_blame = false
# Deep Debugging (v0.4)
config.enable_local_variables = false
config.enable_instance_variables = false
config.detect_swallowed_exceptions = false # Requires Ruby 3.3+
config.enable_diagnostic_dump = false
config.enable_rack_attack_tracking = false # Requires breadcrumbs
config.enable_crash_capture = false
end
Examples
Example 1: E-commerce Setup
RailsErrorDashboard.configure do |config|
# Security
config.username = ENV['ERROR_DASHBOARD_USERNAME']
config.password = ENV['ERROR_DASHBOARD_PASSWORD']
# Performance (high traffic)
config.async_logging = true
config.async_adapter = :sidekiq
config.sampling_rate = 0.5 # Log 50% of errors
# Critical errors
config.custom_severity_rules = {
'PaymentError' => :critical,
'CheckoutError' => :critical,
'InventoryError' => :high,
'ShippingError' => :high
}
# Notifications
config.enable_slack_notifications = true
config.slack_webhook_url = ENV['SLACK_WEBHOOK_URL']
config.enable_pagerduty_notifications = true
config.pagerduty_integration_key = ENV['PAGERDUTY_KEY']
# Context
config.add_error_context do |context|
context[:checkout_step] = context[:request]&.params&.dig(:step)
context[:cart_value] = context[:user]&.cart&.total
context
end
end
Example 2: SaaS Application
RailsErrorDashboard.configure do |config|
config.async_logging = true
# Severity by plan
config.on_error_logged do |error_log|
if error_log.user&.subscription&.enterprise?
# Notify immediately for enterprise customers
PagerDuty.trigger(error_log)
end
end
# Context
config.add_error_context do |context|
if context[:user]
context[:subscription_plan] = context[:user].subscription&.plan
context[:account_id] = context[:user].account_id
end
context
end
end
Further Reading
- Configuration Guide - Complete reference
- Plugin System - Build custom plugins
- API Reference - Full API documentation
- Database Options - Separate database setup
Questions? Check the documentation or open an issue.