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.
- checksums.yaml +4 -4
- data/README.md +236 -841
- 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/_sidebar_metadata.html.erb +48 -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/system_health_snapshot.rb +33 -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,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
|
|
29
|
+
**Dashboard Overview** — Real-time error stats, severity breakdown, and trend charts.
|
|
34
30
|
|
|
35
31
|

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

|
|
40
36
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-

|
|
37
|
+
---
|
|
44
38
|
|
|
45
|
-
|
|
39
|
+
## Who This Is For
|
|
46
40
|
|
|
47
|
-
|
|
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
|
-
|
|
47
|
+
## What It Replaces
|
|
50
48
|
|
|
51
|
-
|
|
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
|
-
|
|
59
|
+
---
|
|
54
60
|
|
|
55
|
-
|
|
61
|
+
## Features
|
|
56
62
|
|
|
57
|
-
|
|
63
|
+
### Core (Always Enabled)
|
|
58
64
|
|
|
59
|
-
|
|
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
|
-
|
|
67
|
+
### Optional Features
|
|
62
68
|
|
|
63
|
-
|
|
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
|
-
|
|
68
|
-
|
|
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
|
-
|
|
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
|
-
|
|
87
|
+
<details>
|
|
88
|
+
<summary><strong>System Health Snapshot</strong></summary>
|
|
75
89
|
|
|
76
|
-
|
|
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
|
-
|
|
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
|
-
|
|
97
|
+
```ruby
|
|
98
|
+
config.enable_system_health = true
|
|
99
|
+
```
|
|
81
100
|
|
|
82
|
-
|
|
101
|
+
[Complete documentation →](docs/FEATURES.md#system-health-snapshot-new)
|
|
102
|
+
</details>
|
|
83
103
|
|
|
84
|
-
|
|
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
|
-
|
|
109
|
+

|
|
89
110
|
|
|
90
|
-
|
|
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
|
+

|
|
97
112
|
|
|
98
|
-
|
|
113
|
+
Requires breadcrumbs to be enabled.
|
|
99
114
|
|
|
100
|
-
|
|
115
|
+
[Complete documentation →](docs/FEATURES.md#n1-query-detection)
|
|
116
|
+
</details>
|
|
101
117
|
|
|
102
|
-
|
|
118
|
+
<details>
|
|
119
|
+
<summary><strong>Operational Health Panels — Jobs, Database, Cache</strong></summary>
|
|
103
120
|
|
|
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
|
|
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
|
-
|
|
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
|
+

|
|
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
|
-
|
|
127
|
+

|
|
120
128
|
|
|
121
|
-
|
|
129
|
+
**Cache Health** — Per-error cache performance sorted worst-first.
|
|
122
130
|
|
|
123
|
-
|
|
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
|
+

|
|
125
132
|
|
|
126
|
-
|
|
127
|
-
|
|
133
|
+
[Complete documentation →](docs/FEATURES.md#job-health-page)
|
|
134
|
+
</details>
|
|
128
135
|
|
|
129
|
-
|
|
130
|
-
|
|
136
|
+
<details>
|
|
137
|
+
<summary><strong>Source Code Integration + Git Blame</strong></summary>
|
|
131
138
|
|
|
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.
|
|
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
|
-
|
|
136
|
-
|
|
141
|
+
```ruby
|
|
142
|
+
config.enable_source_code_integration = true
|
|
143
|
+
config.enable_git_blame = true
|
|
144
|
+
```
|
|
137
145
|
|
|
138
|
-
|
|
146
|
+
[Complete documentation →](docs/SOURCE_CODE_INTEGRATION.md)
|
|
147
|
+
</details>
|
|
139
148
|
|
|
140
|
-
|
|
149
|
+
<details>
|
|
150
|
+
<summary><strong>Error Replay — Copy as cURL / RSpec</strong></summary>
|
|
141
151
|
|
|
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)
|
|
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
|
-
|
|
154
|
+
[Complete documentation →](docs/FEATURES.md#error-details-page)
|
|
155
|
+
</details>
|
|
149
156
|
|
|
150
|
-
|
|
151
|
-
|
|
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
|
-
|
|
160
|
+
Multi-channel alerting with severity filters, per-error cooldown, and milestone threshold alerts to prevent alert fatigue.
|
|
157
161
|
|
|
158
|
-
|
|
159
|
-
|
|
162
|
+
```ruby
|
|
163
|
+
config.enable_slack_notifications = true
|
|
164
|
+
config.slack_webhook_url = ENV['SLACK_WEBHOOK_URL']
|
|
165
|
+
```
|
|
160
166
|
|
|
161
|
-
|
|
162
|
-
|
|
167
|
+
[Notification setup guide →](docs/guides/NOTIFICATIONS.md)
|
|
168
|
+
</details>
|
|
163
169
|
|
|
164
|
-
|
|
165
|
-
|
|
170
|
+
<details>
|
|
171
|
+
<summary><strong>Advanced Analytics</strong></summary>
|
|
166
172
|
|
|
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.
|
|
173
|
+

|
|
169
174
|
|
|
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.
|
|
175
|
+
Seven analysis engines built in:
|
|
172
176
|
|
|
173
|
-
|
|
174
|
-
|
|
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
|
-
|
|
177
|
-
|
|
185
|
+
[Complete documentation →](docs/FEATURES.md#advanced-analytics-features)
|
|
186
|
+
</details>
|
|
178
187
|
|
|
179
|
-
|
|
180
|
-
|
|
188
|
+
<details>
|
|
189
|
+
<summary><strong>Local Variable + Instance Variable Capture</strong></summary>
|
|
181
190
|
|
|
182
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
+

|
|
191
200
|
|
|
192
201
|
```ruby
|
|
193
|
-
config.
|
|
194
|
-
config.
|
|
202
|
+
config.enable_local_variables = true
|
|
203
|
+
config.enable_instance_variables = true
|
|
195
204
|
```
|
|
196
205
|
|
|
197
|
-
|
|
206
|
+
[Complete documentation →](docs/FEATURES.md)
|
|
207
|
+
</details>
|
|
198
208
|
|
|
199
|
-
|
|
209
|
+
<details>
|
|
210
|
+
<summary><strong>Swallowed Exception Detection</strong></summary>
|
|
200
211
|
|
|
201
|
-
|
|
212
|
+
Detect exceptions that are raised but silently rescued — the hardest bugs to find. No other error tracker does this.
|
|
202
213
|
|
|
203
|
-
-
|
|
204
|
-
-
|
|
205
|
-
-
|
|
206
|
-
-
|
|
207
|
-
-
|
|
208
|
-
|
|
209
|
-
|
|
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
|
+

|
|
213
221
|
|
|
214
222
|
```ruby
|
|
215
|
-
config.
|
|
216
|
-
config.breadcrumb_buffer_size = 40 # Max events per request
|
|
223
|
+
config.detect_swallowed_exceptions = true
|
|
217
224
|
```
|
|
218
225
|
|
|
219
|
-
|
|
226
|
+
[Complete documentation →](docs/FEATURES.md)
|
|
227
|
+
</details>
|
|
228
|
+
|
|
229
|
+
<details>
|
|
230
|
+
<summary><strong>On-Demand Diagnostic Dump</strong></summary>
|
|
220
231
|
|
|
221
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
+

|
|
232
239
|
|
|
233
240
|
```ruby
|
|
234
|
-
config.
|
|
241
|
+
config.enable_diagnostic_dump = true
|
|
235
242
|
```
|
|
236
243
|
|
|
237
|
-
|
|
244
|
+
[Complete documentation →](docs/FEATURES.md)
|
|
245
|
+
</details>
|
|
238
246
|
|
|
239
|
-
|
|
247
|
+
<details>
|
|
248
|
+
<summary><strong>Rack Attack Event Tracking</strong></summary>
|
|
240
249
|
|
|
241
|
-
|
|
250
|
+
Track Rack Attack security events (throttles, blocklists, tracks) as breadcrumbs attached to errors, with a dedicated summary page.
|
|
242
251
|
|
|
243
|
-
-
|
|
244
|
-
-
|
|
245
|
-
-
|
|
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
|
-
|
|
256
|
+
```ruby
|
|
257
|
+
config.enable_rack_attack_tracking = true
|
|
258
|
+
```
|
|
248
259
|
|
|
249
|
-
|
|
260
|
+
[Complete documentation →](docs/FEATURES.md)
|
|
261
|
+
</details>
|
|
262
|
+
|
|
263
|
+
<details>
|
|
264
|
+
<summary><strong>Process Crash Capture</strong></summary>
|
|
250
265
|
|
|
251
|
-
|
|
266
|
+
Capture unhandled exceptions that crash the Ruby process via an `at_exit` hook — the last line of defense.
|
|
252
267
|
|
|
253
|
-
-
|
|
254
|
-
-
|
|
255
|
-
-
|
|
256
|
-
-
|
|
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
|
-
|
|
273
|
+
```ruby
|
|
274
|
+
config.enable_crash_capture = true
|
|
275
|
+
```
|
|
259
276
|
|
|
260
|
-
|
|
277
|
+
[Complete documentation →](docs/FEATURES.md)
|
|
278
|
+
</details>
|
|
261
279
|
|
|
262
|
-
|
|
280
|
+
<details>
|
|
281
|
+
<summary><strong>Plugin System</strong></summary>
|
|
263
282
|
|
|
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
|
|
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
|
-
|
|
277
|
-
|
|
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
|
-
|
|
293
|
+
[Plugin System guide →](docs/PLUGIN_SYSTEM.md)
|
|
294
|
+
</details>
|
|
280
295
|
|
|
281
296
|
---
|
|
282
297
|
|
|
283
|
-
##
|
|
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
|
|
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
|
-
|
|
319
|
-
- Username: `gandalf`
|
|
320
|
-
- Password: `youshallnotpass`
|
|
322
|
+
Default credentials: `gandalf` / `youshallnotpass`
|
|
321
323
|
|
|
322
|
-
|
|
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
|
-
|
|
334
|
-
|
|
335
|
-
**📘 [Full installation guide →](docs/QUICKSTART.md)**
|
|
333
|
+
[Full installation guide →](docs/QUICKSTART.md)
|
|
336
334
|
|
|
337
335
|
---
|
|
338
336
|
|
|
339
|
-
##
|
|
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.)
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
##
|
|
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)**
|
|
709
|
-
- **[Configuration](docs/guides/CONFIGURATION.md)**
|
|
710
|
-
- **[
|
|
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)**
|
|
714
|
-
- **[Notifications](docs/guides/NOTIFICATIONS.md)**
|
|
715
|
-
- **[
|
|
716
|
-
- **[
|
|
717
|
-
- **[
|
|
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)**
|
|
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)**
|
|
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
|
-
|
|
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
|
-
##
|
|
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
|
-
|
|
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
|
-
##
|
|
401
|
+
## Testing
|
|
749
402
|
|
|
750
|
-
2,
|
|
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
|
-
|
|
782
|
-
|
|
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
|
-
##
|
|
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
|
|
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
|
|
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
|
-
|
|
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
|
-
##
|
|
431
|
+
## License
|
|
1028
432
|
|
|
1029
|
-
|
|
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
|
-
|
|
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
|
-
|
|
439
|
+
## Contributors
|
|
1038
440
|
|
|
1039
441
|
[](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
|
|
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.*
|