rails_error_dashboard 0.11.0 → 0.11.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: defed3f836bc0e812c76abfb81b95e5e3f229e5338bfa40cde4604643eb95582
4
- data.tar.gz: 7657043dbf617694e5318a5b0e2829ecca78ade0c67412ede16fbecabc696c36
3
+ metadata.gz: 4aa6cdee526bf9210f3762861a373dbefbe99b9ed94ecdb5f6464fb781bdddb4
4
+ data.tar.gz: 3a7977ff26332c869b5bf6e4e5316d3470e978ff736184dcc4119f0982822c4c
5
5
  SHA512:
6
- metadata.gz: 79992d38956c257a116c1cfcb153429cbf3a082892bc71664c20ba57e801ba33325ae69f43bd0ef8404a3cd08a6d5df9727a989a0f8977826786a179ad70b448
7
- data.tar.gz: 3bbcc477eff8db567415c727037a58d7e27bd8e01ad602674beb05cd6891f75bb06e665273698fed1b49c20806e4f07dbea586647583f6b7da3052a744d58fae
6
+ metadata.gz: ea46f47e2e96da83cf0c83d94596e63d63ab0dafeea5a3f696b2a1021b9eb57026485c9fec4d0827e8f8fcd4852fd587a69d28d3890ec14a5ec295d549826264
7
+ data.tar.gz: 4ea0ff21bbcb9177fd43297a5145e17a6316ec52f2f8a5370b30e36879a32810cd289b22e7c1d66abb2b9f9a66593bc2e013ab3ccfc19af1c0ffc46c42863537
data/README.md CHANGED
@@ -7,27 +7,100 @@
7
7
  [![Sponsor](https://img.shields.io/badge/Sponsor-GitHub%20Sponsors-ea4aaa?logo=githubsponsors)](https://github.com/sponsors/AnjanJ)
8
8
  [![Buy Me A Coffee](https://img.shields.io/badge/Buy%20Me%20A%20Coffee-support-yellow?logo=buymeacoffee)](https://buymeacoffee.com/anjanj)
9
9
 
10
- **Self-hosted Rails error monitoring free, forever.**
10
+ **Rails-native error tracking for failure investigation — see the Ruby state and Rails runtime health behind every exception. Self-hosted, inside your app, in your own database. The gem is MIT and free forever.**
11
11
 
12
12
  ```ruby
13
- gem 'rails_error_dashboard'
13
+ gem "rails_error_dashboard"
14
14
  ```
15
15
 
16
- **5-minute setup** · **Works out-of-the-box** · **PostgreSQL, MySQL/Trilogy, SQLite — shared or separate database** · **No vendor lock-in**
16
+ ```bash
17
+ bundle install
18
+ rails generate rails_error_dashboard:install
19
+ rails db:migrate
20
+ ```
17
21
 
18
- [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
+ Open `/red` and raise a test exception. No monitoring account or ingestion service is required.
19
23
 
20
- ---
24
+ [Try the live demo](https://rails-error-dashboard.anjan.dev) (`gandalf` / `youshallnotpass`) · [Read the documentation](https://anjanj.github.io/rails_error_dashboard/) · [View on RubyGems](https://rubygems.org/gems/rails_error_dashboard)
25
+
26
+ > **Beta:** RED is functional and extensively tested, but configuration and APIs may change before 1.0. Supports Rails 7.0–8.1 and Ruby 3.2–4.0 (CI runs Ruby 3.2–3.4 against every supported Rails version; Ruby 4.0 is verified by the maintainer).
27
+
28
+ ## See the Ruby state and Rails runtime health behind every exception
29
+
30
+ Rails Error Dashboard (RED) is an open-source, self-hosted Rails engine for investigating production failures. It helps you answer not only **what failed**, but **what was happening inside Ruby and Rails when it failed**.
31
+
32
+ - Inspect local variables and the raising object's instance variables before the stack unwinds.
33
+ - See error-time Active Record, Puma, job queue, GC, memory and process health.
34
+ - Follow the SQL, cache, controller, job, mailer and other Rails events leading to the exception.
35
+ - Stay safe during error floods with progressive, count-preserving storm protection.
36
+ - Keep exception data on infrastructure you control.
37
+
38
+ ![Local and instance variables captured at the raise, scrubbed with filter_parameters](docs/images/local-variables.png)
39
+
40
+ ## The questions RED helps you answer
41
+
42
+ A stack trace tells you where execution stopped. RED helps you investigate the state behind it:
43
+
44
+ - What did `params`, local variables and objects such as `@order` contain?
45
+ - Was the Active Record pool exhausted?
46
+ - Was Puma out of thread capacity or building a backlog?
47
+ - Were jobs failing or queues growing?
48
+ - Was the process under GC, memory, descriptor or system pressure?
49
+ - Which SQL queries, cache operations or Rails events preceded the failure?
50
+ - Did a deploy introduce the error?
51
+ - Can the failing request become a cURL reproduction or RSpec regression-test scaffold?
52
+
53
+ ## What makes RED different
54
+
55
+ ### Failure-time Ruby state
56
+
57
+ Optionally capture local variables and — something no other error tracker does — the raising receiver's instance variables at `TracePoint(:raise)`, with bounded serialization and your Rails `filter_parameters` applied to sensitive values. Binding objects are never retained.
21
58
 
22
- ### Try the Live Demo
59
+ ### Failure-time Rails health
23
60
 
24
- **[rails-error-dashboard.anjan.dev](https://rails-error-dashboard.anjan.dev)** Username: `gandalf` · Password: `youshallnotpass`
61
+ Attach connection-pool, Puma, background-job, GC, memory, file-descriptor, TCP, RubyVM and YJIT state to the error record, refreshed on every captured occurrence — not merely to a separate periodic metrics chart. Every APM has these as time-series; none attaches them to the error. Opt-in; the procfs-backed fields are Linux-only.
25
62
 
26
- > **Beta Software** Functional and tested (4,200+ tests passing), but the API may change before v1.0. Supports Rails 7.0-8.1 and Ruby 3.2-4.0.
63
+ ### Monitoring that degrades safely
64
+
65
+ During an error flood, RED progressively reduces captured context and database work, keeps a fresh exemplar every minute, records the storm in a Storm History ledger and reconciles exact in-process occurrence counts onto the error records. On by default.
66
+
67
+ ### Rails-specific investigation
68
+
69
+ Connect exceptions with SQL, caching, Active Job, Action Cable, Active Storage, Rack::Attack, deprecations and other Rails subsystems from one dashboard.
70
+
71
+ ### Things no other tracker does
72
+
73
+ Verified against Sentry, Honeybadger, AppSignal, Rollbar, Bugsnag, Airbrake, Raygun, New Relic, Datadog, Scout, Skylight and every self-hosted Rails tracker in August 2026 ([the ledger](.shipkit/research/red-unique-features-verified.md)):
74
+
75
+ - **Copy as RSpec** — a runnable request spec generated from the captured request (Sentry offers curl only).
76
+ - **Swallowed-exception aggregate** — raise-vs-rescue ratio per location, no APM span needed (Datadog's paid APM detects rescued exceptions but keeps no aggregate).
77
+ - **Rack::Attack ledger** — throttle, blocklist and track events persisted with per-rule stats and an AI-crawler classifier; rack-attack ships no UI of its own.
78
+ - **Codeberg issue tracking**, alongside GitHub, GitLab and Linear with two-way sync.
79
+ - **The tracker instruments itself** — its capture pipeline exported as OpenTelemetry spans, so you can audit its overhead in your own APM.
80
+
81
+ ## How RED compares
82
+
83
+ | Basic embedded tracker | General SaaS monitoring | RED |
84
+ |---|---|---|
85
+ | Stack trace and context | Cross-language telemetry and managed ingestion | Deep failure-time Ruby/Rails state inside the application boundary |
86
+ | Lightweight and local | Strong distributed and frontend observability | Rails-specific operational investigation and storm-safe local capture |
87
+
88
+ That makes RED a self-hosted Sentry alternative for teams that want Rails-specific depth and need error data to stay inside the application boundary — not a replacement for cross-language telemetry. RED has no mobile SDKs, no merge/split, no MCP server and no hosted operations.
89
+
90
+ ## Choose how you run it
91
+
92
+ - Store data in the application's existing PostgreSQL, MySQL/Trilogy or SQLite database.
93
+ - Isolate monitoring writes in a separate error database.
94
+ - Use synchronous writes, or async logging through Sidekiq or Solid Queue (GoodJob is detected for job-health stats but is not an async adapter).
95
+ - Track several Rails applications through a shared database.
96
+
97
+ No RED licence or event-ingestion fee, and no plan limits — your database is the only cap, and storm protection deliberately sheds context during floods.
98
+
99
+ ---
27
100
 
28
101
  ### Screenshots
29
102
 
30
- **Dashboard Overview** — Real-time error stats, severity breakdown, and trend charts.
103
+ **Dashboard Overview** — Live error stats, severity breakdown, and trend charts.
31
104
 
32
105
  ![Dashboard Overview](docs/images/dashboard-overview.png)
33
106
 
@@ -49,25 +122,12 @@ gem 'rails_error_dashboard'
49
122
 
50
123
  ---
51
124
 
52
- ## Who This Is For
53
-
54
- - **Solo bootstrappers** who need professional error tracking without recurring costs
55
- - **Indie SaaS founders** building profitable apps on tight budgets
56
- - **Small dev teams** (2-5 people) who hate SaaS bloat
57
- - **Privacy-conscious apps** that need to keep error data on their own servers
58
- - **Side projects** that might become real businesses
59
-
60
- ## What It Replaces
125
+ ## Safety, performance and compatibility
61
126
 
62
- | Before | After |
63
- |--------|-------|
64
- | $29-99/month for error monitoring | $0/month runs on your existing Rails server |
65
- | Sensitive error data sent to third parties | All data stays on your infrastructure |
66
- | SaaS pricing tiers and usage limits | Unlimited errors, unlimited projects |
67
- | Vendor lock-in with proprietary APIs | 100% open source, fully portable |
68
- | Complex SDK setup and external services | 5-minute Rails Engine installation |
69
- | Pay extra for local variable capture (Sentry) | Local + instance variables included free |
70
- | No tool detects silently rescued exceptions | Swallowed exception detection built in |
127
+ - **Host-app safety** nothing in the capture path raises into your app; every subscriber and callback is rescue-wrapped, `Thread.current` is cleaned up in `ensure`, and the original exception is always re-raised. Variables, health and breadcrumbs are opt-in and off by default; storm protection is on by default and fails open.
128
+ - **Performance** — the storm-protection hot path is a digest plus an atomic increment with no I/O; the figures quoted below are a maintainer's single-machine measurements and no benchmark script ships with the gem yet.
129
+ - **Security** HTTP Basic Auth or your own `authenticate_with` lambda (Devise, Warden, session); your Rails `filter_parameters` are applied to params, variables and breadcrumbs; prompts are never recorded by LLM observability. Vulnerability reports: [SECURITY.md](SECURITY.md).
130
+ - **Compatibility** Rails 7.0–8.1, Ruby 3.2–4.0, PostgreSQL, MySQL/Trilogy or SQLite; `turbo-rails` plus ActionCable are needed for live updates (no polling fallback); the gem's own CSS/JS is inline but Bootstrap JS, Chart.js, highlight.js and Google Fonts load from CDNs, so it is not air-gap clean.
71
131
 
72
132
  ---
73
133
 
@@ -75,14 +135,14 @@ gem 'rails_error_dashboard'
75
135
 
76
136
  ### Core (Always Enabled)
77
137
 
78
- Error capture from controllers, jobs, and middleware. Custom-designed 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, mute/unmute (notification suppression), 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.
138
+ Error capture from controllers, jobs, and middleware. Custom-designed dashboard with dark/light mode, search, filtering, and real-time updates (the latter with `turbo-rails` + ActionCable in the host). Analytics with trend charts, severity breakdown, and spike detection. Workflow management with assignment, priority, snooze, mute/unmute (notification suppression), 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.
79
139
 
80
140
  ### Optional Features
81
141
 
82
142
  <details>
83
143
  <summary><strong>Storm Protection — Circuit Breaker + Adaptive Sampling</strong></summary>
84
144
 
85
- When the error rate spikes (a bad deploy throwing thousands of errors a minute), the nightmare scenario for any in-process tracker is amplifying the outage with its own database writes. Storm protection makes the gem **provably degrade itself first** — ON by default.
145
+ When the error rate spikes (a bad deploy throwing thousands of errors a minute), the nightmare scenario for any in-process tracker is amplifying the outage with its own database writes. Storm protection is designed to **shed the gem's own expensive work first** — ON by default. The behaviour is measured (see Overhead below), though a bundled, reproducible benchmark is still to come.
86
146
 
87
147
  - **Per-fingerprint caps:** past N occurrences/minute per error, context is shed, then rows are sampled deterministically (a fresh exemplar is always kept each minute)
88
148
  - **Global circuit breaker:** sustained floods flip the gem to count-only mode — zero per-event I/O, exact in-memory counts reconciled onto error records every 30s. Async mode is gated too (a SolidQueue enqueue is itself a DB write)
@@ -98,7 +158,7 @@ config.storm_open_threshold_per_second = 50 # per process
98
158
 
99
159
  All thresholds are per process and individually configurable. Disable with one flag.
100
160
 
101
- **Measured overhead** (Apple Silicon, Ruby 4.0): 2.4µs/error with protection active and calm, 2.95µs in count-only mode, 0.2µs when disabled against a 5µs budget. The check is a digest plus an atomic increment; there is no I/O on the hot path.
161
+ **Overhead:** the check is a digest plus an atomic increment; there is no I/O on the hot path. The maintainer's single-machine measurement (Apple Silicon, Ruby 4.0) was 2.4µs/error with protection active and calm, 2.95µs in count-only mode and 0.2µs when disabled, against a 5µs budget a reproducible benchmark script is not yet part of the gem.
102
162
  </details>
103
163
 
104
164
  <details>
@@ -108,7 +168,7 @@ See exactly what happened before the crash — SQL queries, controller actions,
108
168
 
109
169
  - Automatic capture — zero config beyond the enable flag
110
170
  - N+1 query detection with aggregate patterns page
111
- - Deprecation warnings with aggregate view
171
+ - Deprecation warnings with aggregate view (needs the host's deprecation behaviour to include `:notify`; only requests that later raised are seen)
112
172
  - Custom breadcrumbs via `RailsErrorDashboard.add_breadcrumb("checkout started", { cart_id: 123 })`
113
173
  - Safe by design — fixed-size ring buffer, thread-local, every subscriber wrapped in rescue
114
174
 
@@ -146,7 +206,7 @@ Cross-error N+1 detection grouped by SQL fingerprint, and aggregate deprecation
146
206
 
147
207
  ![N+1 Query Patterns](docs/images/n-plus-one-queries.png)
148
208
 
149
- Requires breadcrumbs to be enabled.
209
+ Requires breadcrumbs to be enabled. Deprecations are seen only when the host's `ActiveSupport::Deprecation` behaviour includes `:notify` (the production default does not) and only inside requests that later raised.
150
210
 
151
211
  [Complete documentation →](docs/FEATURES.md#n1-query-detection)
152
212
  </details>
@@ -154,7 +214,7 @@ Requires breadcrumbs to be enabled.
154
214
  <details>
155
215
  <summary><strong>Operational Health Panels — Jobs, Database, Cache, ActionCable</strong></summary>
156
216
 
157
- **Job Health** — Auto-detects Sidekiq, SolidQueue, or GoodJob. Per-error table with adapter badge, failed count (color-coded), sorted worst-first.
217
+ **Job Health** — Aggregates the queue stats captured on each error (Sidekiq, SolidQueue or GoodJob auto-detected; needs `enable_system_health`). Not a live queue view — a per-error table with adapter badge, failed count (color-coded), sorted worst-first.
158
218
 
159
219
  ![Job Health](docs/images/job-health.png)
160
220
 
@@ -184,12 +244,12 @@ config.enable_activestorage_tracking = true # requires enable_breadcrumbs = tru
184
244
  <details>
185
245
  <summary><strong>LLM Observability — Calls, Tokens, Cost, Tool Use</strong></summary>
186
246
 
187
- Capture every LLM call your app makes model, latency, token counts, estimated USD cost, and tool-use requests — as breadcrumbs on the error that follows. When a request crashes, you see the chat completion that preceded it: which model was called, how long it took, what it cost, and which tools it asked to invoke.
247
+ Capture your app's LLM calls through a Faraday middleware, OpenTelemetry GenAI spans or a manual notification; nothing is auto-instrumented — as breadcrumbs on the error that follows, with model, latency, token counts, estimated USD cost and tool-use requests. When a request crashes, you see the chat completion that preceded it: which model was called, how long it took, what it cost, and which tools it asked to invoke.
188
248
 
189
249
  - Three capture paths — pick whichever matches your stack
190
250
  - Cost estimated from a built-in pricing table (Claude 4.x, GPT-4o/o1, Gemini 2.5) — override per-model via `config.llm_pricing_overrides`
191
251
  - Tool-call requests summarized inline; tool *execution* spans captured separately via the OTel path
192
- - Content capture (prompts/completions) **OFF by default** — only token counts and metadata are recorded
252
+ - Prompts and completions are **never recorded** — only token counts and metadata (the `llm_observability_content_capture` flag is reserved and currently a no-op)
193
253
  - Same host-app safety guarantees as the rest of the gem — never raises, never blocks the request, every callback rescue-wrapped
194
254
 
195
255
  ```ruby
@@ -343,7 +403,7 @@ config.enable_git_blame = true
343
403
  <details>
344
404
  <summary><strong>Code Path Coverage (Diagnostic Mode)</strong></summary>
345
405
 
346
- Enable coverage via a dashboard button to see which production code paths were executed. Source code viewer overlays green checkmarks on executed lines and gray dots on unexecuted lines. Uses Ruby's `Coverage.setup(oneshot_lines: true)` — near-zero overhead, each line fires once. Zero overhead when off.
406
+ Enable coverage via a dashboard button to see which production code paths were executed. Source code viewer overlays green checkmarks on executed lines and gray dots on unexecuted lines. Uses Ruby's `Coverage.setup(oneshot_lines: true)` — near-zero overhead, each line fires once. Zero overhead when off. Diagnostic mode only: coverage is process-global (a multi-threaded Puma blends requests), held in memory and not persisted. No error tracker integrates this; Coverband does it standalone with persistence.
347
407
 
348
408
  ```ruby
349
409
  config.enable_coverage_tracking = true # shows Enable/Disable buttons on error detail page
@@ -405,9 +465,9 @@ Seven analysis engines built in:
405
465
  1. **Baseline Anomaly Alerts** — Statistical spike detection (mean + std dev) with intelligent cooldown
406
466
  2. **Fuzzy Error Matching** — Jaccard similarity + Levenshtein distance to find related errors
407
467
  3. **Co-occurring Errors** — Detect errors that happen together within configurable time windows
408
- 4. **Error Cascade Detection** — Identify chains (A causes B causes C) with probability and delays
468
+ 4. **Error Cascade Detection** — Identify potential cascades (A is followed by B is followed by C) with probability and delays — temporal association, not proven causation
409
469
  5. **Error Correlation Analysis** — Correlate errors with app versions, git commits, and users
410
- 6. **Platform Comparison** — iOS vs Android vs Web health metrics side-by-side
470
+ 6. **Platform Comparison** — iOS vs Android vs API health metrics side-by-side
411
471
  7. **Occurrence Pattern Detection** — Cyclical patterns (business hours, weekends) and burst detection
412
472
 
413
473
  [Complete documentation →](docs/FEATURES.md#advanced-analytics-features)
@@ -437,7 +497,7 @@ config.enable_instance_variables = true
437
497
  <details>
438
498
  <summary><strong>Swallowed Exception Detection</strong></summary>
439
499
 
440
- Detect exceptions that are raised but silently rescued — the hardest bugs to find. No other error tracker does this.
500
+ Detect exceptions that are raised but silently rescued — the hardest bugs to find. Only Datadog's paid APM detects rescued exceptions (Ruby 3.3+, and only inside a traced request); RED does it free, without an APM span, and aggregates the raise-vs-rescue ratio per location — no other tracker does that.
441
501
 
442
502
  - Uses TracePoint(`:raise`) + TracePoint(`:rescue`) to track exception lifecycle
443
503
  - Identifies code paths where exceptions are caught but never logged or re-raised
@@ -478,7 +538,8 @@ config.enable_diagnostic_dump = true
478
538
  Track Rack Attack security events (throttles, blocklists, tracks) as breadcrumbs attached to errors, with a dedicated summary page.
479
539
 
480
540
  - Captures throttle, blocklist, and track events automatically
481
- - Dashboard page at `/errors/rack_attack_summary` with event breakdown
541
+ - Dashboard page at `/errors/rack_attack_summary` with event breakdown and per-rule stats — rack-attack ships no UI of its own
542
+ - Classifies AI-agent user agents (GPTBot, ClaudeBot, …) on `track` events
482
543
  - Requires breadcrumbs to be enabled
483
544
 
484
545
  ```ruby
@@ -496,7 +557,7 @@ Capture unhandled exceptions that crash the Ruby process via an `at_exit` hook
496
557
  - Disk-based fallback: writes crash data to disk because the database may be unavailable during shutdown
497
558
  - Imported automatically on next boot
498
559
  - Captures exception details, backtrace, uptime, GC stats, thread count, and cause chain
499
- - A self-hosted only feature impossible for SaaS tools
560
+ - Honeybadger, Bugsnag and AppSignal have `at_exit` reporters too; RED's writes to disk and imports at next boot because the database may already be gone during shutdown
500
561
 
501
562
  ```ruby
502
563
  config.enable_crash_capture = true
@@ -617,7 +678,7 @@ end
617
678
 
618
679
  ## Languages
619
680
 
620
- The dashboard, its emails and its notification payloads are translated. Eleven locales ship:
681
+ RED ships in English with machine-translated previews for ten additional languages, covering the dashboard, its emails and its notification payloads. Native-speaking Rails developers are invited to review and improve them; once a locale has been reviewed it will be marked individually as community-reviewed. Eleven locales ship:
621
682
 
622
683
  | Locale | Language | Status |
623
684
  |---|---|---|
@@ -661,13 +722,13 @@ SQLite, PostgreSQL, and MySQL/Trilogy — in either shared or separate-database
661
722
  Yes. It runs entirely inside your own Rails process — no external services, no SDK calling out, no per-event pricing. Error data never leaves your infrastructure.
662
723
 
663
724
  **Does it capture local variables like Sentry?**
664
- Yes — local **and** instance variables at the moment the exception is raised, via `TracePoint(:raise)`, with sensitive-data filtering and configurable limits. This is opt-in and a capability Sentry charges extra for.
725
+ Yes — local **and** instance variables at the moment the exception is raised, via `TracePoint(:raise)`, with sensitive-data filtering and configurable limits. It is opt-in. (Sentry's SDK can also capture locals as an opt-in option; RED adds instance variables and applies your Rails `filter_parameters` automatically.)
665
726
 
666
727
  **Will a flood of errors take down my app?**
667
- No. Storm protection (a circuit breaker with adaptive sampling, **ON by default**) makes the gem degrade itself first during error floods — occurrence counts stay exact while it sheds the expensive work. Measured hot-path overhead is ~2.4µs/error.
728
+ No. Storm protection (a circuit breaker with adaptive sampling, **ON by default**) makes the gem degrade itself first during error floods — occurrence counts stay exact while it sheds the expensive work, and a Storm History page shows exactly what was shed. There is no I/O on the hot path the check is a digest and an atomic increment.
668
729
 
669
730
  **Does it work with my background jobs?**
670
- Yes — it auto-detects and supports Sidekiq, SolidQueue, and GoodJob, and can log errors asynchronously through any of them.
731
+ Yes — errors raised in jobs are captured, and it can log errors asynchronously through Sidekiq or SolidQueue (or the in-process `:async` adapter). Sidekiq, SolidQueue and GoodJob are all auto-detected for the job-queue stats stored on each error.
671
732
 
672
733
  **Does it work with my authentication?**
673
734
  Yes — HTTP Basic Auth out of the box, or a custom `authenticate_with` lambda that integrates with Devise, Warden, or session-based auth.
@@ -694,7 +755,7 @@ Rails 7.0–8.1 and Ruby 3.2–4.0.
694
755
  - **[Batch Operations](docs/guides/BATCH_OPERATIONS.md)** — Bulk resolve/delete
695
756
  - **[Real-Time Updates](docs/guides/REAL_TIME_UPDATES.md)** — Live dashboard
696
757
  - **[Error Trends](docs/guides/ERROR_TREND_VISUALIZATIONS.md)** — Charts and analytics
697
- - **[Translations](docs/guides/TRANSLATIONS.md)** — Seven shipped locales, correcting a string, adding a language
758
+ - **[Translations](docs/guides/TRANSLATIONS.md)** — Eleven shipped locales, correcting a string, adding a language
698
759
 
699
760
  ### Advanced
700
761
  - **[Multi-App Support](docs/MULTI_APP_PERFORMANCE.md)** — Track multiple applications
@@ -703,7 +764,7 @@ Rails 7.0–8.1 and Ruby 3.2–4.0.
703
764
  - **[Customization](docs/CUSTOMIZATION.md)** — Customize everything
704
765
  - **[Database Options](docs/guides/DATABASE_OPTIONS.md)** — Separate database setup
705
766
  - **[Database Optimization](docs/guides/DATABASE_OPTIMIZATION.md)** — Performance tuning
706
- - **[Mobile App Integration](docs/guides/MOBILE_APP_INTEGRATION.md)** — React Native, Flutter, etc.
767
+ - **[Mobile App Integration](docs/guides/MOBILE_APP_INTEGRATION.md)** — log mobile-originated errors through your own API endpoint, tagged by platform
707
768
  - **[FAQ](docs/FAQ.md)** — Common questions answered
708
769
 
709
770
  [View all documentation →](docs/README.md)
@@ -722,7 +783,7 @@ Built with **CQRS (Command/Query Responsibility Segregation)**:
722
783
 
723
784
  ## Testing
724
785
 
725
- 4,200+ tests covering unit, integration, and browser-based system tests.
786
+ An RSpec suite of unit, request and browser-based system specs runs in CI on every supported Rails version (see the Tests badge above); the current count lives in the CI log rather than here, where it would go stale.
726
787
 
727
788
  ```bash
728
789
  bundle exec rspec # Full suite
@@ -16,6 +16,17 @@ module RailsErrorDashboard
16
16
  # stamped by the first occurrence that claims it, so history migrates
17
17
  # itself without a backfill. An exact match always wins over a NULL one.
18
18
  class FindOrIncrementError
19
+ # Context that describes THIS occurrence rather than the error as a
20
+ # group. It is refreshed on every recurrence so the row always shows the
21
+ # latest moment of failure, not the first one in the 24 h window. Keys
22
+ # absent from @attributes (feature disabled, column not migrated, or a
23
+ # storm :lite capture that shed context) leave the stored payload alone —
24
+ # a shed capture must never blank out a good snapshot.
25
+ REFRESHED_CONTEXT = %i[
26
+ breadcrumbs system_health local_variables instance_variables
27
+ http_method hostname content_type request_duration_ms
28
+ ].freeze
29
+
19
30
  def self.call(error_hash, attributes = {})
20
31
  new(error_hash, attributes).call
21
32
  end
@@ -69,6 +80,13 @@ module RailsErrorDashboard
69
80
  .order(Arel.sql("CASE WHEN environment IS NULL THEN 1 ELSE 0 END"))
70
81
  end
71
82
 
83
+ # The subset of REFRESHED_CONTEXT this occurrence actually captured.
84
+ def latest_context
85
+ REFRESHED_CONTEXT.each_with_object({}) do |key, refreshed|
86
+ refreshed[key] = @attributes[key] unless @attributes[key].nil?
87
+ end
88
+ end
89
+
72
90
  # {} unless this is a legacy NULL-environment row being claimed.
73
91
  def environment_adoption(error)
74
92
  return {} unless ErrorLog.column_names.include?("environment")
@@ -86,6 +104,7 @@ module RailsErrorDashboard
86
104
  request_params: @attributes[:request_params] || error.request_params,
87
105
  user_agent: @attributes[:user_agent] || error.user_agent,
88
106
  ip_address: @attributes[:ip_address] || error.ip_address,
107
+ **latest_context,
89
108
  **environment_adoption(error)
90
109
  )
91
110
  error
@@ -103,6 +122,7 @@ module RailsErrorDashboard
103
122
  request_params: @attributes[:request_params] || error.request_params,
104
123
  user_agent: @attributes[:user_agent] || error.user_agent,
105
124
  ip_address: @attributes[:ip_address] || error.ip_address,
125
+ **latest_context,
106
126
  **environment_adoption(error)
107
127
  }
108
128
  attrs[:reopened_at] = Time.current if ErrorLog.column_names.include?("reopened_at")
@@ -126,6 +146,7 @@ module RailsErrorDashboard
126
146
  retry_existing.update!(
127
147
  occurrence_count: retry_existing.occurrence_count + 1,
128
148
  last_seen_at: Time.current,
149
+ **latest_context,
129
150
  **environment_adoption(retry_existing)
130
151
  )
131
152
  retry_existing
@@ -1,3 +1,3 @@
1
1
  module RailsErrorDashboard
2
- VERSION = "0.11.0"
2
+ VERSION = "0.11.1"
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rails_error_dashboard
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.11.0
4
+ version: 0.11.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Anjan Jagirdar
@@ -219,29 +219,24 @@ dependencies:
219
219
  - - "~>"
220
220
  - !ruby/object:Gem::Version
221
221
  version: '0.15'
222
- description: 'Own your errors. Own your stack. A fully open-source, self-hosted error
223
- tracking Rails engine a free Sentry alternative that runs entirely inside your
224
- own process, with no external services and zero recurring cost. Captures what SaaS
225
- tools charge extra for: local and instance variables at the moment of failure (via
226
- TracePoint), exception cause chains, swallowed-exception detection, breadcrumbs,
227
- and system-health snapshots (GC, memory, threads, connection pool, Puma). Plus N+1
228
- query detection, storm protection (a circuit breaker that shields your app from
229
- error floods, ON by default), multi-app support, error sampling, and async logging
230
- via Sidekiq, SolidQueue, or GoodJob. Runs on SQLite, PostgreSQL, or MySQL/Trilogy
231
- in your app''s existing database or an isolated separate error database. Beautiful
232
- dashboard UI (dark/light), multi-channel notifications (Slack, Email, Discord, PagerDuty,
233
- webhooks), workflow management, advanced analytics, platform detection (iOS/Android/Web/API),
234
- and two-way issue sync with GitHub, GitLab, Codeberg, and Linear. Also: LLM observability,
235
- AI-powered debugging help, and OpenTelemetry span export. The dashboard, mailers
236
- and notification payloads are translated into 11 languages: English, German, Spanish,
237
- French, Brazilian Portuguese, Italian, Polish, Russian, Ukrainian, Japanese, and
238
- Simplified Chinese 1,515 source strings, set via config.dashboard_locale with
239
- a per-user picker. RED translates through its own private I18n backend and never
240
- mutates your app''s I18n; a missing translation falls back to English. Backtraces,
241
- exception names and webhook payload keys stay English by design. The ten non-English
242
- locales are machine-translated and not yet reviewed by native speakers. 5-minute
243
- setup, works out-of-the-box. Rails 7.0-8.1, Ruby 3.2-4.0. BETA: API may change before
244
- v1.0.0. Live demo: https://rails-error-dashboard.anjan.dev (gandalf/youshallnotpass)'
222
+ description: 'Rails Error Dashboard (RED) is an open-source, self-hosted Rails engine
223
+ for investigating production exceptions without sending error data to a monitoring
224
+ vendor. It groups errors and records request context and cause chains and, when
225
+ enabled, breadcrumbs plus local and instance variables captured before Ruby unwinds
226
+ the stack. RED attaches Rails and Ruby runtime health to the error record on every
227
+ captured occurrence, including Active Record pool, Puma, background jobs, GC, memory,
228
+ threads, file descriptors and system pressure. Built-in storm protection progressively
229
+ sheds expensive context and I/O during error floods while retaining useful exemplars
230
+ and exact occurrence counts. Run RED with your application''s database or an isolated
231
+ error database. It supports PostgreSQL, MySQL/Trilogy and SQLite, and includes workflow,
232
+ notifications (Slack, Email, Discord, PagerDuty, webhooks), two-way issue sync with
233
+ GitHub, GitLab, Codeberg and Linear, Copy as RSpec/curl/LLM, swallowed-exception
234
+ detection, LLM observability without prompt capture, OpenTelemetry span export and
235
+ Rails-specific operational views. The dashboard is translated into 11 languages
236
+ (machine-translated outside English, awaiting native review). A self-hosted Sentry
237
+ alternative that keeps error data in your own database. The gem is MIT and free
238
+ forever. Supports Rails 7.0-8.1 and Ruby 3.2-4.0. Beta: APIs may change before 1.0.
239
+ Live demo: https://rails-error-dashboard.anjan.dev'
245
240
  email:
246
241
  - anjan.jagirdar@gmail.com
247
242
  executables: []
@@ -561,7 +556,7 @@ metadata:
561
556
  funding_uri: https://github.com/sponsors/AnjanJ
562
557
  post_install_message: |
563
558
  ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
564
- RED (Rails Error Dashboard) v0.11.0
559
+ RED (Rails Error Dashboard) v0.11.1
565
560
  ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
566
561
 
567
562
  First install:
@@ -599,6 +594,6 @@ required_rubygems_version: !ruby/object:Gem::Requirement
599
594
  requirements: []
600
595
  rubygems_version: 3.6.9
601
596
  specification_version: 4
602
- summary: Self-hosted error tracking for Rails local variables, system health, separate
603
- or shared database, dashboard in 11 languages. A free, open-source Sentry alternative.
597
+ summary: Rails-native, self-hosted error monitoring with exception-time Ruby state,
598
+ runtime health, and storm-safe capture.
604
599
  test_files: []