rails_error_dashboard 0.3.1 → 0.4.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (41) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +236 -841
  3. data/app/controllers/rails_error_dashboard/errors_controller.rb +89 -0
  4. data/app/jobs/rails_error_dashboard/swallowed_exception_flush_job.rb +32 -0
  5. data/app/models/rails_error_dashboard/diagnostic_dump.rb +14 -0
  6. data/app/models/rails_error_dashboard/swallowed_exception.rb +38 -0
  7. data/app/views/layouts/rails_error_dashboard.html.erb +21 -0
  8. data/app/views/rails_error_dashboard/errors/_instance_variables.html.erb +55 -0
  9. data/app/views/rails_error_dashboard/errors/_local_variables.html.erb +46 -0
  10. data/app/views/rails_error_dashboard/errors/_sidebar_metadata.html.erb +48 -0
  11. data/app/views/rails_error_dashboard/errors/diagnostic_dumps.html.erb +182 -0
  12. data/app/views/rails_error_dashboard/errors/rack_attack_summary.html.erb +133 -0
  13. data/app/views/rails_error_dashboard/errors/show.html.erb +4 -0
  14. data/app/views/rails_error_dashboard/errors/swallowed_exceptions.html.erb +126 -0
  15. data/config/routes.rb +4 -0
  16. data/db/migrate/20251223000000_create_rails_error_dashboard_complete_schema.rb +33 -0
  17. data/db/migrate/20260306000001_add_local_variables_to_error_logs.rb +13 -0
  18. data/db/migrate/20260306000002_add_instance_variables_to_error_logs.rb +7 -0
  19. data/db/migrate/20260306000003_create_rails_error_dashboard_swallowed_exceptions.rb +34 -0
  20. data/db/migrate/20260307000001_create_rails_error_dashboard_diagnostic_dumps.rb +17 -0
  21. data/lib/generators/rails_error_dashboard/install/install_generator.rb +32 -0
  22. data/lib/generators/rails_error_dashboard/install/templates/initializer.rb +47 -0
  23. data/lib/rails_error_dashboard/commands/flush_swallowed_exceptions.rb +103 -0
  24. data/lib/rails_error_dashboard/commands/log_error.rb +68 -0
  25. data/lib/rails_error_dashboard/configuration.rb +122 -0
  26. data/lib/rails_error_dashboard/engine.rb +24 -0
  27. data/lib/rails_error_dashboard/queries/dashboard_stats.rb +32 -11
  28. data/lib/rails_error_dashboard/queries/rack_attack_summary.rb +90 -0
  29. data/lib/rails_error_dashboard/queries/swallowed_exception_summary.rb +97 -0
  30. data/lib/rails_error_dashboard/services/breadcrumb_collector.rb +12 -0
  31. data/lib/rails_error_dashboard/services/crash_capture.rb +234 -0
  32. data/lib/rails_error_dashboard/services/diagnostic_dump_generator.rb +98 -0
  33. data/lib/rails_error_dashboard/services/local_variable_capturer.rb +207 -0
  34. data/lib/rails_error_dashboard/services/swallowed_exception_tracker.rb +277 -0
  35. data/lib/rails_error_dashboard/services/system_health_snapshot.rb +33 -0
  36. data/lib/rails_error_dashboard/services/variable_serializer.rb +326 -0
  37. data/lib/rails_error_dashboard/subscribers/rack_attack_subscriber.rb +94 -0
  38. data/lib/rails_error_dashboard/version.rb +1 -1
  39. data/lib/rails_error_dashboard.rb +9 -0
  40. data/lib/tasks/error_dashboard.rake +34 -0
  41. metadata +23 -2
data/README.md CHANGED
@@ -6,11 +6,7 @@
6
6
  [![Tests](https://github.com/AnjanJ/rails_error_dashboard/workflows/Tests/badge.svg)](https://github.com/AnjanJ/rails_error_dashboard/actions)
7
7
  [![Buy Me A Coffee](https://img.shields.io/badge/Buy%20Me%20A%20Coffee-support-yellow?logo=buymeacoffee)](https://buymeacoffee.com/anjanj)
8
8
 
9
- ## Self-hosted Rails error monitoring — free, forever.
10
-
11
- **Own your errors. Own your stack. Zero monthly fees.**
12
-
13
- A fully open-source, self-hosted error dashboard for solo founders, indie hackers, and small teams who want complete control without the SaaS bills.
9
+ **Self-hosted Rails error monitoring — free, forever.**
14
10
 
15
11
  ```ruby
16
12
  gem 'rails_error_dashboard'
@@ -18,19 +14,19 @@ gem 'rails_error_dashboard'
18
14
 
19
15
  **5-minute setup** · **Works out-of-the-box** · **100% Rails + Postgres** · **No vendor lock-in**
20
16
 
21
- 📖 **[Full Documentation](https://anjanj.github.io/rails_error_dashboard/)** · 🎮 **[Live Demo](https://rails-error-dashboard.anjan.dev)** · 💎 **[RubyGems](https://rubygems.org/gems/rails_error_dashboard)**
17
+ [Full Documentation](https://anjanj.github.io/rails_error_dashboard/) · [Live Demo](https://rails-error-dashboard.anjan.dev) · [RubyGems](https://rubygems.org/gems/rails_error_dashboard)
22
18
 
23
- ### 🎮 Try the Live Demo
19
+ ---
24
20
 
25
- **See it in action:** [https://rails-error-dashboard.anjan.dev](https://rails-error-dashboard.anjan.dev)
21
+ ### Try the Live Demo
26
22
 
27
- Username: `gandalf` · Password: `youshallnotpass`
23
+ **[rails-error-dashboard.anjan.dev](https://rails-error-dashboard.anjan.dev)** — Username: `gandalf` · Password: `youshallnotpass`
28
24
 
29
- Experience the full dashboard with 480+ realistic Rails errors, LOTR-themed demo data, cause chains, enriched context, auto-reopened errors, and all features enabled.
25
+ > **Beta Software** Functional and tested (2,600+ tests passing), but the API may change before v1.0. Supports Rails 7.0-8.1 and Ruby 3.2-4.0.
30
26
 
31
27
  ### Screenshots
32
28
 
33
- **Dashboard Overview** — Real-time error stats, severity breakdown, and trend charts at a glance.
29
+ **Dashboard Overview** — Real-time error stats, severity breakdown, and trend charts.
34
30
 
35
31
  ![Dashboard Overview](docs/images/dashboard-overview.png)
36
32
 
@@ -38,249 +34,268 @@ Experience the full dashboard with 480+ realistic Rails errors, LOTR-themed demo
38
34
 
39
35
  ![Error Detail](docs/images/error-detail.png)
40
36
 
41
- **Analytics** — Error trends, platform health, correlation insights, and pattern detection.
42
-
43
- ![Analytics](docs/images/analytics.png)
37
+ ---
44
38
 
45
- **Deprecation Warnings** Aggregate deprecation warnings across all errors with occurrence counts and affected error links.
39
+ ## Who This Is For
46
40
 
47
- ![Deprecation Warnings](docs/images/deprecations.png)
41
+ - **Solo bootstrappers** who need professional error tracking without recurring costs
42
+ - **Indie SaaS founders** building profitable apps on tight budgets
43
+ - **Small dev teams** (2-5 people) who hate SaaS bloat
44
+ - **Privacy-conscious apps** that need to keep error data on their own servers
45
+ - **Side projects** that might become real businesses
48
46
 
49
- **N+1 Query Patterns** — Cross-error N+1 detection grouped by SQL fingerprint.
47
+ ## What It Replaces
50
48
 
51
- ![N+1 Query Patterns](docs/images/n-plus-one-queries.png)
49
+ | Before | After |
50
+ |--------|-------|
51
+ | $29-99/month for error monitoring | $0/month — runs on your existing Rails server |
52
+ | Sensitive error data sent to third parties | All data stays on your infrastructure |
53
+ | SaaS pricing tiers and usage limits | Unlimited errors, unlimited projects |
54
+ | Vendor lock-in with proprietary APIs | 100% open source, fully portable |
55
+ | Complex SDK setup and external services | 5-minute Rails Engine installation |
56
+ | Pay extra for local variable capture (Sentry) | Local + instance variables included free |
57
+ | No tool detects silently rescued exceptions | Swallowed exception detection built in |
52
58
 
53
- **Cache Health** — Per-error cache performance sorted worst-first.
59
+ ---
54
60
 
55
- ![Cache Health](docs/images/cache-health.png)
61
+ ## Features
56
62
 
57
- **Job Health** Background job queue stats across errors, sorted by failed count.
63
+ ### Core (Always Enabled)
58
64
 
59
- ![Job Health](docs/images/job-health.png)
65
+ Error capture from controllers, jobs, and middleware. Beautiful Bootstrap 5 dashboard with dark/light mode, search, filtering, and real-time updates. Analytics with trend charts, severity breakdown, and spike detection. Workflow management with assignment, priority, snooze, comments, and batch operations. Security via HTTP Basic Auth or custom lambda (Devise, Warden, session-based). Exception cause chains, enriched HTTP context, custom fingerprinting, CurrentAttributes integration, auto-reopen on recurrence, and sensitive data filtering — all built in.
60
66
 
61
- **Database Health** — Connection pool utilization, PostgreSQL table stats, and per-error stress scores.
67
+ ### Optional Features
62
68
 
63
- ![Database Health](docs/images/database-health.png)
69
+ <details>
70
+ <summary><strong>Breadcrumbs — Request Activity Trail</strong></summary>
64
71
 
65
- ---
72
+ See exactly what happened before the crash — SQL queries, controller actions, cache operations, job executions, and mailer deliveries captured automatically via `ActiveSupport::Notifications`.
66
73
 
67
- ### ⚠️ BETA SOFTWARE
68
- This Rails Engine is in beta and under active development. While functional and tested (2,226+ tests passing, including browser-based system tests), the API may change before v1.0.0. Use in production at your own discretion.
74
+ - Automatic capture — zero config beyond the enable flag
75
+ - N+1 query detection with aggregate patterns page
76
+ - Deprecation warnings with aggregate view
77
+ - Custom breadcrumbs via `RailsErrorDashboard.add_breadcrumb("checkout started", { cart_id: 123 })`
78
+ - Safe by design — fixed-size ring buffer, thread-local, every subscriber wrapped in rescue
69
79
 
70
- **Supports**: Rails 7.0 - 8.1 | Ruby 3.2 - 4.0
80
+ ```ruby
81
+ config.enable_breadcrumbs = true
82
+ ```
71
83
 
72
- ---
84
+ [Complete documentation →](docs/FEATURES.md#breadcrumbs--request-activity-trail-new)
85
+ </details>
73
86
 
74
- ## 🎯 Who This Is For
87
+ <details>
88
+ <summary><strong>System Health Snapshot</strong></summary>
75
89
 
76
- **Solo bootstrappers** who need professional error tracking without recurring costs
90
+ Know your app's runtime state at the moment of failure — GC stats, process memory, thread count, connection pool utilization, Puma thread stats, RubyVM cache health, and YJIT compilation stats captured automatically.
77
91
 
78
- **Indie SaaS founders** building profitable apps on tight budgets
92
+ - Sub-millisecond total snapshot, every metric individually rescue-wrapped
93
+ - No ObjectSpace scanning, no Thread backtraces, no subprocess calls
94
+ - RubyVM.stat: constant cache invalidations, shape cache stats
95
+ - YJIT runtime stats: compiled iseqs, invalidation count, code region sizes
79
96
 
80
- ✓ **Small dev teams** (2-5 people) who hate SaaS bloat
97
+ ```ruby
98
+ config.enable_system_health = true
99
+ ```
81
100
 
82
- **Privacy-conscious apps** that need to keep error data on their own servers
101
+ [Complete documentation →](docs/FEATURES.md#system-health-snapshot-new)
102
+ </details>
83
103
 
84
- ✓ **Side projects** that might become real businesses
104
+ <details>
105
+ <summary><strong>N+1 Detection + Deprecation Warnings</strong></summary>
85
106
 
86
- ---
107
+ Cross-error N+1 detection grouped by SQL fingerprint, and aggregate deprecation warnings with occurrence counts.
87
108
 
88
- ## 💰 What It Replaces
109
+ ![Deprecation Warnings](docs/images/deprecations.png)
89
110
 
90
- | Before | After |
91
- |--------|-------|
92
- | Pay $29-99/month for error monitoring | $0/month - runs on your existing Rails server |
93
- | Send sensitive error data to third parties | Keep all data on your infrastructure |
94
- | Fight with SaaS pricing tiers and limits | Unlimited errors, unlimited projects |
95
- | Vendor lock-in with proprietary APIs | 100% open source, fully portable |
96
- | Complex setup with SDKs and external services | 5-minute Rails Engine installation |
111
+ ![N+1 Query Patterns](docs/images/n-plus-one-queries.png)
97
112
 
98
- ---
113
+ Requires breadcrumbs to be enabled.
99
114
 
100
- ## 🚀 Why Choose Rails Error Dashboard
115
+ [Complete documentation →](docs/FEATURES.md#n1-query-detection)
116
+ </details>
101
117
 
102
- **"Install once, own it forever"**
118
+ <details>
119
+ <summary><strong>Operational Health Panels — Jobs, Database, Cache</strong></summary>
103
120
 
104
- - **Zero recurring costs** - One-time setup, runs on your existing infrastructure
105
- - ✅ **5-minute installation** - Mount the Rails Engine, run migrations, done
106
- - ✅ **Works immediately** - Automatic error capture from Rails controllers, jobs, models
107
- - ✅ **Beautiful UI** - Professional dashboard you can show to clients
108
- - ✅ **Full control** - Your data stays on your server, modify anything you want
109
- - ✅ **No surprises** - Open source MIT license, no hidden fees or limits
121
+ **Job Health** — Auto-detects Sidekiq, SolidQueue, or GoodJob. Per-error table with adapter badge, failed count (color-coded), sorted worst-first.
110
122
 
111
- **Built for developers who:**
112
- - Want professional error monitoring without the SaaS tax
113
- - Need to debug production issues without paying per error
114
- - Value data privacy and server ownership
115
- - Prefer simple, Rails-native solutions
123
+ ![Job Health](docs/images/job-health.png)
116
124
 
117
- ---
125
+ **Database Health** — PgHero-style live PostgreSQL stats (table sizes, unused indexes, dead tuples, vacuum timestamps) plus historical connection pool data from error snapshots.
118
126
 
119
- ## ✨ Features
127
+ ![Database Health](docs/images/database-health.png)
120
128
 
121
- ### Core Features (Always Enabled)
129
+ **Cache Health** Per-error cache performance sorted worst-first.
122
130
 
123
- #### 🎯 Complete Error Tracking
124
- Automatic error capture from Rails controllers, jobs, and middleware. Frontend & mobile support for React, React Native, Vue, Angular, Flutter. Platform detection (iOS/Android/Web/API), user context tracking, full stack traces.
131
+ ![Cache Health](docs/images/cache-health.png)
125
132
 
126
- #### 📊 Beautiful Dashboard
127
- Modern Bootstrap 5 UI with dark/light mode, responsive design, real-time statistics, search and filtering, fast pagination. Overview dashboard with critical alerts, error trend charts, and platform health summary.
133
+ [Complete documentation →](docs/FEATURES.md#job-health-page)
134
+ </details>
128
135
 
129
- #### 📈 Analytics & Insights
130
- 7-day trend charts, severity breakdown, spike detection, resolution rate tracking, user impact analysis. Comprehensive analytics page with hourly patterns, mobile vs API breakdowns, and top affected users.
136
+ <details>
137
+ <summary><strong>Source Code Integration + Git Blame</strong></summary>
131
138
 
132
- #### 🔧 Workflow Management
133
- Error assignment and status tracking, priority levels (critical/high/medium/low), snooze functionality, comment threads, batch operations (bulk resolve/delete), resolution tracking with references.
139
+ View actual source code directly in error backtraces with +/-7 lines of context. Git blame shows who last modified the code, when, and the commit message. Repository links jump to GitHub/GitLab/Bitbucket at the exact line.
134
140
 
135
- #### 🔒 Security & Privacy
136
- HTTP Basic Auth or custom authentication via `config.authenticate_with` lambda (Devise, Warden, session-based — runs in controller context with access to `warden`, `session`, `request`). Environment-based settings, optional separate database for isolation. Your data stays on your server - no third-party access.
141
+ ```ruby
142
+ config.enable_source_code_integration = true
143
+ config.enable_git_blame = true
144
+ ```
137
145
 
138
- ### Optional Features (Choose During Install)
146
+ [Complete documentation →](docs/SOURCE_CODE_INTEGRATION.md)
147
+ </details>
139
148
 
140
- #### 🚨 Multi-Channel Notifications
149
+ <details>
150
+ <summary><strong>Error Replay — Copy as cURL / RSpec</strong></summary>
141
151
 
142
- - **Slack** - Rich formatted messages with error context and direct dashboard links
143
- - **Email** - HTML formatted alerts with full error details
144
- - **Discord** - Embedded messages with severity color coding
145
- - **PagerDuty** - Critical error escalation with incident management
146
- - **Webhooks** - Custom integrations with any service (JSON payloads)
152
+ Replay failing requests with one click. Copy the request as a cURL command or generate an RSpec test from the captured error context.
147
153
 
148
- #### Performance Optimizations
154
+ [Complete documentation →](docs/FEATURES.md#error-details-page)
155
+ </details>
149
156
 
150
- - **Async Logging** - Non-blocking error capture using ActiveJob (Sidekiq/SolidQueue/Async)
151
- - **Error Sampling** - Reduce storage by sampling high-frequency errors
152
- - **Backtrace Limiting** - Save 70-90% storage with smart truncation
153
- - **Separate Database** - Isolate error data for better performance
154
- - **Database Indexes** - Composite indexes and PostgreSQL GIN full-text search
157
+ <details>
158
+ <summary><strong>Notifications Slack, Discord, PagerDuty, Email, Webhooks</strong></summary>
155
159
 
156
- #### 🧠 Advanced Analytics (7 Powerful Features)
160
+ Multi-channel alerting with severity filters, per-error cooldown, and milestone threshold alerts to prevent alert fatigue.
157
161
 
158
- **1. Baseline Anomaly Alerts** 🔔
159
- Automatically detect unusual error rate spikes using statistical analysis (mean + std dev). Get proactive notifications when errors exceed expected baselines with intelligent cooldown to avoid alert fatigue.
162
+ ```ruby
163
+ config.enable_slack_notifications = true
164
+ config.slack_webhook_url = ENV['SLACK_WEBHOOK_URL']
165
+ ```
160
166
 
161
- **2. Fuzzy Error Matching** 🔍
162
- Find similar errors across different error hashes using Jaccard similarity (70%) and Levenshtein distance (30%). Discover related errors that share common root causes even when they manifest differently.
167
+ [Notification setup guide →](docs/guides/NOTIFICATIONS.md)
168
+ </details>
163
169
 
164
- **3. Co-occurring Errors** 🔗
165
- Detect errors that happen together within configurable time windows (default: 5 minutes). Identify patterns where one error frequently triggers another, helping you prioritize fixes.
170
+ <details>
171
+ <summary><strong>Advanced Analytics</strong></summary>
166
172
 
167
- **4. Error Cascade Detection** ⛓️
168
- Identify error chains (A causes B causes C) with probability calculations and average delays. Visualize parent→child relationships to understand cascading failures and fix root causes.
173
+ ![Analytics](docs/images/analytics.png)
169
174
 
170
- **5. Error Correlation Analysis** 📊
171
- Correlate errors with app versions, git commits, and users. Find problematic releases, identify users affected by multiple error types, and detect time-based patterns.
175
+ Seven analysis engines built in:
172
176
 
173
- **6. Platform Comparison** 📱
174
- Compare iOS vs Android vs Web health metrics side-by-side. Platform-specific error rates, severity distributions, resolution times, and stability scores (0-100).
177
+ 1. **Baseline Anomaly Alerts** — Statistical spike detection (mean + std dev) with intelligent cooldown
178
+ 2. **Fuzzy Error Matching** Jaccard similarity + Levenshtein distance to find related errors
179
+ 3. **Co-occurring Errors** — Detect errors that happen together within configurable time windows
180
+ 4. **Error Cascade Detection** — Identify chains (A causes B causes C) with probability and delays
181
+ 5. **Error Correlation Analysis** — Correlate errors with app versions, git commits, and users
182
+ 6. **Platform Comparison** — iOS vs Android vs Web health metrics side-by-side
183
+ 7. **Occurrence Pattern Detection** — Cyclical patterns (business hours, weekends) and burst detection
175
184
 
176
- **7. Occurrence Pattern Detection** 📈
177
- Detect cyclical patterns (business hours, nighttime, weekend rhythms) and error bursts (many errors in short time). Understand when and how your errors happen.
185
+ [Complete documentation →](docs/FEATURES.md#advanced-analytics-features)
186
+ </details>
178
187
 
179
- **Plus: Developer Insights Dashboard** 💡
180
- Built-in analytics dashboard with severity detection, platform stability scoring, actionable recommendations, and recent error activity summaries (always available, no configuration needed).
188
+ <details>
189
+ <summary><strong>Local Variable + Instance Variable Capture</strong></summary>
181
190
 
182
- #### 🔍 Source Code Integration
191
+ See the exact values of local variables and instance variables at the moment an exception was raised — the most valuable debugging context possible.
183
192
 
184
- **View actual source code directly in error backtraces** - no need to switch to your editor or GitHub.
193
+ - TracePoint(`:raise`) captures locals and ivars before the stack unwinds
194
+ - Configurable limits: max variable count, nesting depth, string truncation length
195
+ - Sensitive data auto-filtered via Rails `filter_parameters` — passwords, tokens, and PII never stored
196
+ - Never stores Binding objects — values extracted immediately, Binding is GC'd
197
+ - Independent config flags: enable one or both
185
198
 
186
- - **Inline Source Code Viewer** - Click "View Source" on any error frame to see the actual code with ±7 lines of context
187
- - **Git Blame Integration** - See who last modified the code, when, and the commit message
188
- - **Repository Links** - Jump directly to GitHub/GitLab/Bitbucket at the exact error line
189
- - **Smart Caching** - Fast performance with 1-hour cache (configurable)
190
- - **Security Controls** - Only shows your app code by default (not gems/frameworks)
199
+ ![Local Variables](docs/images/local-variables.png)
191
200
 
192
201
  ```ruby
193
- config.enable_source_code_integration = true
194
- config.enable_git_blame = true
202
+ config.enable_local_variables = true
203
+ config.enable_instance_variables = true
195
204
  ```
196
205
 
197
- **📖 [Complete documentation →](docs/SOURCE_CODE_INTEGRATION.md)**
206
+ [Complete documentation →](docs/FEATURES.md)
207
+ </details>
198
208
 
199
- #### 🥖 Breadcrumbs — Request Activity Trail (NEW!)
209
+ <details>
210
+ <summary><strong>Swallowed Exception Detection</strong></summary>
200
211
 
201
- **See exactly what happened before the crash**SQL queries, controller actions, cache operations, job executions, and mailer deliveries captured automatically via `ActiveSupport::Notifications`.
212
+ Detect exceptions that are raised but silently rescued the hardest bugs to find. No other error tracker does this.
202
213
 
203
- - **Automatic capture** Zero config beyond the enable flag (Rails already emits the events)
204
- - **Timeline display** Color-coded event list on each error's detail page
205
- - **Deprecation warnings** `deprecation.rails` events captured with caller location
206
- - **N+1 detection** Repeated SQL patterns flagged automatically at display time
207
- - **Custom breadcrumbs** — `RailsErrorDashboard.add_breadcrumb("checkout started", { cart_id: 123 })`
208
- - **Safe by design** — Fixed-size ring buffer, thread-local, every subscriber wrapped in rescue
209
- - **Async-compatible** — Breadcrumbs harvested before background job dispatch
210
- - **Deprecation warnings page** — Aggregate view across all errors at `/errors/deprecations`
211
- - **N+1 query patterns page** — Cross-error N+1 analysis at `/errors/n_plus_one_summary`
212
- - **Cache health page** — App-wide cache performance sorted worst-first at `/errors/cache_health_summary`
214
+ - Uses TracePoint(`:raise`) + TracePoint(`:rescue`) to track exception lifecycle
215
+ - Identifies code paths where exceptions are caught but never logged or re-raised
216
+ - Dashboard page at `/errors/swallowed_exceptions` shows detection counts, locations, and patterns
217
+ - Memory-bounded aggregation with background flush
218
+ - Requires Ruby 3.3+
219
+
220
+ ![Swallowed Exceptions](docs/images/swallowed-exceptions.png)
213
221
 
214
222
  ```ruby
215
- config.enable_breadcrumbs = true
216
- config.breadcrumb_buffer_size = 40 # Max events per request
223
+ config.detect_swallowed_exceptions = true
217
224
  ```
218
225
 
219
- **📖 [Complete documentation →](docs/FEATURES.md#breadcrumbs--request-activity-trail-new)**
226
+ [Complete documentation →](docs/FEATURES.md)
227
+ </details>
228
+
229
+ <details>
230
+ <summary><strong>On-Demand Diagnostic Dump</strong></summary>
220
231
 
221
- #### 💓 System Health Snapshot (NEW!)
232
+ Snapshot your app's entire system state on demand — environment, GC stats, threads, connection pool, memory, job queue health, and more.
222
233
 
223
- **Know your app's runtime state at the moment of failure** — GC stats, process memory, thread count, connection pool utilization, and Puma thread stats captured automatically when errors occur.
234
+ - Trigger via dashboard button or `rake rails_error_dashboard:diagnostic_dump`
235
+ - Dashboard page at `/errors/diagnostic_dumps` with full history
236
+ - Useful for debugging intermittent production issues without reproducing them
224
237
 
225
- - **GC stats** — Heap live/free slots, major GC count, total allocated objects
226
- - **Process memory** — RSS in MB (Linux procfs only, no subprocess/fork)
227
- - **Thread count** — `Thread.list.count` (O(1), safe)
228
- - **Connection pool** — Size, busy, idle, dead, waiting connections
229
- - **Puma stats** — Running threads, max threads, pool capacity, backlog
230
- - **Sub-millisecond** — Total snapshot < 1ms, every metric individually rescue-wrapped
231
- - **Safe by design** — No ObjectSpace scanning, no Thread backtraces, no subprocess calls
238
+ ![Diagnostic Dumps](docs/images/diagnostic-dumps.png)
232
239
 
233
240
  ```ruby
234
- config.enable_system_health = true
241
+ config.enable_diagnostic_dump = true
235
242
  ```
236
243
 
237
- **📖 [Complete documentation →](docs/FEATURES.md#system-health-snapshot-new)**
244
+ [Complete documentation →](docs/FEATURES.md)
245
+ </details>
238
246
 
239
- #### 🏭 Job Health Page
247
+ <details>
248
+ <summary><strong>Rack Attack Event Tracking</strong></summary>
240
249
 
241
- **See background job queue health alongside your errors** auto-detects Sidekiq, SolidQueue, or GoodJob stats captured at error time.
250
+ Track Rack Attack security events (throttles, blocklists, tracks) as breadcrumbs attached to errors, with a dedicated summary page.
242
251
 
243
- - **Per-error table** — Adapter badge, failed count (color-coded), queued/enqueued, other stats
244
- - **Summary cards** Errors with job data, total failed, adapters detected
245
- - **Sorted worst-first** Highest failed count first
252
+ - Captures throttle, blocklist, and track events automatically
253
+ - Dashboard page at `/errors/rack_attack_summary` with event breakdown
254
+ - Requires breadcrumbs to be enabled
246
255
 
247
- **📖 [Complete documentation →](docs/FEATURES.md#job-health-page)**
256
+ ```ruby
257
+ config.enable_rack_attack_tracking = true
258
+ ```
248
259
 
249
- #### 🗄️ Database Health Page
260
+ [Complete documentation →](docs/FEATURES.md)
261
+ </details>
262
+
263
+ <details>
264
+ <summary><strong>Process Crash Capture</strong></summary>
250
265
 
251
- **PgHero-style database health built into the dashboard** live PostgreSQL stats + historical connection pool data from error snapshots.
266
+ Capture unhandled exceptions that crash the Ruby process via an `at_exit` hook the last line of defense.
252
267
 
253
- - **Live stats** (PostgreSQL) Table sizes, unused indexes, dead tuples, vacuum timestamps, connection activity
254
- - **Historical pool data** (all adapters) — Per-error connection pool utilization, sorted by stress score
255
- - **Color-coded** Utilization >=80% danger, >=60% warning; dead/waiting badges
256
- - **Non-PG friendly**SQLite/MySQL still see connection pool stats and historical data
268
+ - Disk-based fallback: writes crash data to disk because the database may be unavailable during shutdown
269
+ - Imported automatically on next boot
270
+ - Captures exception details, backtrace, uptime, GC stats, thread count, and cause chain
271
+ - A self-hosted only feature impossible for SaaS tools
257
272
 
258
- **📖 [Complete documentation →](docs/FEATURES.md#database-health-page)**
273
+ ```ruby
274
+ config.enable_crash_capture = true
275
+ ```
259
276
 
260
- #### 🆕 v0.2 Quick Wins (NEW!)
277
+ [Complete documentation →](docs/FEATURES.md)
278
+ </details>
261
279
 
262
- **11 features that make error tracking smarter, safer, and more actionable:**
280
+ <details>
281
+ <summary><strong>Plugin System</strong></summary>
263
282
 
264
- - **Exception Cause Chains** Automatically captures the full `cause` chain (e.g., `SocketError` `RuntimeError`) so you see root causes, not just wrappers
265
- - **Enriched Context** — Every HTTP error captures `http_method`, `hostname`, `content_type`, and `request_duration_ms` automatically
266
- - **Custom Fingerprint** — Override error grouping with a lambda: group `RecordNotFound` by controller, or any custom logic
267
- - **CurrentAttributes Integration** — Zero-config capture of `Current.user`, `Current.account`, `Current.request_id`
268
- - **Environment Info** — Ruby version, Rails version, gem versions, server, and database adapter captured at error time
269
- - **Sensitive Data Filtering** — Passwords, tokens, secrets, and API keys auto-filtered from error context before storage
270
- - **Auto-Reopen** — Resolved errors automatically reopen when they recur, with a "Reopened" badge in the UI
271
- - **Notification Throttling** — Severity filters, per-error cooldown, and milestone threshold alerts prevent alert fatigue
272
- - **BRIN Indexes** — PostgreSQL BRIN index on `occurred_at` for dramatically faster time-range queries (72KB vs 676MB)
273
- - **Structured Backtrace** — Uses `backtrace_locations` for richer backtrace data with proper path/line/method fields
274
- - **Reduced Dependencies** — Core gem now requires only `rails` + `pagy`; `browser`, `chartkick`, `httparty`, `turbo-rails` are optional
283
+ Event-driven extensibility with hooks for `on_error_logged`, `on_error_resolved`, `on_threshold_exceeded`. Built-in examples for Jira integration, metrics tracking, and audit logging.
275
284
 
276
- #### 🔌 Plugin System
277
- Extensible architecture with event hooks (`on_error_logged`, `on_error_resolved`, `on_threshold_exceeded`). Built-in examples for Jira integration, metrics tracking, audit logging. Easy to create custom plugins - just drop a file in `config/initializers/error_dashboard_plugins/`.
285
+ ```ruby
286
+ class MyPlugin < RailsErrorDashboard::Plugin
287
+ def on_error_logged(error_log)
288
+ # Your custom logic
289
+ end
290
+ end
291
+ ```
278
292
 
279
- **📚 [View complete feature list with examples →](docs/FEATURES.md)**
293
+ [Plugin System guide →](docs/PLUGIN_SYSTEM.md)
294
+ </details>
280
295
 
281
296
  ---
282
297
 
283
- ## 📦 Quick Start
298
+ ## Quick Start
284
299
 
285
300
  ### 1. Add to Gemfile
286
301
 
@@ -296,756 +311,136 @@ rails generate rails_error_dashboard:install
296
311
  rails db:migrate
297
312
  ```
298
313
 
299
- The installer will guide you through optional feature selection:
300
- - **Notifications** (Slack, Email, Discord, PagerDuty, Webhooks)
301
- - **Performance** (Async Logging, Error Sampling, Separate Database)
302
- - **Advanced Analytics** (7 powerful features including baseline alerts, fuzzy matching, platform comparison)
303
-
304
- **All features are opt-in** - choose what you need during installation, or enable/disable them later in the initializer.
305
-
306
- This will:
307
- - Create `config/initializers/rails_error_dashboard.rb` with your selected features
308
- - Copy database migrations
309
- - Mount the engine at `/error_dashboard`
314
+ The installer guides you through optional feature selection — notifications, performance optimizations, advanced analytics. All features are opt-in.
310
315
 
311
316
  ### 3. Visit your dashboard
312
317
 
313
- Start your server and visit:
314
318
  ```
315
319
  http://localhost:3000/error_dashboard
316
320
  ```
317
321
 
318
- **Default credentials:**
319
- - Username: `gandalf`
320
- - Password: `youshallnotpass`
322
+ Default credentials: `gandalf` / `youshallnotpass`
321
323
 
322
- ⚠️ **Change these before production!** Edit `config/initializers/rails_error_dashboard.rb`
324
+ **Change these before production!** Edit `config/initializers/rails_error_dashboard.rb`
323
325
 
324
326
  ### 4. Test it out
325
327
 
326
- Trigger a test error to see it in action:
327
-
328
328
  ```ruby
329
329
  # In Rails console or any controller
330
330
  raise "Test error from Rails Error Dashboard!"
331
331
  ```
332
332
 
333
- The error will appear instantly in your dashboard with full context, backtrace, and platform information.
334
-
335
- **📘 [Full installation guide →](docs/QUICKSTART.md)**
333
+ [Full installation guide →](docs/QUICKSTART.md)
336
334
 
337
335
  ---
338
336
 
339
- ## 🗑️ Uninstalling
340
-
341
- Need to remove Rails Error Dashboard? We've made it simple with both automated and manual options:
342
-
343
- ```bash
344
- # Automated uninstall (recommended)
345
- rails generate rails_error_dashboard:uninstall
346
-
347
- # Keep error data, remove code
348
- rails generate rails_error_dashboard:uninstall --keep-data
349
-
350
- # Show manual instructions only
351
- rails generate rails_error_dashboard:uninstall --manual-only
352
- ```
353
-
354
- The uninstaller will:
355
- - ✅ Show exactly what will be removed
356
- - ✅ Ask for confirmation before making changes
357
- - ✅ Remove initializer, routes, and migrations
358
- - ✅ Optionally drop database tables (with double confirmation)
359
- - ✅ Provide clear next steps
360
-
361
- **📘 [Complete uninstall guide →](docs/UNINSTALL.md)**
362
-
363
- ---
364
-
365
- ## ⚙️ Configuration
366
-
367
- ### Opt-in Feature System
368
-
369
- Rails Error Dashboard uses an **opt-in architecture** - core features (error capture, dashboard UI, analytics) are always enabled, while everything else is disabled by default.
370
-
371
- **Tier 1 Features (Always ON)**:
372
- - ✅ Error capture (controllers, jobs, middleware)
373
- - ✅ Dashboard UI with search and filtering
374
- - ✅ Real-time updates
375
- - ✅ Analytics and trend charts
376
-
377
- **Optional Features (Choose During Install)**:
378
- - 📧 Multi-channel notifications (Slack, Email, Discord, PagerDuty, Webhooks)
379
- - ⚡ Performance optimizations (Async logging, Error sampling)
380
- - 📊 Advanced analytics (Baseline alerts, Fuzzy matching, Platform comparison, and more)
381
-
382
- ### Basic Configuration
383
-
384
- Edit `config/initializers/rails_error_dashboard.rb`:
337
+ ## Configuration
385
338
 
386
339
  ```ruby
387
340
  RailsErrorDashboard.configure do |config|
388
- # ============================================================================
389
- # AUTHENTICATION (Always Required)
390
- # ============================================================================
341
+ # Authentication
391
342
  config.dashboard_username = ENV.fetch('ERROR_DASHBOARD_USER', 'gandalf')
392
343
  config.dashboard_password = ENV.fetch('ERROR_DASHBOARD_PASSWORD', 'youshallnotpass')
393
344
 
394
- # Or use your existing auth (Devise, Warden, etc.) instead of Basic Auth:
345
+ # Or use your existing auth (Devise, Warden, etc.):
395
346
  # config.authenticate_with = -> { warden.authenticated? }
396
347
 
397
- # ============================================================================
398
- # OPTIONAL FEATURES (Enable as needed)
399
- # ============================================================================
400
-
401
- # Slack notifications (if enabled during install)
348
+ # Optional features — enable as needed
402
349
  config.enable_slack_notifications = true
403
350
  config.slack_webhook_url = ENV['SLACK_WEBHOOK_URL']
404
-
405
- # Email notifications (if enabled during install)
406
- config.enable_email_notifications = true
407
- config.notification_email_recipients = ["dev@yourapp.com"]
408
- config.notification_email_from = "errors@yourapp.com"
409
-
410
- # Async logging for better performance (if enabled during install)
411
351
  config.async_logging = true
412
352
  config.async_adapter = :sidekiq # or :solid_queue, :async
413
-
414
- # Advanced analytics features (if enabled during install)
415
- config.enable_baseline_alerts = true
416
- config.enable_similar_errors = true
417
- config.enable_platform_comparison = true
418
353
  end
419
354
  ```
420
355
 
421
- All features can be toggled on/off at any time by editing the initializer.
422
-
423
- ### Environment Variables
424
-
425
- ```bash
426
- # .env
427
- ERROR_DASHBOARD_USER=your_username
428
- ERROR_DASHBOARD_PASSWORD=your_secure_password
429
- SLACK_WEBHOOK_URL=https://hooks.slack.com/services/YOUR/WEBHOOK/URL
430
- DASHBOARD_BASE_URL=https://yourapp.com
431
- ```
356
+ [Complete configuration guide →](docs/guides/CONFIGURATION.md)
432
357
 
433
- **📖 [Complete configuration guide →](docs/guides/CONFIGURATION.md)**
358
+ **Multi-App Support** — Track errors from multiple Rails apps in a single shared database. Auto-detects app name, supports per-app filtering. [Multi-App guide →](docs/MULTI_APP_PERFORMANCE.md)
434
359
 
435
360
  ---
436
361
 
437
- ## 🏢 Multi-App Support
438
-
439
- **Rails Error Dashboard supports logging errors from multiple Rails applications to a single shared database.**
440
-
441
- This is ideal for:
442
- - Managing errors across microservices
443
- - Monitoring production, staging, and development environments separately
444
- - Tracking different apps from a central dashboard
445
- - Organizations running multiple Rails applications
446
-
447
- ### Automatic Configuration
448
-
449
- By default, the dashboard automatically detects your application name from `Rails.application.class.module_parent_name`:
450
-
451
- ```ruby
452
- # BlogApp::Application → "BlogApp"
453
- # AdminPanel::Application → "AdminPanel"
454
- # ApiService::Application → "ApiService"
455
- ```
456
-
457
- **No configuration needed!** Each app will automatically register itself when logging its first error.
458
-
459
- ### Manual Override
460
-
461
- Override the auto-detected name if desired:
462
-
463
- ```ruby
464
- # config/initializers/rails_error_dashboard.rb
465
- RailsErrorDashboard.configure do |config|
466
- config.application_name = "MyCustomAppName"
467
- end
468
- ```
469
-
470
- Or use an environment variable:
471
-
472
- ```bash
473
- # .env
474
- APPLICATION_NAME="Production API"
475
- ```
476
-
477
- This allows you to use different names for different environments:
478
- ```bash
479
- # Production
480
- APPLICATION_NAME="MyApp-Production"
481
-
482
- # Staging
483
- APPLICATION_NAME="MyApp-Staging"
484
-
485
- # Development
486
- APPLICATION_NAME="MyApp-Development"
487
- ```
488
-
489
- ### Shared Database Setup
490
-
491
- All apps must use the same error dashboard database. Configure your `database.yml`:
492
-
493
- ```yaml
494
- # config/database.yml
495
- production:
496
- primary:
497
- database: my_app_production
498
- # ... other connection settings
499
-
500
- error_dashboard:
501
- database: shared_error_dashboard_production
502
- host: error-db.example.com
503
- # ... other connection settings
504
- ```
505
-
506
- Then in your initializer:
507
-
508
- ```ruby
509
- # config/initializers/rails_error_dashboard.rb
510
- RailsErrorDashboard.configure do |config|
511
- config.database = :error_dashboard # Use the shared database
512
- end
513
- ```
514
-
515
- ### Dashboard UI Features
516
-
517
- **Navbar Application Switcher:**
518
- - Quick dropdown to switch between applications
519
- - Shows "All Apps" by default
520
- - Only appears when multiple apps are registered
521
-
522
- **Filter Form:**
523
- - Filter errors by specific application
524
- - Combine with other filters (error type, platform, etc.)
525
- - Active filter pills show current selection
526
-
527
- **Application Column:**
528
- - Displays application name for each error
529
- - Only shown when viewing "All Apps"
530
- - Hidden when filtered to a single app
531
-
532
- ### Per-App Error Tracking
533
-
534
- Errors are tracked independently per application:
535
-
536
- ```ruby
537
- # Same error in different apps creates separate records
538
- # App A: StandardError "Database timeout" → Error #1
539
- # App B: StandardError "Database timeout" → Error #2
540
-
541
- # Each has its own:
542
- # - Occurrence counts
543
- # - Resolution status
544
- # - Comments and history
545
- # - Analytics and trends
546
- ```
547
-
548
- ### API Usage
549
-
550
- When logging errors via API, specify the application:
551
-
552
- ```ruby
553
- RailsErrorDashboard::Commands::LogError.call(
554
- error_type: "TypeError",
555
- message: "Cannot read property 'name' of null",
556
- platform: "iOS",
557
- # ... other parameters
558
- )
559
- # Uses config.application_name automatically
560
- ```
561
-
562
- Or override per-error (advanced):
563
-
564
- ```ruby
565
- # Create application first
566
- app = RailsErrorDashboard::Application.find_or_create_by!(name: "Mobile App")
567
-
568
- # Then create error
569
- RailsErrorDashboard::ErrorLog.create!(
570
- application: app,
571
- error_type: "NetworkError",
572
- message: "Request failed",
573
- # ... other fields
574
- )
575
- ```
576
-
577
- ### Performance & Concurrency
578
-
579
- Multi-app support is designed for high-concurrency scenarios:
580
-
581
- ✅ **Row-level locking** - No table locks, apps write independently
582
- ✅ **Cached lookups** - Application names cached for 1 hour
583
- ✅ **Composite indexes** - Fast filtering on `[application_id, occurred_at]`
584
- ✅ **Per-app deduplication** - Same error in different apps tracked separately
585
- ✅ **No deadlocks** - Scoped locking prevents cross-app conflicts
586
-
587
- **Benchmark**: Tested with 5 apps writing 1000 errors/sec with zero deadlocks.
588
-
589
- ### Rake Tasks
590
-
591
- Manage applications via rake tasks:
592
-
593
- ```bash
594
- # List all registered applications
595
- rails error_dashboard:list_applications
596
-
597
- # Backfill application for existing errors
598
- rails error_dashboard:backfill_application APP_NAME="Legacy App"
599
- ```
600
-
601
- ### Migration Guide
602
-
603
- If you have existing errors before enabling multi-app support:
604
-
605
- 1. Run migrations: `rails db:migrate`
606
- 2. Backfill existing errors:
607
- ```bash
608
- rails error_dashboard:backfill_application APP_NAME="My App"
609
- ```
610
- 3. All existing errors will be assigned to "My App"
611
- 4. New applications will auto-register on first error
612
-
613
- **Zero downtime** - Errors can continue logging during migration.
614
-
615
- ---
616
-
617
- ## 🚀 Usage
618
-
619
- ### Automatic Error Tracking
620
-
621
- Rails Error Dashboard automatically tracks errors from:
622
- - **Controllers** (via Rails error reporting)
623
- - **Background jobs** (ActiveJob, Sidekiq)
624
- - **Rack middleware** (catches everything else)
625
-
626
- No additional code needed! Just install and it works.
627
-
628
- ### Manual Error Logging
629
-
630
- For frontend/mobile apps or custom error logging:
631
-
632
- ```ruby
633
- # From your Rails API
634
- RailsErrorDashboard::Commands::LogError.call(
635
- error_type: "TypeError",
636
- message: "Cannot read property 'name' of null",
637
- backtrace: ["App.js:42", "index.js:12"],
638
- platform: "iOS",
639
- app_version: "2.1.0",
640
- user_id: current_user.id,
641
- context: {
642
- component: "ProfileScreen",
643
- device_model: "iPhone 14 Pro"
644
- }
645
- )
646
- ```
647
-
648
- ### Frontend Integration
649
-
650
- ```javascript
651
- // React Native example
652
- try {
653
- // Your code
654
- } catch (error) {
655
- fetch('https://yourapp.com/api/errors', {
656
- method: 'POST',
657
- headers: { 'Content-Type': 'application/json' },
658
- body: JSON.stringify({
659
- error_type: error.name,
660
- message: error.message,
661
- backtrace: error.stack.split('\n'),
662
- platform: Platform.OS, // 'ios' or 'android'
663
- app_version: VERSION
664
- })
665
- });
666
- }
667
- ```
668
-
669
- **📱 [Mobile app integration guide →](docs/guides/MOBILE_APP_INTEGRATION.md)**
670
-
671
- ---
672
-
673
- ## 🔔 Notifications
674
-
675
- Set up multi-channel notifications in minutes:
676
-
677
- ### Slack
678
- ```ruby
679
- config.enable_slack_notifications = true
680
- config.slack_webhook_url = ENV['SLACK_WEBHOOK_URL']
681
- ```
682
-
683
- ### Discord
684
- ```ruby
685
- config.enable_discord_notifications = true
686
- config.discord_webhook_url = ENV['DISCORD_WEBHOOK_URL']
687
- ```
688
-
689
- ### PagerDuty (Critical Errors Only)
690
- ```ruby
691
- config.enable_pagerduty_notifications = true
692
- config.pagerduty_integration_key = ENV['PAGERDUTY_INTEGRATION_KEY']
693
- ```
694
-
695
- ### Custom Webhooks
696
- ```ruby
697
- config.enable_webhook_notifications = true
698
- config.webhook_urls = ['https://yourapp.com/hooks/errors']
699
- ```
700
-
701
- **🔕 [Notification setup guide →](docs/guides/NOTIFICATIONS.md)**
702
-
703
- ---
704
-
705
- ## 📚 Documentation
362
+ ## Documentation
706
363
 
707
364
  ### Getting Started
708
- - **[Quickstart Guide](docs/QUICKSTART.md)** - Complete 5-minute setup
709
- - **[Configuration](docs/guides/CONFIGURATION.md)** - All configuration options
710
- - **[Mobile App Integration](docs/guides/MOBILE_APP_INTEGRATION.md)** - React Native, Flutter, etc.
365
+ - **[Quickstart Guide](docs/QUICKSTART.md)** 5-minute setup
366
+ - **[Configuration](docs/guides/CONFIGURATION.md)** All configuration options
367
+ - **[Uninstalling](docs/UNINSTALL.md)** Clean removal
711
368
 
712
369
  ### Features
713
- - **[Complete Feature List](docs/FEATURES.md)** - Every feature explained
714
- - **[Notifications](docs/guides/NOTIFICATIONS.md)** - Multi-channel alerting
715
- - **[Batch Operations](docs/guides/BATCH_OPERATIONS.md)** - Bulk resolve/delete
716
- - **[Real-Time Updates](docs/guides/REAL_TIME_UPDATES.md)** - Live dashboard
717
- - **[Error Trend Visualizations](docs/guides/ERROR_TREND_VISUALIZATIONS.md)** - Charts & analytics
370
+ - **[Complete Feature List](docs/FEATURES.md)** Every feature explained
371
+ - **[Notifications](docs/guides/NOTIFICATIONS.md)** Multi-channel alerting
372
+ - **[Source Code Integration](docs/SOURCE_CODE_INTEGRATION.md)** Inline source + git blame
373
+ - **[Batch Operations](docs/guides/BATCH_OPERATIONS.md)** Bulk resolve/delete
374
+ - **[Real-Time Updates](docs/guides/REAL_TIME_UPDATES.md)** Live dashboard
375
+ - **[Error Trends](docs/guides/ERROR_TREND_VISUALIZATIONS.md)** — Charts and analytics
718
376
 
719
377
  ### Advanced
720
- - **[Multi-App Support](docs/MULTI_APP_PERFORMANCE.md)** - Track multiple applications
721
- - **[Plugin System](docs/PLUGIN_SYSTEM.md)** - Build custom integrations
722
- - **[API Reference](docs/API_REFERENCE.md)** - Complete API documentation
723
- - **[Customization Guide](docs/CUSTOMIZATION.md)** - Customize everything
724
- - **[Database Options](docs/guides/DATABASE_OPTIONS.md)** - Separate database setup
725
- - **[Database Optimization](docs/guides/DATABASE_OPTIMIZATION.md)** - Performance tuning
378
+ - **[Multi-App Support](docs/MULTI_APP_PERFORMANCE.md)** Track multiple applications
379
+ - **[Plugin System](docs/PLUGIN_SYSTEM.md)** Build custom integrations
380
+ - **[API Reference](docs/API_REFERENCE.md)** Complete API documentation
381
+ - **[Customization](docs/CUSTOMIZATION.md)** Customize everything
382
+ - **[Database Options](docs/guides/DATABASE_OPTIONS.md)** Separate database setup
383
+ - **[Database Optimization](docs/guides/DATABASE_OPTIMIZATION.md)** Performance tuning
384
+ - **[Mobile App Integration](docs/guides/MOBILE_APP_INTEGRATION.md)** — React Native, Flutter, etc.
385
+ - **[FAQ](docs/FAQ.md)** — Common questions answered
726
386
 
727
- ### Development
728
- - **[Testing](docs/development/TESTING.md)** - Multi-version testing
729
- - **[Smoke Tests](SMOKE_TESTS.md)** - Deployment verification tests
730
-
731
- **📖 [View all documentation →](docs/README.md)**
387
+ [View all documentation →](docs/README.md)
732
388
 
733
389
  ---
734
390
 
735
- ## 🏗️ Architecture
736
-
737
- Built with **Service Objects + CQRS Principles**:
738
- - **Commands**: LogError, ResolveError, BatchOperations (write operations)
739
- - **Queries**: ErrorsList, DashboardStats, Analytics (read operations)
740
- - **Value Objects**: ErrorContext (immutable data)
741
- - **Services**: PlatformDetector, SimilarityCalculator (business logic)
742
- - **Plugins**: Event-driven extensibility
391
+ ## Architecture
743
392
 
744
- Clean, maintainable, testable architecture you can understand and modify.
393
+ Built with **CQRS (Command/Query Responsibility Segregation)**:
394
+ - **Commands** — LogError, ResolveError, BatchOperations (writes)
395
+ - **Queries** — ErrorsList, DashboardStats, Analytics (reads)
396
+ - **Services** — PlatformDetector, SimilarityCalculator (business logic)
397
+ - **Plugins** — Event-driven extensibility
745
398
 
746
399
  ---
747
400
 
748
- ## 🧪 Testing
401
+ ## Testing
749
402
 
750
- 2,100+ tests covering unit, integration, and browser-based system tests.
751
-
752
- ### Running Tests
753
-
754
- ```bash
755
- # Run all tests
756
- bundle exec rspec
757
-
758
- # Run unit/integration tests only (fast)
759
- bundle exec rspec --exclude-pattern "spec/system/**/*"
760
-
761
- # Run system tests only (requires Chrome)
762
- bundle exec rspec spec/system/
763
-
764
- # Run with visible browser for debugging
765
- HEADLESS=false bundle exec rspec spec/system/
766
-
767
- # Run with Chrome DevTools inspector
768
- INSPECTOR=true HEADLESS=false bundle exec rspec spec/system/
769
-
770
- # Run with coverage report
771
- COVERAGE=true bundle exec rspec
772
- ```
773
-
774
- ### System Tests (Browser-Based)
775
-
776
- System tests use **Capybara + Cuprite** (Chrome DevTools Protocol) to simulate real user interactions — opening modals, filling forms, clicking buttons, and verifying page content. No Selenium or chromedriver management needed.
777
-
778
- **Requirements:** Chrome or Chromium installed locally.
403
+ 2,600+ tests covering unit, integration, and browser-based system tests.
779
404
 
780
405
  ```bash
781
- # Verify Chrome is available
782
- which google-chrome || which chromium-browser || which chromium
783
-
784
- # macOS: Chrome is typically at /Applications/Google Chrome.app
406
+ bundle exec rspec # Full suite
407
+ bundle exec rspec spec/system/ # System tests (Capybara + Cuprite)
408
+ HEADLESS=false bundle exec rspec spec/system/ # Visible browser
785
409
  ```
786
410
 
787
411
  ---
788
412
 
789
- ## 🤝 Contributing
790
-
791
- We welcome contributions! Here's how to get started:
413
+ ## Contributing
792
414
 
793
415
  1. Fork the repository
794
416
  2. Create your feature branch (`git checkout -b feature/amazing-feature`)
795
- 3. Write tests for your changes
796
- 4. Ensure all tests pass (`bundle exec rspec`)
797
- 5. Commit your changes (`git commit -m 'Add amazing feature'`)
798
- 6. Push to the branch (`git push origin feature/amazing-feature`)
799
- 7. Open a Pull Request
800
-
801
- ### Development Setup
417
+ 3. Write tests, ensure all pass (`bundle exec rspec`)
418
+ 4. Commit and push
419
+ 5. Open a Pull Request
802
420
 
803
421
  ```bash
804
422
  git clone https://github.com/AnjanJ/rails_error_dashboard.git
805
423
  cd rails_error_dashboard
806
-
807
- # Automated setup (installs deps, hooks, runs tests)
808
- bin/setup
809
-
810
- # Or manual setup
811
- bundle install
812
- bundle exec lefthook install # Installs git hooks
813
- bundle exec rspec
814
- ```
815
-
816
- **Git Hooks:** We use [Lefthook](https://github.com/evilmartians/lefthook) to run quality checks before commit/push. This ensures CI passes and saves GitHub Actions minutes!
817
-
818
- **🔧 [Development guide →](DEVELOPMENT.md)** | **🧪 [Testing guide →](docs/development/TESTING.md)**
819
-
820
- ---
821
-
822
- ## 📝 License
823
-
824
- Rails Error Dashboard is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
825
-
826
- ---
827
-
828
- ## 🙏 Acknowledgments
829
-
830
- - Built with [Rails](https://rubyonrails.org/)
831
- - UI powered by [Bootstrap 5](https://getbootstrap.com/)
832
- - Charts by [Chart.js](https://www.chartjs.org/)
833
- - Pagination by [Pagy](https://github.com/ddnexus/pagy)
834
- - Platform detection by [Browser gem](https://github.com/fnando/browser)
835
-
836
- ---
837
-
838
- ## ❓ Frequently Asked Questions
839
-
840
- <details>
841
- <summary><strong>Is this production-ready?</strong></summary>
842
-
843
- This is currently in **beta** but actively tested with 2,100+ passing tests across Rails 7.0-8.1 and Ruby 3.2-4.0. Many users are running it in production. See [production requirements](docs/FEATURES.md#production-readiness).
844
- </details>
845
-
846
- <details>
847
- <summary><strong>How does this compare to Sentry/Rollbar/Honeybadger?</strong></summary>
848
-
849
- **Similar**: Error tracking, grouping, notifications, dashboards
850
- **Better**: 100% free, self-hosted (your data stays with you), no usage limits, Rails-optimized
851
- **Trade-offs**: You manage hosting/backups, fewer integrations than commercial services
852
-
853
- See [full comparison](docs/features/PLATFORM_COMPARISON.md).
854
- </details>
855
-
856
- <details>
857
- <summary><strong>What's the performance impact?</strong></summary>
858
-
859
- Minimal with async logging enabled:
860
- - **Synchronous**: ~10-50ms per error (blocks request)
861
- - **Async (recommended)**: ~1-2ms (queues to background job)
862
- - **Sampling**: Log only 10% of non-critical errors for high-traffic apps
863
-
864
- See [Performance Guide](docs/guides/ERROR_SAMPLING_AND_FILTERING.md).
865
- </details>
866
-
867
- <details>
868
- <summary><strong>Can I use a separate database?</strong></summary>
869
-
870
- Yes! Configure in your initializer:
871
-
872
- ```ruby
873
- RailsErrorDashboard.configure do |config|
874
- config.database = :errors # Use separate database
875
- end
424
+ bin/setup # Installs deps, hooks, runs tests
876
425
  ```
877
426
 
878
- See [Database Options Guide](docs/guides/DATABASE_OPTIONS.md).
879
- </details>
880
-
881
- <details>
882
- <summary><strong>How do I migrate from Sentry/Rollbar?</strong></summary>
883
-
884
- 1. Install Rails Error Dashboard
885
- 2. Run both systems in parallel (1-2 weeks)
886
- 3. Verify all errors are captured
887
- 4. Remove old error tracking gem
888
- 5. Update team documentation
889
-
890
- Historical data cannot be imported (different formats).
891
- </details>
892
-
893
- <details>
894
- <summary><strong>Does it work with API-only Rails apps?</strong></summary>
895
-
896
- Yes! The error logging works in API-only mode. The dashboard UI requires a browser but can be:
897
- - Mounted in a separate admin app
898
- - Run in a separate Rails instance pointing to the same database
899
- - Accessed via SSH tunnel
900
-
901
- See [API-only setup](docs/guides/MOBILE_APP_INTEGRATION.md#backend-setup-rails-api).
902
- </details>
903
-
904
- <details>
905
- <summary><strong>How do I track multiple Rails apps?</strong></summary>
906
-
907
- Automatic! Just set `APP_NAME` environment variable:
908
-
909
- ```bash
910
- # App 1
911
- APP_NAME=my-api rails server
912
-
913
- # App 2
914
- APP_NAME=my-admin rails server
915
- ```
916
-
917
- All apps share the same dashboard. See [Multi-App Guide](docs/MULTI_APP_PERFORMANCE.md).
918
- </details>
919
-
920
- <details>
921
- <summary><strong>Can I customize error severity levels?</strong></summary>
922
-
923
- Yes! Configure custom rules in your initializer:
924
-
925
- ```ruby
926
- RailsErrorDashboard.configure do |config|
927
- config.custom_severity_rules = {
928
- /ActiveRecord::RecordNotFound/ => :low,
929
- /Stripe::/ => :critical
930
- }
931
- end
932
- ```
933
-
934
- See [Customization Guide](docs/CUSTOMIZATION.md).
935
- </details>
936
-
937
- <details>
938
- <summary><strong>How long are errors stored?</strong></summary>
939
-
940
- Forever by default (no automatic deletion). Manual cleanup with rake task:
941
-
942
- ```bash
943
- # Delete resolved errors older than 90 days
944
- rails error_dashboard:cleanup_resolved DAYS=90
945
-
946
- # Filter by application name
947
- rails error_dashboard:cleanup_resolved DAYS=30 APP_NAME="My App"
948
- ```
949
-
950
- Or schedule with cron/whenever. See [Database Optimization](docs/guides/DATABASE_OPTIMIZATION.md).
951
- </details>
952
-
953
- <details>
954
- <summary><strong>Can I get Slack/Discord notifications?</strong></summary>
955
-
956
- Yes! Enable during installation or configure manually:
957
-
958
- ```ruby
959
- RailsErrorDashboard.configure do |config|
960
- config.enable_slack_notifications = true
961
- config.slack_webhook_url = ENV['SLACK_WEBHOOK_URL']
962
- end
963
- ```
964
-
965
- Supports Slack, Discord, Email, PagerDuty, and custom webhooks. See [Notifications Guide](docs/guides/NOTIFICATIONS.md).
966
- </details>
967
-
968
- <details>
969
- <summary><strong>Does it work with Turbo/Hotwire?</strong></summary>
970
-
971
- Yes! Includes Turbo Streams support for real-time updates. Errors appear in the dashboard instantly without page refresh.
972
- </details>
973
-
974
- <details>
975
- <summary><strong>How do I report errors from mobile apps (React Native/Flutter)?</strong></summary>
976
-
977
- Make HTTP POST requests to your Rails API:
978
-
979
- ```javascript
980
- // React Native example
981
- fetch('https://api.example.com/error_dashboard/api/v1/errors', {
982
- method: 'POST',
983
- headers: {
984
- 'Content-Type': 'application/json',
985
- 'Authorization': 'Basic ' + btoa('admin:password')
986
- },
987
- body: JSON.stringify({
988
- error_class: 'TypeError',
989
- message: 'Cannot read property...',
990
- platform: 'iOS'
991
- })
992
- });
993
- ```
994
-
995
- See [Mobile App Integration](docs/guides/MOBILE_APP_INTEGRATION.md).
996
- </details>
997
-
998
- <details>
999
- <summary><strong>Can I build custom integrations?</strong></summary>
1000
-
1001
- Yes! Use the plugin system:
1002
-
1003
- ```ruby
1004
- class MyCustomPlugin < RailsErrorDashboard::Plugin
1005
- def on_error_logged(error_log)
1006
- # Your custom logic
1007
- end
1008
- end
1009
-
1010
- RailsErrorDashboard::PluginRegistry.register(MyCustomPlugin.new)
1011
- ```
1012
-
1013
- See [Plugin System Guide](docs/PLUGIN_SYSTEM.md).
1014
- </details>
1015
-
1016
- <details>
1017
- <summary><strong>What if I need help?</strong></summary>
1018
-
1019
- - **📖 Read the docs**: [docs/README.md](docs/README.md)
1020
- - **🐛 Report bugs**: [GitHub Issues](https://github.com/AnjanJ/rails_error_dashboard/issues)
1021
- - **💡 Ask questions**: [GitHub Discussions](https://github.com/AnjanJ/rails_error_dashboard/discussions)
1022
- - **🔒 Security issues**: See [SECURITY.md](SECURITY.md)
1023
- </details>
427
+ [Development guide →](DEVELOPMENT.md) · [Testing guide ](docs/development/TESTING.md)
1024
428
 
1025
429
  ---
1026
430
 
1027
- ## 💬 Support
431
+ ## License
1028
432
 
1029
- - **📖 Documentation**: [docs/](docs/README.md)
1030
- - **🐛 Issues**: [GitHub Issues](https://github.com/AnjanJ/rails_error_dashboard/issues)
1031
- - **💡 Discussions**: [GitHub Discussions](https://github.com/AnjanJ/rails_error_dashboard/discussions)
433
+ Available as open source under the [MIT License](https://opensource.org/licenses/MIT).
1032
434
 
1033
- ---
435
+ ## Acknowledgments
1034
436
 
1035
- ## 🙏 Contributors
437
+ Built with [Rails](https://rubyonrails.org/) · UI by [Bootstrap 5](https://getbootstrap.com/) · Charts by [Chart.js](https://www.chartjs.org/) · Pagination by [Pagy](https://github.com/ddnexus/pagy)
1036
438
 
1037
- Thank you to everyone who has contributed to Rails Error Dashboard!
439
+ ## Contributors
1038
440
 
1039
441
  [![Contributors](https://contrib.rocks/image?repo=AnjanJ/rails_error_dashboard)](https://github.com/AnjanJ/rails_error_dashboard/graphs/contributors)
1040
442
 
1041
- Special thanks to:
1042
- - [@bonniesimon](https://github.com/bonniesimon) - Turbo helpers production fix
1043
- - [@gundestrup](https://github.com/gundestrup) - Security fixes, dependency updates, CI/CD improvements
1044
- - [@midwire](https://github.com/midwire) - Backtrace line numbers, loading states & skeleton screens
1045
-
1046
- See [CONTRIBUTORS.md](CONTRIBUTORS.md) for the complete list of contributors and their contributions.
1047
-
1048
- Want to contribute? Check out our [Contributing Guide](CONTRIBUTING.md)!
443
+ Special thanks to [@bonniesimon](https://github.com/bonniesimon), [@gundestrup](https://github.com/gundestrup), [@midwire](https://github.com/midwire), and [@RafaelTurtle](https://github.com/RafaelTurtle). See [CONTRIBUTORS.md](CONTRIBUTORS.md) for the full list.
1049
444
 
1050
445
  ---
1051
446
 
@@ -1055,6 +450,6 @@ If this gem saves you some headaches (or some money on error tracking SaaS), con
1055
450
 
1056
451
  ---
1057
452
 
1058
- **Made with ❤️ by [Anjan](https://www.anjan.dev) for the Rails community**
453
+ **Made with care by [Anjan](https://www.anjan.dev) for the Rails community**
1059
454
 
1060
- *One Gem to rule them all, One Gem to find them, One Gem to bring them all, and in the dashboard bind them.* 🧙‍♂️
455
+ *One Gem to rule them all, One Gem to find them, One Gem to bring them all, and in the dashboard bind them.*