rails_error_dashboard 0.14.2 → 0.14.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.
Files changed (38) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +36 -18
  3. data/app/helpers/rails_error_dashboard/application_helper.rb +8 -0
  4. data/app/jobs/rails_error_dashboard/retention_cleanup_job.rb +27 -23
  5. data/app/views/layouts/rails_error_dashboard.html.erb +13 -0
  6. data/config/locales/de.yml +4 -0
  7. data/config/locales/en.yml +5 -0
  8. data/config/locales/es.yml +4 -0
  9. data/config/locales/fr.yml +4 -0
  10. data/config/locales/it.yml +4 -0
  11. data/config/locales/ja.yml +4 -0
  12. data/config/locales/pl.yml +4 -0
  13. data/config/locales/pt-BR.yml +4 -0
  14. data/config/locales/ru.yml +4 -0
  15. data/config/locales/uk.yml +4 -0
  16. data/config/locales/zh-CN.yml +4 -0
  17. data/db/migrate/20251225074653_remove_environment_from_error_logs.rb +9 -0
  18. data/lib/generators/rails_error_dashboard/install/install_generator.rb +45 -50
  19. data/lib/generators/rails_error_dashboard/install/templates/initializer.rb +17 -10
  20. data/lib/generators/rails_error_dashboard/solid_queue/solid_queue_generator.rb +41 -21
  21. data/lib/generators/rails_error_dashboard/uninstall/uninstall_generator.rb +79 -66
  22. data/lib/rails_error_dashboard/commands/drop_all_tables.rb +77 -0
  23. data/lib/rails_error_dashboard/commands/log_error.rb +5 -2
  24. data/lib/rails_error_dashboard/configuration.rb +67 -4
  25. data/lib/rails_error_dashboard/engine.rb +10 -4
  26. data/lib/rails_error_dashboard/logger.rb +11 -3
  27. data/lib/rails_error_dashboard/middleware/rate_limiter.rb +15 -43
  28. data/lib/rails_error_dashboard/plugin.rb +30 -0
  29. data/lib/rails_error_dashboard/queries/errors_list.rb +3 -1
  30. data/lib/rails_error_dashboard/queries/uninstall_plan.rb +63 -0
  31. data/lib/rails_error_dashboard/services/exception_filter.rb +4 -1
  32. data/lib/rails_error_dashboard/services/solid_queue_config_check.rb +261 -0
  33. data/lib/rails_error_dashboard/version.rb +1 -1
  34. data/lib/rails_error_dashboard.rb +3 -0
  35. data/lib/tasks/error_dashboard.rake +77 -5
  36. data/lib/tasks/rails_error_dashboard_tasks.rake +37 -43
  37. metadata +5 -3
  38. data/lib/generators/rails_error_dashboard/solid_queue/templates/queue.yml +0 -55
@@ -34,6 +34,25 @@ namespace :error_dashboard do
34
34
  end
35
35
  checks_passed += 1
36
36
 
37
+ # 2b. Separate database: the database.yml entry for this environment. Without
38
+ # it the engine skips connects_to and RED uses the main database, which
39
+ # usually has no RED tables, so nothing is recorded.
40
+ if config.use_separate_database
41
+ print " Error database entry... "
42
+ db_name = config.database || :error_dashboard
43
+ if config.separate_database_entry?
44
+ puts "OK"
45
+ checks_passed += 1
46
+ else
47
+ puts "FAILED"
48
+ puts " config/database.yml has no '#{db_name}' entry for the '#{Rails.env}' environment."
49
+ puts " RED is using the main database instead, so errors are not recorded in the error database."
50
+ puts " Add '#{db_name}:' under '#{Rails.env}:' with migrations_paths: db/error_dashboard_migrate"
51
+ puts " (see docs/guides/DATABASE_OPTIONS.md), then restart."
52
+ checks_failed += 1
53
+ end
54
+ end
55
+
37
56
  # 3. Database connection
38
57
  print " Database connection... "
39
58
  begin
@@ -177,8 +196,12 @@ namespace :error_dashboard do
177
196
  if config.refuse_default_credentials?
178
197
  puts "WARNING - #{label} outside development and test!"
179
198
  checks_failed += 1
199
+ elsif problem == :blank
200
+ # The login denies everyone on a blank credential, in every environment.
201
+ puts "WARNING - #{label}: every login is denied"
202
+ warnings += 1
180
203
  else
181
- puts "OK (#{label} - change before production)"
204
+ puts "OK (#{label} - set ERROR_DASHBOARD_USER and ERROR_DASHBOARD_PASSWORD before deploying)"
182
205
  warnings += 1
183
206
  end
184
207
  elsif config.dashboard_password == RailsErrorDashboard::Configuration::DEFAULT_DASHBOARD_PASSWORD
@@ -189,6 +212,53 @@ namespace :error_dashboard do
189
212
  checks_passed += 1
190
213
  end
191
214
 
215
+ # 9. Solid Queue config. A section with workers and no dispatchers runs no
216
+ # dispatcher, so no delayed job ever runs, the app's own included; the
217
+ # retired rails_error_dashboard:solid_queue generator wrote exactly that.
218
+ # Checked whenever Solid Queue is loaded, not only when it is the current
219
+ # adapter: Rails 8 sets it in production only, and verify usually runs locally.
220
+ queue_check = RailsErrorDashboard::Services::SolidQueueConfigCheck
221
+ queue_config = queue_check.config_path(Rails.root)
222
+ if defined?(SolidQueue) && queue_config.exist?
223
+ print " Solid Queue config... "
224
+ environments = queue_check.app_environments(Rails.root).presence || [ Rails.env.to_s ]
225
+ result = queue_check.call(queue_config, environments: environments)
226
+ if result[:skipped]
227
+ puts "SKIPPED (#{result[:skipped]})"
228
+ warnings += 1
229
+ elsif result[:problems].any?
230
+ puts "FAILED"
231
+ result[:problems].each { |problem| puts " - #{problem}" }
232
+ queue_check::FIX.each { |line| puts " #{line}" }
233
+ checks_failed += 1
234
+ else
235
+ puts "OK"
236
+ checks_passed += 1
237
+ end
238
+ end
239
+
240
+ # 10. json 3.0 breaks Rails before 8.1.4 and 7.2.4: dashboard pages return
241
+ # 500 and captures can fail, with no error message. The bug is in Rails.
242
+ json_version = Gem.loaded_specs["json"]&.version
243
+ if json_version && json_version >= Gem::Version.new("3")
244
+ print " json gem... "
245
+ rails_version = Gem::Version.new(Rails.version)
246
+ series = rails_version.segments.first(2)
247
+ json3_ok = (series == [ 8, 1 ] && rails_version >= Gem::Version.new("8.1.4")) ||
248
+ (series == [ 7, 2 ] && rails_version >= Gem::Version.new("7.2.4")) ||
249
+ (series <=> [ 8, 1 ]) == 1
250
+ if json3_ok
251
+ puts "OK (json #{json_version}, Rails #{Rails.version})"
252
+ checks_passed += 1
253
+ else
254
+ puts "WARNING"
255
+ puts " json #{json_version} breaks Rails #{Rails.version} (fixed in Rails 8.1.4 and 7.2.4):"
256
+ puts " dashboard pages return 500 and errors can fail to be captured."
257
+ puts " Add gem \"json\", \"< 3\" to your Gemfile and run bundle update json, or upgrade Rails."
258
+ warnings += 1
259
+ end
260
+ end
261
+
192
262
  # Summary
193
263
  puts "\n" + "-" * 70
194
264
  puts " Results: #{checks_passed} passed, #{checks_failed} failed, #{warnings} warnings"
@@ -295,7 +365,7 @@ namespace :error_dashboard do
295
365
 
296
366
  # Confirm before proceeding
297
367
  print "\nProceed with backfill? (y/N): "
298
- confirmation = $stdin.gets.chomp.downcase
368
+ confirmation = $stdin.gets.to_s.chomp.downcase
299
369
 
300
370
  unless confirmation == "y" || confirmation == "yes"
301
371
  puts "\n✗ Backfill cancelled"
@@ -453,7 +523,7 @@ namespace :error_dashboard do
453
523
 
454
524
  # Confirm before proceeding
455
525
  print "\nProceed with deletion? (y/N): "
456
- confirmation = $stdin.gets.chomp.downcase
526
+ confirmation = $stdin.gets.to_s.chomp.downcase
457
527
 
458
528
  unless confirmation == "y" || confirmation == "yes"
459
529
  puts "\n✗ Cleanup cancelled"
@@ -463,7 +533,9 @@ namespace :error_dashboard do
463
533
 
464
534
  puts "\nDeleting errors..."
465
535
  start_time = Time.current
466
- deleted = scope.delete_all
536
+ # Dependents first, in batches: occurrences, comments and cascade patterns
537
+ # hold foreign keys to the log, so a plain delete_all failed on them.
538
+ deleted = RailsErrorDashboard::RetentionCleanupJob.delete_with_dependents(scope)
467
539
  # delete_all skips callbacks, and the stat cards are cached.
468
540
  RailsErrorDashboard::Services::AnalyticsCacheManager.clear
469
541
  elapsed = (Time.current - start_time).round(2)
@@ -538,7 +610,7 @@ namespace :error_dashboard do
538
610
  end
539
611
 
540
612
  print "\n Proceed with deletion? (y/N): "
541
- confirmation = $stdin.gets.chomp.downcase
613
+ confirmation = $stdin.gets.to_s.chomp.downcase
542
614
 
543
615
  unless confirmation == "y" || confirmation == "yes"
544
616
  puts "\n Cleanup cancelled"
@@ -16,75 +16,69 @@ namespace :rails_error_dashboard do
16
16
  puts "=" * 80
17
17
  puts "\n"
18
18
 
19
- # List tables that will be dropped
20
- tables_to_drop = [
21
- "rails_error_dashboard_error_comments",
22
- "rails_error_dashboard_error_occurrences",
23
- "rails_error_dashboard_cascade_patterns",
24
- "rails_error_dashboard_error_baselines",
25
- "rails_error_dashboard_error_logs"
26
- ]
19
+ # The connection RED's models use: the separate or shared error database
20
+ # when there is one. Raises if the engine fell back to the primary one.
21
+ connection = RailsErrorDashboard::Commands::DropAllTables.connection
22
+ database = connection.pool.db_config.name
23
+ plan = RailsErrorDashboard::Queries::UninstallPlan.call(connection)
27
24
 
28
- existing_tables = tables_to_drop.select do |table|
29
- ActiveRecord::Base.connection.table_exists?(table)
30
- end
31
-
32
- if existing_tables.empty?
33
- puts "No Rails Error Dashboard tables found in the database."
25
+ if plan.empty?
26
+ puts "No Rails Error Dashboard tables found in the '#{database}' database."
34
27
  puts "\n"
35
- exit 0
28
+ next
36
29
  end
37
30
 
38
- puts "The following tables will be PERMANENTLY DELETED:"
39
- existing_tables.each do |table|
40
- record_count = ActiveRecord::Base.connection.execute("SELECT COUNT(*) FROM #{table}").first.values.first rescue 0
41
- puts " • #{table} (#{record_count} records)"
31
+ puts "The following tables in the '#{database}' database will be PERMANENTLY DELETED:"
32
+ plan.each do |entry|
33
+ puts " • #{entry[:table]} (#{entry[:rows] || '?'} records)"
42
34
  end
43
35
  puts "\n"
36
+
37
+ if plan.any? { |entry| entry[:table] == "rails_error_dashboard_applications" }
38
+ names = connection.select_values("SELECT name FROM #{connection.quote_table_name('rails_error_dashboard_applications')} ORDER BY name")
39
+ if names.size > 1
40
+ puts "⚠️ This database holds errors for #{names.size} applications, and ALL of them will be deleted:"
41
+ names.each { |name| puts " • #{name}" }
42
+ puts "\n"
43
+ end
44
+ end
45
+
44
46
  puts "⚠️ This action CANNOT be undone!"
45
47
  puts "\n"
46
48
 
47
- # Ask for confirmation
48
49
  print "Type 'DELETE ALL DATA' to confirm: "
49
- confirmation = $stdin.gets.chomp
50
+ confirmation = $stdin.gets.to_s.chomp
50
51
 
51
52
  if confirmation != "DELETE ALL DATA"
52
53
  puts "\n"
53
54
  puts "Cancelled. No tables were dropped."
54
55
  puts "\n"
55
- exit 0
56
+ next
56
57
  end
57
58
 
58
59
  puts "\n"
59
60
  puts "Dropping tables..."
60
-
61
- # Drop tables in reverse order (respects foreign keys)
62
- dropped_count = 0
63
- existing_tables.reverse.each do |table|
64
- begin
65
- ActiveRecord::Base.connection.drop_table(table, if_exists: true)
66
- puts " ✓ Dropped #{table}"
67
- dropped_count += 1
68
- rescue => e
69
- puts " ✗ Failed to drop #{table}: #{e.message}"
70
- end
71
- end
61
+ dropped = RailsErrorDashboard::Commands::DropAllTables.call(connection: connection)
62
+ dropped.each { |table| puts " ✓ Dropped #{table}" }
72
63
 
73
64
  puts "\n"
74
65
  puts "=" * 80
75
- puts " ✅ Successfully dropped #{dropped_count} table(s)"
66
+ puts " ✅ Successfully dropped #{dropped.size} table(s)"
76
67
  puts "=" * 80
77
68
  puts "\n"
78
69
  puts "Next steps:"
79
- puts " 1. Remove gem 'rails_error_dashboard' from Gemfile"
80
- puts " 2. Run: bundle install"
81
- puts " 3. Remove initializer: config/initializers/rails_error_dashboard.rb"
82
- puts " 4. Remove route from config/routes.rb"
83
- puts " 5. Delete migration files: db/migrate/*rails_error_dashboard*.rb"
84
- puts " 6. Restart your Rails server"
70
+ puts " 1. Remove the initializer: config/initializers/rails_error_dashboard.rb"
71
+ puts " 2. Remove the route from config/routes.rb (mount RailsErrorDashboard::Engine)"
72
+ puts " 3. Delete RED's migrations: db/migrate/*rails_error_dashboard*.rb"
73
+ puts " (and db/error_dashboard_migrate/ with a separate database)"
74
+ puts " 4. Separate database: remove its entry from config/database.yml"
75
+ puts " 5. Regenerate the schema file: bin/rails db:schema:dump"
76
+ puts " (otherwise db:schema:load recreates these tables)"
77
+ puts " 6. Remove gem 'rails_error_dashboard' from the Gemfile and run: bundle install"
78
+ puts " 7. Restart your Rails server"
85
79
  puts "\n"
86
- puts "Or use the automated uninstaller:"
87
- puts " rails generate rails_error_dashboard:uninstall"
80
+ puts "Or use the automated uninstaller, before removing the gem:"
81
+ puts " bin/rails generate rails_error_dashboard:uninstall"
88
82
  puts "\n"
89
83
  end
90
84
  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.14.2
4
+ version: 0.14.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Anjan Jagirdar
@@ -429,7 +429,6 @@ files:
429
429
  - lib/generators/rails_error_dashboard/install/templates/README
430
430
  - lib/generators/rails_error_dashboard/install/templates/initializer.rb
431
431
  - lib/generators/rails_error_dashboard/solid_queue/solid_queue_generator.rb
432
- - lib/generators/rails_error_dashboard/solid_queue/templates/queue.yml
433
432
  - lib/generators/rails_error_dashboard/uninstall/uninstall_generator.rb
434
433
  - lib/rails_error_dashboard.rb
435
434
  - lib/rails_error_dashboard/commands/add_error_comment.rb
@@ -442,6 +441,7 @@ files:
442
441
  - lib/rails_error_dashboard/commands/batch_unmute_errors.rb
443
442
  - lib/rails_error_dashboard/commands/calculate_cascade_probability.rb
444
443
  - lib/rails_error_dashboard/commands/create_issue.rb
444
+ - lib/rails_error_dashboard/commands/drop_all_tables.rb
445
445
  - lib/rails_error_dashboard/commands/find_or_create_application.rb
446
446
  - lib/rails_error_dashboard/commands/find_or_increment_error.rb
447
447
  - lib/rails_error_dashboard/commands/flush_rack_attack_events.rb
@@ -508,6 +508,7 @@ files:
508
508
  - lib/rails_error_dashboard/queries/similar_errors.rb
509
509
  - lib/rails_error_dashboard/queries/storm_history.rb
510
510
  - lib/rails_error_dashboard/queries/swallowed_exception_summary.rb
511
+ - lib/rails_error_dashboard/queries/uninstall_plan.rb
511
512
  - lib/rails_error_dashboard/queries/user_impact_summary.rb
512
513
  - lib/rails_error_dashboard/services/ai_agent_classifier.rb
513
514
  - lib/rails_error_dashboard/services/analytics_cache_manager.rb
@@ -563,6 +564,7 @@ files:
563
564
  - lib/rails_error_dashboard/services/severity_classifier.rb
564
565
  - lib/rails_error_dashboard/services/similarity_calculator.rb
565
566
  - lib/rails_error_dashboard/services/slack_payload_builder.rb
567
+ - lib/rails_error_dashboard/services/solid_queue_config_check.rb
566
568
  - lib/rails_error_dashboard/services/source_code_reader.rb
567
569
  - lib/rails_error_dashboard/services/statistical_classifier.rb
568
570
  - lib/rails_error_dashboard/services/storm_protection/circuit_breaker.rb
@@ -599,7 +601,7 @@ metadata:
599
601
  funding_uri: https://github.com/sponsors/AnjanJ
600
602
  post_install_message: |
601
603
  ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
602
- RED (Rails Error Dashboard) v0.14.2
604
+ RED (Rails Error Dashboard) v0.14.4
603
605
  ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
604
606
 
605
607
  First install:
@@ -1,55 +0,0 @@
1
- # Solid Queue configuration for RailsErrorDashboard
2
- #
3
- # This file configures workers for error logging and notifications.
4
- # Adjust threads and processes based on your application's needs.
5
-
6
- # Development environment - optimized for low resource usage
7
- development:
8
- workers:
9
- # Error notifications (Slack, Email, Discord, PagerDuty, Webhooks)
10
- - queues: error_notifications
11
- threads: 2
12
- processes: 1
13
- polling_interval: 1
14
-
15
- # Default queue (includes async error logging)
16
- - queues: default
17
- threads: 3
18
- processes: 1
19
- polling_interval: 1
20
-
21
- # Test environment - minimal configuration
22
- test:
23
- workers:
24
- - queues: "*"
25
- threads: 1
26
- processes: 1
27
- polling_interval: 0.1
28
-
29
- # Production environment - optimized for throughput
30
- production:
31
- workers:
32
- # Error notifications - lower concurrency (external API calls)
33
- - queues: error_notifications
34
- threads: 3
35
- processes: 1
36
- polling_interval: 0.5
37
-
38
- # Default queue - higher concurrency (database operations)
39
- - queues: default
40
- threads: 5
41
- processes: 2
42
- polling_interval: 0.5
43
-
44
- # Staging environment - similar to production but scaled down
45
- staging:
46
- workers:
47
- - queues: error_notifications
48
- threads: 2
49
- processes: 1
50
- polling_interval: 0.5
51
-
52
- - queues: default
53
- threads: 3
54
- processes: 1
55
- polling_interval: 0.5