rails_error_dashboard 0.2.2 → 0.2.4

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: a1cc76e092da14b5ec94ca8b6977837fdd10b87946d46249bfd8c5f5e300874a
4
- data.tar.gz: 5dab8f740555c28018905a9b031df6bff749cddd470d131ba0a807dbe16710e2
3
+ metadata.gz: 68039a8977f567c9175c9a1493c8162ff9d05cef23abe3f2cba629e815608bb2
4
+ data.tar.gz: e448d91e7038288916b705c048f1e9f7e2debc654e4bf136c243190a6a9a2a0b
5
5
  SHA512:
6
- metadata.gz: fee35c5ab9248ab74aed67f2171fec3cc1acb143f6bf84c3f2c017027d1b4825bb2b77b6d6d9e6d93422065c0257bd6b8c3e6fcca7c51fc1a79d68639159d8bd
7
- data.tar.gz: 9407c784ed243265cf34970d1deac082e4d5748c1e9899984370735e48eb93e3519ce09ed597054d9f26564ee079222a65e518eb885e8b92e9c6d39fe6922f64
6
+ metadata.gz: '034283ec93474130ec2786c3c0de00fcba1d15e2b358b167e0856e95b2fc62398cd71f0cef767ab7a4ea538d60cf7fc9dbfb56c0951efa9bf19eded0ba5a2c9e'
7
+ data.tar.gz: 40496fc117f9695d0da1cbb0ef9b5d4a1ceea6dc13c2fdd73c8ff262e60424bc142646af7ff442d880858e8c2eb10d3fbb9cb00c7d064117a24733f774cfe062
data/README.md CHANGED
@@ -1,6 +1,7 @@
1
1
  # Rails Error Dashboard
2
2
 
3
3
  [![Gem Version](https://badge.fury.io/rb/rails_error_dashboard.svg)](https://badge.fury.io/rb/rails_error_dashboard)
4
+ [![Downloads](https://img.shields.io/gem/dt/rails_error_dashboard)](https://rubygems.org/gems/rails_error_dashboard)
4
5
  [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
5
6
  [![Tests](https://github.com/AnjanJ/rails_error_dashboard/workflows/Tests/badge.svg)](https://github.com/AnjanJ/rails_error_dashboard/actions)
6
7
 
@@ -26,6 +27,20 @@ Username: `gandalf` · Password: `youshallnotpass`
26
27
 
27
28
  Experience the full dashboard with 480+ realistic Rails errors, LOTR-themed demo data, cause chains, enriched context, auto-reopened errors, and all features enabled.
28
29
 
30
+ ### Screenshots
31
+
32
+ **Dashboard Overview** — Real-time error stats, severity breakdown, and trend charts at a glance.
33
+
34
+ ![Dashboard Overview](docs/images/dashboard-overview.png)
35
+
36
+ **Error Detail** — Full stack trace, cause chain, enriched context, and workflow management.
37
+
38
+ ![Error Detail](docs/images/error-detail.png)
39
+
40
+ **Analytics** — Error trends, platform health, correlation insights, and pattern detection.
41
+
42
+ ![Analytics](docs/images/analytics.png)
43
+
29
44
  ---
30
45
 
31
46
  ### ⚠️ BETA SOFTWARE
@@ -144,6 +144,8 @@
144
144
  </h6>
145
145
  <div class="cause-chain">
146
146
  <% cause_chain.each_with_index do |cause, index| %>
147
+ <% cause_bt = cause["backtrace"] %>
148
+ <% cause_bt = cause_bt.is_a?(String) ? cause_bt.split("\n") : Array(cause_bt) %>
147
149
  <div class="card mb-2 border-warning">
148
150
  <div class="card-header bg-warning bg-opacity-10 py-2">
149
151
  <div class="d-flex justify-content-between align-items-center">
@@ -151,7 +153,7 @@
151
153
  <small class="text-muted">Caused by<%= " (##{index + 1})" if cause_chain.length > 1 %>:</small>
152
154
  <strong class="ms-1"><code><%= cause["class_name"] %></code></strong>
153
155
  </div>
154
- <% if cause["backtrace"].present? %>
156
+ <% if cause_bt.any? %>
155
157
  <button class="btn btn-sm btn-outline-secondary py-0" type="button"
156
158
  data-bs-toggle="collapse"
157
159
  data-bs-target="#cause-backtrace-<%= index %>"
@@ -164,11 +166,11 @@
164
166
  <div class="card-body py-2">
165
167
  <small><%= cause["message"] %></small>
166
168
  </div>
167
- <% if cause["backtrace"].present? %>
169
+ <% if cause_bt.any? %>
168
170
  <div class="collapse" id="cause-backtrace-<%= index %>">
169
171
  <div class="card-body p-0 border-top">
170
172
  <div class="code-block p-2" style="max-height: 200px; overflow-y: auto; overflow-x: auto; font-size: 0.8rem;">
171
- <pre class="mb-0"><code><% cause["backtrace"].each do |line| %><%= line %>
173
+ <pre class="mb-0"><code><% cause_bt.each do |line| %><%= line %>
172
174
  <% end %></code></pre>
173
175
  </div>
174
176
  </div>
@@ -66,7 +66,7 @@ class CreateRailsErrorDashboardCompleteSchema < ActiveRecord::Migration[7.0]
66
66
  t.integer :priority_level, default: 0
67
67
 
68
68
  # Application association (from 20260106094233)
69
- t.integer :application_id, null: false
69
+ t.bigint :application_id, null: false
70
70
 
71
71
  # Exception cause chain (from 20260220000001)
72
72
  t.text :exception_cause
@@ -129,7 +129,7 @@ class CreateRailsErrorDashboardCompleteSchema < ActiveRecord::Migration[7.0]
129
129
 
130
130
  # Create error_occurrences table (from 20251225100236)
131
131
  create_table :rails_error_dashboard_error_occurrences do |t|
132
- t.integer :error_log_id, null: false
132
+ t.bigint :error_log_id, null: false
133
133
  t.datetime :occurred_at, null: false
134
134
  t.integer :user_id
135
135
  t.string :request_id
@@ -143,8 +143,8 @@ class CreateRailsErrorDashboardCompleteSchema < ActiveRecord::Migration[7.0]
143
143
 
144
144
  # Create cascade_patterns table (from 20251225101920)
145
145
  create_table :rails_error_dashboard_cascade_patterns do |t|
146
- t.integer :parent_error_id, null: false
147
- t.integer :child_error_id, null: false
146
+ t.bigint :parent_error_id, null: false
147
+ t.bigint :child_error_id, null: false
148
148
  t.integer :frequency, default: 1, null: false
149
149
  t.float :avg_delay_seconds
150
150
  t.float :cascade_probability
@@ -177,7 +177,7 @@ class CreateRailsErrorDashboardCompleteSchema < ActiveRecord::Migration[7.0]
177
177
 
178
178
  # Create error_comments table (from 20251226020100)
179
179
  create_table :rails_error_dashboard_error_comments do |t|
180
- t.integer :error_log_id, null: false
180
+ t.bigint :error_log_id, null: false
181
181
  t.string :author_name, null: false
182
182
  t.text :body, null: false
183
183
  t.timestamps
@@ -224,7 +224,29 @@ module RailsErrorDashboard
224
224
  @database_name = "error_dashboard"
225
225
  @application_name = detect_application_name
226
226
 
227
+ say "\n Is this the first app using the shared error database,", :white
228
+ say " or are you connecting to one that already exists?\n", :white
229
+ say " a) First app - create a new shared error database", :white
230
+ say " b) Existing - connect to a database already used by another app", :white
231
+ say "\n"
232
+
233
+ shared_response = ask(" Choose (a/b):", :yellow, limited_to: [ "a", "A", "b", "B", "" ])
234
+
235
+ if shared_response.downcase == "b"
236
+ say "\n Enter the base database name from your other app's database.yml.", :white
237
+ say " We'll append _development/_production automatically.", :white
238
+ say " (e.g., if your DB is 'my_errors_development', enter 'my_errors'):\n", :white
239
+ @shared_db_name = ask(" Database name:", :yellow)
240
+ @shared_db_name = @shared_db_name.strip
241
+ # Strip environment suffixes in case the user pasted the full name
242
+ @shared_db_name = @shared_db_name.sub(/_(development|production|test)$/, "")
243
+ @shared_db_name = "shared_errors" if @shared_db_name.empty?
244
+ else
245
+ @shared_db_name = "shared_errors"
246
+ end
247
+
227
248
  say "\n Database key: error_dashboard", :green
249
+ say " Shared database: #{@shared_db_name}", :green
228
250
  say " Application name: #{@application_name}", :green
229
251
  say " This app will share the error database with your other apps.", :white
230
252
  say "\n"
@@ -270,7 +292,31 @@ module RailsErrorDashboard
270
292
  end
271
293
 
272
294
  def copy_migrations
273
- rails_command "rails_error_dashboard:install:migrations"
295
+ source_dir = File.expand_path("../../../../db/migrate", __dir__)
296
+ migrate_subdir = @enable_separate_database ? "db/error_dashboard_migrate" : "db/migrate"
297
+ target_dir = File.join(destination_root, migrate_subdir)
298
+
299
+ FileUtils.mkdir_p(target_dir)
300
+
301
+ # Check which migrations are already installed (by descriptive name, ignoring timestamp)
302
+ existing = Dir.glob(File.join(target_dir, "*rails_error_dashboard*.rb")).map { |f|
303
+ File.basename(f).sub(/^\d+_/, "")
304
+ }.to_set
305
+
306
+ timestamp = Time.now.utc.strftime("%Y%m%d%H%M%S").to_i
307
+
308
+ Dir.glob(File.join(source_dir, "*.rb")).sort.each do |source_file|
309
+ basename = File.basename(source_file)
310
+ name_without_ts = basename.sub(/^\d+_/, "")
311
+ suffixed = name_without_ts.sub(/\.rb$/, ".rails_error_dashboard.rb")
312
+
313
+ next if existing.include?(suffixed)
314
+
315
+ FileUtils.cp(source_file, File.join(target_dir, "#{timestamp}_#{suffixed}"))
316
+ timestamp += 1
317
+ end
318
+
319
+ say_status "copied", "migrations to #{migrate_subdir}", :green
274
320
  end
275
321
 
276
322
  def add_route
@@ -432,7 +478,8 @@ module RailsErrorDashboard
432
478
  say " error_dashboard:", :white
433
479
  say " <<: *default", :white
434
480
  if @enable_multi_app
435
- say " database: shared_errors_development", :white
481
+ shared_db_base = @shared_db_name || "shared_errors"
482
+ say " database: #{shared_db_base}_development", :white
436
483
  else
437
484
  say " database: #{app_name_snake}_errors_development", :white
438
485
  end
@@ -445,7 +492,8 @@ module RailsErrorDashboard
445
492
  say " error_dashboard:", :white
446
493
  say " <<: *default", :white
447
494
  if @enable_multi_app
448
- say " database: shared_errors_production", :white
495
+ shared_db_base = @shared_db_name || "shared_errors"
496
+ say " database: #{shared_db_base}_production", :white
449
497
  else
450
498
  say " database: #{app_name_snake}_errors_production", :white
451
499
  end
@@ -9,6 +9,15 @@ module RailsErrorDashboard
9
9
  if RailsErrorDashboard.configuration&.use_separate_database
10
10
  database_name = RailsErrorDashboard.configuration&.database || :error_dashboard
11
11
 
12
+ # Guard: skip connects_to if the database config doesn't exist yet in database.yml.
13
+ # This happens during `rails generate` when the initializer was just created but
14
+ # the user hasn't added the database.yml entry yet.
15
+ db_configs = ActiveRecord::Base.configurations.configs_for(env_name: Rails.env)
16
+ unless db_configs.any? { |c| c.name == database_name.to_s }
17
+ Rails.logger.warn "[Rails Error Dashboard] Separate database '#{database_name}' is not configured in database.yml for the '#{Rails.env}' environment. Skipping connects_to. See docs/guides/DATABASE_OPTIONS.md"
18
+ next
19
+ end
20
+
12
21
  RailsErrorDashboard::ErrorLogsRecord.connects_to(
13
22
  database: { writing: database_name, reading: database_name }
14
23
  )
@@ -1,3 +1,3 @@
1
1
  module RailsErrorDashboard
2
- VERSION = "0.2.2"
2
+ VERSION = "0.2.4"
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.2.2
4
+ version: 0.2.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Anjan Jagirdar
@@ -225,12 +225,14 @@ dependencies:
225
225
  - - "~>"
226
226
  - !ruby/object:Gem::Version
227
227
  version: '0.15'
228
- description: "Own your errors. Own your stack. A fully open-source, self-hosted error
229
- dashboard for solo founders, indie hackers, and small teams. Professional error
230
- tracking with beautiful UI, multi-channel notifications (Slack, Email, Discord,
231
- PagerDuty), platform detection (iOS/Android/Web/API), and analytics. 5-minute setup,
232
- works out-of-the-box. Rails 7.0-8.1 compatible. ⚠️ BETA: API may change before v1.0.0.
233
- \U0001F3AE Live demo: https://rails-error-dashboard.anjan.dev (gandalf/youshallnotpass)"
228
+ description: 'Own your errors. Own your stack. A fully open-source, self-hosted error
229
+ tracking Rails engine for solo founders, indie hackers, and small teams. Exception
230
+ monitoring with beautiful dashboard UI, multi-channel notifications (Slack, Email,
231
+ Discord, PagerDuty), platform detection (iOS/Android/Web/API), advanced analytics,
232
+ workflow management, and cause chain capture. A self-hosted Sentry alternative with
233
+ 5-minute setup that works out-of-the-box. Production error monitoring for Rails
234
+ 7.0-8.1. BETA: API may change before v1.0.0. Live demo: https://rails-error-dashboard.anjan.dev
235
+ (gandalf/youshallnotpass)'
234
236
  email:
235
237
  - anjan.jagirdar@gmail.com
236
238
  executables: []
@@ -393,7 +395,7 @@ files:
393
395
  - lib/rails_error_dashboard/version.rb
394
396
  - lib/tasks/error_dashboard.rake
395
397
  - lib/tasks/rails_error_dashboard_tasks.rake
396
- homepage: https://github.com/AnjanJ/rails_error_dashboard
398
+ homepage: https://AnjanJ.github.io/rails_error_dashboard
397
399
  licenses:
398
400
  - MIT
399
401
  metadata:
@@ -403,7 +405,7 @@ metadata:
403
405
  documentation_uri: https://AnjanJ.github.io/rails_error_dashboard
404
406
  bug_tracker_uri: https://github.com/AnjanJ/rails_error_dashboard/issues
405
407
  post_install_message: "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n
406
- \ Rails Error Dashboard v0.2.2\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n\n\U0001F195
408
+ \ Rails Error Dashboard v0.2.4\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n\n\U0001F195
407
409
  First time? Quick start:\n rails generate rails_error_dashboard:install\n rails
408
410
  db:migrate\n # Add to config/routes.rb:\n mount RailsErrorDashboard::Engine
409
411
  => '/error_dashboard'\n\n\U0001F504 Upgrading from v0.1.x?\n rails db:migrate\n
@@ -426,6 +428,5 @@ required_rubygems_version: !ruby/object:Gem::Requirement
426
428
  requirements: []
427
429
  rubygems_version: 4.0.3
428
430
  specification_version: 4
429
- summary: Self-hosted Rails error monitoring free, forever. Zero SaaS fees, zero
430
- lock-in.
431
+ summary: Self-hosted error tracking and exception monitoring for Rails. Free, forever.
431
432
  test_files: []