rails_error_dashboard 0.5.15 → 0.6.1
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/app/controllers/rails_error_dashboard/application_controller.rb +37 -12
- data/app/controllers/rails_error_dashboard/errors_controller.rb +48 -26
- data/app/helpers/rails_error_dashboard/application_helper.rb +12 -5
- data/app/views/layouts/rails_error_dashboard.html.erb +1219 -1927
- data/app/views/rails_error_dashboard/errors/_breadcrumbs_group.html.erb +4 -4
- data/app/views/rails_error_dashboard/errors/_co_occurring_errors.html.erb +1 -1
- data/app/views/rails_error_dashboard/errors/_discussion.html.erb +3 -3
- data/app/views/rails_error_dashboard/errors/_error_cascades.html.erb +1 -1
- data/app/views/rails_error_dashboard/errors/_error_row.html.erb +69 -79
- data/app/views/rails_error_dashboard/errors/_instance_variables.html.erb +1 -1
- data/app/views/rails_error_dashboard/errors/_issue_section.html.erb +1 -1
- data/app/views/rails_error_dashboard/errors/_local_variables.html.erb +1 -1
- data/app/views/rails_error_dashboard/errors/_pattern_insights.html.erb +2 -2
- data/app/views/rails_error_dashboard/errors/_request_context.html.erb +1 -1
- data/app/views/rails_error_dashboard/errors/_sidebar_metadata.html.erb +1 -1
- data/app/views/rails_error_dashboard/errors/_similar_errors.html.erb +1 -1
- data/app/views/rails_error_dashboard/errors/_timeline.html.erb +4 -4
- data/app/views/rails_error_dashboard/errors/actioncable_health_summary.html.erb +6 -6
- data/app/views/rails_error_dashboard/errors/activestorage_health_summary.html.erb +6 -6
- data/app/views/rails_error_dashboard/errors/analytics.html.erb +34 -50
- data/app/views/rails_error_dashboard/errors/cache_health_summary.html.erb +7 -7
- data/app/views/rails_error_dashboard/errors/correlation.html.erb +11 -11
- data/app/views/rails_error_dashboard/errors/database_health_summary.html.erb +114 -172
- data/app/views/rails_error_dashboard/errors/deprecations.html.erb +7 -7
- data/app/views/rails_error_dashboard/errors/diagnostic_dumps.html.erb +6 -6
- data/app/views/rails_error_dashboard/errors/index.html.erb +311 -613
- data/app/views/rails_error_dashboard/errors/job_health_summary.html.erb +7 -7
- data/app/views/rails_error_dashboard/errors/n_plus_one_summary.html.erb +7 -7
- data/app/views/rails_error_dashboard/errors/overview.html.erb +192 -363
- data/app/views/rails_error_dashboard/errors/platform_comparison.html.erb +11 -11
- data/app/views/rails_error_dashboard/errors/rack_attack_summary.html.erb +6 -6
- data/app/views/rails_error_dashboard/errors/releases.html.erb +6 -6
- data/app/views/rails_error_dashboard/errors/settings.html.erb +53 -51
- data/app/views/rails_error_dashboard/errors/show.html.erb +200 -203
- data/app/views/rails_error_dashboard/errors/swallowed_exceptions.html.erb +19 -19
- data/app/views/rails_error_dashboard/errors/user_impact.html.erb +6 -6
- data/config/routes.rb +1 -0
- data/lib/rails_error_dashboard/configuration.rb +6 -0
- data/lib/rails_error_dashboard/services/error_broadcaster.rb +1 -1
- data/lib/rails_error_dashboard/services/system_health_snapshot.rb +1 -1
- data/lib/rails_error_dashboard/test_error.rb +7 -0
- data/lib/rails_error_dashboard/version.rb +1 -1
- data/lib/rails_error_dashboard.rb +1 -0
- metadata +3 -2
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
<% deprecation_crumbs = breadcrumbs.select { |c| c["c"] == "deprecation" } %>
|
|
6
6
|
<% if deprecation_crumbs.any? %>
|
|
7
7
|
<div class="card mb-4" id="section-deprecation-warnings" style="border-color: var(--bs-danger);">
|
|
8
|
-
<div class="card-header
|
|
8
|
+
<div class="card-header">
|
|
9
9
|
<h5 class="mb-0">
|
|
10
10
|
<i class="bi bi-exclamation-triangle text-danger"></i> Deprecation Warnings
|
|
11
11
|
<span class="badge bg-danger"><%= deprecation_crumbs.size %></span>
|
|
@@ -49,7 +49,7 @@
|
|
|
49
49
|
<% n_plus_one_patterns = RailsErrorDashboard::Services::NplusOneDetector.call(breadcrumbs) %>
|
|
50
50
|
<% if n_plus_one_patterns.any? %>
|
|
51
51
|
<div class="card mb-4" id="section-n-plus-one" style="border-color: var(--bs-warning);">
|
|
52
|
-
<div class="card-header
|
|
52
|
+
<div class="card-header">
|
|
53
53
|
<h5 class="mb-0">
|
|
54
54
|
<i class="bi bi-arrow-repeat text-warning"></i> N+1 Query Detection
|
|
55
55
|
<span class="badge bg-warning text-dark"><%= n_plus_one_patterns.size %> pattern<%= n_plus_one_patterns.size == 1 ? "" : "s" %></span>
|
|
@@ -108,7 +108,7 @@
|
|
|
108
108
|
<% cache_analysis = RailsErrorDashboard::Services::CacheAnalyzer.call(breadcrumbs) %>
|
|
109
109
|
<% if cache_analysis %>
|
|
110
110
|
<div class="card mb-4" id="section-cache-health" style="border-color: var(--bs-info);">
|
|
111
|
-
<div class="card-header
|
|
111
|
+
<div class="card-header">
|
|
112
112
|
<h5 class="mb-0">
|
|
113
113
|
<i class="bi bi-lightning-charge text-info"></i> Cache Health
|
|
114
114
|
<span class="badge bg-info text-dark"><%= cache_analysis[:reads] + cache_analysis[:writes] %> operations</span>
|
|
@@ -189,7 +189,7 @@
|
|
|
189
189
|
<% end %>
|
|
190
190
|
|
|
191
191
|
<div class="card mb-4" id="section-breadcrumbs">
|
|
192
|
-
<div class="card-header
|
|
192
|
+
<div class="card-header">
|
|
193
193
|
<h5 class="mb-0">
|
|
194
194
|
<i class="bi bi-signpost-2"></i> Breadcrumbs
|
|
195
195
|
<span class="badge bg-secondary"><%= breadcrumbs.size %> events</span>
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
<% co_occurring = error.co_occurring_errors(window_minutes: 5, min_frequency: 2, limit: 5) %>
|
|
4
4
|
<% if co_occurring.any? %>
|
|
5
5
|
<div class="card mb-4" id="section-co-occurring">
|
|
6
|
-
<div class="card-header
|
|
6
|
+
<div class="card-header">
|
|
7
7
|
<h5 class="mb-0">
|
|
8
8
|
<i class="bi bi-clock-history"></i> Co-occurring Errors
|
|
9
9
|
<span class="badge bg-info text-dark">Time Patterns</span>
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
|
|
6
6
|
<% if has_linked_issue && (platform_comments.any? || has_audit_comments) %>
|
|
7
7
|
<div class="card mb-4" id="section-discussion">
|
|
8
|
-
<div class="card-header
|
|
8
|
+
<div class="card-header d-flex justify-content-between align-items-center">
|
|
9
9
|
<h5 class="mb-0">
|
|
10
10
|
<i class="bi bi-chat-dots"></i> Discussion
|
|
11
11
|
<% if platform_comments.any? %>
|
|
@@ -62,7 +62,7 @@
|
|
|
62
62
|
<% elsif has_linked_issue %>
|
|
63
63
|
<!-- Issue linked but no comments yet -->
|
|
64
64
|
<div class="card mb-4" id="section-discussion">
|
|
65
|
-
<div class="card-header
|
|
65
|
+
<div class="card-header d-flex justify-content-between align-items-center">
|
|
66
66
|
<h5 class="mb-0">
|
|
67
67
|
<i class="bi bi-chat-dots"></i> Discussion
|
|
68
68
|
</h5>
|
|
@@ -77,7 +77,7 @@
|
|
|
77
77
|
<% elsif has_audit_comments %>
|
|
78
78
|
<!-- No issue linked, but has audit trail -->
|
|
79
79
|
<div class="card mb-4" id="section-discussion">
|
|
80
|
-
<div class="card-header
|
|
80
|
+
<div class="card-header">
|
|
81
81
|
<h5 class="mb-0">
|
|
82
82
|
<i class="bi bi-clock-history"></i> Activity Log
|
|
83
83
|
</h5>
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
<% cascades = error.error_cascades %>
|
|
4
4
|
<% if cascades[:parents].any? || cascades[:children].any? %>
|
|
5
5
|
<div class="card" id="section-error-cascades">
|
|
6
|
-
<div class="card-header
|
|
6
|
+
<div class="card-header">
|
|
7
7
|
<h5 class="mb-0">
|
|
8
8
|
<i class="bi bi-diagram-3"></i> Error Cascades
|
|
9
9
|
<small class="text-muted ms-2">Causal relationships between errors</small>
|
|
@@ -1,54 +1,83 @@
|
|
|
1
|
-
<tr id="error_<%= error.id %>"
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
<tr id="error_<%= error.id %>"
|
|
2
|
+
onclick="window.location='<%= error_path(error, **app_context) %>'"
|
|
3
|
+
style="border-bottom: 1px solid var(--border-primary); cursor: pointer; transition: background 0.1s ease;"
|
|
4
|
+
onmouseenter="this.style.background='var(--surface-hover)'; this.querySelector('.sev-bar').style.opacity='1';"
|
|
5
|
+
onmouseleave="this.style.background='transparent'; this.querySelector('.sev-bar').style.opacity='0';">
|
|
6
|
+
<td style="padding: var(--space-3) var(--space-4); text-align: center; position: relative;" onclick="event.stopPropagation(); var cb = this.querySelector('input'); cb.checked = !cb.checked; cb.dispatchEvent(new Event('change'));">
|
|
7
|
+
<span class="sev-bar" style="position: absolute; left: 0; top: 0; bottom: 0; width: 3px; background: <%= severity_color_var(error.severity) %>; opacity: 0; transition: opacity 0.1s ease; border-radius: 0 2px 2px 0;"></span>
|
|
8
|
+
<input type="checkbox" class="error-checkbox form-check-input" value="<%= error.id %>" data-error-id="<%= error.id %>" onclick="event.stopPropagation();" style="accent-color: var(--accent);">
|
|
4
9
|
</td>
|
|
5
|
-
<td onclick="window.location='<%= error_path(error) %>'
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
10
|
+
<td style="padding: var(--space-3) var(--space-4);" onclick="window.location='<%= error_path(error, **app_context) %>'">
|
|
11
|
+
<div style="display: flex; align-items: center; gap: 8px;">
|
|
12
|
+
<span class="badge bg-<%= severity_color(error.severity) %>" style="display: inline-flex; align-items: center; gap: 4px;">
|
|
13
|
+
<span style="width: 6px; height: 6px; border-radius: 50%; background: currentColor;"></span>
|
|
14
|
+
<%= error.severity %>
|
|
15
|
+
</span>
|
|
16
|
+
<div style="min-width: 0;">
|
|
17
|
+
<div style="font-weight: 600; color: var(--text-primary); font-family: var(--font-mono); font-size: 12px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;">
|
|
18
|
+
<%= error.error_type %>
|
|
19
|
+
<% if error.recent? %>
|
|
20
|
+
<span style="display: inline-block; padding: 1px 6px; font-size: 9px; font-weight: 600; border-radius: var(--radius-full); background: var(--status-success-bg); color: var(--status-success); margin-left: 4px; text-transform: uppercase;">NEW</span>
|
|
21
|
+
<% end %>
|
|
22
|
+
</div>
|
|
23
|
+
<div style="color: var(--text-tertiary); font-size: 12px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;" title="<%= error.message %>"><%= error.message %></div>
|
|
24
|
+
</div>
|
|
25
|
+
</div>
|
|
19
26
|
</td>
|
|
20
|
-
<td onclick="window.location='<%= error_path(error) %>'
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
+
<td style="padding: var(--space-3) var(--space-4);" onclick="window.location='<%= error_path(error, **app_context) %>'">
|
|
28
|
+
<%
|
|
29
|
+
# Use the model's status field if it has a meaningful workflow status
|
|
30
|
+
raw_status = error.respond_to?(:status) ? error.status : nil
|
|
31
|
+
status_text = if error.respond_to?(:muted?) && error.muted?
|
|
32
|
+
'muted'
|
|
33
|
+
elsif error.respond_to?(:snoozed?) && error.snoozed?
|
|
34
|
+
'snoozed'
|
|
35
|
+
elsif raw_status.present? && raw_status != 'new'
|
|
36
|
+
raw_status.tr('_', ' ')
|
|
37
|
+
elsif error.resolved?
|
|
38
|
+
'resolved'
|
|
39
|
+
else
|
|
40
|
+
'unresolved'
|
|
41
|
+
end
|
|
42
|
+
status_colors = {
|
|
43
|
+
'unresolved' => { bg: 'var(--status-critical-bg)', color: 'var(--status-critical)' },
|
|
44
|
+
'resolved' => { bg: 'var(--status-success-bg)', color: 'var(--status-success)' },
|
|
45
|
+
'in progress' => { bg: 'var(--status-info-bg)', color: 'var(--status-info)' },
|
|
46
|
+
'investigating' => { bg: 'var(--status-caution-bg)', color: 'var(--status-caution)' },
|
|
47
|
+
'wont fix' => { bg: 'var(--surface-tertiary)', color: 'var(--text-tertiary)' },
|
|
48
|
+
'assigned' => { bg: 'var(--accent-subtle)', color: 'var(--accent)' },
|
|
49
|
+
'snoozed' => { bg: 'var(--status-caution-bg)', color: 'var(--status-caution)' },
|
|
50
|
+
'muted' => { bg: 'var(--surface-tertiary)', color: 'var(--text-tertiary)' },
|
|
51
|
+
}
|
|
52
|
+
sc = status_colors[status_text] || status_colors['unresolved']
|
|
53
|
+
%>
|
|
54
|
+
<span style="display: inline-flex; align-items: center; gap: 4px; padding: 3px 10px; font-size: 11px; font-weight: 600; border-radius: var(--radius-full); background: <%= sc[:bg] %>; color: <%= sc[:color] %>; text-transform: capitalize;">
|
|
55
|
+
<%= status_text %>
|
|
56
|
+
</span>
|
|
57
|
+
<% if error.reopened? %>
|
|
58
|
+
<i class="bi bi-arrow-counterclockwise" style="color: var(--status-warning); margin-left: 4px; font-size: 12px;" title="Reopened"></i>
|
|
27
59
|
<% end %>
|
|
28
60
|
</td>
|
|
29
|
-
<td onclick="window.location='<%= error_path(error) %>'
|
|
30
|
-
|
|
31
|
-
<%= error.message %>
|
|
32
|
-
</div>
|
|
61
|
+
<td style="padding: var(--space-3) var(--space-4); text-align: right; font-weight: 600; font-variant-numeric: tabular-nums; color: var(--text-primary);" onclick="window.location='<%= error_path(error, **app_context) %>'">
|
|
62
|
+
<%= error.occurrence_count.to_s(:delimited) rescue error.occurrence_count %>
|
|
33
63
|
</td>
|
|
34
|
-
<td onclick="window.location='<%= error_path(error) %>'
|
|
35
|
-
|
|
64
|
+
<td style="padding: var(--space-3) var(--space-4); text-align: right; font-variant-numeric: tabular-nums; color: var(--text-secondary);" onclick="window.location='<%= error_path(error, **app_context) %>'">
|
|
65
|
+
<% if error.user_id %>
|
|
66
|
+
<%= error.user_id %>
|
|
67
|
+
<% else %>
|
|
68
|
+
<span style="color: var(--text-tertiary);">—</span>
|
|
69
|
+
<% end %>
|
|
36
70
|
</td>
|
|
37
|
-
<td onclick="window.location='<%= error_path(error) %>'
|
|
38
|
-
|
|
39
|
-
<strong>First:</strong> <%= local_time(error.first_seen_at, format: :short) %><br>
|
|
40
|
-
<strong>Last:</strong> <%= local_time(error.last_seen_at, format: :short) %>
|
|
41
|
-
</small>
|
|
71
|
+
<td style="padding: var(--space-3) var(--space-4); text-align: right; color: var(--text-tertiary); font-size: 12px;" onclick="window.location='<%= error_path(error, **app_context) %>'">
|
|
72
|
+
<%= local_time_ago(error.last_seen_at) %>
|
|
42
73
|
</td>
|
|
43
74
|
<% if local_assigns[:show_application] %>
|
|
44
|
-
<td onclick="window.location='<%= error_path(error) %>'
|
|
45
|
-
<span class="badge bg-info">
|
|
46
|
-
<%= error.application&.name || 'Unknown' %>
|
|
47
|
-
</span>
|
|
75
|
+
<td style="padding: var(--space-3) var(--space-4); font-size: 12px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;" title="<%= error.application&.name || 'Unknown' %>" onclick="window.location='<%= error_path(error, **app_context) %>'">
|
|
76
|
+
<span class="badge bg-info"><%= error.application&.name || 'Unknown' %></span>
|
|
48
77
|
</td>
|
|
49
78
|
<% end %>
|
|
50
79
|
<% if local_assigns[:show_platform] %>
|
|
51
|
-
<td onclick="window.location='<%= error_path(error) %>'
|
|
80
|
+
<td style="padding: var(--space-3) var(--space-4); font-size: 12px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;" title="<%= error.platform || 'API' %>" onclick="window.location='<%= error_path(error, **app_context) %>'">
|
|
52
81
|
<% if error.platform == 'iOS' %>
|
|
53
82
|
<span class="badge badge-ios"><i class="bi bi-apple"></i> iOS</span>
|
|
54
83
|
<% elsif error.platform == 'Android' %>
|
|
@@ -60,43 +89,4 @@
|
|
|
60
89
|
<% end %>
|
|
61
90
|
</td>
|
|
62
91
|
<% end %>
|
|
63
|
-
<td onclick="window.location='<%= error_path(error) %>';">
|
|
64
|
-
<% if error.user_id %>
|
|
65
|
-
<small data-bs-toggle="tooltip" title="User affected by this error">User #<%= error.user_id %></small>
|
|
66
|
-
<% if error.respond_to?(:user_impact_percentage) %>
|
|
67
|
-
<% impact = error.user_impact_percentage %>
|
|
68
|
-
<% if impact > 0 %>
|
|
69
|
-
<br><small class="badge bg-warning text-dark" data-bs-toggle="tooltip" title="Percentage of users affected by this error type"><%= impact %>% impact</small>
|
|
70
|
-
<% end %>
|
|
71
|
-
<% end %>
|
|
72
|
-
<% else %>
|
|
73
|
-
<small class="text-muted" data-bs-toggle="tooltip" title="No specific user affected">-</small>
|
|
74
|
-
<% end %>
|
|
75
|
-
</td>
|
|
76
|
-
<td onclick="window.location='<%= error_path(error) %>';">
|
|
77
|
-
<% if error.resolved? %>
|
|
78
|
-
<i class="bi bi-check-circle-fill text-success"
|
|
79
|
-
data-bs-toggle="tooltip"
|
|
80
|
-
data-bs-placement="left"
|
|
81
|
-
data-bs-html="true"
|
|
82
|
-
title="<%= if error.resolution_comment.present?
|
|
83
|
-
"<strong>Resolved</strong><br><em>#{error.resolution_comment.truncate(100).gsub('"', '"').gsub("'", ''')}</em>"
|
|
84
|
-
else
|
|
85
|
-
'Resolved'
|
|
86
|
-
end %>"></i>
|
|
87
|
-
<% else %>
|
|
88
|
-
<i class="bi bi-exclamation-circle-fill text-danger" data-bs-toggle="tooltip" title="Unresolved"></i>
|
|
89
|
-
<% end %>
|
|
90
|
-
<% if error.reopened? %>
|
|
91
|
-
<i class="bi bi-arrow-counterclockwise text-warning ms-1" data-bs-toggle="tooltip" title="Reopened"></i>
|
|
92
|
-
<% end %>
|
|
93
|
-
<% if error.respond_to?(:muted?) && error.muted? %>
|
|
94
|
-
<i class="bi bi-bell-slash text-secondary ms-1" data-bs-toggle="tooltip" title="Muted - notifications silenced"></i>
|
|
95
|
-
<% end %>
|
|
96
|
-
</td>
|
|
97
|
-
<td onclick="event.stopPropagation();">
|
|
98
|
-
<%= link_to error_path(error), class: "btn btn-sm btn-outline-primary" do %>
|
|
99
|
-
<i class="bi bi-eye"></i>
|
|
100
|
-
<% end %>
|
|
101
|
-
</td>
|
|
102
92
|
</tr>
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
<% self_class = instance_vars.delete("_self_class") %>
|
|
5
5
|
<% if instance_vars.any? %>
|
|
6
6
|
<div class="card mb-4" id="section-instance-variables">
|
|
7
|
-
<div class="card-header
|
|
7
|
+
<div class="card-header">
|
|
8
8
|
<h5 class="mb-0">
|
|
9
9
|
<i class="bi bi-box"></i> Instance Variables
|
|
10
10
|
<span class="badge bg-secondary"><%= instance_vars.size %> captured</span>
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
<% if RailsErrorDashboard.configuration.enable_issue_tracking %>
|
|
2
2
|
<div class="card mb-4" id="issue-tracking">
|
|
3
|
-
<div class="card-header
|
|
3
|
+
<div class="card-header d-flex justify-content-between align-items-center">
|
|
4
4
|
<h5 class="mb-0">
|
|
5
5
|
<i class="bi bi-link-45deg me-2"></i>
|
|
6
6
|
Issue Tracker
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
<% local_vars = JSON.parse(error.local_variables) rescue {} %>
|
|
4
4
|
<% if local_vars.any? %>
|
|
5
5
|
<div class="card mb-4" id="section-local-variables">
|
|
6
|
-
<div class="card-header
|
|
6
|
+
<div class="card-header">
|
|
7
7
|
<h5 class="mb-0">
|
|
8
8
|
<i class="bi bi-braces"></i> Local Variables
|
|
9
9
|
<span class="badge bg-secondary"><%= local_vars.size %> captured</span>
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
|
|
8
8
|
<% if pattern_data.present? && pattern_data[:total_errors] > 0 %>
|
|
9
9
|
<div class="card mb-4" id="section-occurrence-patterns">
|
|
10
|
-
<div class="card-header
|
|
10
|
+
<div class="card-header">
|
|
11
11
|
<h5 class="mb-0">
|
|
12
12
|
<i class="bi bi-graph-up"></i> Occurrence Patterns
|
|
13
13
|
<small class="text-muted">(Last 30 days)</small>
|
|
@@ -128,7 +128,7 @@
|
|
|
128
128
|
<!-- Error Bursts -->
|
|
129
129
|
<% if bursts.present? && bursts.any? %>
|
|
130
130
|
<div class="card mb-4">
|
|
131
|
-
<div class="card-header
|
|
131
|
+
<div class="card-header">
|
|
132
132
|
<h5 class="mb-0">
|
|
133
133
|
<i class="bi bi-lightning-charge-fill text-warning"></i> Error Bursts
|
|
134
134
|
<span class="badge bg-warning text-dark"><%= bursts.count %></span>
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
<!-- Request Context -->
|
|
2
2
|
<% cache [error, 'request_context_v3'] do %>
|
|
3
3
|
<div class="card mb-4" id="section-request-context">
|
|
4
|
-
<div class="card-header
|
|
4
|
+
<div class="card-header">
|
|
5
5
|
<h5 class="mb-0"><i class="bi bi-globe"></i> Request Context</h5>
|
|
6
6
|
</div>
|
|
7
7
|
<div class="card-body">
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
<% if similar.any? %>
|
|
5
5
|
<% cache [error, 'similar_errors_v1', similar.map { |s| s[:error]&.updated_at }.compact.max] do %>
|
|
6
6
|
<div class="card mb-4" id="section-similar-errors">
|
|
7
|
-
<div class="card-header
|
|
7
|
+
<div class="card-header">
|
|
8
8
|
<h5 class="mb-0">
|
|
9
9
|
<i class="bi bi-diagram-3"></i> Similar Errors
|
|
10
10
|
<span class="badge bg-info text-dark">Fuzzy Matching</span>
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
<%# Timeline view for related errors leading up to this error %>
|
|
2
2
|
<% if @related_errors.any? %>
|
|
3
3
|
<div class="card" id="section-timeline">
|
|
4
|
-
<div class="card-header
|
|
4
|
+
<div class="card-header">
|
|
5
5
|
<h5 class="mb-0">
|
|
6
6
|
<i class="bi bi-clock-history"></i> Timeline
|
|
7
7
|
<small class="text-muted ms-2">Recent related errors</small>
|
|
@@ -87,11 +87,11 @@
|
|
|
87
87
|
</div>
|
|
88
88
|
|
|
89
89
|
<% if error.resolved? && error.resolution_comment.present? %>
|
|
90
|
-
<div
|
|
91
|
-
<small
|
|
90
|
+
<div style="margin-top: var(--space-2); padding: var(--space-2) var(--space-3); background: var(--status-success-bg); border: 1px solid var(--status-success); border-radius: var(--radius-sm);">
|
|
91
|
+
<small style="color: var(--status-success); font-weight: 600;">
|
|
92
92
|
<i class="bi bi-journal-text"></i> Resolution Notes:
|
|
93
93
|
</small>
|
|
94
|
-
<div
|
|
94
|
+
<div style="font-size: 13px; color: var(--text-primary); margin-top: 4px;">
|
|
95
95
|
<%= auto_link_urls(truncate(error.resolution_comment, length: 200), error: error).html_safe %>
|
|
96
96
|
</div>
|
|
97
97
|
</div>
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
<% content_for :page_title, "ActionCable Health" %>
|
|
2
2
|
|
|
3
|
-
<div
|
|
3
|
+
<div>
|
|
4
4
|
<div class="d-flex justify-content-between align-items-center mb-4">
|
|
5
|
-
<h1
|
|
5
|
+
<h1 style="font-size: 20px; font-weight: 700; margin: 0;">
|
|
6
6
|
<i class="bi bi-broadcast me-2"></i>
|
|
7
7
|
ActionCable Health
|
|
8
8
|
</h1>
|
|
@@ -21,9 +21,9 @@
|
|
|
21
21
|
</div>
|
|
22
22
|
|
|
23
23
|
<% if @unique_channels == 0 %>
|
|
24
|
-
<div class="
|
|
24
|
+
<div class="red-empty-state">
|
|
25
25
|
<i class="bi bi-broadcast display-1 text-success mb-3"></i>
|
|
26
|
-
<
|
|
26
|
+
<div class="red-empty-state-title">No ActionCable Events Found</div>
|
|
27
27
|
<p class="text-muted">
|
|
28
28
|
No ActionCable channel actions, transmissions, or subscription events were detected in error breadcrumbs over the last <%= @days %> days.
|
|
29
29
|
</p>
|
|
@@ -68,7 +68,7 @@
|
|
|
68
68
|
</div>
|
|
69
69
|
|
|
70
70
|
<div class="card mb-4">
|
|
71
|
-
<div class="card-header
|
|
71
|
+
<div class="card-header d-flex justify-content-between align-items-center">
|
|
72
72
|
<h5 class="mb-0">
|
|
73
73
|
<i class="bi bi-broadcast text-primary me-2"></i>
|
|
74
74
|
ActionCable Events by Channel
|
|
@@ -112,7 +112,7 @@
|
|
|
112
112
|
</table>
|
|
113
113
|
</div>
|
|
114
114
|
</div>
|
|
115
|
-
<div class="card-footer
|
|
115
|
+
<div class="card-footer border-top d-flex justify-content-between align-items-center">
|
|
116
116
|
<div>
|
|
117
117
|
<small class="text-muted">
|
|
118
118
|
<i class="bi bi-lightbulb text-warning"></i> ActionCable events are captured when they coincide with errors. High rejection counts may indicate authentication or authorization issues.
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
<% content_for :page_title, "ActiveStorage Health" %>
|
|
2
2
|
|
|
3
|
-
<div
|
|
3
|
+
<div>
|
|
4
4
|
<div class="d-flex justify-content-between align-items-center mb-4">
|
|
5
|
-
<h1
|
|
5
|
+
<h1 style="font-size: 20px; font-weight: 700; margin: 0;">
|
|
6
6
|
<i class="bi bi-cloud-arrow-up me-2"></i>
|
|
7
7
|
ActiveStorage Health
|
|
8
8
|
</h1>
|
|
@@ -21,9 +21,9 @@
|
|
|
21
21
|
</div>
|
|
22
22
|
|
|
23
23
|
<% if @unique_services == 0 %>
|
|
24
|
-
<div class="
|
|
24
|
+
<div class="red-empty-state">
|
|
25
25
|
<i class="bi bi-cloud-arrow-up display-1 text-success mb-3"></i>
|
|
26
|
-
<
|
|
26
|
+
<div class="red-empty-state-title">No ActiveStorage Events Found</div>
|
|
27
27
|
<p class="text-muted">
|
|
28
28
|
No ActiveStorage service operations were detected in error breadcrumbs over the last <%= @days %> days.
|
|
29
29
|
</p>
|
|
@@ -68,7 +68,7 @@
|
|
|
68
68
|
</div>
|
|
69
69
|
|
|
70
70
|
<div class="card mb-4">
|
|
71
|
-
<div class="card-header
|
|
71
|
+
<div class="card-header d-flex justify-content-between align-items-center">
|
|
72
72
|
<h5 class="mb-0">
|
|
73
73
|
<i class="bi bi-cloud-arrow-up text-primary me-2"></i>
|
|
74
74
|
Storage Operations by Service
|
|
@@ -128,7 +128,7 @@
|
|
|
128
128
|
</table>
|
|
129
129
|
</div>
|
|
130
130
|
</div>
|
|
131
|
-
<div class="card-footer
|
|
131
|
+
<div class="card-footer border-top d-flex justify-content-between align-items-center">
|
|
132
132
|
<div>
|
|
133
133
|
<small class="text-muted">
|
|
134
134
|
<i class="bi bi-lightbulb text-warning"></i> Slow storage operations may indicate network issues, large file sizes, or service provider throttling.
|