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.
- checksums.yaml +4 -4
- data/README.md +36 -18
- data/app/helpers/rails_error_dashboard/application_helper.rb +8 -0
- data/app/jobs/rails_error_dashboard/retention_cleanup_job.rb +27 -23
- data/app/views/layouts/rails_error_dashboard.html.erb +13 -0
- data/config/locales/de.yml +4 -0
- data/config/locales/en.yml +5 -0
- data/config/locales/es.yml +4 -0
- data/config/locales/fr.yml +4 -0
- data/config/locales/it.yml +4 -0
- data/config/locales/ja.yml +4 -0
- data/config/locales/pl.yml +4 -0
- data/config/locales/pt-BR.yml +4 -0
- data/config/locales/ru.yml +4 -0
- data/config/locales/uk.yml +4 -0
- data/config/locales/zh-CN.yml +4 -0
- data/db/migrate/20251225074653_remove_environment_from_error_logs.rb +9 -0
- data/lib/generators/rails_error_dashboard/install/install_generator.rb +45 -50
- data/lib/generators/rails_error_dashboard/install/templates/initializer.rb +17 -10
- data/lib/generators/rails_error_dashboard/solid_queue/solid_queue_generator.rb +41 -21
- data/lib/generators/rails_error_dashboard/uninstall/uninstall_generator.rb +79 -66
- data/lib/rails_error_dashboard/commands/drop_all_tables.rb +77 -0
- data/lib/rails_error_dashboard/commands/log_error.rb +5 -2
- data/lib/rails_error_dashboard/configuration.rb +67 -4
- data/lib/rails_error_dashboard/engine.rb +10 -4
- data/lib/rails_error_dashboard/logger.rb +11 -3
- data/lib/rails_error_dashboard/middleware/rate_limiter.rb +15 -43
- data/lib/rails_error_dashboard/plugin.rb +30 -0
- data/lib/rails_error_dashboard/queries/errors_list.rb +3 -1
- data/lib/rails_error_dashboard/queries/uninstall_plan.rb +63 -0
- data/lib/rails_error_dashboard/services/exception_filter.rb +4 -1
- data/lib/rails_error_dashboard/services/solid_queue_config_check.rb +261 -0
- data/lib/rails_error_dashboard/version.rb +1 -1
- data/lib/rails_error_dashboard.rb +3 -0
- data/lib/tasks/error_dashboard.rake +77 -5
- data/lib/tasks/rails_error_dashboard_tasks.rake +37 -43
- metadata +5 -3
- 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} -
|
|
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
|
-
|
|
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
|
-
#
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
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
|
-
|
|
29
|
-
|
|
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
|
-
|
|
28
|
+
next
|
|
36
29
|
end
|
|
37
30
|
|
|
38
|
-
puts "The following tables will be PERMANENTLY DELETED:"
|
|
39
|
-
|
|
40
|
-
|
|
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
|
-
|
|
56
|
+
next
|
|
56
57
|
end
|
|
57
58
|
|
|
58
59
|
puts "\n"
|
|
59
60
|
puts "Dropping tables..."
|
|
60
|
-
|
|
61
|
-
|
|
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 #{
|
|
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
|
|
80
|
-
puts " 2.
|
|
81
|
-
puts " 3.
|
|
82
|
-
puts "
|
|
83
|
-
puts "
|
|
84
|
-
puts "
|
|
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.
|
|
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.
|
|
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
|