rails_error_dashboard 0.1.28 → 0.1.30
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 +50 -6
- data/app/controllers/rails_error_dashboard/errors_controller.rb +22 -0
- data/app/helpers/rails_error_dashboard/application_helper.rb +79 -7
- data/app/helpers/rails_error_dashboard/backtrace_helper.rb +149 -0
- data/app/models/rails_error_dashboard/application.rb +1 -1
- data/app/models/rails_error_dashboard/error_log.rb +44 -16
- data/app/views/layouts/rails_error_dashboard.html.erb +71 -1237
- data/app/views/rails_error_dashboard/errors/_error_row.html.erb +10 -2
- data/app/views/rails_error_dashboard/errors/_source_code.html.erb +76 -0
- data/app/views/rails_error_dashboard/errors/_timeline.html.erb +18 -82
- data/app/views/rails_error_dashboard/errors/_user_errors_table.html.erb +70 -0
- data/app/views/rails_error_dashboard/errors/analytics.html.erb +9 -37
- data/app/views/rails_error_dashboard/errors/correlation.html.erb +11 -37
- data/app/views/rails_error_dashboard/errors/index.html.erb +64 -31
- data/app/views/rails_error_dashboard/errors/overview.html.erb +181 -3
- data/app/views/rails_error_dashboard/errors/platform_comparison.html.erb +2 -1
- data/app/views/rails_error_dashboard/errors/settings/_value_badge.html.erb +286 -0
- data/app/views/rails_error_dashboard/errors/settings.html.erb +146 -480
- data/app/views/rails_error_dashboard/errors/show.html.erb +102 -76
- data/db/migrate/20251223000000_create_rails_error_dashboard_complete_schema.rb +188 -0
- data/db/migrate/20251224000001_create_rails_error_dashboard_error_logs.rb +5 -0
- data/db/migrate/20251224081522_add_better_tracking_to_error_logs.rb +3 -0
- data/db/migrate/20251224101217_add_controller_action_to_error_logs.rb +3 -0
- data/db/migrate/20251225071314_add_optimized_indexes_to_error_logs.rb +4 -0
- data/db/migrate/20251225074653_remove_environment_from_error_logs.rb +3 -0
- data/db/migrate/20251225085859_add_enhanced_metrics_to_error_logs.rb +3 -0
- data/db/migrate/20251225093603_add_similarity_tracking_to_error_logs.rb +3 -0
- data/db/migrate/20251225100236_create_error_occurrences.rb +3 -0
- data/db/migrate/20251225101920_create_cascade_patterns.rb +3 -0
- data/db/migrate/20251225102500_create_error_baselines.rb +3 -0
- data/db/migrate/20251226020000_add_workflow_fields_to_error_logs.rb +3 -0
- data/db/migrate/20251226020100_create_error_comments.rb +3 -0
- data/db/migrate/20251229111223_add_additional_performance_indexes.rb +4 -0
- data/db/migrate/20260106094220_create_rails_error_dashboard_applications.rb +3 -0
- data/db/migrate/20260106094233_add_application_to_error_logs.rb +3 -0
- data/db/migrate/20260106094318_finalize_application_foreign_key.rb +5 -0
- data/lib/generators/rails_error_dashboard/install/install_generator.rb +32 -0
- data/lib/generators/rails_error_dashboard/install/templates/initializer.rb +37 -4
- data/lib/rails_error_dashboard/configuration.rb +160 -3
- data/lib/rails_error_dashboard/configuration_error.rb +24 -0
- data/lib/rails_error_dashboard/engine.rb +17 -0
- data/lib/rails_error_dashboard/helpers/user_model_detector.rb +138 -0
- data/lib/rails_error_dashboard/queries/analytics_stats.rb +1 -2
- data/lib/rails_error_dashboard/queries/dashboard_stats.rb +19 -4
- data/lib/rails_error_dashboard/queries/errors_list.rb +27 -8
- data/lib/rails_error_dashboard/services/error_normalizer.rb +143 -0
- data/lib/rails_error_dashboard/services/git_blame_reader.rb +195 -0
- data/lib/rails_error_dashboard/services/github_link_generator.rb +159 -0
- data/lib/rails_error_dashboard/services/source_code_reader.rb +214 -0
- data/lib/rails_error_dashboard/version.rb +1 -1
- data/lib/rails_error_dashboard.rb +6 -0
- metadata +14 -10
- data/app/assets/stylesheets/rails_error_dashboard/_catppuccin_mocha.scss +0 -107
- data/app/assets/stylesheets/rails_error_dashboard/_components.scss +0 -625
- data/app/assets/stylesheets/rails_error_dashboard/_layout.scss +0 -257
- data/app/assets/stylesheets/rails_error_dashboard/_theme_variables.scss +0 -203
- data/app/assets/stylesheets/rails_error_dashboard/application.css +0 -15
- data/app/assets/stylesheets/rails_error_dashboard/application.css.map +0 -7
- data/app/assets/stylesheets/rails_error_dashboard/application.scss +0 -61
- data/app/views/layouts/rails_error_dashboard/application.html.erb +0 -55
|
@@ -1,5 +1,120 @@
|
|
|
1
1
|
<% content_for :page_title, "Settings" %>
|
|
2
2
|
|
|
3
|
+
<%
|
|
4
|
+
# Define setting groups with metadata
|
|
5
|
+
setting_groups = {
|
|
6
|
+
"Core Features" => {
|
|
7
|
+
icon: "bi-shield-check",
|
|
8
|
+
color: "primary",
|
|
9
|
+
settings: {
|
|
10
|
+
enable_middleware: { label: "Error Middleware", description: "Catches unhandled exceptions", type: :boolean },
|
|
11
|
+
enable_error_subscriber: { label: "Rails.error Subscriber", description: "Subscribes to Rails error events", type: :boolean },
|
|
12
|
+
retention_days: { label: "Data Retention", description: "Manual cleanup only (run: rails error_dashboard:cleanup_resolved DAYS=90)", type: :retention_days },
|
|
13
|
+
max_backtrace_lines: { label: "Max Backtrace Lines", description: "Stack trace depth limit", type: :integer, unit: "lines" },
|
|
14
|
+
sampling_rate: { label: "Sampling Rate", description: "Percentage of errors captured", type: :percentage }
|
|
15
|
+
}
|
|
16
|
+
},
|
|
17
|
+
"Multi-App Support" => {
|
|
18
|
+
icon: "bi-collection",
|
|
19
|
+
color: "info",
|
|
20
|
+
settings: {
|
|
21
|
+
application_name: { label: "Application Name", description: "Name of this application (auto-detected if not set)", type: :application_name },
|
|
22
|
+
database: { label: "Database Connection", description: "Active database for error logs", type: :database_name },
|
|
23
|
+
use_separate_database: { label: "Separate Database", description: "Use dedicated DB for error logs", type: :boolean }
|
|
24
|
+
}
|
|
25
|
+
},
|
|
26
|
+
"User Integration" => {
|
|
27
|
+
icon: "bi-people",
|
|
28
|
+
color: "secondary",
|
|
29
|
+
settings: {
|
|
30
|
+
user_model: { label: "User Model", description: "Model name for user associations (auto-detected if not set)", type: :user_model },
|
|
31
|
+
total_users_for_impact: { label: "Total Users", description: "For impact % calculation (auto-detected if not set)", type: :total_users }
|
|
32
|
+
}
|
|
33
|
+
},
|
|
34
|
+
"Performance Settings" => {
|
|
35
|
+
icon: "bi-lightning-charge",
|
|
36
|
+
color: "dark",
|
|
37
|
+
settings: {
|
|
38
|
+
async_logging: { label: "Async Logging", description: "Background job processing", type: :boolean, extra: :async_adapter },
|
|
39
|
+
async_adapter: { label: "Async Adapter", description: "Job queue adapter", type: :symbol, show_if: :async_logging },
|
|
40
|
+
enable_rate_limiting: { label: "Rate Limiting", description: "Throttle API requests", type: :boolean },
|
|
41
|
+
rate_limit_per_minute: { label: "Rate Limit Threshold", description: "Requests per minute per IP", type: :integer, show_if: :enable_rate_limiting }
|
|
42
|
+
}
|
|
43
|
+
},
|
|
44
|
+
"Notification Channels" => {
|
|
45
|
+
icon: "bi-bell",
|
|
46
|
+
color: "info",
|
|
47
|
+
settings: {
|
|
48
|
+
enable_slack_notifications: { label: "Slack", description: "Real-time notifications", type: :boolean },
|
|
49
|
+
slack_webhook_url: { label: "Slack Webhook URL", description: "Slack webhook endpoint", type: :url, show_if: :enable_slack_notifications },
|
|
50
|
+
enable_email_notifications: { label: "Email", description: "Email alerts", type: :boolean },
|
|
51
|
+
notification_email_recipients: { label: "Email Recipients", description: "Recipient addresses", type: :array, show_if: :enable_email_notifications },
|
|
52
|
+
notification_email_from: { label: "Email From", description: "Sender address", type: :string, show_if: :enable_email_notifications },
|
|
53
|
+
enable_discord_notifications: { label: "Discord", description: "Discord webhook notifications", type: :boolean },
|
|
54
|
+
discord_webhook_url: { label: "Discord Webhook URL", description: "Discord webhook endpoint", type: :url, show_if: :enable_discord_notifications },
|
|
55
|
+
enable_pagerduty_notifications: { label: "PagerDuty", description: "Critical error escalation", type: :boolean },
|
|
56
|
+
pagerduty_integration_key: { label: "PagerDuty Integration Key", description: "PagerDuty API key", type: :string, show_if: :enable_pagerduty_notifications },
|
|
57
|
+
enable_webhook_notifications: { label: "Custom Webhooks", description: "Generic webhook endpoints", type: :boolean },
|
|
58
|
+
webhook_urls: { label: "Webhook URLs", description: "Custom webhook endpoints", type: :array, show_if: :enable_webhook_notifications }
|
|
59
|
+
}
|
|
60
|
+
},
|
|
61
|
+
"Advanced Analytics Features" => {
|
|
62
|
+
icon: "bi-graph-up",
|
|
63
|
+
color: "success",
|
|
64
|
+
settings: {
|
|
65
|
+
enable_similar_errors: { label: "Similar Errors (Fuzzy Matching)", description: "Find related errors by similarity", type: :boolean },
|
|
66
|
+
enable_co_occurring_errors: { label: "Co-occurring Errors", description: "Errors happening together", type: :boolean },
|
|
67
|
+
enable_error_cascades: { label: "Error Cascades", description: "Parent→child error chains", type: :boolean },
|
|
68
|
+
enable_error_correlation: { label: "Error Correlation", description: "Version/user/time analysis", type: :boolean },
|
|
69
|
+
enable_platform_comparison: { label: "Platform Comparison", description: "iOS vs Android analytics", type: :boolean },
|
|
70
|
+
enable_occurrence_patterns: { label: "Occurrence Patterns", description: "Cyclical/burst detection", type: :boolean },
|
|
71
|
+
enable_baseline_alerts: { label: "Baseline Alerts", description: "Anomaly detection", type: :boolean },
|
|
72
|
+
baseline_alert_threshold_std_devs: { label: "Alert Threshold", description: "Standard deviations to trigger alert", type: :float, show_if: :enable_baseline_alerts, unit: "σ" },
|
|
73
|
+
baseline_alert_severities: { label: "Alert Severities", description: "Severities to alert on", type: :array, show_if: :enable_baseline_alerts },
|
|
74
|
+
baseline_alert_cooldown_minutes: { label: "Alert Cooldown", description: "Minutes between alerts for same error type", type: :integer, show_if: :enable_baseline_alerts, unit: "minutes" }
|
|
75
|
+
}
|
|
76
|
+
},
|
|
77
|
+
"Source Code Integration" => {
|
|
78
|
+
icon: "bi-code-square",
|
|
79
|
+
color: "dark",
|
|
80
|
+
settings: {
|
|
81
|
+
enable_source_code_integration: { label: "Source Code Integration", description: "Show code in backtrace", type: :boolean },
|
|
82
|
+
source_code_context_lines: { label: "Context Lines", description: "Lines before/after target line", type: :integer, show_if: :enable_source_code_integration },
|
|
83
|
+
enable_git_blame: { label: "Git Blame", description: "Show git blame info", type: :boolean, show_if: :enable_source_code_integration },
|
|
84
|
+
source_code_cache_ttl: { label: "Cache TTL", description: "Source code cache duration", type: :integer, show_if: :enable_source_code_integration, unit: "seconds" },
|
|
85
|
+
only_show_app_code_source: { label: "Only App Code", description: "Hide gems/stdlib for security", type: :boolean, show_if: :enable_source_code_integration },
|
|
86
|
+
git_branch_strategy: { label: "Git Branch Strategy", description: "Branch resolution strategy", type: :symbol, show_if: :enable_source_code_integration }
|
|
87
|
+
}
|
|
88
|
+
},
|
|
89
|
+
"Enhanced Metrics" => {
|
|
90
|
+
icon: "bi-speedometer",
|
|
91
|
+
color: "secondary",
|
|
92
|
+
settings: {
|
|
93
|
+
app_version: { label: "App Version", description: "Current application version", type: :string },
|
|
94
|
+
git_sha: { label: "Git SHA", description: "Deployed commit", type: :git_sha },
|
|
95
|
+
git_repository_url: { label: "Git Repository URL", description: "GitHub/GitLab repo URL", type: :url },
|
|
96
|
+
dashboard_base_url: { label: "Dashboard Base URL", description: "Base URL for dashboard links", type: :url }
|
|
97
|
+
}
|
|
98
|
+
},
|
|
99
|
+
"Advanced Configuration" => {
|
|
100
|
+
icon: "bi-sliders",
|
|
101
|
+
color: "secondary",
|
|
102
|
+
settings: {
|
|
103
|
+
custom_severity_rules: { label: "Custom Severity Rules", description: "Error type → severity mapping", type: :hash },
|
|
104
|
+
ignored_exceptions: { label: "Ignored Exceptions", description: "Exceptions to ignore", type: :array }
|
|
105
|
+
}
|
|
106
|
+
},
|
|
107
|
+
"Internal Logging" => {
|
|
108
|
+
icon: "bi-terminal",
|
|
109
|
+
color: "light",
|
|
110
|
+
settings: {
|
|
111
|
+
enable_internal_logging: { label: "Internal Logging", description: "Gem debugging output", type: :boolean },
|
|
112
|
+
log_level: { label: "Log Level", description: "Verbosity level", type: :symbol, show_if: :enable_internal_logging }
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
%>
|
|
117
|
+
|
|
3
118
|
<div class="container-fluid py-4">
|
|
4
119
|
<!-- Page Header -->
|
|
5
120
|
<div class="d-flex justify-content-between align-items-center mb-4">
|
|
@@ -20,399 +135,42 @@
|
|
|
20
135
|
<code>config/initializers/rails_error_dashboard.rb</code>
|
|
21
136
|
</div>
|
|
22
137
|
|
|
23
|
-
<!--
|
|
24
|
-
|
|
25
|
-
<div class="card
|
|
26
|
-
<
|
|
27
|
-
<
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
<div class="card-body">
|
|
31
|
-
<div class="row">
|
|
32
|
-
<div class="col-md-6 mb-3">
|
|
33
|
-
<div class="d-flex justify-content-between align-items-center">
|
|
34
|
-
<div>
|
|
35
|
-
<strong>Error Middleware</strong>
|
|
36
|
-
<br><small class="text-muted">Catches unhandled exceptions</small>
|
|
37
|
-
</div>
|
|
38
|
-
<% if @config.enable_middleware %>
|
|
39
|
-
<span class="badge bg-success fs-6">
|
|
40
|
-
<i class="bi bi-check-circle"></i> Enabled
|
|
41
|
-
</span>
|
|
42
|
-
<% else %>
|
|
43
|
-
<span class="badge bg-secondary fs-6">
|
|
44
|
-
<i class="bi bi-x-circle"></i> Disabled
|
|
45
|
-
</span>
|
|
46
|
-
<% end %>
|
|
47
|
-
</div>
|
|
48
|
-
</div>
|
|
49
|
-
|
|
50
|
-
<div class="col-md-6 mb-3">
|
|
51
|
-
<div class="d-flex justify-content-between align-items-center">
|
|
52
|
-
<div>
|
|
53
|
-
<strong>Rails.error Subscriber</strong>
|
|
54
|
-
<br><small class="text-muted">Subscribes to Rails error events</small>
|
|
55
|
-
</div>
|
|
56
|
-
<% if @config.enable_error_subscriber %>
|
|
57
|
-
<span class="badge bg-success fs-6">
|
|
58
|
-
<i class="bi bi-check-circle"></i> Enabled
|
|
59
|
-
</span>
|
|
60
|
-
<% else %>
|
|
61
|
-
<span class="badge bg-secondary fs-6">
|
|
62
|
-
<i class="bi bi-x-circle"></i> Disabled
|
|
63
|
-
</span>
|
|
64
|
-
<% end %>
|
|
65
|
-
</div>
|
|
66
|
-
</div>
|
|
67
|
-
|
|
68
|
-
<div class="col-md-6 mb-3">
|
|
69
|
-
<div class="d-flex justify-content-between align-items-center">
|
|
70
|
-
<div>
|
|
71
|
-
<strong>Authentication</strong>
|
|
72
|
-
<br><small class="text-muted">HTTP Basic Auth protection (always enforced)</small>
|
|
73
|
-
</div>
|
|
74
|
-
<span class="badge bg-success fs-6">
|
|
75
|
-
<i class="bi bi-lock-fill"></i> Always Required
|
|
76
|
-
</span>
|
|
77
|
-
</div>
|
|
78
|
-
</div>
|
|
79
|
-
|
|
80
|
-
<div class="col-md-6 mb-3">
|
|
81
|
-
<div class="d-flex justify-content-between align-items-center">
|
|
82
|
-
<div>
|
|
83
|
-
<strong>Data Retention</strong>
|
|
84
|
-
<br><small class="text-muted">How long errors are kept</small>
|
|
85
|
-
</div>
|
|
86
|
-
<span class="badge bg-info fs-6">
|
|
87
|
-
<%= @config.retention_days %> days
|
|
88
|
-
</span>
|
|
89
|
-
</div>
|
|
90
|
-
</div>
|
|
91
|
-
|
|
92
|
-
<div class="col-md-6 mb-3">
|
|
93
|
-
<div class="d-flex justify-content-between align-items-center">
|
|
94
|
-
<div>
|
|
95
|
-
<strong>Max Backtrace Lines</strong>
|
|
96
|
-
<br><small class="text-muted">Stack trace depth limit</small>
|
|
97
|
-
</div>
|
|
98
|
-
<span class="badge bg-info fs-6">
|
|
99
|
-
<%= @config.max_backtrace_lines %> lines
|
|
100
|
-
</span>
|
|
101
|
-
</div>
|
|
102
|
-
</div>
|
|
103
|
-
|
|
104
|
-
<div class="col-md-6 mb-3">
|
|
105
|
-
<div class="d-flex justify-content-between align-items-center">
|
|
106
|
-
<div>
|
|
107
|
-
<strong>Sampling Rate</strong>
|
|
108
|
-
<br><small class="text-muted">Percentage of errors captured</small>
|
|
109
|
-
</div>
|
|
110
|
-
<span class="badge bg-info fs-6">
|
|
111
|
-
<%= (@config.sampling_rate * 100).to_i %>%
|
|
112
|
-
</span>
|
|
113
|
-
</div>
|
|
114
|
-
</div>
|
|
115
|
-
</div>
|
|
116
|
-
</div>
|
|
117
|
-
</div>
|
|
118
|
-
|
|
119
|
-
<!-- Performance Settings -->
|
|
120
|
-
<div class="card mb-4">
|
|
121
|
-
<div class="card-header bg-warning text-dark">
|
|
122
|
-
<h5 class="mb-0">
|
|
123
|
-
<i class="bi bi-lightning-charge"></i> Performance Settings
|
|
124
|
-
</h5>
|
|
125
|
-
</div>
|
|
126
|
-
<div class="card-body">
|
|
127
|
-
<div class="row">
|
|
128
|
-
<div class="col-md-6 mb-3">
|
|
129
|
-
<div class="d-flex justify-content-between align-items-center">
|
|
130
|
-
<div>
|
|
131
|
-
<strong>Async Logging</strong>
|
|
132
|
-
<br><small class="text-muted">Background job processing</small>
|
|
133
|
-
</div>
|
|
134
|
-
<% if @config.async_logging %>
|
|
135
|
-
<span class="badge bg-success fs-6">
|
|
136
|
-
<i class="bi bi-check-circle"></i> Enabled
|
|
137
|
-
<% if @config.async_adapter %>
|
|
138
|
-
(<%= @config.async_adapter %>)
|
|
139
|
-
<% end %>
|
|
140
|
-
</span>
|
|
141
|
-
<% else %>
|
|
142
|
-
<span class="badge bg-secondary fs-6">
|
|
143
|
-
<i class="bi bi-x-circle"></i> Disabled
|
|
144
|
-
</span>
|
|
145
|
-
<% end %>
|
|
146
|
-
</div>
|
|
147
|
-
</div>
|
|
148
|
-
|
|
149
|
-
<div class="col-md-6 mb-3">
|
|
150
|
-
<div class="d-flex justify-content-between align-items-center">
|
|
151
|
-
<div>
|
|
152
|
-
<strong>Separate Database</strong>
|
|
153
|
-
<br><small class="text-muted">Dedicated DB for error logs</small>
|
|
154
|
-
</div>
|
|
155
|
-
<% if @config.use_separate_database %>
|
|
156
|
-
<span class="badge bg-success fs-6">
|
|
157
|
-
<i class="bi bi-check-circle"></i> Enabled
|
|
158
|
-
</span>
|
|
159
|
-
<% else %>
|
|
160
|
-
<span class="badge bg-secondary fs-6">
|
|
161
|
-
<i class="bi bi-x-circle"></i> Disabled
|
|
162
|
-
</span>
|
|
163
|
-
<% end %>
|
|
164
|
-
</div>
|
|
165
|
-
</div>
|
|
166
|
-
</div>
|
|
167
|
-
</div>
|
|
168
|
-
</div>
|
|
169
|
-
|
|
170
|
-
<!-- Notification Channels -->
|
|
171
|
-
<div class="card mb-4">
|
|
172
|
-
<div class="card-header bg-info text-white">
|
|
173
|
-
<h5 class="mb-0">
|
|
174
|
-
<i class="bi bi-bell"></i> Notification Channels
|
|
175
|
-
</h5>
|
|
176
|
-
</div>
|
|
177
|
-
<div class="card-body">
|
|
178
|
-
<div class="row">
|
|
179
|
-
<div class="col-md-6 mb-3">
|
|
180
|
-
<div class="d-flex justify-content-between align-items-center">
|
|
181
|
-
<div>
|
|
182
|
-
<strong>Slack</strong>
|
|
183
|
-
<br><small class="text-muted">Real-time notifications</small>
|
|
184
|
-
</div>
|
|
185
|
-
<% if @config.enable_slack_notifications %>
|
|
186
|
-
<span class="badge bg-success fs-6">
|
|
187
|
-
<i class="bi bi-check-circle"></i> Enabled
|
|
188
|
-
</span>
|
|
189
|
-
<% else %>
|
|
190
|
-
<span class="badge bg-secondary fs-6">
|
|
191
|
-
<i class="bi bi-x-circle"></i> Disabled
|
|
192
|
-
</span>
|
|
193
|
-
<% end %>
|
|
194
|
-
</div>
|
|
195
|
-
</div>
|
|
196
|
-
|
|
197
|
-
<div class="col-md-6 mb-3">
|
|
198
|
-
<div class="d-flex justify-content-between align-items-center">
|
|
199
|
-
<div>
|
|
200
|
-
<strong>Email</strong>
|
|
201
|
-
<br><small class="text-muted">Email alerts</small>
|
|
202
|
-
</div>
|
|
203
|
-
<% if @config.enable_email_notifications %>
|
|
204
|
-
<span class="badge bg-success fs-6">
|
|
205
|
-
<i class="bi bi-check-circle"></i> Enabled
|
|
206
|
-
<% if @config.notification_email_recipients&.any? %>
|
|
207
|
-
(<%= @config.notification_email_recipients.count %> recipient<%= @config.notification_email_recipients.count != 1 ? 's' : '' %>)
|
|
208
|
-
<% end %>
|
|
209
|
-
</span>
|
|
210
|
-
<% else %>
|
|
211
|
-
<span class="badge bg-secondary fs-6">
|
|
212
|
-
<i class="bi bi-x-circle"></i> Disabled
|
|
213
|
-
</span>
|
|
214
|
-
<% end %>
|
|
215
|
-
</div>
|
|
216
|
-
</div>
|
|
217
|
-
|
|
218
|
-
<div class="col-md-6 mb-3">
|
|
219
|
-
<div class="d-flex justify-content-between align-items-center">
|
|
220
|
-
<div>
|
|
221
|
-
<strong>Discord</strong>
|
|
222
|
-
<br><small class="text-muted">Discord webhook notifications</small>
|
|
223
|
-
</div>
|
|
224
|
-
<% if @config.enable_discord_notifications %>
|
|
225
|
-
<span class="badge bg-success fs-6">
|
|
226
|
-
<i class="bi bi-check-circle"></i> Enabled
|
|
227
|
-
</span>
|
|
228
|
-
<% else %>
|
|
229
|
-
<span class="badge bg-secondary fs-6">
|
|
230
|
-
<i class="bi bi-x-circle"></i> Disabled
|
|
231
|
-
</span>
|
|
232
|
-
<% end %>
|
|
233
|
-
</div>
|
|
234
|
-
</div>
|
|
235
|
-
|
|
236
|
-
<div class="col-md-6 mb-3">
|
|
237
|
-
<div class="d-flex justify-content-between align-items-center">
|
|
238
|
-
<div>
|
|
239
|
-
<strong>PagerDuty</strong>
|
|
240
|
-
<br><small class="text-muted">Critical error escalation</small>
|
|
241
|
-
</div>
|
|
242
|
-
<% if @config.enable_pagerduty_notifications %>
|
|
243
|
-
<span class="badge bg-success fs-6">
|
|
244
|
-
<i class="bi bi-check-circle"></i> Enabled
|
|
245
|
-
</span>
|
|
246
|
-
<% else %>
|
|
247
|
-
<span class="badge bg-secondary fs-6">
|
|
248
|
-
<i class="bi bi-x-circle"></i> Disabled
|
|
249
|
-
</span>
|
|
250
|
-
<% end %>
|
|
251
|
-
</div>
|
|
252
|
-
</div>
|
|
253
|
-
|
|
254
|
-
<div class="col-md-6 mb-3">
|
|
255
|
-
<div class="d-flex justify-content-between align-items-center">
|
|
256
|
-
<div>
|
|
257
|
-
<strong>Custom Webhooks</strong>
|
|
258
|
-
<br><small class="text-muted">Generic webhook endpoints</small>
|
|
259
|
-
</div>
|
|
260
|
-
<% if @config.enable_webhook_notifications %>
|
|
261
|
-
<span class="badge bg-success fs-6">
|
|
262
|
-
<i class="bi bi-check-circle"></i> Enabled
|
|
263
|
-
<% if @config.webhook_urls&.any? %>
|
|
264
|
-
(<%= @config.webhook_urls.count %> URL<%= @config.webhook_urls.count != 1 ? 's' : '' %>)
|
|
265
|
-
<% end %>
|
|
266
|
-
</span>
|
|
267
|
-
<% else %>
|
|
268
|
-
<span class="badge bg-secondary fs-6">
|
|
269
|
-
<i class="bi bi-x-circle"></i> Disabled
|
|
270
|
-
</span>
|
|
271
|
-
<% end %>
|
|
272
|
-
</div>
|
|
273
|
-
</div>
|
|
138
|
+
<!-- Dynamically render setting groups -->
|
|
139
|
+
<% setting_groups.each do |group_name, group_config| %>
|
|
140
|
+
<div class="card mb-4">
|
|
141
|
+
<div class="card-header bg-<%= group_config[:color] %> <%= group_config[:color] == 'light' ? 'text-dark' : 'text-white' %>">
|
|
142
|
+
<h5 class="mb-0">
|
|
143
|
+
<i class="<%= group_config[:icon] %>"></i> <%= group_name %>
|
|
144
|
+
</h5>
|
|
274
145
|
</div>
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
</
|
|
297
|
-
<% else %>
|
|
298
|
-
<span class="badge bg-secondary fs-6">
|
|
299
|
-
<i class="bi bi-x-circle"></i> Disabled
|
|
300
|
-
</span>
|
|
301
|
-
<% end %>
|
|
302
|
-
</div>
|
|
303
|
-
</div>
|
|
304
|
-
|
|
305
|
-
<div class="col-md-6 mb-3">
|
|
306
|
-
<div class="d-flex justify-content-between align-items-center">
|
|
307
|
-
<div>
|
|
308
|
-
<strong>Co-occurring Errors</strong>
|
|
309
|
-
<br><small class="text-muted">Errors happening together</small>
|
|
310
|
-
</div>
|
|
311
|
-
<% if @config.enable_co_occurring_errors %>
|
|
312
|
-
<span class="badge bg-success fs-6">
|
|
313
|
-
<i class="bi bi-check-circle"></i> Enabled
|
|
314
|
-
</span>
|
|
315
|
-
<% else %>
|
|
316
|
-
<span class="badge bg-secondary fs-6">
|
|
317
|
-
<i class="bi bi-x-circle"></i> Disabled
|
|
318
|
-
</span>
|
|
319
|
-
<% end %>
|
|
320
|
-
</div>
|
|
321
|
-
</div>
|
|
322
|
-
|
|
323
|
-
<div class="col-md-6 mb-3">
|
|
324
|
-
<div class="d-flex justify-content-between align-items-center">
|
|
325
|
-
<div>
|
|
326
|
-
<strong>Error Cascades</strong>
|
|
327
|
-
<br><small class="text-muted">Parent→child error chains</small>
|
|
328
|
-
</div>
|
|
329
|
-
<% if @config.enable_error_cascades %>
|
|
330
|
-
<span class="badge bg-success fs-6">
|
|
331
|
-
<i class="bi bi-check-circle"></i> Enabled
|
|
332
|
-
</span>
|
|
333
|
-
<% else %>
|
|
334
|
-
<span class="badge bg-secondary fs-6">
|
|
335
|
-
<i class="bi bi-x-circle"></i> Disabled
|
|
336
|
-
</span>
|
|
337
|
-
<% end %>
|
|
338
|
-
</div>
|
|
339
|
-
</div>
|
|
340
|
-
|
|
341
|
-
<div class="col-md-6 mb-3">
|
|
342
|
-
<div class="d-flex justify-content-between align-items-center">
|
|
343
|
-
<div>
|
|
344
|
-
<strong>Error Correlation</strong>
|
|
345
|
-
<br><small class="text-muted">Version/user/time analysis</small>
|
|
346
|
-
</div>
|
|
347
|
-
<% if @config.enable_error_correlation %>
|
|
348
|
-
<span class="badge bg-success fs-6">
|
|
349
|
-
<i class="bi bi-check-circle"></i> Enabled
|
|
350
|
-
</span>
|
|
351
|
-
<% else %>
|
|
352
|
-
<span class="badge bg-secondary fs-6">
|
|
353
|
-
<i class="bi bi-x-circle"></i> Disabled
|
|
354
|
-
</span>
|
|
355
|
-
<% end %>
|
|
356
|
-
</div>
|
|
357
|
-
</div>
|
|
358
|
-
|
|
359
|
-
<div class="col-md-6 mb-3">
|
|
360
|
-
<div class="d-flex justify-content-between align-items-center">
|
|
361
|
-
<div>
|
|
362
|
-
<strong>Platform Comparison</strong>
|
|
363
|
-
<br><small class="text-muted">iOS vs Android analytics</small>
|
|
364
|
-
</div>
|
|
365
|
-
<% if @config.enable_platform_comparison %>
|
|
366
|
-
<span class="badge bg-success fs-6">
|
|
367
|
-
<i class="bi bi-check-circle"></i> Enabled
|
|
368
|
-
</span>
|
|
369
|
-
<% else %>
|
|
370
|
-
<span class="badge bg-secondary fs-6">
|
|
371
|
-
<i class="bi bi-x-circle"></i> Disabled
|
|
372
|
-
</span>
|
|
373
|
-
<% end %>
|
|
374
|
-
</div>
|
|
375
|
-
</div>
|
|
376
|
-
|
|
377
|
-
<div class="col-md-6 mb-3">
|
|
378
|
-
<div class="d-flex justify-content-between align-items-center">
|
|
379
|
-
<div>
|
|
380
|
-
<strong>Occurrence Patterns</strong>
|
|
381
|
-
<br><small class="text-muted">Cyclical/burst detection</small>
|
|
382
|
-
</div>
|
|
383
|
-
<% if @config.enable_occurrence_patterns %>
|
|
384
|
-
<span class="badge bg-success fs-6">
|
|
385
|
-
<i class="bi bi-check-circle"></i> Enabled
|
|
386
|
-
</span>
|
|
387
|
-
<% else %>
|
|
388
|
-
<span class="badge bg-secondary fs-6">
|
|
389
|
-
<i class="bi bi-x-circle"></i> Disabled
|
|
390
|
-
</span>
|
|
391
|
-
<% end %>
|
|
392
|
-
</div>
|
|
393
|
-
</div>
|
|
394
|
-
|
|
395
|
-
<div class="col-md-6 mb-3">
|
|
396
|
-
<div class="d-flex justify-content-between align-items-center">
|
|
397
|
-
<div>
|
|
398
|
-
<strong>Baseline Alerts</strong>
|
|
399
|
-
<br><small class="text-muted">Anomaly detection</small>
|
|
146
|
+
<div class="card-body">
|
|
147
|
+
<div class="row">
|
|
148
|
+
<% group_config[:settings].each do |setting_key, setting_meta| %>
|
|
149
|
+
<%
|
|
150
|
+
# Check if this setting should be displayed based on show_if condition
|
|
151
|
+
show_if_key = setting_meta[:show_if]
|
|
152
|
+
should_show = show_if_key.nil? || @config.send(show_if_key)
|
|
153
|
+
next unless should_show
|
|
154
|
+
|
|
155
|
+
value = @config.send(setting_key)
|
|
156
|
+
%>
|
|
157
|
+
<div class="col-md-6 mb-3">
|
|
158
|
+
<div class="d-flex justify-content-between align-items-center">
|
|
159
|
+
<div>
|
|
160
|
+
<strong><%= setting_meta[:label] %></strong>
|
|
161
|
+
<br><small class="text-muted"><%= setting_meta[:description] %></small>
|
|
162
|
+
</div>
|
|
163
|
+
<div class="text-end">
|
|
164
|
+
<%= render partial: 'rails_error_dashboard/errors/settings/value_badge',
|
|
165
|
+
locals: { value: value, type: setting_meta[:type], unit: setting_meta[:unit] } %>
|
|
166
|
+
</div>
|
|
167
|
+
</div>
|
|
400
168
|
</div>
|
|
401
|
-
|
|
402
|
-
<span class="badge bg-success fs-6">
|
|
403
|
-
<i class="bi bi-check-circle"></i> Enabled
|
|
404
|
-
(± <%= @config.baseline_alert_threshold_std_devs %>σ)
|
|
405
|
-
</span>
|
|
406
|
-
<% else %>
|
|
407
|
-
<span class="badge bg-secondary fs-6">
|
|
408
|
-
<i class="bi bi-x-circle"></i> Disabled
|
|
409
|
-
</span>
|
|
410
|
-
<% end %>
|
|
411
|
-
</div>
|
|
169
|
+
<% end %>
|
|
412
170
|
</div>
|
|
413
171
|
</div>
|
|
414
172
|
</div>
|
|
415
|
-
|
|
173
|
+
<% end %>
|
|
416
174
|
|
|
417
175
|
<!-- Active Plugins -->
|
|
418
176
|
<div class="card mb-4">
|
|
@@ -464,98 +222,6 @@
|
|
|
464
222
|
</div>
|
|
465
223
|
</div>
|
|
466
224
|
|
|
467
|
-
<!-- Enhanced Metrics -->
|
|
468
|
-
<% if @config.app_version || @config.git_sha || @config.total_users_for_impact %>
|
|
469
|
-
<div class="card mb-4">
|
|
470
|
-
<div class="card-header bg-secondary text-white">
|
|
471
|
-
<h5 class="mb-0">
|
|
472
|
-
<i class="bi bi-speedometer"></i> Enhanced Metrics
|
|
473
|
-
</h5>
|
|
474
|
-
</div>
|
|
475
|
-
<div class="card-body">
|
|
476
|
-
<div class="row">
|
|
477
|
-
<% if @config.app_version %>
|
|
478
|
-
<div class="col-md-4 mb-3">
|
|
479
|
-
<div class="d-flex justify-content-between align-items-center">
|
|
480
|
-
<div>
|
|
481
|
-
<strong>App Version</strong>
|
|
482
|
-
<br><small class="text-muted">Current application version</small>
|
|
483
|
-
</div>
|
|
484
|
-
<code class="fs-6"><%= @config.app_version %></code>
|
|
485
|
-
</div>
|
|
486
|
-
</div>
|
|
487
|
-
<% end %>
|
|
488
|
-
|
|
489
|
-
<% if @config.git_sha %>
|
|
490
|
-
<div class="col-md-4 mb-3">
|
|
491
|
-
<div class="d-flex justify-content-between align-items-center">
|
|
492
|
-
<div>
|
|
493
|
-
<strong>Git SHA</strong>
|
|
494
|
-
<br><small class="text-muted">Deployed commit</small>
|
|
495
|
-
</div>
|
|
496
|
-
<span class="fs-6"><%= git_commit_link(@config.git_sha) %></span>
|
|
497
|
-
</div>
|
|
498
|
-
</div>
|
|
499
|
-
<% end %>
|
|
500
|
-
|
|
501
|
-
<% if @config.total_users_for_impact %>
|
|
502
|
-
<div class="col-md-4 mb-3">
|
|
503
|
-
<div class="d-flex justify-content-between align-items-center">
|
|
504
|
-
<div>
|
|
505
|
-
<strong>Total Users</strong>
|
|
506
|
-
<br><small class="text-muted">For impact % calculation</small>
|
|
507
|
-
</div>
|
|
508
|
-
<span class="badge bg-info fs-6"><%= @config.total_users_for_impact %></span>
|
|
509
|
-
</div>
|
|
510
|
-
</div>
|
|
511
|
-
<% end %>
|
|
512
|
-
</div>
|
|
513
|
-
</div>
|
|
514
|
-
</div>
|
|
515
|
-
<% end %>
|
|
516
|
-
|
|
517
|
-
<!-- Internal Logging -->
|
|
518
|
-
<div class="card mb-4">
|
|
519
|
-
<div class="card-header bg-light">
|
|
520
|
-
<h5 class="mb-0">
|
|
521
|
-
<i class="bi bi-terminal"></i> Internal Logging
|
|
522
|
-
</h5>
|
|
523
|
-
</div>
|
|
524
|
-
<div class="card-body">
|
|
525
|
-
<div class="row">
|
|
526
|
-
<div class="col-md-6 mb-3">
|
|
527
|
-
<div class="d-flex justify-content-between align-items-center">
|
|
528
|
-
<div>
|
|
529
|
-
<strong>Internal Logging</strong>
|
|
530
|
-
<br><small class="text-muted">Gem debugging output</small>
|
|
531
|
-
</div>
|
|
532
|
-
<% if @config.enable_internal_logging %>
|
|
533
|
-
<span class="badge bg-warning text-dark fs-6">
|
|
534
|
-
<i class="bi bi-check-circle"></i> Enabled
|
|
535
|
-
</span>
|
|
536
|
-
<% else %>
|
|
537
|
-
<span class="badge bg-secondary fs-6">
|
|
538
|
-
<i class="bi bi-x-circle"></i> Disabled
|
|
539
|
-
</span>
|
|
540
|
-
<% end %>
|
|
541
|
-
</div>
|
|
542
|
-
</div>
|
|
543
|
-
|
|
544
|
-
<div class="col-md-6 mb-3">
|
|
545
|
-
<div class="d-flex justify-content-between align-items-center">
|
|
546
|
-
<div>
|
|
547
|
-
<strong>Log Level</strong>
|
|
548
|
-
<br><small class="text-muted">Verbosity level</small>
|
|
549
|
-
</div>
|
|
550
|
-
<span class="badge bg-info fs-6">
|
|
551
|
-
<%= @config.log_level.to_s.upcase %>
|
|
552
|
-
</span>
|
|
553
|
-
</div>
|
|
554
|
-
</div>
|
|
555
|
-
</div>
|
|
556
|
-
</div>
|
|
557
|
-
</div>
|
|
558
|
-
|
|
559
225
|
<!-- Help Text -->
|
|
560
226
|
<div class="alert alert-light border">
|
|
561
227
|
<h6 class="alert-heading">
|