rails_error_dashboard 0.1.0 → 0.1.3

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 (95) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +305 -703
  3. data/app/assets/stylesheets/rails_error_dashboard/_catppuccin_mocha.scss +107 -0
  4. data/app/assets/stylesheets/rails_error_dashboard/_components.scss +625 -0
  5. data/app/assets/stylesheets/rails_error_dashboard/_layout.scss +257 -0
  6. data/app/assets/stylesheets/rails_error_dashboard/_theme_variables.scss +203 -0
  7. data/app/assets/stylesheets/rails_error_dashboard/application.css +926 -15
  8. data/app/assets/stylesheets/rails_error_dashboard/application.css.map +7 -0
  9. data/app/assets/stylesheets/rails_error_dashboard/application.scss +61 -0
  10. data/app/controllers/rails_error_dashboard/application_controller.rb +18 -0
  11. data/app/controllers/rails_error_dashboard/errors_controller.rb +140 -4
  12. data/app/helpers/rails_error_dashboard/application_helper.rb +55 -0
  13. data/app/helpers/rails_error_dashboard/backtrace_helper.rb +91 -0
  14. data/app/helpers/rails_error_dashboard/overview_helper.rb +78 -0
  15. data/app/helpers/rails_error_dashboard/user_agent_helper.rb +118 -0
  16. data/app/jobs/rails_error_dashboard/application_job.rb +19 -0
  17. data/app/jobs/rails_error_dashboard/async_error_logging_job.rb +48 -0
  18. data/app/jobs/rails_error_dashboard/baseline_alert_job.rb +263 -0
  19. data/app/jobs/rails_error_dashboard/discord_error_notification_job.rb +4 -8
  20. data/app/jobs/rails_error_dashboard/email_error_notification_job.rb +2 -1
  21. data/app/jobs/rails_error_dashboard/pagerduty_error_notification_job.rb +5 -5
  22. data/app/jobs/rails_error_dashboard/slack_error_notification_job.rb +10 -6
  23. data/app/jobs/rails_error_dashboard/webhook_error_notification_job.rb +5 -6
  24. data/app/mailers/rails_error_dashboard/application_mailer.rb +1 -1
  25. data/app/mailers/rails_error_dashboard/error_notification_mailer.rb +1 -1
  26. data/app/models/rails_error_dashboard/cascade_pattern.rb +74 -0
  27. data/app/models/rails_error_dashboard/error_baseline.rb +100 -0
  28. data/app/models/rails_error_dashboard/error_comment.rb +27 -0
  29. data/app/models/rails_error_dashboard/error_log.rb +471 -3
  30. data/app/models/rails_error_dashboard/error_occurrence.rb +49 -0
  31. data/app/views/layouts/rails_error_dashboard.html.erb +816 -178
  32. data/app/views/layouts/rails_error_dashboard_old_backup.html.erb +383 -0
  33. data/app/views/rails_error_dashboard/error_notification_mailer/error_alert.html.erb +3 -10
  34. data/app/views/rails_error_dashboard/error_notification_mailer/error_alert.text.erb +1 -2
  35. data/app/views/rails_error_dashboard/errors/_error_row.html.erb +78 -0
  36. data/app/views/rails_error_dashboard/errors/_pattern_insights.html.erb +209 -0
  37. data/app/views/rails_error_dashboard/errors/_stats.html.erb +34 -0
  38. data/app/views/rails_error_dashboard/errors/_timeline.html.erb +167 -0
  39. data/app/views/rails_error_dashboard/errors/analytics.html.erb +152 -56
  40. data/app/views/rails_error_dashboard/errors/correlation.html.erb +373 -0
  41. data/app/views/rails_error_dashboard/errors/index.html.erb +294 -138
  42. data/app/views/rails_error_dashboard/errors/overview.html.erb +253 -0
  43. data/app/views/rails_error_dashboard/errors/platform_comparison.html.erb +399 -0
  44. data/app/views/rails_error_dashboard/errors/show.html.erb +781 -65
  45. data/config/routes.rb +9 -0
  46. data/db/migrate/20251225071314_add_optimized_indexes_to_error_logs.rb +66 -0
  47. data/db/migrate/20251225074653_remove_environment_from_error_logs.rb +26 -0
  48. data/db/migrate/20251225085859_add_enhanced_metrics_to_error_logs.rb +12 -0
  49. data/db/migrate/20251225093603_add_similarity_tracking_to_error_logs.rb +9 -0
  50. data/db/migrate/20251225100236_create_error_occurrences.rb +31 -0
  51. data/db/migrate/20251225101920_create_cascade_patterns.rb +33 -0
  52. data/db/migrate/20251225102500_create_error_baselines.rb +38 -0
  53. data/db/migrate/20251226020000_add_workflow_fields_to_error_logs.rb +27 -0
  54. data/db/migrate/20251226020100_create_error_comments.rb +18 -0
  55. data/lib/generators/rails_error_dashboard/install/install_generator.rb +276 -1
  56. data/lib/generators/rails_error_dashboard/install/templates/initializer.rb +272 -37
  57. data/lib/generators/rails_error_dashboard/solid_queue/solid_queue_generator.rb +36 -0
  58. data/lib/generators/rails_error_dashboard/solid_queue/templates/queue.yml +55 -0
  59. data/lib/rails_error_dashboard/commands/batch_delete_errors.rb +1 -1
  60. data/lib/rails_error_dashboard/commands/batch_resolve_errors.rb +2 -2
  61. data/lib/rails_error_dashboard/commands/log_error.rb +272 -7
  62. data/lib/rails_error_dashboard/commands/resolve_error.rb +16 -0
  63. data/lib/rails_error_dashboard/configuration.rb +90 -5
  64. data/lib/rails_error_dashboard/error_reporter.rb +15 -7
  65. data/lib/rails_error_dashboard/logger.rb +105 -0
  66. data/lib/rails_error_dashboard/middleware/error_catcher.rb +17 -10
  67. data/lib/rails_error_dashboard/plugin.rb +6 -3
  68. data/lib/rails_error_dashboard/plugin_registry.rb +2 -2
  69. data/lib/rails_error_dashboard/plugins/audit_log_plugin.rb +0 -1
  70. data/lib/rails_error_dashboard/plugins/jira_integration_plugin.rb +3 -4
  71. data/lib/rails_error_dashboard/plugins/metrics_plugin.rb +1 -3
  72. data/lib/rails_error_dashboard/queries/analytics_stats.rb +44 -6
  73. data/lib/rails_error_dashboard/queries/baseline_stats.rb +107 -0
  74. data/lib/rails_error_dashboard/queries/co_occurring_errors.rb +86 -0
  75. data/lib/rails_error_dashboard/queries/dashboard_stats.rb +242 -2
  76. data/lib/rails_error_dashboard/queries/error_cascades.rb +74 -0
  77. data/lib/rails_error_dashboard/queries/error_correlation.rb +375 -0
  78. data/lib/rails_error_dashboard/queries/errors_list.rb +106 -10
  79. data/lib/rails_error_dashboard/queries/filter_options.rb +0 -1
  80. data/lib/rails_error_dashboard/queries/platform_comparison.rb +254 -0
  81. data/lib/rails_error_dashboard/queries/similar_errors.rb +93 -0
  82. data/lib/rails_error_dashboard/services/backtrace_parser.rb +113 -0
  83. data/lib/rails_error_dashboard/services/baseline_alert_throttler.rb +88 -0
  84. data/lib/rails_error_dashboard/services/baseline_calculator.rb +269 -0
  85. data/lib/rails_error_dashboard/services/cascade_detector.rb +95 -0
  86. data/lib/rails_error_dashboard/services/pattern_detector.rb +268 -0
  87. data/lib/rails_error_dashboard/services/similarity_calculator.rb +144 -0
  88. data/lib/rails_error_dashboard/value_objects/error_context.rb +27 -1
  89. data/lib/rails_error_dashboard/version.rb +1 -1
  90. data/lib/rails_error_dashboard.rb +57 -7
  91. metadata +69 -10
  92. data/app/models/rails_error_dashboard/application_record.rb +0 -5
  93. data/lib/rails_error_dashboard/queries/developer_insights.rb +0 -277
  94. data/lib/rails_error_dashboard/queries/errors_list_v2.rb +0 -149
  95. data/lib/tasks/rails_error_dashboard_tasks.rake +0 -4
data/config/routes.rb CHANGED
@@ -4,9 +4,18 @@ RailsErrorDashboard::Engine.routes.draw do
4
4
  resources :errors, only: [ :index, :show ] do
5
5
  member do
6
6
  post :resolve
7
+ post :assign
8
+ post :unassign
9
+ post :update_priority
10
+ post :snooze
11
+ post :unsnooze
12
+ post :update_status
13
+ post :add_comment
7
14
  end
8
15
  collection do
9
16
  get :analytics
17
+ get :platform_comparison
18
+ get :correlation
10
19
  post :batch_action
11
20
  end
12
21
  end
@@ -0,0 +1,66 @@
1
+ # frozen_string_literal: true
2
+
3
+ class AddOptimizedIndexesToErrorLogs < ActiveRecord::Migration[8.1]
4
+ def change
5
+ # Composite indexes for common query patterns
6
+ # These improve performance when filtering and sorting together
7
+
8
+ # Dashboard stats: Count unresolved errors from recent time periods
9
+ # Query: WHERE resolved = false AND occurred_at >= ?
10
+ add_index :rails_error_dashboard_error_logs, [ :resolved, :occurred_at ],
11
+ name: 'index_error_logs_on_resolved_and_occurred_at'
12
+
13
+ # Error type filtering with time ordering
14
+ # Query: WHERE error_type = ? ORDER BY occurred_at DESC
15
+ add_index :rails_error_dashboard_error_logs, [ :error_type, :occurred_at ],
16
+ name: 'index_error_logs_on_error_type_and_occurred_at'
17
+
18
+ # Platform filtering with time ordering
19
+ # Query: WHERE platform = ? ORDER BY occurred_at DESC
20
+ add_index :rails_error_dashboard_error_logs, [ :platform, :occurred_at ],
21
+ name: 'index_error_logs_on_platform_and_occurred_at'
22
+
23
+ # Deduplication lookup: Find existing unresolved errors by hash within 24 hours
24
+ # Query: WHERE error_hash = ? AND resolved = false AND occurred_at >= ?
25
+ # This is the hot path for error logging - happens on EVERY error
26
+ add_index :rails_error_dashboard_error_logs, [ :error_hash, :resolved, :occurred_at ],
27
+ name: 'index_error_logs_on_hash_resolved_occurred'
28
+
29
+ # Partial index for unresolved errors (most queries filter by resolved=false)
30
+ # Only indexes unresolved errors, making it smaller and faster
31
+ # PostgreSQL-specific but gracefully ignored on other databases
32
+ if postgresql?
33
+ add_index :rails_error_dashboard_error_logs, :occurred_at,
34
+ where: "resolved = false",
35
+ name: 'index_error_logs_on_occurred_at_unresolved'
36
+
37
+ # Full-text search index for message field (PostgreSQL only)
38
+ # Dramatically improves search performance
39
+ execute <<-SQL
40
+ CREATE INDEX index_error_logs_on_message_gin
41
+ ON rails_error_dashboard_error_logs
42
+ USING gin(to_tsvector('english', message))
43
+ SQL
44
+ end
45
+ end
46
+
47
+ def down
48
+ # Remove composite indexes
49
+ remove_index :rails_error_dashboard_error_logs, name: 'index_error_logs_on_resolved_and_occurred_at'
50
+ remove_index :rails_error_dashboard_error_logs, name: 'index_error_logs_on_error_type_and_occurred_at'
51
+ remove_index :rails_error_dashboard_error_logs, name: 'index_error_logs_on_platform_and_occurred_at'
52
+ remove_index :rails_error_dashboard_error_logs, name: 'index_error_logs_on_hash_resolved_occurred'
53
+
54
+ # Remove partial/GIN indexes if PostgreSQL
55
+ if postgresql?
56
+ remove_index :rails_error_dashboard_error_logs, name: 'index_error_logs_on_occurred_at_unresolved'
57
+ execute "DROP INDEX IF EXISTS index_error_logs_on_message_gin"
58
+ end
59
+ end
60
+
61
+ private
62
+
63
+ def postgresql?
64
+ ActiveRecord::Base.connection.adapter_name.downcase == 'postgresql'
65
+ end
66
+ end
@@ -0,0 +1,26 @@
1
+ class RemoveEnvironmentFromErrorLogs < ActiveRecord::Migration[8.1]
2
+ def up
3
+ # Remove composite index first
4
+ remove_index :rails_error_dashboard_error_logs,
5
+ name: 'index_error_logs_on_environment_and_occurred_at',
6
+ if_exists: true
7
+
8
+ # Remove single column index
9
+ remove_index :rails_error_dashboard_error_logs,
10
+ column: :environment,
11
+ if_exists: true
12
+
13
+ # Remove the column
14
+ remove_column :rails_error_dashboard_error_logs, :environment, :string
15
+ end
16
+
17
+ def down
18
+ # Add column back
19
+ add_column :rails_error_dashboard_error_logs, :environment, :string, null: false, default: 'production'
20
+
21
+ # Recreate indexes
22
+ add_index :rails_error_dashboard_error_logs, :environment
23
+ add_index :rails_error_dashboard_error_logs, [ :environment, :occurred_at ],
24
+ name: 'index_error_logs_on_environment_and_occurred_at'
25
+ end
26
+ end
@@ -0,0 +1,12 @@
1
+ class AddEnhancedMetricsToErrorLogs < ActiveRecord::Migration[8.0]
2
+ def change
3
+ add_column :rails_error_dashboard_error_logs, :app_version, :string
4
+ add_column :rails_error_dashboard_error_logs, :git_sha, :string
5
+ add_column :rails_error_dashboard_error_logs, :priority_score, :integer
6
+
7
+ # Indexes for enhanced metrics
8
+ add_index :rails_error_dashboard_error_logs, :app_version
9
+ add_index :rails_error_dashboard_error_logs, :git_sha
10
+ add_index :rails_error_dashboard_error_logs, :priority_score
11
+ end
12
+ end
@@ -0,0 +1,9 @@
1
+ class AddSimilarityTrackingToErrorLogs < ActiveRecord::Migration[8.0]
2
+ def change
3
+ add_column :rails_error_dashboard_error_logs, :similarity_score, :float
4
+ add_column :rails_error_dashboard_error_logs, :backtrace_signature, :string
5
+
6
+ add_index :rails_error_dashboard_error_logs, :similarity_score
7
+ add_index :rails_error_dashboard_error_logs, :backtrace_signature
8
+ end
9
+ end
@@ -0,0 +1,31 @@
1
+ # frozen_string_literal: true
2
+
3
+ class CreateErrorOccurrences < ActiveRecord::Migration[8.0]
4
+ def change
5
+ create_table :rails_error_dashboard_error_occurrences do |t|
6
+ t.references :error_log, null: false, foreign_key: { to_table: :rails_error_dashboard_error_logs }
7
+ t.datetime :occurred_at, null: false
8
+ t.integer :user_id
9
+ t.string :request_id
10
+ t.string :session_id
11
+
12
+ t.timestamps
13
+ end
14
+
15
+ # Index for finding co-occurring errors by time window
16
+ add_index :rails_error_dashboard_error_occurrences, [ :occurred_at, :error_log_id ],
17
+ name: 'index_error_occurrences_on_time_and_error'
18
+
19
+ # Index for finding all occurrences of a specific error
20
+ add_index :rails_error_dashboard_error_occurrences, :error_log_id,
21
+ name: 'index_error_occurrences_on_error_log'
22
+
23
+ # Index for finding errors by user
24
+ add_index :rails_error_dashboard_error_occurrences, :user_id,
25
+ name: 'index_error_occurrences_on_user'
26
+
27
+ # Index for finding errors by request
28
+ add_index :rails_error_dashboard_error_occurrences, :request_id,
29
+ name: 'index_error_occurrences_on_request'
30
+ end
31
+ end
@@ -0,0 +1,33 @@
1
+ # frozen_string_literal: true
2
+
3
+ class CreateCascadePatterns < ActiveRecord::Migration[8.0]
4
+ def change
5
+ create_table :rails_error_dashboard_cascade_patterns do |t|
6
+ t.references :parent_error, null: false, foreign_key: { to_table: :rails_error_dashboard_error_logs }
7
+ t.references :child_error, null: false, foreign_key: { to_table: :rails_error_dashboard_error_logs }
8
+ t.integer :frequency, default: 1, null: false
9
+ t.float :avg_delay_seconds
10
+ t.float :cascade_probability # 0.0-1.0, percentage of time parent leads to child
11
+ t.datetime :last_detected_at
12
+
13
+ t.timestamps
14
+ end
15
+
16
+ # Composite index for finding cascade patterns
17
+ add_index :rails_error_dashboard_cascade_patterns, [ :parent_error_id, :child_error_id ],
18
+ name: 'index_cascade_patterns_on_parent_and_child',
19
+ unique: true
20
+
21
+ # Index for finding children of a parent error
22
+ add_index :rails_error_dashboard_cascade_patterns, :parent_error_id,
23
+ name: 'index_cascade_patterns_on_parent'
24
+
25
+ # Index for finding parents of a child error
26
+ add_index :rails_error_dashboard_cascade_patterns, :child_error_id,
27
+ name: 'index_cascade_patterns_on_child'
28
+
29
+ # Index for finding by probability (for high-confidence cascades)
30
+ add_index :rails_error_dashboard_cascade_patterns, :cascade_probability,
31
+ name: 'index_cascade_patterns_on_probability'
32
+ end
33
+ end
@@ -0,0 +1,38 @@
1
+ # frozen_string_literal: true
2
+
3
+ class CreateErrorBaselines < ActiveRecord::Migration[8.0]
4
+ def change
5
+ create_table :rails_error_dashboard_error_baselines do |t|
6
+ t.string :error_type, null: false
7
+ t.string :platform, null: false
8
+ t.string :baseline_type, null: false # hourly, daily, weekly
9
+ t.datetime :period_start, null: false
10
+ t.datetime :period_end, null: false
11
+
12
+ # Statistical metrics
13
+ t.integer :count, null: false, default: 0
14
+ t.float :mean
15
+ t.float :std_dev
16
+ t.float :percentile_95
17
+ t.float :percentile_99
18
+ t.integer :sample_size, null: false, default: 0
19
+
20
+ t.timestamps
21
+ end
22
+
23
+ # Composite index for efficient baseline lookups
24
+ add_index :rails_error_dashboard_error_baselines,
25
+ [ :error_type, :platform, :baseline_type, :period_start ],
26
+ name: 'index_error_baselines_on_type_platform_baseline_period'
27
+
28
+ # Index for querying by error_type and platform
29
+ add_index :rails_error_dashboard_error_baselines,
30
+ [ :error_type, :platform ],
31
+ name: 'index_error_baselines_on_error_type_and_platform'
32
+
33
+ # Index for cleaning up old baselines
34
+ add_index :rails_error_dashboard_error_baselines,
35
+ :period_end,
36
+ name: 'index_error_baselines_on_period_end'
37
+ end
38
+ end
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+
3
+ class AddWorkflowFieldsToErrorLogs < ActiveRecord::Migration[8.0]
4
+ def change
5
+ add_column :rails_error_dashboard_error_logs, :status, :string, default: 'new', null: false
6
+ add_column :rails_error_dashboard_error_logs, :assigned_to, :string
7
+ add_column :rails_error_dashboard_error_logs, :assigned_at, :datetime
8
+ add_column :rails_error_dashboard_error_logs, :snoozed_until, :datetime
9
+ add_column :rails_error_dashboard_error_logs, :priority_level, :integer, default: 0, null: false
10
+
11
+ add_index :rails_error_dashboard_error_logs, :status
12
+ add_index :rails_error_dashboard_error_logs, :assigned_to
13
+ add_index :rails_error_dashboard_error_logs, :snoozed_until
14
+ add_index :rails_error_dashboard_error_logs, :priority_level
15
+
16
+ # Update existing resolved errors to have status='resolved'
17
+ reversible do |dir|
18
+ dir.up do
19
+ execute <<-SQL
20
+ UPDATE rails_error_dashboard_error_logs
21
+ SET status = 'resolved'
22
+ WHERE resolved = true
23
+ SQL
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ class CreateErrorComments < ActiveRecord::Migration[8.0]
4
+ def change
5
+ create_table :rails_error_dashboard_error_comments do |t|
6
+ t.references :error_log,
7
+ null: false,
8
+ foreign_key: { to_table: :rails_error_dashboard_error_logs }
9
+ t.string :author_name, null: false
10
+ t.text :body, null: false
11
+
12
+ t.timestamps
13
+ end
14
+
15
+ add_index :rails_error_dashboard_error_comments, [ :error_log_id, :created_at ],
16
+ name: 'index_error_comments_on_error_and_time'
17
+ end
18
+ end
@@ -7,7 +7,194 @@ module RailsErrorDashboard
7
7
 
8
8
  desc "Installs Rails Error Dashboard and generates the necessary files"
9
9
 
10
+ class_option :interactive, type: :boolean, default: true, desc: "Interactive feature selection"
11
+ # Notification options
12
+ class_option :slack, type: :boolean, default: false, desc: "Enable Slack notifications"
13
+ class_option :email, type: :boolean, default: false, desc: "Enable email notifications"
14
+ class_option :discord, type: :boolean, default: false, desc: "Enable Discord notifications"
15
+ class_option :pagerduty, type: :boolean, default: false, desc: "Enable PagerDuty notifications"
16
+ class_option :webhooks, type: :boolean, default: false, desc: "Enable webhook notifications"
17
+ # Performance options
18
+ class_option :async_logging, type: :boolean, default: false, desc: "Enable async error logging"
19
+ class_option :error_sampling, type: :boolean, default: false, desc: "Enable error sampling (reduce volume)"
20
+ class_option :separate_database, type: :boolean, default: false, desc: "Use separate database for errors"
21
+ # Advanced analytics options
22
+ class_option :baseline_alerts, type: :boolean, default: false, desc: "Enable baseline anomaly alerts"
23
+ class_option :similar_errors, type: :boolean, default: false, desc: "Enable fuzzy error matching"
24
+ class_option :co_occurring_errors, type: :boolean, default: false, desc: "Enable co-occurring error detection"
25
+ class_option :error_cascades, type: :boolean, default: false, desc: "Enable error cascade detection"
26
+ class_option :error_correlation, type: :boolean, default: false, desc: "Enable error correlation analysis"
27
+ class_option :platform_comparison, type: :boolean, default: false, desc: "Enable platform comparison analytics"
28
+ class_option :occurrence_patterns, type: :boolean, default: false, desc: "Enable occurrence pattern detection"
29
+
30
+ def welcome_message
31
+ say "\n"
32
+ say "=" * 70
33
+ say " 📊 Rails Error Dashboard Installation", :cyan
34
+ say "=" * 70
35
+ say "\n"
36
+ say "Core features will be enabled automatically:", :green
37
+ say " ✓ Error capture (controllers, jobs, middleware)"
38
+ say " ✓ Dashboard UI at /error_dashboard"
39
+ say " ✓ Real-time updates"
40
+ say " ✓ Analytics & spike detection"
41
+ say " ✓ 90-day error retention"
42
+ say "\n"
43
+ end
44
+
45
+ def select_optional_features
46
+ return unless options[:interactive] && behavior == :invoke
47
+ return unless $stdin.tty? # Skip interactive mode if not running in a terminal
48
+
49
+ say "Let's configure optional features...\n", :cyan
50
+ say "(You can always enable/disable these later in the initializer)\n\n", :yellow
51
+
52
+ @selected_features = {}
53
+
54
+ # Feature definitions with descriptions - organized by category
55
+ features = [
56
+ # === NOTIFICATIONS ===
57
+ {
58
+ key: :slack,
59
+ name: "Slack Notifications",
60
+ description: "Send error alerts to Slack channels",
61
+ category: "Notifications"
62
+ },
63
+ {
64
+ key: :email,
65
+ name: "Email Notifications",
66
+ description: "Send error alerts via email",
67
+ category: "Notifications"
68
+ },
69
+ {
70
+ key: :discord,
71
+ name: "Discord Notifications",
72
+ description: "Send error alerts to Discord",
73
+ category: "Notifications"
74
+ },
75
+ {
76
+ key: :pagerduty,
77
+ name: "PagerDuty Integration",
78
+ description: "Critical errors to PagerDuty",
79
+ category: "Notifications"
80
+ },
81
+ {
82
+ key: :webhooks,
83
+ name: "Generic Webhooks",
84
+ description: "Send data to custom endpoints",
85
+ category: "Notifications"
86
+ },
87
+
88
+ # === PERFORMANCE & SCALABILITY ===
89
+ {
90
+ key: :async_logging,
91
+ name: "Async Error Logging",
92
+ description: "Process errors in background jobs (faster responses)",
93
+ category: "Performance"
94
+ },
95
+ {
96
+ key: :error_sampling,
97
+ name: "Error Sampling",
98
+ description: "Log only % of non-critical errors (reduce volume)",
99
+ category: "Performance"
100
+ },
101
+ {
102
+ key: :separate_database,
103
+ name: "Separate Error Database",
104
+ description: "Store errors in dedicated database",
105
+ category: "Performance"
106
+ },
107
+
108
+ # === ADVANCED ANALYTICS ===
109
+ {
110
+ key: :baseline_alerts,
111
+ name: "Baseline Anomaly Alerts",
112
+ description: "Auto-detect unusual error rate spikes",
113
+ category: "Advanced Analytics"
114
+ },
115
+ {
116
+ key: :similar_errors,
117
+ name: "Fuzzy Error Matching",
118
+ description: "Find similar errors across different hashes",
119
+ category: "Advanced Analytics"
120
+ },
121
+ {
122
+ key: :co_occurring_errors,
123
+ name: "Co-occurring Errors",
124
+ description: "Detect errors that happen together",
125
+ category: "Advanced Analytics"
126
+ },
127
+ {
128
+ key: :error_cascades,
129
+ name: "Error Cascade Detection",
130
+ description: "Identify error chains (A causes B causes C)",
131
+ category: "Advanced Analytics"
132
+ },
133
+ {
134
+ key: :error_correlation,
135
+ name: "Error Correlation Analysis",
136
+ description: "Correlate with versions, users, time",
137
+ category: "Advanced Analytics"
138
+ },
139
+ {
140
+ key: :platform_comparison,
141
+ name: "Platform Comparison",
142
+ description: "Compare iOS vs Android vs Web health",
143
+ category: "Advanced Analytics"
144
+ },
145
+ {
146
+ key: :occurrence_patterns,
147
+ name: "Occurrence Pattern Detection",
148
+ description: "Detect cyclical patterns and bursts",
149
+ category: "Advanced Analytics"
150
+ }
151
+ ]
152
+
153
+ features.each_with_index do |feature, index|
154
+ say "\n[#{index + 1}/#{features.length}] #{feature[:name]}", :cyan
155
+ say " #{feature[:description]}", :light_black
156
+
157
+ # Check if feature was passed via command line option
158
+ if options[feature[:key]]
159
+ @selected_features[feature[:key]] = true
160
+ say " ✓ Enabled (via --#{feature[:key]} flag)", :green
161
+ else
162
+ response = ask(" Enable? (y/N):", :yellow, limited_to: [ "y", "Y", "n", "N", "" ])
163
+ @selected_features[feature[:key]] = response.downcase == "y"
164
+
165
+ if @selected_features[feature[:key]]
166
+ say " ✓ Enabled", :green
167
+ else
168
+ say " ✗ Disabled", :light_black
169
+ end
170
+ end
171
+ end
172
+
173
+ say "\n"
174
+ end
175
+
10
176
  def create_initializer_file
177
+ # Notifications
178
+ @enable_slack = @selected_features&.dig(:slack) || options[:slack]
179
+ @enable_email = @selected_features&.dig(:email) || options[:email]
180
+ @enable_discord = @selected_features&.dig(:discord) || options[:discord]
181
+ @enable_pagerduty = @selected_features&.dig(:pagerduty) || options[:pagerduty]
182
+ @enable_webhooks = @selected_features&.dig(:webhooks) || options[:webhooks]
183
+
184
+ # Performance
185
+ @enable_async_logging = @selected_features&.dig(:async_logging) || options[:async_logging]
186
+ @enable_error_sampling = @selected_features&.dig(:error_sampling) || options[:error_sampling]
187
+ @enable_separate_database = @selected_features&.dig(:separate_database) || options[:separate_database]
188
+
189
+ # Advanced Analytics
190
+ @enable_baseline_alerts = @selected_features&.dig(:baseline_alerts) || options[:baseline_alerts]
191
+ @enable_similar_errors = @selected_features&.dig(:similar_errors) || options[:similar_errors]
192
+ @enable_co_occurring_errors = @selected_features&.dig(:co_occurring_errors) || options[:co_occurring_errors]
193
+ @enable_error_cascades = @selected_features&.dig(:error_cascades) || options[:error_cascades]
194
+ @enable_error_correlation = @selected_features&.dig(:error_correlation) || options[:error_correlation]
195
+ @enable_platform_comparison = @selected_features&.dig(:platform_comparison) || options[:platform_comparison]
196
+ @enable_occurrence_patterns = @selected_features&.dig(:occurrence_patterns) || options[:occurrence_patterns]
197
+
11
198
  template "initializer.rb", "config/initializers/rails_error_dashboard.rb"
12
199
  end
13
200
 
@@ -19,8 +206,96 @@ module RailsErrorDashboard
19
206
  route "mount RailsErrorDashboard::Engine => '/error_dashboard'"
20
207
  end
21
208
 
209
+ def show_feature_summary
210
+ return unless behavior == :invoke
211
+
212
+ say "\n"
213
+ say "=" * 70
214
+ say " ✓ Installation Complete!", :green
215
+ say "=" * 70
216
+ say "\n"
217
+
218
+ say "Core Features (Always ON):", :cyan
219
+ say " ✓ Error Capture", :green
220
+ say " ✓ Dashboard UI", :green
221
+ say " ✓ Real-time Updates", :green
222
+ say " ✓ Analytics", :green
223
+
224
+ # Count optional features enabled
225
+ enabled_count = 0
226
+
227
+ # Notifications
228
+ notification_features = []
229
+ notification_features << "Slack" if @enable_slack
230
+ notification_features << "Email" if @enable_email
231
+ notification_features << "Discord" if @enable_discord
232
+ notification_features << "PagerDuty" if @enable_pagerduty
233
+ notification_features << "Webhooks" if @enable_webhooks
234
+
235
+ if notification_features.any?
236
+ say "\nNotifications:", :cyan
237
+ say " ✓ #{notification_features.join(", ")}", :green
238
+ enabled_count += notification_features.size
239
+ end
240
+
241
+ # Performance
242
+ performance_features = []
243
+ performance_features << "Async Logging" if @enable_async_logging
244
+ performance_features << "Error Sampling" if @enable_error_sampling
245
+ performance_features << "Separate Database" if @enable_separate_database
246
+
247
+ if performance_features.any?
248
+ say "\nPerformance:", :cyan
249
+ say " ✓ #{performance_features.join(", ")}", :green
250
+ enabled_count += performance_features.size
251
+ end
252
+
253
+ # Advanced Analytics
254
+ analytics_features = []
255
+ analytics_features << "Baseline Alerts" if @enable_baseline_alerts
256
+ analytics_features << "Fuzzy Matching" if @enable_similar_errors
257
+ analytics_features << "Co-occurring Errors" if @enable_co_occurring_errors
258
+ analytics_features << "Error Cascades" if @enable_error_cascades
259
+ analytics_features << "Error Correlation" if @enable_error_correlation
260
+ analytics_features << "Platform Comparison" if @enable_platform_comparison
261
+ analytics_features << "Pattern Detection" if @enable_occurrence_patterns
262
+
263
+ if analytics_features.any?
264
+ say "\nAdvanced Analytics:", :cyan
265
+ say " ✓ #{analytics_features.join(", ")}", :green
266
+ enabled_count += analytics_features.size
267
+ end
268
+
269
+ say "\n"
270
+ say "Configuration Required:", :yellow if enabled_count > 0
271
+ say " → Edit config/initializers/rails_error_dashboard.rb", :yellow if @enable_error_sampling
272
+ say " → Set SLACK_WEBHOOK_URL in .env", :yellow if @enable_slack
273
+ say " → Set ERROR_NOTIFICATION_EMAILS in .env", :yellow if @enable_email
274
+ say " → Set DISCORD_WEBHOOK_URL in .env", :yellow if @enable_discord
275
+ say " → Set PAGERDUTY_INTEGRATION_KEY in .env", :yellow if @enable_pagerduty
276
+ say " → Set WEBHOOK_URLS in .env", :yellow if @enable_webhooks
277
+ say " → Ensure Sidekiq/Solid Queue running", :yellow if @enable_async_logging
278
+ say " → Configure database.yml (docs/guides/DATABASE_OPTIONS.md)", :yellow if @enable_separate_database
279
+
280
+ say "\n"
281
+ say "Next Steps:", :cyan
282
+ say " 1. Run: rails db:migrate"
283
+ say " 2. Update credentials in config/initializers/rails_error_dashboard.rb"
284
+ say " 3. Restart your Rails server"
285
+ say " 4. Visit http://localhost:3000/error_dashboard"
286
+ say "\n"
287
+ say "📖 Documentation:", :light_black
288
+ say " • Quick Start: docs/QUICKSTART.md", :light_black
289
+ say " • Complete Feature Guide: docs/FEATURES.md", :light_black
290
+ say " • All Docs: docs/README.md", :light_black
291
+ say "\n"
292
+ say "⚙️ To enable/disable features later:", :light_black
293
+ say " Edit config/initializers/rails_error_dashboard.rb", :light_black
294
+ say "\n"
295
+ end
296
+
22
297
  def show_readme
23
- readme "README" if behavior == :invoke
298
+ # Skip the old README display since we have the new summary
24
299
  end
25
300
  end
26
301
  end