rails_error_dashboard 0.9.1 → 0.11.0

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 (63) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +16 -3
  3. data/app/controllers/rails_error_dashboard/errors_controller.rb +9 -0
  4. data/app/helpers/rails_error_dashboard/i18n_helper.rb +26 -0
  5. data/app/jobs/rails_error_dashboard/rack_attack_flush_job.rb +7 -3
  6. data/app/mailers/rails_error_dashboard/error_notification_mailer.rb +8 -1
  7. data/app/models/rails_error_dashboard/error_log.rb +1 -0
  8. data/app/models/rails_error_dashboard/rack_attack_event.rb +6 -2
  9. data/app/views/layouts/rails_error_dashboard.html.erb +85 -0
  10. data/app/views/rails_error_dashboard/error_notification_mailer/error_alert.html.erb +5 -0
  11. data/app/views/rails_error_dashboard/error_notification_mailer/error_alert.text.erb +1 -0
  12. data/app/views/rails_error_dashboard/errors/_error_row.html.erb +8 -0
  13. data/app/views/rails_error_dashboard/errors/_sidebar_metadata.html.erb +9 -0
  14. data/app/views/rails_error_dashboard/errors/analytics.html.erb +58 -13
  15. data/app/views/rails_error_dashboard/errors/correlation.html.erb +4 -4
  16. data/app/views/rails_error_dashboard/errors/database_health_summary.html.erb +1 -1
  17. data/app/views/rails_error_dashboard/errors/index.html.erb +8 -1
  18. data/app/views/rails_error_dashboard/errors/overview.html.erb +2 -2
  19. data/app/views/rails_error_dashboard/errors/platform_comparison.html.erb +1 -1
  20. data/app/views/rails_error_dashboard/errors/rack_attack_summary.html.erb +36 -3
  21. data/app/views/rails_error_dashboard/errors/settings.html.erb +2 -0
  22. data/config/locales/de.yml +22 -0
  23. data/config/locales/en.yml +24 -0
  24. data/config/locales/es.yml +21 -0
  25. data/config/locales/fr.yml +22 -0
  26. data/config/locales/it.yml +30 -1
  27. data/config/locales/ja.yml +19 -0
  28. data/config/locales/pl.yml +22 -0
  29. data/config/locales/pt-BR.yml +21 -0
  30. data/config/locales/ru.yml +21 -0
  31. data/config/locales/uk.yml +21 -0
  32. data/config/locales/zh-CN.yml +17 -0
  33. data/db/migrate/20260824000001_add_user_agent_to_rack_attack_events.rb +19 -0
  34. data/db/migrate/20260826000001_add_environment_to_error_logs.rb +26 -0
  35. data/lib/generators/rails_error_dashboard/install/install_generator.rb +12 -0
  36. data/lib/generators/rails_error_dashboard/install/templates/initializer.rb +11 -0
  37. data/lib/rails_error_dashboard/commands/backfill_environments.rb +58 -0
  38. data/lib/rails_error_dashboard/commands/find_or_increment_error.rb +55 -29
  39. data/lib/rails_error_dashboard/commands/flush_rack_attack_events.rb +12 -3
  40. data/lib/rails_error_dashboard/commands/flush_storm_counts.rb +40 -9
  41. data/lib/rails_error_dashboard/commands/log_error.rb +17 -0
  42. data/lib/rails_error_dashboard/configuration.rb +52 -0
  43. data/lib/rails_error_dashboard/engine.rb +7 -0
  44. data/lib/rails_error_dashboard/queries/analytics_stats.rb +9 -0
  45. data/lib/rails_error_dashboard/queries/errors_list.rb +8 -0
  46. data/lib/rails_error_dashboard/queries/filter_options.rb +9 -0
  47. data/lib/rails_error_dashboard/queries/rack_attack_summary.rb +31 -5
  48. data/lib/rails_error_dashboard/services/ai_agent_classifier.rb +154 -0
  49. data/lib/rails_error_dashboard/services/discord_payload_builder.rb +8 -0
  50. data/lib/rails_error_dashboard/services/error_broadcaster.rb +6 -2
  51. data/lib/rails_error_dashboard/services/issue_body_formatter.rb +1 -0
  52. data/lib/rails_error_dashboard/services/markdown_error_formatter.rb +1 -0
  53. data/lib/rails_error_dashboard/services/notification_throttler.rb +23 -0
  54. data/lib/rails_error_dashboard/services/pagerduty_payload_builder.rb +1 -0
  55. data/lib/rails_error_dashboard/services/rack_attack_tracker.rb +91 -9
  56. data/lib/rails_error_dashboard/services/slack_payload_builder.rb +9 -0
  57. data/lib/rails_error_dashboard/services/storm_protection/gate.rb +2 -0
  58. data/lib/rails_error_dashboard/services/webhook_payload_builder.rb +1 -0
  59. data/lib/rails_error_dashboard/subscribers/rack_attack_subscriber.rb +40 -2
  60. data/lib/rails_error_dashboard/version.rb +1 -1
  61. data/lib/rails_error_dashboard.rb +2 -0
  62. data/lib/tasks/rails_error_dashboard_tasks.rake +6 -0
  63. metadata +6 -2
@@ -139,6 +139,7 @@ ja:
139
139
  any: 深刻度を指定しない
140
140
  all_apps: すべてのアプリ
141
141
  all_platforms: すべてのプラットフォーム
142
+ all_environments: すべての環境
142
143
  all_types: すべての種類
143
144
  all_timeframes: 全期間
144
145
  all_frequencies: すべての頻度
@@ -167,6 +168,7 @@ ja:
167
168
  search: '検索: %{value}'
168
169
  application: 'アプリ: %{value}'
169
170
  platform: 'プラットフォーム: %{value}'
171
+ environment: '環境: %{value}'
170
172
  error_type: '種類: %{value}'
171
173
  severity: '深刻度: %{value}'
172
174
  timeframe: '期間: %{value}'
@@ -182,6 +184,7 @@ ja:
182
184
  last_seen: 最終発生
183
185
  application: アプリ
184
186
  platform: プラットフォーム
187
+ environment: 環境
185
188
  select_all: すべてのエラーを選択
186
189
  batch:
187
190
  selected:
@@ -569,6 +572,7 @@ ja:
569
572
  low: 低
570
573
  platform: プラットフォーム
571
574
  view_all_platform: "%{platform}のエラーをすべて表示"
575
+ view_all_environment: "%{environment}のエラーをすべて表示"
572
576
  user: ユーザー
573
577
  view_user_errors: このユーザーのエラーをすべて表示
574
578
  user_id: 'ID: %{id}'
@@ -755,12 +759,16 @@ ja:
755
759
  unique_rules: ルール数
756
760
  total_events: 総イベント数
757
761
  unique_ips: ユニーク IP 数
762
+ ai_events: AI エージェントのリクエスト数
758
763
  all_title: ルール別レート制限イベント
759
764
  column_rule: ルール
760
765
  column_type: 種類
761
766
  column_count: 件数
762
767
  column_ips: IP 数
763
768
  column_top_path: 上位パス
769
+ column_top_agent: 主要エージェント
770
+ overflow_notice_html: トラッカーのバッファが満杯だったため、%{count} 件のイベントをルールに割り当てられませんでした。より多く記録するには
771
+ %{option} を増やしてください。
764
772
  match_type:
765
773
  blocklist: blocklist
766
774
  throttle: throttle
@@ -950,6 +958,8 @@ ja:
950
958
  max_backtrace_lines: スタックトレースの深さの上限
951
959
  sampling_rate: エラーを記録する割合
952
960
  application_name: このアプリケーションの名前 (未設定の場合は自動検出)
961
+ environment: エラーを紐付ける環境(未設定の場合は Rails.env)
962
+ notification_environments: 通知する環境を限定(未設定の場合はすべて)
953
963
  database: エラーログで使用中のデータベース
954
964
  use_separate_database: エラーログ専用の DB を使用します
955
965
  user_model: ユーザー紐づけに使うモデル名 (未設定の場合は自動検出)
@@ -1089,11 +1099,14 @@ ja:
1089
1099
  unknown_application: 不明
1090
1100
  error_alert:
1091
1101
  subject: "\U0001F6A8 [%{application}] %{error_type}: %{message}"
1102
+ subject_with_environment: "\U0001F6A8 [%{application} · %{environment}] %{error_type}:
1103
+ %{message}"
1092
1104
  heading: "\U0001F6A8 エラーアラート"
1093
1105
  labels:
1094
1106
  application: アプリケーション
1095
1107
  error_type: エラー種別
1096
1108
  platform: プラットフォーム
1109
+ environment: 環境
1097
1110
  occurred_at: 発生日時
1098
1111
  user_id: ユーザーID
1099
1112
  ip_address: IP アドレス
@@ -1156,6 +1169,7 @@ ja:
1156
1169
  application: アプリケーション
1157
1170
  error_type: エラー種別
1158
1171
  platform: プラットフォーム
1172
+ environment: 環境
1159
1173
  occurred: 発生日時
1160
1174
  message: メッセージ
1161
1175
  user: ユーザー
@@ -1459,6 +1473,10 @@ ja:
1459
1473
  platform_chart:
1460
1474
  title: プラットフォーム別エラー
1461
1475
  quick_links: 'クイックリンク:'
1476
+ environment_chart:
1477
+ title: 環境別のエラー
1478
+ quick_links: 'クイックリンク:'
1479
+ unknown: 不明
1462
1480
  type_chart:
1463
1481
  title: エラー種別 上位10件
1464
1482
  hour_chart:
@@ -1798,5 +1816,6 @@ ja:
1798
1816
  axis_count: 件数
1799
1817
  axis_number_of_errors: エラー件数
1800
1818
  axis_hours: 時間
1819
+ suffix_hours: 時間
1801
1820
  series_total_errors: 総エラー数
1802
1821
  series_hours_to_resolve: 解決までの時間
@@ -147,6 +147,7 @@ pl:
147
147
  any: Dowolna waga
148
148
  all_apps: Wszystkie aplikacje
149
149
  all_platforms: Wszystkie platformy
150
+ all_environments: Wszystkie środowiska
150
151
  all_types: Wszystkie typy
151
152
  all_timeframes: Od początku
152
153
  all_frequencies: Wszystkie częstotliwości
@@ -175,6 +176,7 @@ pl:
175
176
  search: 'Szukaj: %{value}'
176
177
  application: 'Aplikacja: %{value}'
177
178
  platform: 'Platforma: %{value}'
179
+ environment: 'Środowisko: %{value}'
178
180
  error_type: 'Typ: %{value}'
179
181
  severity: 'Waga: %{value}'
180
182
  timeframe: 'Okres: %{value}'
@@ -190,6 +192,7 @@ pl:
190
192
  last_seen: Ostatnio widziany
191
193
  application: Aplikacja
192
194
  platform: Platforma
195
+ environment: Środowisko
193
196
  select_all: Zaznacz wszystkie błędy
194
197
  batch:
195
198
  selected:
@@ -656,6 +659,7 @@ pl:
656
659
  low: NISKI
657
660
  platform: Platforma
658
661
  view_all_platform: Zobacz wszystkie błędy %{platform}
662
+ view_all_environment: Zobacz wszystkie błędy %{environment}
659
663
  user: Użytkownik
660
664
  view_user_errors: Zobacz wszystkie błędy tego użytkownika
661
665
  user_id: 'ID: %{id}'
@@ -869,12 +873,17 @@ pl:
869
873
  unique_rules: Unikalne reguły
870
874
  total_events: Łącznie zdarzeń
871
875
  unique_ips: Unikalne adresy IP
876
+ ai_events: Żądania agentów AI
872
877
  all_title: Zdarzenia limitu żądań wg reguły
873
878
  column_rule: Reguła
874
879
  column_type: Typ
875
880
  column_count: Liczba
876
881
  column_ips: Adresy IP
877
882
  column_top_path: Najczęstsza ścieżka
883
+ column_top_agent: Główny agent
884
+ overflow_notice_html: Nie udało się przypisać %{count} zdarzeń do żadnej reguły,
885
+ ponieważ bufor mechanizmu śledzenia był pełny. Zwiększ %{option}, aby rejestrować
886
+ więcej.
878
887
  match_type:
879
888
  blocklist: blocklist
880
889
  throttle: throttle
@@ -1129,6 +1138,10 @@ pl:
1129
1138
  sampling_rate: Odsetek przechwytywanych błędów
1130
1139
  application_name: Nazwa tej aplikacji (wykrywana automatycznie, jeśli nie
1131
1140
  ustawiono)
1141
+ environment: Środowisko, do którego przypisywane są błędy (Rails.env, jeśli
1142
+ nie ustawiono)
1143
+ notification_environments: Powiadamiaj tylko dla tych środowisk (wszystkie,
1144
+ jeśli nie ustawiono)
1132
1145
  database: Aktywna baza danych dla dzienników błędów
1133
1146
  use_separate_database: Używaj dedykowanej BD dla dzienników błędów
1134
1147
  user_model: Nazwa modelu powiązań z użytkownikami (wykrywana automatycznie,
@@ -1304,11 +1317,14 @@ pl:
1304
1317
  unknown_application: Nieznana
1305
1318
  error_alert:
1306
1319
  subject: "\U0001F6A8 [%{application}] %{error_type}: %{message}"
1320
+ subject_with_environment: "\U0001F6A8 [%{application} · %{environment}] %{error_type}:
1321
+ %{message}"
1307
1322
  heading: "\U0001F6A8 Alert o błędzie"
1308
1323
  labels:
1309
1324
  application: Aplikacja
1310
1325
  error_type: Typ błędu
1311
1326
  platform: Platforma
1327
+ environment: Środowisko
1312
1328
  occurred_at: Czas wystąpienia
1313
1329
  user_id: ID użytkownika
1314
1330
  ip_address: Adres IP
@@ -1380,6 +1396,7 @@ pl:
1380
1396
  application: Aplikacja
1381
1397
  error_type: Typ błędu
1382
1398
  platform: Platforma
1399
+ environment: Środowisko
1383
1400
  occurred: Wystąpił
1384
1401
  message: Komunikat
1385
1402
  user: Użytkownik
@@ -1710,6 +1727,10 @@ pl:
1710
1727
  platform_chart:
1711
1728
  title: Błędy wg platformy
1712
1729
  quick_links: 'Szybkie odnośniki:'
1730
+ environment_chart:
1731
+ title: Błędy według środowiska
1732
+ quick_links: 'Szybkie odnośniki:'
1733
+ unknown: Nieznane
1713
1734
  type_chart:
1714
1735
  title: 10 najczęstszych typów błędów
1715
1736
  hour_chart:
@@ -2104,5 +2125,6 @@ pl:
2104
2125
  axis_count: Liczba
2105
2126
  axis_number_of_errors: Liczba błędów
2106
2127
  axis_hours: Godziny
2128
+ suffix_hours: " godz."
2107
2129
  series_total_errors: Łącznie błędów
2108
2130
  series_hours_to_resolve: Godzin do rozwiązania
@@ -147,6 +147,7 @@ pt-BR:
147
147
  any: Qualquer gravidade
148
148
  all_apps: Todas as aplicações
149
149
  all_platforms: Todas as plataformas
150
+ all_environments: Todos os ambientes
150
151
  all_types: Todos os tipos
151
152
  all_timeframes: Todo o período
152
153
  all_frequencies: Todas as frequências
@@ -175,6 +176,7 @@ pt-BR:
175
176
  search: 'Busca: %{value}'
176
177
  application: 'Aplicação: %{value}'
177
178
  platform: 'Plataforma: %{value}'
179
+ environment: 'Ambiente: %{value}'
178
180
  error_type: 'Tipo: %{value}'
179
181
  severity: 'Gravidade: %{value}'
180
182
  timeframe: 'Período: %{value}'
@@ -190,6 +192,7 @@ pt-BR:
190
192
  last_seen: Última ocorrência
191
193
  application: Aplicação
192
194
  platform: Plataforma
195
+ environment: Ambiente
193
196
  select_all: Selecionar todos os erros
194
197
  batch:
195
198
  selected:
@@ -650,6 +653,7 @@ pt-BR:
650
653
  low: BAIXA
651
654
  platform: Plataforma
652
655
  view_all_platform: Ver todos os erros de %{platform}
656
+ view_all_environment: Ver todos os erros de %{environment}
653
657
  user: Usuário
654
658
  view_user_errors: Ver todos os erros deste usuário
655
659
  user_id: 'ID: %{id}'
@@ -859,12 +863,17 @@ pt-BR:
859
863
  unique_rules: Regras únicas
860
864
  total_events: Total de eventos
861
865
  unique_ips: IPs únicos
866
+ ai_events: Solicitações de agentes de IA
862
867
  all_title: Eventos de limite de taxa por regra
863
868
  column_rule: Regra
864
869
  column_type: Tipo
865
870
  column_count: Quantidade
866
871
  column_ips: IPs
867
872
  column_top_path: Caminho principal
873
+ column_top_agent: Agente principal
874
+ overflow_notice_html: Não foi possível atribuir %{count} eventos a nenhuma
875
+ regra porque o buffer do rastreador estava cheio. Aumente %{option} para
876
+ capturar mais.
868
877
  match_type:
869
878
  blocklist: blocklist
870
879
  throttle: throttle
@@ -1103,6 +1112,9 @@ pt-BR:
1103
1112
  sampling_rate: Porcentagem de erros capturados
1104
1113
  application_name: Nome desta aplicação (detectado automaticamente se não for
1105
1114
  definido)
1115
+ environment: Ambiente ao qual os erros são atribuídos (Rails.env se não definido)
1116
+ notification_environments: Notificar apenas para estes ambientes (todos se
1117
+ não definido)
1106
1118
  database: Banco de dados ativo para os logs de erros
1107
1119
  use_separate_database: Usar um banco de dados dedicado para os logs de erros
1108
1120
  user_model: Nome do modelo para as associações de usuário (detectado automaticamente
@@ -1273,11 +1285,14 @@ pt-BR:
1273
1285
  unknown_application: Desconhecida
1274
1286
  error_alert:
1275
1287
  subject: "\U0001F6A8 [%{application}] %{error_type}: %{message}"
1288
+ subject_with_environment: "\U0001F6A8 [%{application} · %{environment}] %{error_type}:
1289
+ %{message}"
1276
1290
  heading: "\U0001F6A8 Alerta de erro"
1277
1291
  labels:
1278
1292
  application: Aplicação
1279
1293
  error_type: Tipo de erro
1280
1294
  platform: Plataforma
1295
+ environment: Ambiente
1281
1296
  occurred_at: Ocorreu em
1282
1297
  user_id: ID do usuário
1283
1298
  ip_address: Endereço IP
@@ -1346,6 +1361,7 @@ pt-BR:
1346
1361
  application: Aplicação
1347
1362
  error_type: Tipo de erro
1348
1363
  platform: Plataforma
1364
+ environment: Ambiente
1349
1365
  occurred: Ocorreu
1350
1366
  message: Mensagem
1351
1367
  user: Usuário
@@ -1678,6 +1694,10 @@ pt-BR:
1678
1694
  platform_chart:
1679
1695
  title: Erros por plataforma
1680
1696
  quick_links: 'Links rápidos:'
1697
+ environment_chart:
1698
+ title: Erros por ambiente
1699
+ quick_links: 'Links rápidos:'
1700
+ unknown: Desconhecido
1681
1701
  type_chart:
1682
1702
  title: Os 10 tipos de erro mais frequentes
1683
1703
  hour_chart:
@@ -2060,5 +2080,6 @@ pt-BR:
2060
2080
  axis_count: Quantidade
2061
2081
  axis_number_of_errors: Número de erros
2062
2082
  axis_hours: Horas
2083
+ suffix_hours: " horas"
2063
2084
  series_total_errors: Total de erros
2064
2085
  series_hours_to_resolve: Horas até a resolução
@@ -147,6 +147,7 @@ ru:
147
147
  any: Любая важность
148
148
  all_apps: Все приложения
149
149
  all_platforms: Все платформы
150
+ all_environments: Все окружения
150
151
  all_types: Все типы
151
152
  all_timeframes: За всё время
152
153
  all_frequencies: Любая частота
@@ -175,6 +176,7 @@ ru:
175
176
  search: 'Поиск: %{value}'
176
177
  application: 'Приложение: %{value}'
177
178
  platform: 'Платформа: %{value}'
179
+ environment: 'Окружение: %{value}'
178
180
  error_type: 'Тип: %{value}'
179
181
  severity: 'Важность: %{value}'
180
182
  timeframe: 'Период: %{value}'
@@ -190,6 +192,7 @@ ru:
190
192
  last_seen: Последнее появление
191
193
  application: Приложение
192
194
  platform: Платформа
195
+ environment: Окружение
193
196
  select_all: Выбрать все ошибки
194
197
  batch:
195
198
  selected:
@@ -659,6 +662,7 @@ ru:
659
662
  low: НИЗКАЯ
660
663
  platform: Платформа
661
664
  view_all_platform: 'Все ошибки: %{platform}'
665
+ view_all_environment: 'Все ошибки: %{environment}'
662
666
  user: Пользователь
663
667
  view_user_errors: Все ошибки этого пользователя
664
668
  user_id: 'ID: %{id}'
@@ -871,12 +875,17 @@ ru:
871
875
  unique_rules: Уникальные правила
872
876
  total_events: Всего событий
873
877
  unique_ips: Уникальные IP
878
+ ai_events: Запросы ИИ-агентов
874
879
  all_title: События ограничения частоты по правилам
875
880
  column_rule: Правило
876
881
  column_type: Тип
877
882
  column_count: Количество
878
883
  column_ips: IP-адреса
879
884
  column_top_path: Частый путь
885
+ column_top_agent: Основной агент
886
+ overflow_notice_html: Не удалось отнести %{count} событий ни к одному правилу,
887
+ так как буфер трекера был заполнен. Увеличьте %{option}, чтобы записывать
888
+ больше.
880
889
  match_type:
881
890
  blocklist: blocklist
882
891
  throttle: throttle
@@ -1132,6 +1141,9 @@ ru:
1132
1141
  sampling_rate: Доля захватываемых ошибок
1133
1142
  application_name: Имя этого приложения (определяется автоматически, если не
1134
1143
  задано)
1144
+ environment: Окружение, к которому относятся ошибки (Rails.env, если не задано)
1145
+ notification_environments: Уведомлять только для этих окружений (все, если
1146
+ не задано)
1135
1147
  database: Активная база данных для журнала ошибок
1136
1148
  use_separate_database: Использовать отдельную БД для журнала ошибок
1137
1149
  user_model: Имя модели для связи с пользователями (определяется автоматически,
@@ -1305,11 +1317,14 @@ ru:
1305
1317
  unknown_application: Неизвестно
1306
1318
  error_alert:
1307
1319
  subject: "\U0001F6A8 [%{application}] %{error_type}: %{message}"
1320
+ subject_with_environment: "\U0001F6A8 [%{application} · %{environment}] %{error_type}:
1321
+ %{message}"
1308
1322
  heading: "\U0001F6A8 Оповещение об ошибке"
1309
1323
  labels:
1310
1324
  application: Приложение
1311
1325
  error_type: Тип ошибки
1312
1326
  platform: Платформа
1327
+ environment: Окружение
1313
1328
  occurred_at: Время возникновения
1314
1329
  user_id: ID пользователя
1315
1330
  ip_address: IP-адрес
@@ -1381,6 +1396,7 @@ ru:
1381
1396
  application: Приложение
1382
1397
  error_type: Тип ошибки
1383
1398
  platform: Платформа
1399
+ environment: Окружение
1384
1400
  occurred: Возникла
1385
1401
  message: Сообщение
1386
1402
  user: Пользователь
@@ -1711,6 +1727,10 @@ ru:
1711
1727
  platform_chart:
1712
1728
  title: Ошибки по платформам
1713
1729
  quick_links: 'Быстрые ссылки:'
1730
+ environment_chart:
1731
+ title: Ошибки по окружениям
1732
+ quick_links: 'Быстрые ссылки:'
1733
+ unknown: Неизвестно
1714
1734
  type_chart:
1715
1735
  title: Топ-10 типов ошибок
1716
1736
  hour_chart:
@@ -2105,5 +2125,6 @@ ru:
2105
2125
  axis_count: Количество
2106
2126
  axis_number_of_errors: Количество ошибок
2107
2127
  axis_hours: Часы
2128
+ suffix_hours: " ч"
2108
2129
  series_total_errors: Всего ошибок
2109
2130
  series_hours_to_resolve: Часов до решения
@@ -147,6 +147,7 @@ uk:
147
147
  any: Будь-яка критичність
148
148
  all_apps: Усі застосунки
149
149
  all_platforms: Усі платформи
150
+ all_environments: Усі середовища
150
151
  all_types: Усі типи
151
152
  all_timeframes: За весь час
152
153
  all_frequencies: Усі частоти
@@ -175,6 +176,7 @@ uk:
175
176
  search: 'Пошук: %{value}'
176
177
  application: 'Застосунок: %{value}'
177
178
  platform: 'Платформа: %{value}'
179
+ environment: 'Середовище: %{value}'
178
180
  error_type: 'Тип: %{value}'
179
181
  severity: 'Критичність: %{value}'
180
182
  timeframe: 'Період: %{value}'
@@ -190,6 +192,7 @@ uk:
190
192
  last_seen: Востаннє помічено
191
193
  application: Застосунок
192
194
  platform: Платформа
195
+ environment: Середовище
193
196
  select_all: Вибрати всі помилки
194
197
  batch:
195
198
  selected:
@@ -657,6 +660,7 @@ uk:
657
660
  low: НИЗЬКА
658
661
  platform: Платформа
659
662
  view_all_platform: Переглянути всі помилки %{platform}
663
+ view_all_environment: Переглянути всі помилки %{environment}
660
664
  user: Користувач
661
665
  view_user_errors: Переглянути всі помилки цього користувача
662
666
  user_id: 'ID: %{id}'
@@ -869,12 +873,17 @@ uk:
869
873
  unique_rules: Унікальні правила
870
874
  total_events: Усього подій
871
875
  unique_ips: Унікальні IP
876
+ ai_events: Запити ШІ-агентів
872
877
  all_title: Події обмеження запитів за правилами
873
878
  column_rule: Правило
874
879
  column_type: Тип
875
880
  column_count: Кількість
876
881
  column_ips: IP-адреси
877
882
  column_top_path: Найчастіший шлях
883
+ column_top_agent: Основний агент
884
+ overflow_notice_html: Не вдалося віднести %{count} подій до жодного правила,
885
+ оскільки буфер трекера був заповнений. Збільште %{option}, щоб записувати
886
+ більше.
878
887
  match_type:
879
888
  blocklist: blocklist
880
889
  throttle: throttle
@@ -1128,6 +1137,9 @@ uk:
1128
1137
  sampling_rate: Відсоток захоплених помилок
1129
1138
  application_name: Назва цього застосунку (визначається автоматично, якщо не
1130
1139
  задано)
1140
+ environment: Середовище, до якого належать помилки (Rails.env, якщо не задано)
1141
+ notification_environments: Сповіщати лише для цих середовищ (усі, якщо не
1142
+ задано)
1131
1143
  database: Активна база даних для журналів помилок
1132
1144
  use_separate_database: Використовувати окрему БД для журналів помилок
1133
1145
  user_model: Назва моделі для звʼязків із користувачами (визначається автоматично,
@@ -1303,11 +1315,14 @@ uk:
1303
1315
  unknown_application: Невідомо
1304
1316
  error_alert:
1305
1317
  subject: "\U0001F6A8 [%{application}] %{error_type}: %{message}"
1318
+ subject_with_environment: "\U0001F6A8 [%{application} · %{environment}] %{error_type}:
1319
+ %{message}"
1306
1320
  heading: "\U0001F6A8 Сповіщення про помилку"
1307
1321
  labels:
1308
1322
  application: Застосунок
1309
1323
  error_type: Тип помилки
1310
1324
  platform: Платформа
1325
+ environment: Середовище
1311
1326
  occurred_at: Час виникнення
1312
1327
  user_id: ID користувача
1313
1328
  ip_address: IP-адреса
@@ -1379,6 +1394,7 @@ uk:
1379
1394
  application: Застосунок
1380
1395
  error_type: Тип помилки
1381
1396
  platform: Платформа
1397
+ environment: Середовище
1382
1398
  occurred: Сталася
1383
1399
  message: Повідомлення
1384
1400
  user: Користувач
@@ -1710,6 +1726,10 @@ uk:
1710
1726
  platform_chart:
1711
1727
  title: Помилки за платформами
1712
1728
  quick_links: 'Швидкі посилання:'
1729
+ environment_chart:
1730
+ title: Помилки за середовищами
1731
+ quick_links: 'Швидкі посилання:'
1732
+ unknown: Невідомо
1713
1733
  type_chart:
1714
1734
  title: 10 найчастіших типів помилок
1715
1735
  hour_chart:
@@ -2102,5 +2122,6 @@ uk:
2102
2122
  axis_count: Кількість
2103
2123
  axis_number_of_errors: Кількість помилок
2104
2124
  axis_hours: Години
2125
+ suffix_hours: " год"
2105
2126
  series_total_errors: Усього помилок
2106
2127
  series_hours_to_resolve: Годин до вирішення
@@ -137,6 +137,7 @@ zh-CN:
137
137
  any: 任意严重程度
138
138
  all_apps: 全部应用
139
139
  all_platforms: 全部平台
140
+ all_environments: 全部环境
140
141
  all_types: 全部类型
141
142
  all_timeframes: 全部时间
142
143
  all_frequencies: 全部频率
@@ -165,6 +166,7 @@ zh-CN:
165
166
  search: 搜索:%{value}
166
167
  application: 应用:%{value}
167
168
  platform: 平台:%{value}
169
+ environment: 环境:%{value}
168
170
  error_type: 类型:%{value}
169
171
  severity: 严重程度:%{value}
170
172
  timeframe: 时间范围:%{value}
@@ -180,6 +182,7 @@ zh-CN:
180
182
  last_seen: 最近出现
181
183
  application: 应用
182
184
  platform: 平台
185
+ environment: 环境
183
186
  select_all: 选择全部错误
184
187
  batch:
185
188
  selected:
@@ -566,6 +569,7 @@ zh-CN:
566
569
  low: 低
567
570
  platform: 平台
568
571
  view_all_platform: 查看 %{platform} 的所有错误
572
+ view_all_environment: 查看 %{environment} 的所有错误
569
573
  user: 用户
570
574
  view_user_errors: 查看该用户的所有错误
571
575
  user_id: ID:%{id}
@@ -751,12 +755,15 @@ zh-CN:
751
755
  unique_rules: 规则数
752
756
  total_events: 事件总数
753
757
  unique_ips: 独立 IP 数
758
+ ai_events: AI 代理请求数
754
759
  all_title: 按规则查看限流事件
755
760
  column_rule: 规则
756
761
  column_type: 类型
757
762
  column_count: 数量
758
763
  column_ips: IP 地址
759
764
  column_top_path: 主要路径
765
+ column_top_agent: 主要代理
766
+ overflow_notice_html: 由于跟踪器缓冲区已满,%{count} 个事件无法归属到任何规则。请调高 %{option} 以捕获更多事件。
760
767
  match_type:
761
768
  blocklist: blocklist
762
769
  throttle: throttle
@@ -946,6 +953,8 @@ zh-CN:
946
953
  max_backtrace_lines: 堆栈跟踪深度上限
947
954
  sampling_rate: 错误捕获的采样比例
948
955
  application_name: 本应用的名称(未设置时自动检测)
956
+ environment: 错误所属的环境(未设置时为 Rails.env)
957
+ notification_environments: 仅对这些环境发送通知(未设置时为全部)
949
958
  database: 错误日志使用的数据库
950
959
  use_separate_database: 为错误日志使用独立数据库
951
960
  user_model: 用户关联所用的模型名(未设置时自动检测)
@@ -1083,11 +1092,13 @@ zh-CN:
1083
1092
  unknown_application: 未知
1084
1093
  error_alert:
1085
1094
  subject: "\U0001F6A8 [%{application}] %{error_type}:%{message}"
1095
+ subject_with_environment: "\U0001F6A8 [%{application} · %{environment}] %{error_type}:%{message}"
1086
1096
  heading: "\U0001F6A8 错误告警"
1087
1097
  labels:
1088
1098
  application: 应用
1089
1099
  error_type: 错误类型
1090
1100
  platform: 平台
1101
+ environment: 环境
1091
1102
  occurred_at: 发生时间
1092
1103
  user_id: 用户 ID
1093
1104
  ip_address: IP 地址
@@ -1150,6 +1161,7 @@ zh-CN:
1150
1161
  application: 应用
1151
1162
  error_type: 错误类型
1152
1163
  platform: 平台
1164
+ environment: 环境
1153
1165
  occurred: 发生时间
1154
1166
  message: 消息
1155
1167
  user: 用户
@@ -1448,6 +1460,10 @@ zh-CN:
1448
1460
  platform_chart:
1449
1461
  title: 按平台统计错误
1450
1462
  quick_links: 快捷链接:
1463
+ environment_chart:
1464
+ title: 按环境统计的错误
1465
+ quick_links: 快捷链接:
1466
+ unknown: 未知
1451
1467
  type_chart:
1452
1468
  title: 出现最多的 10 种错误类型
1453
1469
  hour_chart:
@@ -1787,5 +1803,6 @@ zh-CN:
1787
1803
  axis_count: 数量
1788
1804
  axis_number_of_errors: 错误数量
1789
1805
  axis_hours: 小时
1806
+ suffix_hours: 小时
1790
1807
  series_total_errors: 错误总数
1791
1808
  series_hours_to_resolve: 解决耗时(小时)
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ class AddUserAgentToRackAttackEvents < ActiveRecord::Migration[7.0]
4
+ def change
5
+ # Guard against the squashed schema migration having already added this
6
+ # column — without it, every later migration is silently cancelled.
7
+ return if column_exists?(:rails_error_dashboard_rack_attack_events, :user_agent)
8
+
9
+ # Capped at 191 to match the other free-text columns on this table.
10
+ #
11
+ # Deliberately NOT added to index_rack_attack_events_upsert_key. That index
12
+ # is already budgeted at 250+50+191+191 chars = 2736 bytes against MySQL's
13
+ # 3072-byte utf8mb4 limit (see the create migration); a fourth 191-char
14
+ # column would blow it. User agents are also extremely high cardinality, so
15
+ # indexing them would fragment the hourly buckets this table exists to
16
+ # aggregate. It is stored first-write-wins per bucket, like http_method.
17
+ add_column :rails_error_dashboard_rack_attack_events, :user_agent, :string, limit: 191
18
+ end
19
+ end
@@ -0,0 +1,26 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Records which environment an error came from (production, staging, uat, ...).
4
+ #
5
+ # RED had this column in v0.1.x and dropped it in the v1.0-launch refactor. It
6
+ # returns as a nullable string: NULL means "captured before this column
7
+ # existed", which is information the dashboard uses (no badge, matched as a
8
+ # wildcard by FindOrIncrementError and adopted on the next occurrence), not a
9
+ # gap to paper over with a default. `rails_error_dashboard:backfill_environments`
10
+ # fills NULLs from environment_info.rails_env for anyone who wants history too.
11
+ class AddEnvironmentToErrorLogs < ActiveRecord::Migration[7.0]
12
+ def change
13
+ # Guard against the squashed schema migration having already added this
14
+ # column -- without it, every later migration is silently cancelled.
15
+ return if column_exists?(:rails_error_dashboard_error_logs, :environment)
16
+
17
+ # 64 chars: long enough for "preprod-eu-west-2-canary", short enough that
18
+ # the composite index below stays cheap on MySQL's utf8mb4 key limit.
19
+ add_column :rails_error_dashboard_error_logs, :environment, :string, limit: 64
20
+
21
+ # Mirrors index_error_logs_on_platform_and_occurred_at: the index filter is
22
+ # "this environment, newest first".
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
@@ -348,7 +348,19 @@ module RailsErrorDashboard
348
348
  end
349
349
  end
350
350
 
351
+ # Start after the highest timestamp already present, not at the current
352
+ # clock. The counter increments per copied file, so a re-run that happens
353
+ # within N seconds of the previous install (N = number of migrations)
354
+ # would otherwise reuse numbers the first install already consumed —
355
+ # and Rails aborts the whole `db:migrate` with "Multiple migrations have
356
+ # the version number ...", so the upgrade silently applies nothing.
351
357
  timestamp = Time.now.utc.strftime("%Y%m%d%H%M%S").to_i
358
+ highest_existing = [ "db/migrate", "db/error_dashboard_migrate" ].flat_map do |dir|
359
+ full_path = File.join(destination_root, dir)
360
+ next [] unless Dir.exist?(full_path)
361
+ Dir.glob(File.join(full_path, "*.rb")).map { |f| File.basename(f)[/^\d+/].to_i }
362
+ end.max
363
+ timestamp = highest_existing + 1 if highest_existing && highest_existing >= timestamp
352
364
 
353
365
  Dir.glob(File.join(source_dir, "*.rb")).sort.each do |source_file|
354
366
  basename = File.basename(source_file)
@@ -11,6 +11,17 @@ RailsErrorDashboard.configure do |config|
11
11
  config.dashboard_username = ENV.fetch("ERROR_DASHBOARD_USER", "gandalf")
12
12
  config.dashboard_password = ENV.fetch("ERROR_DASHBOARD_PASSWORD", "youshallnotpass")
13
13
 
14
+ # Environment awareness (v0.11.0). Every error records the environment it
15
+ # came from, the index can filter by it, and staging can be kept out of
16
+ # your pager. Defaults to Rails.env; override when a deploy runs under
17
+ # RAILS_ENV=production but is really "staging", "uat", "preprod"... names
18
+ # are free-form, never an enum.
19
+ # config.environment = ENV.fetch("ERROR_DASHBOARD_ENVIRONMENT", "staging")
20
+ #
21
+ # Only notify (Slack, email, Discord, PagerDuty, webhooks, storm and
22
+ # baseline alerts) for these environments. nil = every environment.
23
+ # config.notification_environments = %w[production]
24
+
14
25
  # === Custom Authentication (optional) ===
15
26
  # Use your app's existing auth instead of HTTP Basic Auth.
16
27
  # The lambda runs in controller context (via instance_exec), giving access to