rails_error_dashboard 0.3.1 → 0.4.0
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.
- checksums.yaml +4 -4
- data/README.md +160 -861
- data/app/controllers/rails_error_dashboard/errors_controller.rb +89 -0
- data/app/jobs/rails_error_dashboard/swallowed_exception_flush_job.rb +32 -0
- data/app/models/rails_error_dashboard/diagnostic_dump.rb +14 -0
- data/app/models/rails_error_dashboard/swallowed_exception.rb +38 -0
- data/app/views/layouts/rails_error_dashboard.html.erb +21 -0
- data/app/views/rails_error_dashboard/errors/_instance_variables.html.erb +55 -0
- data/app/views/rails_error_dashboard/errors/_local_variables.html.erb +46 -0
- data/app/views/rails_error_dashboard/errors/diagnostic_dumps.html.erb +182 -0
- data/app/views/rails_error_dashboard/errors/rack_attack_summary.html.erb +133 -0
- data/app/views/rails_error_dashboard/errors/show.html.erb +4 -0
- data/app/views/rails_error_dashboard/errors/swallowed_exceptions.html.erb +126 -0
- data/config/routes.rb +4 -0
- data/db/migrate/20251223000000_create_rails_error_dashboard_complete_schema.rb +33 -0
- data/db/migrate/20260306000001_add_local_variables_to_error_logs.rb +13 -0
- data/db/migrate/20260306000002_add_instance_variables_to_error_logs.rb +7 -0
- data/db/migrate/20260306000003_create_rails_error_dashboard_swallowed_exceptions.rb +34 -0
- data/db/migrate/20260307000001_create_rails_error_dashboard_diagnostic_dumps.rb +17 -0
- data/lib/generators/rails_error_dashboard/install/install_generator.rb +32 -0
- data/lib/generators/rails_error_dashboard/install/templates/initializer.rb +47 -0
- data/lib/rails_error_dashboard/commands/flush_swallowed_exceptions.rb +103 -0
- data/lib/rails_error_dashboard/commands/log_error.rb +68 -0
- data/lib/rails_error_dashboard/configuration.rb +122 -0
- data/lib/rails_error_dashboard/engine.rb +24 -0
- data/lib/rails_error_dashboard/queries/dashboard_stats.rb +32 -11
- data/lib/rails_error_dashboard/queries/rack_attack_summary.rb +90 -0
- data/lib/rails_error_dashboard/queries/swallowed_exception_summary.rb +97 -0
- data/lib/rails_error_dashboard/services/breadcrumb_collector.rb +12 -0
- data/lib/rails_error_dashboard/services/crash_capture.rb +234 -0
- data/lib/rails_error_dashboard/services/diagnostic_dump_generator.rb +98 -0
- data/lib/rails_error_dashboard/services/local_variable_capturer.rb +207 -0
- data/lib/rails_error_dashboard/services/swallowed_exception_tracker.rb +277 -0
- data/lib/rails_error_dashboard/services/variable_serializer.rb +326 -0
- data/lib/rails_error_dashboard/subscribers/rack_attack_subscriber.rb +94 -0
- data/lib/rails_error_dashboard/version.rb +1 -1
- data/lib/rails_error_dashboard.rb +9 -0
- data/lib/tasks/error_dashboard.rake +34 -0
- metadata +23 -2
data/README.md
CHANGED
|
@@ -6,11 +6,7 @@
|
|
|
6
6
|
[](https://github.com/AnjanJ/rails_error_dashboard/actions)
|
|
7
7
|
[](https://buymeacoffee.com/anjanj)
|
|
8
8
|
|
|
9
|
-
|
|
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
|
-
|
|
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
|
-
|
|
19
|
+
---
|
|
24
20
|
|
|
25
|
-
|
|
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
|
-
|
|
25
|
+
> **Beta Software** — Functional and tested (2,100+ 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
|
|
29
|
+
**Dashboard Overview** — Real-time error stats, severity breakdown, and trend charts.
|
|
34
30
|
|
|
35
31
|

|
|
36
32
|
|
|
@@ -38,249 +34,172 @@ Experience the full dashboard with 480+ realistic Rails errors, LOTR-themed demo
|
|
|
38
34
|
|
|
39
35
|

|
|
40
36
|
|
|
41
|
-
**Analytics** — Error trends, platform health, correlation insights, and pattern detection.
|
|
42
|
-
|
|
43
|
-

|
|
44
|
-
|
|
45
|
-
**Deprecation Warnings** — Aggregate deprecation warnings across all errors with occurrence counts and affected error links.
|
|
46
|
-
|
|
47
|
-

|
|
48
|
-
|
|
49
|
-
**N+1 Query Patterns** — Cross-error N+1 detection grouped by SQL fingerprint.
|
|
50
|
-
|
|
51
|
-

|
|
52
|
-
|
|
53
|
-
**Cache Health** — Per-error cache performance sorted worst-first.
|
|
54
|
-
|
|
55
|
-

|
|
56
|
-
|
|
57
|
-
**Job Health** — Background job queue stats across errors, sorted by failed count.
|
|
58
|
-
|
|
59
|
-

|
|
60
|
-
|
|
61
|
-
**Database Health** — Connection pool utilization, PostgreSQL table stats, and per-error stress scores.
|
|
62
|
-
|
|
63
|
-

|
|
64
|
-
|
|
65
37
|
---
|
|
66
38
|
|
|
67
|
-
|
|
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.
|
|
39
|
+
## Who This Is For
|
|
69
40
|
|
|
70
|
-
**
|
|
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
|
|
71
46
|
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
## 🎯 Who This Is For
|
|
75
|
-
|
|
76
|
-
✓ **Solo bootstrappers** who need professional error tracking without recurring costs
|
|
77
|
-
|
|
78
|
-
✓ **Indie SaaS founders** building profitable apps on tight budgets
|
|
79
|
-
|
|
80
|
-
✓ **Small dev teams** (2-5 people) who hate SaaS bloat
|
|
81
|
-
|
|
82
|
-
✓ **Privacy-conscious apps** that need to keep error data on their own servers
|
|
83
|
-
|
|
84
|
-
✓ **Side projects** that might become real businesses
|
|
85
|
-
|
|
86
|
-
---
|
|
87
|
-
|
|
88
|
-
## 💰 What It Replaces
|
|
47
|
+
## What It Replaces
|
|
89
48
|
|
|
90
49
|
| Before | After |
|
|
91
50
|
|--------|-------|
|
|
92
|
-
|
|
|
93
|
-
|
|
|
94
|
-
|
|
|
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 |
|
|
95
54
|
| Vendor lock-in with proprietary APIs | 100% open source, fully portable |
|
|
96
|
-
| Complex setup
|
|
55
|
+
| Complex SDK setup and external services | 5-minute Rails Engine installation |
|
|
97
56
|
|
|
98
57
|
---
|
|
99
58
|
|
|
100
|
-
##
|
|
59
|
+
## Features
|
|
101
60
|
|
|
102
|
-
|
|
61
|
+
### Core (Always Enabled)
|
|
103
62
|
|
|
104
|
-
|
|
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
|
|
63
|
+
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.
|
|
110
64
|
|
|
111
|
-
|
|
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
|
|
65
|
+
### Optional Features
|
|
116
66
|
|
|
117
|
-
|
|
67
|
+
<details>
|
|
68
|
+
<summary><strong>Breadcrumbs — Request Activity Trail</strong></summary>
|
|
118
69
|
|
|
119
|
-
|
|
70
|
+
See exactly what happened before the crash — SQL queries, controller actions, cache operations, job executions, and mailer deliveries captured automatically via `ActiveSupport::Notifications`.
|
|
120
71
|
|
|
121
|
-
|
|
72
|
+
- Automatic capture — zero config beyond the enable flag
|
|
73
|
+
- N+1 query detection with aggregate patterns page
|
|
74
|
+
- Deprecation warnings with aggregate view
|
|
75
|
+
- Custom breadcrumbs via `RailsErrorDashboard.add_breadcrumb("checkout started", { cart_id: 123 })`
|
|
76
|
+
- Safe by design — fixed-size ring buffer, thread-local, every subscriber wrapped in rescue
|
|
122
77
|
|
|
123
|
-
|
|
124
|
-
|
|
78
|
+
```ruby
|
|
79
|
+
config.enable_breadcrumbs = true
|
|
80
|
+
```
|
|
125
81
|
|
|
126
|
-
|
|
127
|
-
|
|
82
|
+
[Complete documentation →](docs/FEATURES.md#breadcrumbs--request-activity-trail-new)
|
|
83
|
+
</details>
|
|
128
84
|
|
|
129
|
-
|
|
130
|
-
|
|
85
|
+
<details>
|
|
86
|
+
<summary><strong>System Health Snapshot</strong></summary>
|
|
131
87
|
|
|
132
|
-
|
|
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.
|
|
88
|
+
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.
|
|
134
89
|
|
|
135
|
-
|
|
136
|
-
|
|
90
|
+
- Sub-millisecond total snapshot, every metric individually rescue-wrapped
|
|
91
|
+
- No ObjectSpace scanning, no Thread backtraces, no subprocess calls
|
|
137
92
|
|
|
138
|
-
|
|
93
|
+
```ruby
|
|
94
|
+
config.enable_system_health = true
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
[Complete documentation →](docs/FEATURES.md#system-health-snapshot-new)
|
|
98
|
+
</details>
|
|
139
99
|
|
|
140
|
-
|
|
100
|
+
<details>
|
|
101
|
+
<summary><strong>N+1 Detection + Deprecation Warnings</strong></summary>
|
|
141
102
|
|
|
142
|
-
-
|
|
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)
|
|
103
|
+
Cross-error N+1 detection grouped by SQL fingerprint, and aggregate deprecation warnings with occurrence counts.
|
|
147
104
|
|
|
148
|
-
|
|
105
|
+

|
|
149
106
|
|
|
150
|
-
|
|
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
|
|
107
|
+

|
|
155
108
|
|
|
156
|
-
|
|
109
|
+
Requires breadcrumbs to be enabled.
|
|
157
110
|
|
|
158
|
-
|
|
159
|
-
|
|
111
|
+
[Complete documentation →](docs/FEATURES.md#n1-query-detection)
|
|
112
|
+
</details>
|
|
160
113
|
|
|
161
|
-
|
|
162
|
-
|
|
114
|
+
<details>
|
|
115
|
+
<summary><strong>Operational Health Panels — Jobs, Database, Cache</strong></summary>
|
|
163
116
|
|
|
164
|
-
**
|
|
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.
|
|
117
|
+
**Job Health** — Auto-detects Sidekiq, SolidQueue, or GoodJob. Per-error table with adapter badge, failed count (color-coded), sorted worst-first.
|
|
166
118
|
|
|
167
|
-
|
|
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.
|
|
119
|
+

|
|
169
120
|
|
|
170
|
-
**
|
|
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.
|
|
121
|
+
**Database Health** — PgHero-style live PostgreSQL stats (table sizes, unused indexes, dead tuples, vacuum timestamps) plus historical connection pool data from error snapshots.
|
|
172
122
|
|
|
173
|
-
|
|
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).
|
|
123
|
+

|
|
175
124
|
|
|
176
|
-
**
|
|
177
|
-
Detect cyclical patterns (business hours, nighttime, weekend rhythms) and error bursts (many errors in short time). Understand when and how your errors happen.
|
|
125
|
+
**Cache Health** — Per-error cache performance sorted worst-first.
|
|
178
126
|
|
|
179
|
-
|
|
180
|
-
Built-in analytics dashboard with severity detection, platform stability scoring, actionable recommendations, and recent error activity summaries (always available, no configuration needed).
|
|
127
|
+

|
|
181
128
|
|
|
182
|
-
|
|
129
|
+
[Complete documentation →](docs/FEATURES.md#job-health-page)
|
|
130
|
+
</details>
|
|
183
131
|
|
|
184
|
-
|
|
132
|
+
<details>
|
|
133
|
+
<summary><strong>Source Code Integration + Git Blame</strong></summary>
|
|
185
134
|
|
|
186
|
-
|
|
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)
|
|
135
|
+
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.
|
|
191
136
|
|
|
192
137
|
```ruby
|
|
193
138
|
config.enable_source_code_integration = true
|
|
194
139
|
config.enable_git_blame = true
|
|
195
140
|
```
|
|
196
141
|
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
#### 🥖 Breadcrumbs — Request Activity Trail (NEW!)
|
|
200
|
-
|
|
201
|
-
**See exactly what happened before the crash** — SQL queries, controller actions, cache operations, job executions, and mailer deliveries captured automatically via `ActiveSupport::Notifications`.
|
|
202
|
-
|
|
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`
|
|
142
|
+
[Complete documentation →](docs/SOURCE_CODE_INTEGRATION.md)
|
|
143
|
+
</details>
|
|
213
144
|
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
config.breadcrumb_buffer_size = 40 # Max events per request
|
|
217
|
-
```
|
|
145
|
+
<details>
|
|
146
|
+
<summary><strong>Error Replay — Copy as cURL / RSpec</strong></summary>
|
|
218
147
|
|
|
219
|
-
|
|
148
|
+
Replay failing requests with one click. Copy the request as a cURL command or generate an RSpec test from the captured error context.
|
|
220
149
|
|
|
221
|
-
|
|
150
|
+
[Complete documentation →](docs/FEATURES.md#error-details-page)
|
|
151
|
+
</details>
|
|
222
152
|
|
|
223
|
-
|
|
153
|
+
<details>
|
|
154
|
+
<summary><strong>Notifications — Slack, Discord, PagerDuty, Email, Webhooks</strong></summary>
|
|
224
155
|
|
|
225
|
-
-
|
|
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
|
|
156
|
+
Multi-channel alerting with severity filters, per-error cooldown, and milestone threshold alerts to prevent alert fatigue.
|
|
232
157
|
|
|
233
158
|
```ruby
|
|
234
|
-
config.
|
|
159
|
+
config.enable_slack_notifications = true
|
|
160
|
+
config.slack_webhook_url = ENV['SLACK_WEBHOOK_URL']
|
|
235
161
|
```
|
|
236
162
|
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
#### 🏭 Job Health Page
|
|
240
|
-
|
|
241
|
-
**See background job queue health alongside your errors** — auto-detects Sidekiq, SolidQueue, or GoodJob stats captured at error time.
|
|
242
|
-
|
|
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
|
|
246
|
-
|
|
247
|
-
**📖 [Complete documentation →](docs/FEATURES.md#job-health-page)**
|
|
163
|
+
[Notification setup guide →](docs/guides/NOTIFICATIONS.md)
|
|
164
|
+
</details>
|
|
248
165
|
|
|
249
|
-
|
|
166
|
+
<details>
|
|
167
|
+
<summary><strong>Advanced Analytics</strong></summary>
|
|
250
168
|
|
|
251
|
-
|
|
169
|
+

|
|
252
170
|
|
|
253
|
-
|
|
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
|
|
171
|
+
Seven analysis engines built in:
|
|
257
172
|
|
|
258
|
-
|
|
173
|
+
1. **Baseline Anomaly Alerts** — Statistical spike detection (mean + std dev) with intelligent cooldown
|
|
174
|
+
2. **Fuzzy Error Matching** — Jaccard similarity + Levenshtein distance to find related errors
|
|
175
|
+
3. **Co-occurring Errors** — Detect errors that happen together within configurable time windows
|
|
176
|
+
4. **Error Cascade Detection** — Identify chains (A causes B causes C) with probability and delays
|
|
177
|
+
5. **Error Correlation Analysis** — Correlate errors with app versions, git commits, and users
|
|
178
|
+
6. **Platform Comparison** — iOS vs Android vs Web health metrics side-by-side
|
|
179
|
+
7. **Occurrence Pattern Detection** — Cyclical patterns (business hours, weekends) and burst detection
|
|
259
180
|
|
|
260
|
-
|
|
181
|
+
[Complete documentation →](docs/FEATURES.md#advanced-analytics-features)
|
|
182
|
+
</details>
|
|
261
183
|
|
|
262
|
-
|
|
184
|
+
<details>
|
|
185
|
+
<summary><strong>Plugin System</strong></summary>
|
|
263
186
|
|
|
264
|
-
-
|
|
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
|
|
187
|
+
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
188
|
|
|
276
|
-
|
|
277
|
-
|
|
189
|
+
```ruby
|
|
190
|
+
class MyPlugin < RailsErrorDashboard::Plugin
|
|
191
|
+
def on_error_logged(error_log)
|
|
192
|
+
# Your custom logic
|
|
193
|
+
end
|
|
194
|
+
end
|
|
195
|
+
```
|
|
278
196
|
|
|
279
|
-
|
|
197
|
+
[Plugin System guide →](docs/PLUGIN_SYSTEM.md)
|
|
198
|
+
</details>
|
|
280
199
|
|
|
281
200
|
---
|
|
282
201
|
|
|
283
|
-
##
|
|
202
|
+
## Quick Start
|
|
284
203
|
|
|
285
204
|
### 1. Add to Gemfile
|
|
286
205
|
|
|
@@ -296,756 +215,136 @@ rails generate rails_error_dashboard:install
|
|
|
296
215
|
rails db:migrate
|
|
297
216
|
```
|
|
298
217
|
|
|
299
|
-
The installer
|
|
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`
|
|
218
|
+
The installer guides you through optional feature selection — notifications, performance optimizations, advanced analytics. All features are opt-in.
|
|
310
219
|
|
|
311
220
|
### 3. Visit your dashboard
|
|
312
221
|
|
|
313
|
-
Start your server and visit:
|
|
314
222
|
```
|
|
315
223
|
http://localhost:3000/error_dashboard
|
|
316
224
|
```
|
|
317
225
|
|
|
318
|
-
|
|
319
|
-
- Username: `gandalf`
|
|
320
|
-
- Password: `youshallnotpass`
|
|
226
|
+
Default credentials: `gandalf` / `youshallnotpass`
|
|
321
227
|
|
|
322
|
-
|
|
228
|
+
**Change these before production!** Edit `config/initializers/rails_error_dashboard.rb`
|
|
323
229
|
|
|
324
230
|
### 4. Test it out
|
|
325
231
|
|
|
326
|
-
Trigger a test error to see it in action:
|
|
327
|
-
|
|
328
232
|
```ruby
|
|
329
233
|
# In Rails console or any controller
|
|
330
234
|
raise "Test error from Rails Error Dashboard!"
|
|
331
235
|
```
|
|
332
236
|
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
**📘 [Full installation guide →](docs/QUICKSTART.md)**
|
|
336
|
-
|
|
337
|
-
---
|
|
338
|
-
|
|
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)**
|
|
237
|
+
[Full installation guide →](docs/QUICKSTART.md)
|
|
362
238
|
|
|
363
239
|
---
|
|
364
240
|
|
|
365
|
-
##
|
|
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`:
|
|
241
|
+
## Configuration
|
|
385
242
|
|
|
386
243
|
```ruby
|
|
387
244
|
RailsErrorDashboard.configure do |config|
|
|
388
|
-
#
|
|
389
|
-
# AUTHENTICATION (Always Required)
|
|
390
|
-
# ============================================================================
|
|
245
|
+
# Authentication
|
|
391
246
|
config.dashboard_username = ENV.fetch('ERROR_DASHBOARD_USER', 'gandalf')
|
|
392
247
|
config.dashboard_password = ENV.fetch('ERROR_DASHBOARD_PASSWORD', 'youshallnotpass')
|
|
393
248
|
|
|
394
|
-
# Or use your existing auth (Devise, Warden, etc.)
|
|
249
|
+
# Or use your existing auth (Devise, Warden, etc.):
|
|
395
250
|
# config.authenticate_with = -> { warden.authenticated? }
|
|
396
251
|
|
|
397
|
-
#
|
|
398
|
-
# OPTIONAL FEATURES (Enable as needed)
|
|
399
|
-
# ============================================================================
|
|
400
|
-
|
|
401
|
-
# Slack notifications (if enabled during install)
|
|
252
|
+
# Optional features — enable as needed
|
|
402
253
|
config.enable_slack_notifications = true
|
|
403
254
|
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
255
|
config.async_logging = true
|
|
412
256
|
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
257
|
end
|
|
419
258
|
```
|
|
420
259
|
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
### Environment Variables
|
|
260
|
+
[Complete configuration guide →](docs/guides/CONFIGURATION.md)
|
|
424
261
|
|
|
425
|
-
|
|
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
|
-
```
|
|
432
|
-
|
|
433
|
-
**📖 [Complete configuration guide →](docs/guides/CONFIGURATION.md)**
|
|
262
|
+
**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
263
|
|
|
435
264
|
---
|
|
436
265
|
|
|
437
|
-
##
|
|
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
|
|
266
|
+
## Documentation
|
|
706
267
|
|
|
707
268
|
### Getting Started
|
|
708
|
-
- **[Quickstart Guide](docs/QUICKSTART.md)**
|
|
709
|
-
- **[Configuration](docs/guides/CONFIGURATION.md)**
|
|
710
|
-
- **[
|
|
269
|
+
- **[Quickstart Guide](docs/QUICKSTART.md)** — 5-minute setup
|
|
270
|
+
- **[Configuration](docs/guides/CONFIGURATION.md)** — All configuration options
|
|
271
|
+
- **[Uninstalling](docs/UNINSTALL.md)** — Clean removal
|
|
711
272
|
|
|
712
273
|
### Features
|
|
713
|
-
- **[Complete Feature List](docs/FEATURES.md)**
|
|
714
|
-
- **[Notifications](docs/guides/NOTIFICATIONS.md)**
|
|
715
|
-
- **[
|
|
716
|
-
- **[
|
|
717
|
-
- **[
|
|
274
|
+
- **[Complete Feature List](docs/FEATURES.md)** — Every feature explained
|
|
275
|
+
- **[Notifications](docs/guides/NOTIFICATIONS.md)** — Multi-channel alerting
|
|
276
|
+
- **[Source Code Integration](docs/SOURCE_CODE_INTEGRATION.md)** — Inline source + git blame
|
|
277
|
+
- **[Batch Operations](docs/guides/BATCH_OPERATIONS.md)** — Bulk resolve/delete
|
|
278
|
+
- **[Real-Time Updates](docs/guides/REAL_TIME_UPDATES.md)** — Live dashboard
|
|
279
|
+
- **[Error Trends](docs/guides/ERROR_TREND_VISUALIZATIONS.md)** — Charts and analytics
|
|
718
280
|
|
|
719
281
|
### Advanced
|
|
720
|
-
- **[Multi-App Support](docs/MULTI_APP_PERFORMANCE.md)**
|
|
721
|
-
- **[Plugin System](docs/PLUGIN_SYSTEM.md)**
|
|
722
|
-
- **[API Reference](docs/API_REFERENCE.md)**
|
|
723
|
-
- **[Customization
|
|
724
|
-
- **[Database Options](docs/guides/DATABASE_OPTIONS.md)**
|
|
725
|
-
- **[Database Optimization](docs/guides/DATABASE_OPTIMIZATION.md)**
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
- **[Testing](docs/development/TESTING.md)** - Multi-version testing
|
|
729
|
-
- **[Smoke Tests](SMOKE_TESTS.md)** - Deployment verification tests
|
|
282
|
+
- **[Multi-App Support](docs/MULTI_APP_PERFORMANCE.md)** — Track multiple applications
|
|
283
|
+
- **[Plugin System](docs/PLUGIN_SYSTEM.md)** — Build custom integrations
|
|
284
|
+
- **[API Reference](docs/API_REFERENCE.md)** — Complete API documentation
|
|
285
|
+
- **[Customization](docs/CUSTOMIZATION.md)** — Customize everything
|
|
286
|
+
- **[Database Options](docs/guides/DATABASE_OPTIONS.md)** — Separate database setup
|
|
287
|
+
- **[Database Optimization](docs/guides/DATABASE_OPTIMIZATION.md)** — Performance tuning
|
|
288
|
+
- **[Mobile App Integration](docs/guides/MOBILE_APP_INTEGRATION.md)** — React Native, Flutter, etc.
|
|
289
|
+
- **[FAQ](docs/FAQ.md)** — Common questions answered
|
|
730
290
|
|
|
731
|
-
|
|
291
|
+
[View all documentation →](docs/README.md)
|
|
732
292
|
|
|
733
293
|
---
|
|
734
294
|
|
|
735
|
-
##
|
|
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
|
|
295
|
+
## Architecture
|
|
743
296
|
|
|
744
|
-
|
|
297
|
+
Built with **CQRS (Command/Query Responsibility Segregation)**:
|
|
298
|
+
- **Commands** — LogError, ResolveError, BatchOperations (writes)
|
|
299
|
+
- **Queries** — ErrorsList, DashboardStats, Analytics (reads)
|
|
300
|
+
- **Services** — PlatformDetector, SimilarityCalculator (business logic)
|
|
301
|
+
- **Plugins** — Event-driven extensibility
|
|
745
302
|
|
|
746
303
|
---
|
|
747
304
|
|
|
748
|
-
##
|
|
305
|
+
## Testing
|
|
749
306
|
|
|
750
307
|
2,100+ tests covering unit, integration, and browser-based system tests.
|
|
751
308
|
|
|
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.
|
|
779
|
-
|
|
780
309
|
```bash
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
# macOS: Chrome is typically at /Applications/Google Chrome.app
|
|
310
|
+
bundle exec rspec # Full suite
|
|
311
|
+
bundle exec rspec spec/system/ # System tests (Capybara + Cuprite)
|
|
312
|
+
HEADLESS=false bundle exec rspec spec/system/ # Visible browser
|
|
785
313
|
```
|
|
786
314
|
|
|
787
315
|
---
|
|
788
316
|
|
|
789
|
-
##
|
|
790
|
-
|
|
791
|
-
We welcome contributions! Here's how to get started:
|
|
317
|
+
## Contributing
|
|
792
318
|
|
|
793
319
|
1. Fork the repository
|
|
794
320
|
2. Create your feature branch (`git checkout -b feature/amazing-feature`)
|
|
795
|
-
3. Write tests
|
|
796
|
-
4.
|
|
797
|
-
5.
|
|
798
|
-
6. Push to the branch (`git push origin feature/amazing-feature`)
|
|
799
|
-
7. Open a Pull Request
|
|
800
|
-
|
|
801
|
-
### Development Setup
|
|
321
|
+
3. Write tests, ensure all pass (`bundle exec rspec`)
|
|
322
|
+
4. Commit and push
|
|
323
|
+
5. Open a Pull Request
|
|
802
324
|
|
|
803
325
|
```bash
|
|
804
326
|
git clone https://github.com/AnjanJ/rails_error_dashboard.git
|
|
805
327
|
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
|
|
328
|
+
bin/setup # Installs deps, hooks, runs tests
|
|
814
329
|
```
|
|
815
330
|
|
|
816
|
-
|
|
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)
|
|
331
|
+
[Development guide →](DEVELOPMENT.md) · [Testing guide →](docs/development/TESTING.md)
|
|
835
332
|
|
|
836
333
|
---
|
|
837
334
|
|
|
838
|
-
##
|
|
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>
|
|
335
|
+
## License
|
|
858
336
|
|
|
859
|
-
|
|
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
|
|
337
|
+
Available as open source under the [MIT License](https://opensource.org/licenses/MIT).
|
|
863
338
|
|
|
864
|
-
|
|
865
|
-
</details>
|
|
339
|
+
## Acknowledgments
|
|
866
340
|
|
|
867
|
-
|
|
868
|
-
<summary><strong>Can I use a separate database?</strong></summary>
|
|
341
|
+
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)
|
|
869
342
|
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
```ruby
|
|
873
|
-
RailsErrorDashboard.configure do |config|
|
|
874
|
-
config.database = :errors # Use separate database
|
|
875
|
-
end
|
|
876
|
-
```
|
|
877
|
-
|
|
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>
|
|
1024
|
-
|
|
1025
|
-
---
|
|
1026
|
-
|
|
1027
|
-
## 💬 Support
|
|
1028
|
-
|
|
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)
|
|
1032
|
-
|
|
1033
|
-
---
|
|
1034
|
-
|
|
1035
|
-
## 🙏 Contributors
|
|
1036
|
-
|
|
1037
|
-
Thank you to everyone who has contributed to Rails Error Dashboard!
|
|
343
|
+
## Contributors
|
|
1038
344
|
|
|
1039
345
|
[](https://github.com/AnjanJ/rails_error_dashboard/graphs/contributors)
|
|
1040
346
|
|
|
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)!
|
|
347
|
+
Special thanks to [@bonniesimon](https://github.com/bonniesimon), [@gundestrup](https://github.com/gundestrup), and [@midwire](https://github.com/midwire). See [CONTRIBUTORS.md](CONTRIBUTORS.md) for the full list.
|
|
1049
348
|
|
|
1050
349
|
---
|
|
1051
350
|
|
|
@@ -1055,6 +354,6 @@ If this gem saves you some headaches (or some money on error tracking SaaS), con
|
|
|
1055
354
|
|
|
1056
355
|
---
|
|
1057
356
|
|
|
1058
|
-
**Made with
|
|
357
|
+
**Made with care by [Anjan](https://www.anjan.dev) for the Rails community**
|
|
1059
358
|
|
|
1060
|
-
*One Gem to rule them all, One Gem to find them, One Gem to bring them all, and in the dashboard bind them.*
|
|
359
|
+
*One Gem to rule them all, One Gem to find them, One Gem to bring them all, and in the dashboard bind them.*
|