rails_error_dashboard 0.16.0 → 0.16.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/README.md +2 -1
- data/app/views/rails_error_dashboard/errors/correlation.html.erb +2 -2
- data/app/views/rails_error_dashboard/errors/overview.html.erb +4 -0
- data/app/views/rails_error_dashboard/errors/platform_comparison.html.erb +10 -6
- data/config/locales/de.yml +2 -1
- data/config/locales/en.yml +2 -1
- data/config/locales/es.yml +2 -1
- data/config/locales/fr.yml +2 -1
- data/config/locales/it.yml +2 -1
- data/config/locales/ja.yml +2 -1
- data/config/locales/pl.yml +2 -1
- data/config/locales/pt-BR.yml +2 -1
- data/config/locales/ru.yml +2 -1
- data/config/locales/uk.yml +2 -1
- data/config/locales/zh-CN.yml +2 -1
- data/lib/rails_error_dashboard/configuration.rb +7 -0
- data/lib/rails_error_dashboard/queries/platform_comparison.rb +50 -21
- data/lib/rails_error_dashboard/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 5e1c8b34bf48e03bc9b163397dc1acbe54d0900b539805159c3361b74e5aad2c
|
|
4
|
+
data.tar.gz: 5940d53e5b99cf6fbac71597f09e20275026b49f3e09e3699d51aa50c1eac615
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: bd17c0b7c07fb32bcdd872c677c738f6c6d48caa1a12e8024943f5470cc22a58fbfef647d400b6badf69ee2c6aacdcfe1c739bbf00b84c2ff5e15ae55f2598c7
|
|
7
|
+
data.tar.gz: 5702dd3b52bda8e361d0ff2ef4ecac9835865b6572030c0f56fba735b9b4c7e84b9098fe576d2614ed45c25fe2020f8c8b9762adf8f1e74e4ef653e191a70168
|
data/README.md
CHANGED
|
@@ -127,7 +127,7 @@ No RED licence or event-ingestion fee, and no plan limits — your database is t
|
|
|
127
127
|
- **Host-app safety** — nothing in the capture path raises into your app; every subscriber and callback is rescue-wrapped, `Thread.current` is cleaned up in `ensure`, and the original exception is always re-raised. Variables, health and breadcrumbs are opt-in and off by default; storm protection is on by default and fails open.
|
|
128
128
|
- **Performance** — the storm-protection hot path is a digest plus an atomic increment with no I/O; the figures quoted below are a maintainer's single-machine measurements and no benchmark script ships with the gem yet.
|
|
129
129
|
- **Security** — HTTP Basic Auth or your own `authenticate_with` lambda (Devise, Warden, session); your Rails `filter_parameters` are applied to params, variables and breadcrumbs; prompts are never recorded by LLM observability. Vulnerability reports: [SECURITY.md](SECURITY.md).
|
|
130
|
-
- **Compatibility** — Rails 7.0–8.1, Ruby 3.2–4.0, PostgreSQL, MySQL/Trilogy or SQLite; `turbo-rails` plus ActionCable are needed for live updates (no polling fallback); the gem's own CSS/JS is inline but Bootstrap JS, Chart.js, highlight.js and Google Fonts load from CDNs, so it is not air-gap clean.
|
|
130
|
+
- **Compatibility** — Rails 7.0–8.1 (on Rails 7.0.0 to 7.0.8.7, unhandled request errors are not recorded; Rails 7.0.10 fixes it), Ruby 3.2–4.0, PostgreSQL, MySQL/Trilogy or SQLite; `turbo-rails` plus ActionCable are needed for live updates (no polling fallback); the gem's own CSS/JS is inline but Bootstrap JS, Chart.js, highlight.js and Google Fonts load from CDNs, so it is not air-gap clean.
|
|
131
131
|
|
|
132
132
|
---
|
|
133
133
|
|
|
@@ -632,6 +632,7 @@ gem 'rails_error_dashboard'
|
|
|
632
632
|
|
|
633
633
|
RED requires Rails 7.0 or newer, Ruby 3.2 or newer, `pagy ~> 43` and `groupdate ~> 6`. An app that pins an older Pagy or groupdate must upgrade it first, or `bundle install` fails.
|
|
634
634
|
|
|
635
|
+
- **Rails 7.0.0 to 7.0.8.7**: unhandled exceptions from web requests are not recorded, because these versions render the error page without reporting the exception. Upgrade to Rails 7.0.10 or later, which reports them; until then RED logs a warning at boot. See [Troubleshooting](docs/TROUBLESHOOTING.md#request-errors-not-recorded-on-rails-70).
|
|
635
636
|
- **Rails before 8.1.4 or 7.2.4** (every 8.0, 7.1 and 7.0 release): also add `gem "json", "< 3"`. json 3 breaks those Rails versions, and the dashboard returns 500. See [the json pin](docs/UPGRADING.md#rails-before-814-or-724-pin-json-below-3).
|
|
636
637
|
- **MySQL**: load the time-zone tables (`mysql_tzinfo_to_sql /usr/share/zoneinfo | mysql -u root mysql`), or the charts fail.
|
|
637
638
|
|
|
@@ -109,7 +109,7 @@
|
|
|
109
109
|
<td><%= release[:error_types] %></td>
|
|
110
110
|
<td>
|
|
111
111
|
<% release[:platforms].each do |platform| %>
|
|
112
|
-
<span class="badge bg-secondary
|
|
112
|
+
<span class="badge bg-secondary me-1"><%= platform %></span>
|
|
113
113
|
<% end %>
|
|
114
114
|
</td>
|
|
115
115
|
<td>
|
|
@@ -326,7 +326,7 @@
|
|
|
326
326
|
<div class="row">
|
|
327
327
|
<% @platform_specific_errors.each do |platform, errors| %>
|
|
328
328
|
<div class="col-md-6 mb-3">
|
|
329
|
-
<h6
|
|
329
|
+
<h6><%= platform %></h6>
|
|
330
330
|
<div class="list-group">
|
|
331
331
|
<% errors.each do |error_data| %>
|
|
332
332
|
<div class="list-group-item">
|
|
@@ -211,6 +211,10 @@
|
|
|
211
211
|
<div class="progress" style="height: 4px; margin-bottom: var(--space-3);">
|
|
212
212
|
<div class="progress-bar" style="width: <%= health[:stability_score] %>%; background: var(--status-<%= health[:health_status] == :healthy ? 'success' : health[:health_status] == :warning ? 'warning' : 'critical' %>);"></div>
|
|
213
213
|
</div>
|
|
214
|
+
<%# Scored on volume alone: nothing from the window is resolved %>
|
|
215
|
+
<% unless health[:resolution_measured] %>
|
|
216
|
+
<div style="font-size: 12px; color: var(--text-tertiary); margin-bottom: var(--space-2);"><%= red_t("red.common.health_status.nothing_resolved") %></div>
|
|
217
|
+
<% end %>
|
|
214
218
|
<% end %>
|
|
215
219
|
<div style="font-size: 12px; color: var(--text-tertiary);">
|
|
216
220
|
<%= red_t("red.errors.overview_page.platform_summary", total: health[:total_errors], critical: health[:critical_errors], unresolved: health[:unresolved_errors]) %>
|
|
@@ -38,7 +38,7 @@
|
|
|
38
38
|
<div class="col-md-6 col-lg-3 mb-3">
|
|
39
39
|
<div class="card h-100 <%= { healthy: 'border-success', warning: 'border-warning', not_rated: 'border-secondary' }.fetch(health[:health_status], 'border-danger') %>">
|
|
40
40
|
<div class="card-body">
|
|
41
|
-
<h5 class="card-title
|
|
41
|
+
<h5 class="card-title">
|
|
42
42
|
<%= platform || red_t("red.common.unknown") %>
|
|
43
43
|
<% if health[:health_status] == :healthy %>
|
|
44
44
|
<span class="badge bg-success float-end"><%= red_t("red.analytics.platform_comparison.health_card.healthy") %></span>
|
|
@@ -64,6 +64,10 @@
|
|
|
64
64
|
style="width: <%= health[:stability_score] %>%">
|
|
65
65
|
</div>
|
|
66
66
|
</div>
|
|
67
|
+
<%# Scored on volume alone: nothing from the window is resolved %>
|
|
68
|
+
<% unless health[:resolution_measured] %>
|
|
69
|
+
<small class="text-muted d-block mt-1"><%= red_t("red.common.health_status.nothing_resolved") %></small>
|
|
70
|
+
<% end %>
|
|
67
71
|
</div>
|
|
68
72
|
<% end %>
|
|
69
73
|
|
|
@@ -139,7 +143,7 @@
|
|
|
139
143
|
<div class="card-body">
|
|
140
144
|
<% @severity_distribution.each do |platform, severities| %>
|
|
141
145
|
<div class="mb-3">
|
|
142
|
-
<h6
|
|
146
|
+
<h6><%= platform || red_t("red.common.unknown") %></h6>
|
|
143
147
|
<% total = severities.values.sum %>
|
|
144
148
|
<% if total > 0 %>
|
|
145
149
|
<div class="progress" style="height: 25px;">
|
|
@@ -239,7 +243,7 @@
|
|
|
239
243
|
</td>
|
|
240
244
|
<td>
|
|
241
245
|
<% error[:platforms].each do |platform| %>
|
|
242
|
-
<span class="badge bg-secondary
|
|
246
|
+
<span class="badge bg-secondary me-1"><%= platform %></span>
|
|
243
247
|
<% end %>
|
|
244
248
|
</td>
|
|
245
249
|
<td>
|
|
@@ -318,7 +322,7 @@
|
|
|
318
322
|
new Chart(errorRateCtx, {
|
|
319
323
|
type: 'bar',
|
|
320
324
|
data: {
|
|
321
|
-
labels: <%= js_safe_json(@error_rate_by_platform.keys.map
|
|
325
|
+
labels: <%= js_safe_json(@error_rate_by_platform.keys.map(&:to_s)) %>,
|
|
322
326
|
datasets: [{
|
|
323
327
|
label: '<%= red_js_t("red.ui_js.charts.series_total_errors") %>',
|
|
324
328
|
data: <%= js_safe_json(@error_rate_by_platform.values) %>,
|
|
@@ -345,7 +349,7 @@
|
|
|
345
349
|
if (dailyTrendCtx) {
|
|
346
350
|
const datasets = <%= js_safe_json(@daily_trends.map { |platform, data|
|
|
347
351
|
{
|
|
348
|
-
label: platform.to_s
|
|
352
|
+
label: platform.to_s,
|
|
349
353
|
data: data.values,
|
|
350
354
|
platform: platform.to_s.downcase,
|
|
351
355
|
tension: 0.4
|
|
@@ -382,7 +386,7 @@
|
|
|
382
386
|
// Resolution Time Chart
|
|
383
387
|
const resolutionTimeCtx = document.getElementById('resolutionTimeChart');
|
|
384
388
|
if (resolutionTimeCtx) {
|
|
385
|
-
const platforms = <%= js_safe_json(@resolution_times.keys.map
|
|
389
|
+
const platforms = <%= js_safe_json(@resolution_times.keys.map(&:to_s)) %>;
|
|
386
390
|
const times = <%= js_safe_json(@resolution_times.values.map { |v| v || 0 }) %>;
|
|
387
391
|
|
|
388
392
|
new Chart(resolutionTimeCtx, {
|
data/config/locales/de.yml
CHANGED
|
@@ -38,6 +38,7 @@ de:
|
|
|
38
38
|
critical: "\U0001F534 Kritisch"
|
|
39
39
|
not_rated: "Nicht bewertet"
|
|
40
40
|
not_rated_hint: "Eine Bewertung vergleicht Plattformen und braucht daher Fehler auf mindestens zwei."
|
|
41
|
+
nothing_resolved: "Noch keine Fehler aus diesem Zeitraum behoben"
|
|
41
42
|
device_type:
|
|
42
43
|
mobile: Mobil
|
|
43
44
|
tablet: Tablet
|
|
@@ -349,7 +350,7 @@ de:
|
|
|
349
350
|
types:
|
|
350
351
|
business_hours:
|
|
351
352
|
label: Muster der Geschäftszeiten
|
|
352
|
-
description: Fehler häufen sich während der Geschäftszeiten (9–17
|
|
353
|
+
description: Fehler häufen sich während der Geschäftszeiten (9:00–17:59),
|
|
353
354
|
was auf einen Zusammenhang mit der Nutzeraktivität hindeutet
|
|
354
355
|
night:
|
|
355
356
|
label: Nachtmuster
|
data/config/locales/en.yml
CHANGED
|
@@ -84,6 +84,7 @@ en:
|
|
|
84
84
|
critical: "🔴 Critical"
|
|
85
85
|
not_rated: "Not rated"
|
|
86
86
|
not_rated_hint: "A rating compares platforms, so it needs errors on at least two."
|
|
87
|
+
nothing_resolved: "No errors from this period resolved yet"
|
|
87
88
|
|
|
88
89
|
# Device classes reported by the user-agent parser. Browser and OS names
|
|
89
90
|
# (Chrome, Safari, Windows, iOS) are brands and stay as written; these
|
|
@@ -520,7 +521,7 @@ en:
|
|
|
520
521
|
types:
|
|
521
522
|
business_hours:
|
|
522
523
|
label: "Business Hours Pattern"
|
|
523
|
-
description: "Errors peak during business hours (
|
|
524
|
+
description: "Errors peak during business hours (9:00–17:59), suggesting user activity correlation"
|
|
524
525
|
night:
|
|
525
526
|
label: "Night Pattern"
|
|
526
527
|
description: "Errors peak during night hours (midnight-6am), possibly from background jobs or automated tasks"
|
data/config/locales/es.yml
CHANGED
|
@@ -38,6 +38,7 @@ es:
|
|
|
38
38
|
critical: "\U0001F534 Crítico"
|
|
39
39
|
not_rated: "Sin calificar"
|
|
40
40
|
not_rated_hint: "La calificación compara plataformas, así que necesita errores en al menos dos."
|
|
41
|
+
nothing_resolved: "Aún no se ha resuelto ningún error de este período"
|
|
41
42
|
device_type:
|
|
42
43
|
mobile: Móvil
|
|
43
44
|
tablet: Tableta
|
|
@@ -363,7 +364,7 @@ es:
|
|
|
363
364
|
types:
|
|
364
365
|
business_hours:
|
|
365
366
|
label: Patrón de horario laboral
|
|
366
|
-
description: Los errores se concentran en el horario laboral (9:00
|
|
367
|
+
description: Los errores se concentran en el horario laboral (9:00–17:59),
|
|
367
368
|
lo que sugiere relación con la actividad de los usuarios
|
|
368
369
|
night:
|
|
369
370
|
label: Patrón nocturno
|
data/config/locales/fr.yml
CHANGED
|
@@ -38,6 +38,7 @@ fr:
|
|
|
38
38
|
critical: "\U0001F534 Critique"
|
|
39
39
|
not_rated: "Non évalué"
|
|
40
40
|
not_rated_hint: "L'évaluation compare les plateformes : il faut des erreurs sur au moins deux."
|
|
41
|
+
nothing_resolved: "Aucune erreur de cette période n'est encore résolue"
|
|
41
42
|
device_type:
|
|
42
43
|
mobile: Mobile
|
|
43
44
|
tablet: Tablette
|
|
@@ -364,7 +365,7 @@ fr:
|
|
|
364
365
|
types:
|
|
365
366
|
business_hours:
|
|
366
367
|
label: Motif des heures ouvrées
|
|
367
|
-
description: Les erreurs culminent pendant les heures ouvrées (
|
|
368
|
+
description: Les erreurs culminent pendant les heures ouvrées (9:00–17:59),
|
|
368
369
|
ce qui suggère un lien avec l'activité des utilisateurs
|
|
369
370
|
night:
|
|
370
371
|
label: Motif nocturne
|
data/config/locales/it.yml
CHANGED
|
@@ -38,6 +38,7 @@ it:
|
|
|
38
38
|
critical: "\U0001F534 Critico"
|
|
39
39
|
not_rated: "Non valutato"
|
|
40
40
|
not_rated_hint: "La valutazione confronta le piattaforme, quindi servono errori su almeno due."
|
|
41
|
+
nothing_resolved: "Nessun errore di questo periodo è stato ancora risolto"
|
|
41
42
|
device_type:
|
|
42
43
|
mobile: Mobile
|
|
43
44
|
tablet: Tablet
|
|
@@ -358,7 +359,7 @@ it:
|
|
|
358
359
|
types:
|
|
359
360
|
business_hours:
|
|
360
361
|
label: Schema da orario d'ufficio
|
|
361
|
-
description: Il picco di errori cade nell'orario d'ufficio (9–17), il
|
|
362
|
+
description: Il picco di errori cade nell'orario d'ufficio (9:00–17:59), il
|
|
362
363
|
che suggerisce una correlazione con l'attività degli utenti
|
|
363
364
|
night:
|
|
364
365
|
label: Schema notturno
|
data/config/locales/ja.yml
CHANGED
|
@@ -38,6 +38,7 @@ ja:
|
|
|
38
38
|
critical: "\U0001F534 重大"
|
|
39
39
|
not_rated: "評価なし"
|
|
40
40
|
not_rated_hint: "評価はプラットフォーム同士の比較なので、2つ以上のプラットフォームのエラーが必要です。"
|
|
41
|
+
nothing_resolved: "この期間のエラーはまだ1件も解決されていません"
|
|
41
42
|
device_type:
|
|
42
43
|
mobile: モバイル
|
|
43
44
|
tablet: タブレット
|
|
@@ -325,7 +326,7 @@ ja:
|
|
|
325
326
|
types:
|
|
326
327
|
business_hours:
|
|
327
328
|
label: 業務時間帯パターン
|
|
328
|
-
description: エラーは業務時間帯(9
|
|
329
|
+
description: エラーは業務時間帯(9:00–17:59)に集中しており、ユーザーの利用状況との関連が考えられます
|
|
329
330
|
night:
|
|
330
331
|
label: 夜間パターン
|
|
331
332
|
description: エラーは夜間(0時〜6時)に集中しており、バックグラウンドジョブや自動処理が原因の可能性があります
|
data/config/locales/pl.yml
CHANGED
|
@@ -38,6 +38,7 @@ pl:
|
|
|
38
38
|
critical: "\U0001F534 Krytyczny"
|
|
39
39
|
not_rated: "Bez oceny"
|
|
40
40
|
not_rated_hint: "Ocena porównuje platformy, więc potrzebne są błędy na co najmniej dwóch."
|
|
41
|
+
nothing_resolved: "Żaden błąd z tego okresu nie został jeszcze rozwiązany"
|
|
41
42
|
device_type:
|
|
42
43
|
mobile: Mobile
|
|
43
44
|
tablet: Tablet
|
|
@@ -366,7 +367,7 @@ pl:
|
|
|
366
367
|
types:
|
|
367
368
|
business_hours:
|
|
368
369
|
label: Wzorzec godzin pracy
|
|
369
|
-
description: Szczyt błędów przypada na godziny pracy (9:00–17:
|
|
370
|
+
description: Szczyt błędów przypada na godziny pracy (9:00–17:59), co
|
|
370
371
|
sugeruje związek z aktywnością użytkowników
|
|
371
372
|
night:
|
|
372
373
|
label: Wzorzec nocny
|
data/config/locales/pt-BR.yml
CHANGED
|
@@ -38,6 +38,7 @@ pt-BR:
|
|
|
38
38
|
critical: "\U0001F534 Crítico"
|
|
39
39
|
not_rated: "Sem avaliação"
|
|
40
40
|
not_rated_hint: "A avaliação compara plataformas, então precisa de erros em pelo menos duas."
|
|
41
|
+
nothing_resolved: "Nenhum erro deste período foi resolvido ainda"
|
|
41
42
|
device_type:
|
|
42
43
|
mobile: Celular
|
|
43
44
|
tablet: Tablet
|
|
@@ -363,7 +364,7 @@ pt-BR:
|
|
|
363
364
|
types:
|
|
364
365
|
business_hours:
|
|
365
366
|
label: Padrão de horário comercial
|
|
366
|
-
description: Os erros se concentram no horário comercial (
|
|
367
|
+
description: Os erros se concentram no horário comercial (9:00–17:59), o que
|
|
367
368
|
sugere relação com a atividade dos usuários
|
|
368
369
|
night:
|
|
369
370
|
label: Padrão noturno
|
data/config/locales/ru.yml
CHANGED
|
@@ -38,6 +38,7 @@ ru:
|
|
|
38
38
|
critical: "\U0001F534 Критично"
|
|
39
39
|
not_rated: "Без оценки"
|
|
40
40
|
not_rated_hint: "Оценка сравнивает платформы, поэтому нужны ошибки как минимум на двух."
|
|
41
|
+
nothing_resolved: "Ни одна ошибка за этот период ещё не решена"
|
|
41
42
|
device_type:
|
|
42
43
|
mobile: Мобильное
|
|
43
44
|
tablet: Планшет
|
|
@@ -368,7 +369,7 @@ ru:
|
|
|
368
369
|
types:
|
|
369
370
|
business_hours:
|
|
370
371
|
label: Рабочие часы
|
|
371
|
-
description: Пик ошибок приходится на рабочие часы (9:00–17:
|
|
372
|
+
description: Пик ошибок приходится на рабочие часы (9:00–17:59), что указывает
|
|
372
373
|
на связь с активностью пользователей
|
|
373
374
|
night:
|
|
374
375
|
label: Ночная закономерность
|
data/config/locales/uk.yml
CHANGED
|
@@ -38,6 +38,7 @@ uk:
|
|
|
38
38
|
critical: "\U0001F534 Критичний"
|
|
39
39
|
not_rated: "Без оцінки"
|
|
40
40
|
not_rated_hint: "Оцінка порівнює платформи, тому потрібні помилки щонайменше на двох."
|
|
41
|
+
nothing_resolved: "Жодну помилку за цей період ще не вирішено"
|
|
41
42
|
device_type:
|
|
42
43
|
mobile: Mobile
|
|
43
44
|
tablet: Tablet
|
|
@@ -366,7 +367,7 @@ uk:
|
|
|
366
367
|
types:
|
|
367
368
|
business_hours:
|
|
368
369
|
label: Закономірність робочих годин
|
|
369
|
-
description: Пік помилок припадає на робочі години (9:00–17:
|
|
370
|
+
description: Пік помилок припадає на робочі години (9:00–17:59), що вказує
|
|
370
371
|
на звʼязок з активністю користувачів
|
|
371
372
|
night:
|
|
372
373
|
label: Нічна закономірність
|
data/config/locales/zh-CN.yml
CHANGED
|
@@ -38,6 +38,7 @@ zh-CN:
|
|
|
38
38
|
critical: "\U0001F534 严重"
|
|
39
39
|
not_rated: "未评级"
|
|
40
40
|
not_rated_hint: "评级是在平台之间比较的,因此至少需要两个平台上的错误。"
|
|
41
|
+
nothing_resolved: "此期间的错误均尚未解决"
|
|
41
42
|
device_type:
|
|
42
43
|
mobile: Mobile
|
|
43
44
|
tablet: Tablet
|
|
@@ -323,7 +324,7 @@ zh-CN:
|
|
|
323
324
|
types:
|
|
324
325
|
business_hours:
|
|
325
326
|
label: 工作时段规律
|
|
326
|
-
description: 错误高峰出现在工作时段(9:00–17:
|
|
327
|
+
description: 错误高峰出现在工作时段(9:00–17:59),说明与用户活动相关
|
|
327
328
|
night:
|
|
328
329
|
label: 夜间规律
|
|
329
330
|
description: 错误高峰出现在夜间(0:00–6:00),可能来自后台任务或定时作业
|
|
@@ -735,6 +735,13 @@ module RailsErrorDashboard
|
|
|
735
735
|
"Feature has been auto-disabled. Upgrade Ruby to use this feature."
|
|
736
736
|
@detect_swallowed_exceptions = false
|
|
737
737
|
end
|
|
738
|
+
|
|
739
|
+
# Rails 7.0.0-7.0.8.7 render request exceptions without reporting them, so
|
|
740
|
+
# RED never sees them. Rails 7.0.10 backported 7.1's reporting.
|
|
741
|
+
if defined?(ActionPack) && ActionPack.gem_version < Gem::Version.new("7.0.10")
|
|
742
|
+
warnings << "Rails #{ActionPack.gem_version} does not report the request exceptions it renders as error pages, " \
|
|
743
|
+
"so unhandled request errors are not recorded. Upgrading to Rails 7.0.10 or later fixes this."
|
|
744
|
+
end
|
|
738
745
|
# Validate sub-settings only if feature is still active after version check
|
|
739
746
|
if detect_swallowed_exceptions
|
|
740
747
|
if swallowed_exception_max_cache_size && swallowed_exception_max_cache_size < 1
|
|
@@ -65,6 +65,13 @@ module RailsErrorDashboard
|
|
|
65
65
|
@volume ||= Queries::EventVolume.new(base_scope, @start_date)
|
|
66
66
|
end
|
|
67
67
|
|
|
68
|
+
# Events per platform for the platforms with errors in the window, the
|
|
69
|
+
# only ones scored or given a health card. Errors with no platform value
|
|
70
|
+
# belong to none.
|
|
71
|
+
def active_error_rates
|
|
72
|
+
@active_error_rates ||= error_rate_by_platform.except(nil)
|
|
73
|
+
end
|
|
74
|
+
|
|
68
75
|
# platform => { error_type => events in the window }.
|
|
69
76
|
#
|
|
70
77
|
# Severity, critical counts and cross-platform totals all fold from this
|
|
@@ -158,32 +165,50 @@ module RailsErrorDashboard
|
|
|
158
165
|
# Higher score = more stable (fewer errors, faster resolution)
|
|
159
166
|
# @return [Hash] Platform => stability score
|
|
160
167
|
def platform_stability_scores
|
|
161
|
-
platforms
|
|
162
|
-
|
|
168
|
+
# Only platforms with errors in the window are scored. Every platform
|
|
169
|
+
# ever seen used to be, and one with none in the window scored 100.
|
|
170
|
+
error_rates = active_error_rates
|
|
163
171
|
# A score compares platforms. With fewer than two that have errors in
|
|
164
172
|
# the window there is nothing to compare against, so none is rated (a
|
|
165
|
-
# lone platform used to come out Critical every time).
|
|
166
|
-
# platforms with errors in the window: the list above is every
|
|
167
|
-
# platform ever seen.
|
|
173
|
+
# lone platform used to come out Critical every time).
|
|
168
174
|
return {} if error_rates.size < 2
|
|
169
175
|
resolution_times = resolution_time_by_platform
|
|
170
176
|
|
|
171
177
|
total_errors = error_rates.values.sum
|
|
172
|
-
|
|
178
|
+
even_share = 1.0 / error_rates.size
|
|
179
|
+
fastest_resolution = resolution_times.values_at(*error_rates.keys).compact.min
|
|
180
|
+
|
|
181
|
+
error_rates.each_with_object({}) do |(platform, error_count), result|
|
|
182
|
+
avg_resolution = resolution_times[platform]
|
|
183
|
+
|
|
184
|
+
# This platform's share of all errors against an even split: full
|
|
185
|
+
# credit at or below it, falling linearly to 0 when one platform has
|
|
186
|
+
# every error. Against the raw share instead, no evenly split app
|
|
187
|
+
# could be Healthy. The even-split test is done in integers so an
|
|
188
|
+
# exact split is never lost to rounding.
|
|
189
|
+
error_score = if error_count * error_rates.size <= total_errors
|
|
190
|
+
1.0
|
|
191
|
+
else
|
|
192
|
+
1.0 - (((error_count.to_f / total_errors) - even_share) / (1.0 - even_share))
|
|
193
|
+
end
|
|
173
194
|
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
#
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
195
|
+
# The fastest platform's average resolution time over this one's,
|
|
196
|
+
# each floored at one hour: the fastest and any as fast get full
|
|
197
|
+
# credit, one twice as slow gets half. Against the slowest instead,
|
|
198
|
+
# the slowest always scored 0 here. The floor keeps an average of 0.0
|
|
199
|
+
# (resolved at once) from leaving every other platform with none.
|
|
200
|
+
result[platform] = if avg_resolution
|
|
201
|
+
resolution_score = [ fastest_resolution, 1.0 ].max / [ avg_resolution, 1.0 ].max
|
|
202
|
+
|
|
203
|
+
# Weight: 70% error count, 30% resolution time
|
|
204
|
+
# Convert to 0-100 scale
|
|
205
|
+
((error_score * 0.7 + resolution_score * 0.3) * 100).round(1)
|
|
206
|
+
else
|
|
207
|
+
# Nothing resolved in the window: no resolution time to compare, so
|
|
208
|
+
# the score is the volume credit alone, on the same scale. It used
|
|
209
|
+
# to get the full resolution credit. The cards say which it is.
|
|
210
|
+
(error_score * 100).round(1)
|
|
211
|
+
end
|
|
187
212
|
end
|
|
188
213
|
end
|
|
189
214
|
|
|
@@ -227,12 +252,13 @@ module RailsErrorDashboard
|
|
|
227
252
|
# Get platform health summary
|
|
228
253
|
# @return [Hash] Platform => health metrics
|
|
229
254
|
def platform_health_summary
|
|
230
|
-
error_rates =
|
|
255
|
+
error_rates = active_error_rates
|
|
231
256
|
stability_scores = platform_stability_scores
|
|
232
257
|
severities = severity_distribution_by_platform
|
|
233
258
|
midpoint = @start_date + (@days / 2.0).days
|
|
234
259
|
|
|
235
|
-
|
|
260
|
+
# A card for each platform with errors in the window, as the scores
|
|
261
|
+
error_rates.each_key.with_object({}) do |platform, result|
|
|
236
262
|
platform_scope = base_scope.where(platform: platform)
|
|
237
263
|
groups_in_window = platform_scope.where("occurred_at >= ?", @start_date)
|
|
238
264
|
|
|
@@ -259,6 +285,9 @@ module RailsErrorDashboard
|
|
|
259
285
|
critical_errors: critical_errors,
|
|
260
286
|
unresolved_errors: unresolved_errors,
|
|
261
287
|
resolution_rate: resolution_rate,
|
|
288
|
+
# false when nothing from the window is resolved, so the stability
|
|
289
|
+
# score is volume alone
|
|
290
|
+
resolution_measured: resolved_errors.positive?,
|
|
262
291
|
# nil and :not_rated when there are fewer than two platforms
|
|
263
292
|
stability_score: stability_scores[platform],
|
|
264
293
|
error_velocity: velocity, # Positive = increasing, negative = decreasing
|
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.16.
|
|
4
|
+
version: 0.16.1
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Anjan Jagirdar
|
|
@@ -628,7 +628,7 @@ metadata:
|
|
|
628
628
|
funding_uri: https://github.com/sponsors/AnjanJ
|
|
629
629
|
post_install_message: |
|
|
630
630
|
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
631
|
-
RED (Rails Error Dashboard) v0.16.
|
|
631
|
+
RED (Rails Error Dashboard) v0.16.1
|
|
632
632
|
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
633
633
|
|
|
634
634
|
First install:
|