rails_error_dashboard 0.8.4 → 0.9.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.
- checksums.yaml +4 -4
- data/README.md +35 -0
- data/app/controllers/rails_error_dashboard/application_controller.rb +107 -4
- data/app/controllers/rails_error_dashboard/errors_controller.rb +91 -73
- data/app/controllers/rails_error_dashboard/locales_controller.rb +87 -0
- data/app/helpers/rails_error_dashboard/application_helper.rb +20 -14
- data/app/helpers/rails_error_dashboard/backtrace_helper.rb +15 -6
- data/app/helpers/rails_error_dashboard/i18n_helper.rb +154 -0
- data/app/helpers/rails_error_dashboard/mailer_i18n_helper.rb +69 -0
- data/app/helpers/rails_error_dashboard/overview_helper.rb +18 -6
- data/app/helpers/rails_error_dashboard/user_agent_helper.rb +25 -11
- data/app/jobs/rails_error_dashboard/application_job.rb +5 -0
- data/app/jobs/rails_error_dashboard/baseline_alert_job.rb +18 -16
- data/app/jobs/rails_error_dashboard/concerns/localized_job.rb +83 -0
- data/app/jobs/rails_error_dashboard/discord_error_notification_job.rb +4 -2
- data/app/jobs/rails_error_dashboard/email_error_notification_job.rb +4 -2
- data/app/jobs/rails_error_dashboard/pagerduty_error_notification_job.rb +6 -2
- data/app/jobs/rails_error_dashboard/scheduled_digest_job.rb +8 -3
- data/app/jobs/rails_error_dashboard/slack_error_notification_job.rb +6 -4
- data/app/jobs/rails_error_dashboard/storm_notification_job.rb +26 -8
- data/app/jobs/rails_error_dashboard/webhook_error_notification_job.rb +4 -2
- data/app/mailers/rails_error_dashboard/application_mailer.rb +14 -0
- data/app/mailers/rails_error_dashboard/digest_mailer.rb +18 -2
- data/app/mailers/rails_error_dashboard/error_notification_mailer.rb +19 -2
- data/app/views/layouts/rails_error_dashboard.html.erb +255 -92
- data/app/views/rails_error_dashboard/digest_mailer/digest_summary.html.erb +23 -22
- data/app/views/rails_error_dashboard/digest_mailer/digest_summary.text.erb +30 -19
- data/app/views/rails_error_dashboard/error_notification_mailer/error_alert.html.erb +18 -16
- data/app/views/rails_error_dashboard/error_notification_mailer/error_alert.text.erb +21 -14
- data/app/views/rails_error_dashboard/errors/_ai_help_panel.html.erb +11 -7
- data/app/views/rails_error_dashboard/errors/_breadcrumbs_group.html.erb +45 -38
- data/app/views/rails_error_dashboard/errors/_co_occurring_errors.html.erb +17 -14
- data/app/views/rails_error_dashboard/errors/_discussion.html.erb +27 -9
- data/app/views/rails_error_dashboard/errors/_error_cascades.html.erb +25 -21
- data/app/views/rails_error_dashboard/errors/_error_info.html.erb +25 -22
- data/app/views/rails_error_dashboard/errors/_error_row.html.erb +24 -12
- data/app/views/rails_error_dashboard/errors/_instance_variables.html.erb +12 -11
- data/app/views/rails_error_dashboard/errors/_issue_section.html.erb +19 -13
- data/app/views/rails_error_dashboard/errors/_llm_summary.html.erb +14 -14
- data/app/views/rails_error_dashboard/errors/_local_variables.html.erb +8 -8
- data/app/views/rails_error_dashboard/errors/_modals.html.erb +60 -52
- data/app/views/rails_error_dashboard/errors/_pattern_insights.html.erb +59 -49
- data/app/views/rails_error_dashboard/errors/_request_context.html.erb +23 -20
- data/app/views/rails_error_dashboard/errors/_show_scripts.html.erb +14 -14
- data/app/views/rails_error_dashboard/errors/_sidebar_metadata.html.erb +118 -93
- data/app/views/rails_error_dashboard/errors/_similar_errors.html.erb +18 -12
- data/app/views/rails_error_dashboard/errors/_source_code.html.erb +20 -5
- data/app/views/rails_error_dashboard/errors/_stats.html.erb +5 -5
- data/app/views/rails_error_dashboard/errors/_timeline.html.erb +7 -7
- data/app/views/rails_error_dashboard/errors/_user_errors_table.html.erb +15 -12
- data/app/views/rails_error_dashboard/errors/actioncable_health_summary.html.erb +25 -25
- data/app/views/rails_error_dashboard/errors/activestorage_health_summary.html.erb +28 -28
- data/app/views/rails_error_dashboard/errors/analytics.html.erb +82 -82
- data/app/views/rails_error_dashboard/errors/cache_health_summary.html.erb +27 -27
- data/app/views/rails_error_dashboard/errors/correlation.html.erb +61 -57
- data/app/views/rails_error_dashboard/errors/database_health_summary.html.erb +64 -65
- data/app/views/rails_error_dashboard/errors/deprecations.html.erb +23 -23
- data/app/views/rails_error_dashboard/errors/diagnostic_dumps.html.erb +48 -36
- data/app/views/rails_error_dashboard/errors/index.html.erb +121 -70
- data/app/views/rails_error_dashboard/errors/job_health_summary.html.erb +30 -30
- data/app/views/rails_error_dashboard/errors/llm_health_summary.html.erb +38 -39
- data/app/views/rails_error_dashboard/errors/n_plus_one_summary.html.erb +28 -25
- data/app/views/rails_error_dashboard/errors/overview.html.erb +45 -39
- data/app/views/rails_error_dashboard/errors/platform_comparison.html.erb +45 -44
- data/app/views/rails_error_dashboard/errors/rack_attack_summary.html.erb +30 -29
- data/app/views/rails_error_dashboard/errors/releases.html.erb +46 -47
- data/app/views/rails_error_dashboard/errors/settings/_value_badge.html.erb +48 -44
- data/app/views/rails_error_dashboard/errors/settings.html.erb +122 -112
- data/app/views/rails_error_dashboard/errors/show.html.erb +44 -37
- data/app/views/rails_error_dashboard/errors/storms.html.erb +30 -24
- data/app/views/rails_error_dashboard/errors/swallowed_exceptions.html.erb +26 -26
- data/app/views/rails_error_dashboard/errors/user_impact.html.erb +31 -30
- data/config/locales/de.yml +2007 -0
- data/config/locales/en.yml +2719 -0
- data/config/locales/es.yml +2079 -0
- data/config/locales/fr.yml +2082 -0
- data/config/locales/it.yml +2060 -0
- data/config/locales/ja.yml +1802 -0
- data/config/locales/pl.yml +2108 -0
- data/config/locales/pt-BR.yml +2064 -0
- data/config/locales/ru.yml +2109 -0
- data/config/locales/uk.yml +2106 -0
- data/config/locales/zh-CN.yml +1791 -0
- data/config/routes.rb +5 -0
- data/db/migrate/20260325000001_fix_swallowed_exceptions_index_for_mysql.rb +9 -3
- data/lib/rails_error_dashboard/commands/batch_delete_errors.rb +3 -1
- data/lib/rails_error_dashboard/commands/batch_mute_errors.rb +4 -2
- data/lib/rails_error_dashboard/commands/batch_resolve_errors.rb +4 -2
- data/lib/rails_error_dashboard/commands/batch_unmute_errors.rb +4 -2
- data/lib/rails_error_dashboard/commands/create_issue.rb +5 -3
- data/lib/rails_error_dashboard/commands/link_existing_issue.rb +4 -2
- data/lib/rails_error_dashboard/commands/log_error.rb +1 -1
- data/lib/rails_error_dashboard/configuration.rb +10 -3
- data/lib/rails_error_dashboard/current.rb +56 -0
- data/lib/rails_error_dashboard/i18n_store.rb +293 -0
- data/lib/rails_error_dashboard/private_backend.rb +213 -0
- data/lib/rails_error_dashboard/services/baseline_alert_payload_builder.rb +89 -22
- data/lib/rails_error_dashboard/services/digest_builder.rb +21 -7
- data/lib/rails_error_dashboard/services/discord_payload_builder.rb +27 -15
- data/lib/rails_error_dashboard/services/error_notification_dispatcher.rb +10 -5
- data/lib/rails_error_dashboard/services/localized_time_formatter.rb +117 -0
- data/lib/rails_error_dashboard/services/notification_helpers.rb +87 -4
- data/lib/rails_error_dashboard/services/pagerduty_payload_builder.rb +22 -5
- data/lib/rails_error_dashboard/services/slack_payload_builder.rb +48 -28
- data/lib/rails_error_dashboard/services/storm_protection/gate.rb +2 -1
- data/lib/rails_error_dashboard/services/webhook_payload_builder.rb +15 -1
- data/lib/rails_error_dashboard/translation.rb +39 -0
- data/lib/rails_error_dashboard/version.rb +1 -1
- data/lib/rails_error_dashboard.rb +4 -0
- data/lib/tasks/error_dashboard.rake +5 -1
- metadata +24 -4
|
@@ -0,0 +1,2719 @@
|
|
|
1
|
+
# RED dashboard translations.
|
|
2
|
+
#
|
|
3
|
+
# This file is authoritative. Every other locale is a translation of it, and
|
|
4
|
+
# every key here must exist before it can be translated elsewhere. A key
|
|
5
|
+
# missing from another locale silently renders the English string — that is by
|
|
6
|
+
# design (see lib/rails_error_dashboard/i18n_store.rb).
|
|
7
|
+
#
|
|
8
|
+
# These translations are loaded into RED's OWN I18n backend, not the host
|
|
9
|
+
# app's. Adding keys here cannot collide with the host application.
|
|
10
|
+
#
|
|
11
|
+
# Conventions and the do-not-translate glossary live in
|
|
12
|
+
# docs/guides/TRANSLATIONS.md. Read it before adding a locale.
|
|
13
|
+
#
|
|
14
|
+
# Namespaces (see tasks/i18n-sprint-plan.md, P1-T2):
|
|
15
|
+
# common shared words reused across pages
|
|
16
|
+
# time date/time formats and relative-time strings
|
|
17
|
+
# nav sidebar and navbar labels
|
|
18
|
+
# errors the errors index, detail page, and partials
|
|
19
|
+
# settings the settings page
|
|
20
|
+
# analytics analytics, correlation, releases, platform comparison
|
|
21
|
+
# health the health summary pages
|
|
22
|
+
# flash controller flash and JSON messages
|
|
23
|
+
# mailers digest and alert emails
|
|
24
|
+
# notifications Slack/Discord/PagerDuty/webhook payload labels
|
|
25
|
+
# js data the browser reads at runtime from window.RED_I18N
|
|
26
|
+
# ui_js strings the server renders into inline <script> blocks
|
|
27
|
+
#
|
|
28
|
+
# Phases 2-4 fill in the rest.
|
|
29
|
+
en:
|
|
30
|
+
red:
|
|
31
|
+
common:
|
|
32
|
+
not_available: "N/A"
|
|
33
|
+
close: "Close"
|
|
34
|
+
unknown: "Unknown"
|
|
35
|
+
|
|
36
|
+
# Severity levels. The stored value is a machine string ("critical");
|
|
37
|
+
# displaying it previously meant capitalize/titleize, which is English
|
|
38
|
+
# morphology applied to an identifier. Shared across pages, so these live
|
|
39
|
+
# in common rather than under errors.
|
|
40
|
+
severity:
|
|
41
|
+
critical: "Critical"
|
|
42
|
+
high: "High"
|
|
43
|
+
medium: "Medium"
|
|
44
|
+
low: "Low"
|
|
45
|
+
|
|
46
|
+
# The day-range toggle repeated verbatim across health summary pages
|
|
47
|
+
# (P2-T5) and several analytics pages (P2-T6). One key set so the
|
|
48
|
+
# wording can't drift page to page, and so P2-T9 pages with the same
|
|
49
|
+
# toggle can reuse it rather than adding their own.
|
|
50
|
+
days_filter:
|
|
51
|
+
"7": "7 Days"
|
|
52
|
+
"14": "14 Days"
|
|
53
|
+
"30": "30 Days"
|
|
54
|
+
"90": "90 Days"
|
|
55
|
+
|
|
56
|
+
# Strings returned by the view helpers (P2-T10). They live in common
|
|
57
|
+
# because a helper has no page of its own — the same value renders on
|
|
58
|
+
# whichever page calls it.
|
|
59
|
+
|
|
60
|
+
# Backtrace frame categories. The frame's origin, not its content: the
|
|
61
|
+
# backtrace itself is diagnostic output and is never translated.
|
|
62
|
+
# "Gem", "Rails" and "Ruby" are product names inside these labels.
|
|
63
|
+
frame_category:
|
|
64
|
+
app: "Your Code"
|
|
65
|
+
gem: "Gem"
|
|
66
|
+
framework: "Rails Framework"
|
|
67
|
+
ruby_core: "Ruby Core"
|
|
68
|
+
unknown: "Unknown"
|
|
69
|
+
|
|
70
|
+
# Error-rate trend direction. The value is a machine symbol
|
|
71
|
+
# (:increasing); these are its display labels.
|
|
72
|
+
trend:
|
|
73
|
+
increasing: "Increasing"
|
|
74
|
+
decreasing: "Decreasing"
|
|
75
|
+
stable: "Stable"
|
|
76
|
+
|
|
77
|
+
# Platform health badge on the overview. The emoji is part of the English
|
|
78
|
+
# rendering and a locale may drop it. Deliberately separate from
|
|
79
|
+
# red.analytics.platform_comparison.health_card, which renders the same
|
|
80
|
+
# states without emoji on a different page.
|
|
81
|
+
health_status:
|
|
82
|
+
healthy: "✅ Healthy"
|
|
83
|
+
warning: "⚠️ Warning"
|
|
84
|
+
critical: "🔴 Critical"
|
|
85
|
+
|
|
86
|
+
# Device classes reported by the user-agent parser. Browser and OS names
|
|
87
|
+
# (Chrome, Safari, Windows, iOS) are brands and stay as written; these
|
|
88
|
+
# four are ordinary words and are translated.
|
|
89
|
+
device_type:
|
|
90
|
+
mobile: "Mobile"
|
|
91
|
+
tablet: "Tablet"
|
|
92
|
+
bot: "Bot"
|
|
93
|
+
desktop: "Desktop"
|
|
94
|
+
|
|
95
|
+
nav:
|
|
96
|
+
# Section headings in the sidebar.
|
|
97
|
+
sections:
|
|
98
|
+
core: "Core"
|
|
99
|
+
health: "Health"
|
|
100
|
+
diagnostics: "Diagnostics"
|
|
101
|
+
insights: "Insights"
|
|
102
|
+
|
|
103
|
+
# Item labels. Shared by the desktop sidebar and the mobile offcanvas,
|
|
104
|
+
# which render the same destinations — a second copy of these strings
|
|
105
|
+
# would drift the moment one is edited.
|
|
106
|
+
overview: "Overview"
|
|
107
|
+
errors: "Errors"
|
|
108
|
+
analytics: "Analytics"
|
|
109
|
+
platform: "Platform"
|
|
110
|
+
cache: "Cache"
|
|
111
|
+
jobs: "Jobs"
|
|
112
|
+
database: "Database"
|
|
113
|
+
rate_limits: "Rate Limits"
|
|
114
|
+
actioncable: "ActionCable"
|
|
115
|
+
activestorage: "ActiveStorage"
|
|
116
|
+
llm: "LLM"
|
|
117
|
+
n_plus_one: "N+1 Queries"
|
|
118
|
+
deprecations: "Deprecations"
|
|
119
|
+
swallowed: "Swallowed"
|
|
120
|
+
diagnostic_dumps: "Diagnostics"
|
|
121
|
+
storms: "Storms"
|
|
122
|
+
correlation: "Correlation"
|
|
123
|
+
releases: "Releases"
|
|
124
|
+
user_impact: "User Impact"
|
|
125
|
+
settings: "Settings"
|
|
126
|
+
|
|
127
|
+
sidebar:
|
|
128
|
+
# %{app} is the host application's module name.
|
|
129
|
+
back_to_app: "Back to %{app}"
|
|
130
|
+
back_to_app_home: "Back to app home"
|
|
131
|
+
|
|
132
|
+
navbar:
|
|
133
|
+
search_placeholder: "Search errors... /"
|
|
134
|
+
toggle_sidebar: "Toggle sidebar (S)"
|
|
135
|
+
toggle_theme: "Toggle theme"
|
|
136
|
+
keyboard_shortcuts_title: "Keyboard shortcuts (?)"
|
|
137
|
+
all_applications: "All Applications"
|
|
138
|
+
# The language picker. The languages themselves are NOT keys — a
|
|
139
|
+
# language's own name does not change with the locale you view it from.
|
|
140
|
+
# See I18nStore::ENDONYMS.
|
|
141
|
+
language: "Language"
|
|
142
|
+
choose_language: "Choose dashboard language"
|
|
143
|
+
# %{count} is the number of applications being aggregated.
|
|
144
|
+
all_apps: "All Apps (%{count})"
|
|
145
|
+
|
|
146
|
+
banners:
|
|
147
|
+
credentials:
|
|
148
|
+
# Rendered as "<strong>Security Warning:</strong> You are using…", so
|
|
149
|
+
# the label and body are separate keys rather than embedded markup.
|
|
150
|
+
label: "Security Warning:"
|
|
151
|
+
body_html: >-
|
|
152
|
+
You are using default credentials (gandalf/youshallnotpass).
|
|
153
|
+
Set <code>ERROR_DASHBOARD_USER</code> and <code>ERROR_DASHBOARD_PASSWORD</code>
|
|
154
|
+
environment variables, or configure <code>authenticate_with</code> in your
|
|
155
|
+
initializer.
|
|
156
|
+
dismiss: "Dismiss for this session"
|
|
157
|
+
|
|
158
|
+
storm:
|
|
159
|
+
# Whole sentences, not fragments. The English original assembled these
|
|
160
|
+
# from a stem plus a conditional clause, which cannot be reordered into
|
|
161
|
+
# a natural sentence in every language.
|
|
162
|
+
active_title: "Error storm in progress"
|
|
163
|
+
recent_title: "Storm protection engaged recently"
|
|
164
|
+
# %{time} is a formatted clock time.
|
|
165
|
+
active_paused: >-
|
|
166
|
+
(since %{time}) — storm protection engaged. Occurrences are being counted
|
|
167
|
+
exactly; detail capture is paused (count-only mode).
|
|
168
|
+
active_sampled: >-
|
|
169
|
+
(since %{time}) — storm protection engaged. Occurrences are being counted
|
|
170
|
+
exactly; context capture is sampled.
|
|
171
|
+
# %{count} is a delimited occurrence count.
|
|
172
|
+
recent_body: >-
|
|
173
|
+
(ended %{time}) — %{count} occurrences were recorded as exact counts with
|
|
174
|
+
sampled detail.
|
|
175
|
+
view_history: "View storm history"
|
|
176
|
+
|
|
177
|
+
footer:
|
|
178
|
+
# "RED — Rails Error Dashboard" is the product name; do not translate it.
|
|
179
|
+
built_with: "Built with"
|
|
180
|
+
# %{author} is a linked name (an <a> tag), so this key is _html.
|
|
181
|
+
# Languages differ on where the attribution goes, hence one whole string
|
|
182
|
+
# rather than "Built with ❤️ by" plus a trailing link.
|
|
183
|
+
credit_html: "Built with ❤️ by %{author}"
|
|
184
|
+
|
|
185
|
+
shortcuts:
|
|
186
|
+
title: "Keyboard Shortcuts"
|
|
187
|
+
refresh: "Refresh page"
|
|
188
|
+
focus_search: "Focus search"
|
|
189
|
+
analytics: "Analytics"
|
|
190
|
+
toggle_sidebar: "Toggle sidebar"
|
|
191
|
+
show_shortcuts: "Show shortcuts"
|
|
192
|
+
|
|
193
|
+
errors:
|
|
194
|
+
index:
|
|
195
|
+
title: "Errors"
|
|
196
|
+
# %{time} is a <span class="local-time"> element rendered by
|
|
197
|
+
# ApplicationHelper#local_time, so this key is _html and the markup
|
|
198
|
+
# must survive interpolation.
|
|
199
|
+
last_updated_html: "Last updated: %{time}"
|
|
200
|
+
live: "Live"
|
|
201
|
+
|
|
202
|
+
# The summary line above the table. The original placed a bare noun
|
|
203
|
+
# after a <strong>-wrapped number; these keys interpolate the styled
|
|
204
|
+
# number instead, so a translation can put it anywhere in the phrase.
|
|
205
|
+
#
|
|
206
|
+
# %{count} selects the plural form and is the plain number; %{value} is
|
|
207
|
+
# the same number wrapped in its <strong>, which is why these are _html.
|
|
208
|
+
# Interpolating markup as %{count} would break form selection.
|
|
209
|
+
summary:
|
|
210
|
+
errors_html:
|
|
211
|
+
one: "%{value} error"
|
|
212
|
+
other: "%{value} errors"
|
|
213
|
+
unresolved_html: "%{value} unresolved"
|
|
214
|
+
all_time: "All time"
|
|
215
|
+
|
|
216
|
+
spike:
|
|
217
|
+
critical: "Critical Error Spike Detected!"
|
|
218
|
+
high: "High Error Spike Detected"
|
|
219
|
+
elevated: "Elevated Error Activity"
|
|
220
|
+
# %{count} is today's error count, %{avg} the 7-day average and
|
|
221
|
+
# %{multiplier} the ratio between them. One sentence, not three
|
|
222
|
+
# fragments — the clause order is not universal.
|
|
223
|
+
today:
|
|
224
|
+
one: "Today: %{count} error"
|
|
225
|
+
other: "Today: %{count} errors"
|
|
226
|
+
average: "(7-day avg: %{avg})"
|
|
227
|
+
multiplier: "%{multiplier}x normal levels"
|
|
228
|
+
|
|
229
|
+
filters:
|
|
230
|
+
search_placeholder: "Search errors..."
|
|
231
|
+
more: "More filters"
|
|
232
|
+
apply: "Apply Filters"
|
|
233
|
+
clear: "Clear"
|
|
234
|
+
clear_all: "Clear all"
|
|
235
|
+
# Label preceding the active-filter chips.
|
|
236
|
+
active_label: "Filters:"
|
|
237
|
+
|
|
238
|
+
status:
|
|
239
|
+
all: "All"
|
|
240
|
+
unresolved: "Unresolved"
|
|
241
|
+
resolved: "Resolved"
|
|
242
|
+
assigned: "Assigned"
|
|
243
|
+
reopened: "Reopened"
|
|
244
|
+
|
|
245
|
+
severity:
|
|
246
|
+
any: "Any severity"
|
|
247
|
+
|
|
248
|
+
# Select-tag "all" options. Each is a whole phrase, not "All" plus a
|
|
249
|
+
# noun — languages differ on agreement between the two.
|
|
250
|
+
all_apps: "All Apps"
|
|
251
|
+
all_platforms: "All Platforms"
|
|
252
|
+
all_types: "All Types"
|
|
253
|
+
all_timeframes: "All Time"
|
|
254
|
+
all_frequencies: "All Frequencies"
|
|
255
|
+
all_priorities: "All Priorities"
|
|
256
|
+
all_assignments: "All Assignments"
|
|
257
|
+
all_assignees: "All Assignees"
|
|
258
|
+
|
|
259
|
+
unassigned: "Unassigned"
|
|
260
|
+
assigned: "Assigned"
|
|
261
|
+
|
|
262
|
+
unresolved_only: "Unresolved only"
|
|
263
|
+
hide_snoozed: "Hide snoozed"
|
|
264
|
+
hide_muted: "Hide muted"
|
|
265
|
+
|
|
266
|
+
# Timeframe and frequency option labels. These were previously
|
|
267
|
+
# produced by humanize() on the param value, which applies English
|
|
268
|
+
# morphology to a machine value and yields nonsense elsewhere. The
|
|
269
|
+
# same keys serve both the select options and the active chips, so
|
|
270
|
+
# the two can never disagree.
|
|
271
|
+
timeframes:
|
|
272
|
+
last_hour: "Last Hour"
|
|
273
|
+
today: "Today"
|
|
274
|
+
yesterday: "Yesterday"
|
|
275
|
+
last_7_days: "Last 7 Days"
|
|
276
|
+
last_30_days: "Last 30 Days"
|
|
277
|
+
last_90_days: "Last 90 Days"
|
|
278
|
+
|
|
279
|
+
frequencies:
|
|
280
|
+
once: "Once"
|
|
281
|
+
few: "2-9 Times"
|
|
282
|
+
frequent: "10-99 Times"
|
|
283
|
+
very_frequent: "100+ Times"
|
|
284
|
+
recurring: "Recurring"
|
|
285
|
+
|
|
286
|
+
# Chip labels. %{value} is the filter's display value — for search
|
|
287
|
+
# terms, application and platform names it is free-form user data and
|
|
288
|
+
# is never translated, only the label around it.
|
|
289
|
+
chips:
|
|
290
|
+
search: "Search: %{value}"
|
|
291
|
+
application: "App: %{value}"
|
|
292
|
+
platform: "Platform: %{value}"
|
|
293
|
+
error_type: "Type: %{value}"
|
|
294
|
+
severity: "Severity: %{value}"
|
|
295
|
+
timeframe: "Timeframe: %{value}"
|
|
296
|
+
frequency: "Frequency: %{value}"
|
|
297
|
+
status: "Status: %{value}"
|
|
298
|
+
priority: "Priority: %{value}"
|
|
299
|
+
remove: "Remove filter"
|
|
300
|
+
|
|
301
|
+
columns:
|
|
302
|
+
error: "Error"
|
|
303
|
+
status: "Status"
|
|
304
|
+
events: "Events"
|
|
305
|
+
users: "Users"
|
|
306
|
+
last_seen: "Last seen"
|
|
307
|
+
application: "App"
|
|
308
|
+
platform: "Platform"
|
|
309
|
+
select_all: "Select all errors"
|
|
310
|
+
|
|
311
|
+
batch:
|
|
312
|
+
# %{count} of the visible errors are selected.
|
|
313
|
+
selected:
|
|
314
|
+
one: "%{count} selected"
|
|
315
|
+
other: "%{count} selected"
|
|
316
|
+
resolve: "Resolve"
|
|
317
|
+
delete: "Delete"
|
|
318
|
+
confirm_delete: "Are you sure you want to delete the selected errors?"
|
|
319
|
+
|
|
320
|
+
# %{from}, %{to} and %{count} bound the current page.
|
|
321
|
+
pagination: "Showing %{from}–%{to} of %{count} errors"
|
|
322
|
+
|
|
323
|
+
empty:
|
|
324
|
+
filtered_title: "No errors match your filters"
|
|
325
|
+
filtered_message: "Try adjusting your search or filter criteria to find what you're looking for."
|
|
326
|
+
filtered_cta: "Clear all filters"
|
|
327
|
+
clear_title: "All clear!"
|
|
328
|
+
clear_message: >-
|
|
329
|
+
No errors have been logged yet. Your application is running smoothly.
|
|
330
|
+
Errors will appear here automatically when they occur.
|
|
331
|
+
|
|
332
|
+
show:
|
|
333
|
+
# %{id} is the error's database id.
|
|
334
|
+
page_title: "Error #%{id}"
|
|
335
|
+
breadcrumb_errors: "Errors"
|
|
336
|
+
|
|
337
|
+
hero:
|
|
338
|
+
reopened: "Reopened"
|
|
339
|
+
# %{count} drives the plural form; %{value} is the same number
|
|
340
|
+
# wrapped in its <strong>, hence _html. Interpolating markup as
|
|
341
|
+
# %{count} would break form selection.
|
|
342
|
+
occurrences_html:
|
|
343
|
+
one: "%{value} occurrence"
|
|
344
|
+
other: "%{value} occurrences"
|
|
345
|
+
# %{value} is a <strong>-wrapped user identifier.
|
|
346
|
+
user_html: "User %{value}"
|
|
347
|
+
# %{time} is a relative time ("3 hours ago"), rendered as markup.
|
|
348
|
+
first_seen_html: "First seen %{time}"
|
|
349
|
+
last_seen_html: "Last seen %{time}"
|
|
350
|
+
|
|
351
|
+
actions:
|
|
352
|
+
resolve: "Resolve"
|
|
353
|
+
assign: "Assign"
|
|
354
|
+
copy_for_llm: "Copy for LLM"
|
|
355
|
+
ai_help: "AI Help"
|
|
356
|
+
export_json: "Export JSON"
|
|
357
|
+
|
|
358
|
+
tabs:
|
|
359
|
+
details: "Details"
|
|
360
|
+
context: "Context"
|
|
361
|
+
history: "History"
|
|
362
|
+
issues: "Issues"
|
|
363
|
+
|
|
364
|
+
coverage:
|
|
365
|
+
active_label: "Coverage Active"
|
|
366
|
+
active_body: "expand source code to see executed lines"
|
|
367
|
+
inactive_label: "Code Path Coverage"
|
|
368
|
+
inactive_body: "enable to see executed lines"
|
|
369
|
+
enable: "Enable"
|
|
370
|
+
disable: "Disable"
|
|
371
|
+
|
|
372
|
+
baselines:
|
|
373
|
+
title: "Baseline Statistics"
|
|
374
|
+
# %{sigma} is a standard-deviation count, %{level} an anomaly level.
|
|
375
|
+
anomaly_label: "Anomaly:"
|
|
376
|
+
anomaly_body: "%{sigma}σ above baseline (%{level})"
|
|
377
|
+
|
|
378
|
+
# Anomaly levels from ErrorBaseline#anomaly_level. These are NOT the
|
|
379
|
+
# severity levels — :elevated has no severity counterpart — so they
|
|
380
|
+
# get their own keys rather than reusing red.common.severity.
|
|
381
|
+
#
|
|
382
|
+
# Stored already uppercased. The English original called .upcase on
|
|
383
|
+
# the value, which is a Latin-alphabet assumption and mangles scripts
|
|
384
|
+
# with no case distinction or with different casing rules.
|
|
385
|
+
levels:
|
|
386
|
+
elevated: "ELEVATED"
|
|
387
|
+
high: "HIGH"
|
|
388
|
+
critical: "CRITICAL"
|
|
389
|
+
hourly: "Hourly"
|
|
390
|
+
daily: "Daily"
|
|
391
|
+
weekly: "Weekly"
|
|
392
|
+
mean: "Mean:"
|
|
393
|
+
std_dev: "σ:"
|
|
394
|
+
percentile_95: "P95:"
|
|
395
|
+
|
|
396
|
+
quick_actions:
|
|
397
|
+
title: "Quick Actions"
|
|
398
|
+
view_similar: "View Similar Errors"
|
|
399
|
+
view_user_errors: "View User's Errors"
|
|
400
|
+
# %{platform} is a platform name (iOS, Android, Web) and is not translated.
|
|
401
|
+
view_platform_errors: "View %{platform} Errors"
|
|
402
|
+
analytics: "Analytics"
|
|
403
|
+
|
|
404
|
+
variables:
|
|
405
|
+
local_title: "Local Variables"
|
|
406
|
+
local_hint: "Variables from the stack frame where the exception was raised"
|
|
407
|
+
instance_title: "Instance Variables"
|
|
408
|
+
# The English original split this sentence around a conditional <code>
|
|
409
|
+
# element ("Instance variables from" + class-or-"the object" + "where
|
|
410
|
+
# the exception was raised"). A clause cannot be spliced into the middle
|
|
411
|
+
# of a sentence in every language, so each branch is whole.
|
|
412
|
+
# %{klass} is a pre-formatted <code> element, hence _html.
|
|
413
|
+
instance_hint_html: "Instance variables from %{klass} where the exception was raised"
|
|
414
|
+
instance_hint_generic: "Instance variables from the object where the exception was raised"
|
|
415
|
+
# %{count} variables were captured.
|
|
416
|
+
captured:
|
|
417
|
+
one: "%{count} captured"
|
|
418
|
+
other: "%{count} captured"
|
|
419
|
+
column_variable: "Variable"
|
|
420
|
+
column_type: "Type"
|
|
421
|
+
column_value: "Value"
|
|
422
|
+
# Shown in place of a value scrubbed by the parameter filter.
|
|
423
|
+
filtered: "[FILTERED]"
|
|
424
|
+
truncated: "truncated"
|
|
425
|
+
|
|
426
|
+
# Issue-tracker provider display names. Brands, so identical in every
|
|
427
|
+
# locale, but keys rather than provider.capitalize — that renders "github"
|
|
428
|
+
# as "Github", which is not how any of them write their own name.
|
|
429
|
+
deprecations:
|
|
430
|
+
title: "Deprecation Warnings"
|
|
431
|
+
hint: "Rails deprecation warnings detected during this request"
|
|
432
|
+
column_warning: "Warning"
|
|
433
|
+
column_source: "Source"
|
|
434
|
+
footer_tip: "Fix deprecations before upgrading Rails to avoid breaking changes."
|
|
435
|
+
upgrade_guide: "Rails Upgrade Guide"
|
|
436
|
+
|
|
437
|
+
n_plus_one:
|
|
438
|
+
title: "N+1 Query Detection"
|
|
439
|
+
hint: "Repeated query patterns detected in this request's SQL breadcrumbs"
|
|
440
|
+
# %{count} repeated query patterns were found.
|
|
441
|
+
patterns:
|
|
442
|
+
one: "%{count} pattern"
|
|
443
|
+
other: "%{count} patterns"
|
|
444
|
+
column_repeats: "Repeats"
|
|
445
|
+
column_query: "Query Pattern"
|
|
446
|
+
column_total_time: "Total Time"
|
|
447
|
+
# %{fingerprint} is a normalized SQL fingerprint — diagnostic, verbatim.
|
|
448
|
+
fingerprint: "Fingerprint: %{fingerprint}"
|
|
449
|
+
# Whole sentences. The English original wrapped prose around <code>
|
|
450
|
+
# elements holding method names; the names stay English, but the words
|
|
451
|
+
# around them cannot be reassembled in that order in every language.
|
|
452
|
+
# %{table}, %{includes} and %{preload} arrive as markup, hence _html.
|
|
453
|
+
tip_preload_html: "Tip: Preload %{table} with %{includes} or %{preload}"
|
|
454
|
+
tip_generic_html: "Tip: Use %{includes} or %{preload} to eager load associations"
|
|
455
|
+
eager_loading_guide: "Rails Eager Loading Guide"
|
|
456
|
+
|
|
457
|
+
cache_health:
|
|
458
|
+
title: "Cache Health"
|
|
459
|
+
# %{count} cache operations were recorded.
|
|
460
|
+
operations:
|
|
461
|
+
one: "%{count} operation"
|
|
462
|
+
other: "%{count} operations"
|
|
463
|
+
hint: "Cache activity analysis from this request's breadcrumbs"
|
|
464
|
+
reads: "Reads"
|
|
465
|
+
writes: "Writes"
|
|
466
|
+
hit_rate: "Hit Rate"
|
|
467
|
+
# %{count} cache hits and misses.
|
|
468
|
+
hits:
|
|
469
|
+
one: "%{count} hit"
|
|
470
|
+
other: "%{count} hits"
|
|
471
|
+
misses:
|
|
472
|
+
one: "%{count} miss"
|
|
473
|
+
other: "%{count} misses"
|
|
474
|
+
# %{count} reads whose hit status was not recorded.
|
|
475
|
+
unknown_status:
|
|
476
|
+
one: "%{count} read with unknown hit status (older breadcrumbs)"
|
|
477
|
+
other: "%{count} reads with unknown hit status (older breadcrumbs)"
|
|
478
|
+
# %{duration} is a formatted millisecond figure wrapped in <strong>,
|
|
479
|
+
# hence _html.
|
|
480
|
+
total_time_html: "Total cache time: %{duration}"
|
|
481
|
+
slowest_html: "Slowest: %{duration}"
|
|
482
|
+
low_hit_rate: "Low hit rate — review cache key design and TTL settings."
|
|
483
|
+
moderate_hit_rate: "Moderate hit rate — consider warming caches or adjusting expiration."
|
|
484
|
+
caching_guide: "Rails Caching Guide"
|
|
485
|
+
|
|
486
|
+
breadcrumbs:
|
|
487
|
+
title: "Breadcrumbs"
|
|
488
|
+
# %{count} breadcrumb events were recorded.
|
|
489
|
+
events:
|
|
490
|
+
one: "%{count} event"
|
|
491
|
+
other: "%{count} events"
|
|
492
|
+
hint: "Activity trail leading up to this error"
|
|
493
|
+
column_category: "Category"
|
|
494
|
+
column_message: "Message"
|
|
495
|
+
column_duration: "Duration"
|
|
496
|
+
|
|
497
|
+
patterns:
|
|
498
|
+
title: "Occurrence Patterns"
|
|
499
|
+
# %{days} is the analysis window.
|
|
500
|
+
window: "(Last %{days} days)"
|
|
501
|
+
pattern_type: "Pattern Type"
|
|
502
|
+
|
|
503
|
+
types:
|
|
504
|
+
business_hours:
|
|
505
|
+
label: "Business Hours Pattern"
|
|
506
|
+
description: "Errors peak during business hours (9am-5pm), suggesting user activity correlation"
|
|
507
|
+
night:
|
|
508
|
+
label: "Night Pattern"
|
|
509
|
+
description: "Errors peak during night hours (midnight-6am), possibly from background jobs or automated tasks"
|
|
510
|
+
weekend:
|
|
511
|
+
label: "Weekend Pattern"
|
|
512
|
+
description: "Most errors occur on weekends, suggesting weekend-specific usage patterns"
|
|
513
|
+
uniform:
|
|
514
|
+
label: "Uniform Pattern"
|
|
515
|
+
description: "Errors distributed evenly throughout the day with no clear pattern"
|
|
516
|
+
none:
|
|
517
|
+
label: "No Pattern Detected"
|
|
518
|
+
description: "Not enough data to identify a clear occurrence pattern"
|
|
519
|
+
|
|
520
|
+
strength: "Pattern Strength"
|
|
521
|
+
# Each strength is one whole sentence. The English original was a bold
|
|
522
|
+
# fragment, a dash, and a trailing clause, which cannot be reassembled
|
|
523
|
+
# in that order in every language. %{label} is the bold part.
|
|
524
|
+
strengths:
|
|
525
|
+
strong:
|
|
526
|
+
label: "Strong pattern"
|
|
527
|
+
description: "Errors highly concentrated in specific hours"
|
|
528
|
+
moderate:
|
|
529
|
+
label: "Moderate pattern"
|
|
530
|
+
description: "Some concentration in specific hours"
|
|
531
|
+
weak:
|
|
532
|
+
label: "Weak pattern"
|
|
533
|
+
description: "Errors distributed fairly evenly"
|
|
534
|
+
|
|
535
|
+
heatmap_title: "Hourly Distribution Heatmap"
|
|
536
|
+
# %{multiplier} is the peak threshold relative to the average.
|
|
537
|
+
heatmap_legend: "Darker cells = more errors. Red borders indicate peak hours (>%{multiplier}x average)."
|
|
538
|
+
# %{hour} is a formatted hour, %{count} the error count in it.
|
|
539
|
+
heatmap_cell:
|
|
540
|
+
one: "%{hour} - %{count} error"
|
|
541
|
+
other: "%{hour} - %{count} errors"
|
|
542
|
+
peak_hours: "Peak Hours:"
|
|
543
|
+
peak_hours_hint: >-
|
|
544
|
+
These hours have more than 2x the average error rate. Consider monitoring
|
|
545
|
+
deployments or load during these times.
|
|
546
|
+
|
|
547
|
+
bursts_title: "Error Bursts"
|
|
548
|
+
# %{days} is the burst analysis window.
|
|
549
|
+
bursts_window: "(Last %{days} days)"
|
|
550
|
+
bursts_hint: >-
|
|
551
|
+
Error bursts are rapid sequences where multiple errors occur within minutes.
|
|
552
|
+
This may indicate cascading failures or load spikes.
|
|
553
|
+
column_start_time: "Start Time"
|
|
554
|
+
column_duration: "Duration"
|
|
555
|
+
column_error_count: "Error Count"
|
|
556
|
+
column_intensity: "Intensity"
|
|
557
|
+
# %{minutes} and %{seconds} are the burst's duration.
|
|
558
|
+
burst_duration: "%{minutes} min"
|
|
559
|
+
burst_duration_seconds: "(%{seconds}s)"
|
|
560
|
+
# %{count} errors in the burst. %{value} is the same number wrapped in
|
|
561
|
+
# its <strong>, hence _html; interpolating markup as %{count} would
|
|
562
|
+
# break plural-form selection.
|
|
563
|
+
burst_errors_html:
|
|
564
|
+
one: "%{value} error"
|
|
565
|
+
other: "%{value} errors"
|
|
566
|
+
intensity_high: "High (20+ errors)"
|
|
567
|
+
intensity_medium: "Medium (10-19 errors)"
|
|
568
|
+
intensity_low: "Low (5-9 errors)"
|
|
569
|
+
# %{shown} of %{total} bursts are listed.
|
|
570
|
+
bursts_truncated: "Showing %{shown} of %{total} detected bursts"
|
|
571
|
+
|
|
572
|
+
recommendation_label: "Recommendation:"
|
|
573
|
+
recommendation_intro: "Multiple error bursts detected. Investigate:"
|
|
574
|
+
recommendation_deploys: "Recent deployments or configuration changes around burst times"
|
|
575
|
+
recommendation_load: "Load spikes or traffic patterns"
|
|
576
|
+
recommendation_cascades: "Cascading failures from related errors"
|
|
577
|
+
recommendation_jobs: "Background job failures or retry storms"
|
|
578
|
+
|
|
579
|
+
empty: "No occurrence patterns or bursts detected. More data may be needed for pattern analysis."
|
|
580
|
+
|
|
581
|
+
providers:
|
|
582
|
+
github: "GitHub"
|
|
583
|
+
gitlab: "GitLab"
|
|
584
|
+
bitbucket: "Bitbucket"
|
|
585
|
+
jira: "Jira"
|
|
586
|
+
linear: "Linear"
|
|
587
|
+
# Used when no provider is configured. Unlike the names above this is a
|
|
588
|
+
# common noun and IS translated.
|
|
589
|
+
generic: "Platform"
|
|
590
|
+
generic_lowercase: "the platform"
|
|
591
|
+
|
|
592
|
+
discussion:
|
|
593
|
+
title: "Discussion"
|
|
594
|
+
activity_log: "Activity Log"
|
|
595
|
+
# %{provider} is a provider display name from red.errors.providers.
|
|
596
|
+
reply_on: "Reply on %{provider}"
|
|
597
|
+
start_on: "Start discussion on %{provider}"
|
|
598
|
+
empty: "No comments yet. Be the first to discuss this error on %{provider}."
|
|
599
|
+
|
|
600
|
+
issue_section:
|
|
601
|
+
title: "Issue Tracker"
|
|
602
|
+
view_issue: "View Issue"
|
|
603
|
+
# Shown instead of a provider name when the provider is unknown.
|
|
604
|
+
linked: "Linked"
|
|
605
|
+
# %{provider} is a display name, %{number} the issue number.
|
|
606
|
+
issue_reference: "%{provider} #%{number}"
|
|
607
|
+
# Issue states are machine values from the tracker's API. capitalize
|
|
608
|
+
# applied English morphology to them.
|
|
609
|
+
states:
|
|
610
|
+
open: "Open"
|
|
611
|
+
closed: "Closed"
|
|
612
|
+
merged: "Merged"
|
|
613
|
+
assignees: "Assignees"
|
|
614
|
+
unassigned: "Unassigned"
|
|
615
|
+
labels: "Labels"
|
|
616
|
+
no_labels: "No labels"
|
|
617
|
+
create_new: "Create New Issue"
|
|
618
|
+
# %{provider} is a provider display name. One key, not "Create " plus a
|
|
619
|
+
# name plus " Issue" — the object does not follow the verb everywhere.
|
|
620
|
+
create_issue: "Create %{provider} Issue"
|
|
621
|
+
# %{token} and %{url} are pre-formatted <code> elements naming config
|
|
622
|
+
# options, hence _html. The option names themselves stay English.
|
|
623
|
+
configure_html: "Configure %{token} and %{url} in your initializer to enable issue creation."
|
|
624
|
+
link_existing: "Link Existing Issue"
|
|
625
|
+
link: "Link"
|
|
626
|
+
|
|
627
|
+
cascades:
|
|
628
|
+
title: "Error Cascades"
|
|
629
|
+
hint: "Causal relationships between errors"
|
|
630
|
+
triggered_by: "Triggered By"
|
|
631
|
+
triggered_by_hint: "(errors that cause this one)"
|
|
632
|
+
triggers: "Triggers"
|
|
633
|
+
triggers_hint: "(errors caused by this one)"
|
|
634
|
+
# One key set: the parent and child tables render the same columns.
|
|
635
|
+
column_error_type: "Error Type"
|
|
636
|
+
column_message: "Message"
|
|
637
|
+
column_probability: "Probability"
|
|
638
|
+
column_frequency: "Frequency"
|
|
639
|
+
column_avg_delay: "Avg Delay"
|
|
640
|
+
view: "View"
|
|
641
|
+
# %{probability} and %{frequency} are the thresholds the footnote cites,
|
|
642
|
+
# so the sentence and the code that sets them cannot drift apart.
|
|
643
|
+
footnote: >-
|
|
644
|
+
Cascade patterns show causal relationships. High probability (≥%{probability}%)
|
|
645
|
+
and frequency (≥%{frequency}) indicate strong cascades.
|
|
646
|
+
|
|
647
|
+
llm_summary:
|
|
648
|
+
title: "LLM Calls"
|
|
649
|
+
hint: "Aggregated from request breadcrumbs"
|
|
650
|
+
calls: "Calls"
|
|
651
|
+
tokens: "Tokens"
|
|
652
|
+
cost: "Cost"
|
|
653
|
+
input: "Input"
|
|
654
|
+
output: "Output"
|
|
655
|
+
tool_calls: "Tool calls"
|
|
656
|
+
total_time: "Total time"
|
|
657
|
+
errors: "Errors"
|
|
658
|
+
by_model: "By model"
|
|
659
|
+
# One sentence, not a count plus a pluralized noun plus a trailing
|
|
660
|
+
# clause bolted on with an em dash.
|
|
661
|
+
failed_calls:
|
|
662
|
+
one: "%{count} failed call — see breadcrumbs trail for details."
|
|
663
|
+
other: "%{count} failed calls — see breadcrumbs trail for details."
|
|
664
|
+
|
|
665
|
+
timeline:
|
|
666
|
+
title: "Timeline"
|
|
667
|
+
hint: "Recent related errors"
|
|
668
|
+
current_error: "Current Error"
|
|
669
|
+
# %{id} is a user identifier — free-form data, not translated.
|
|
670
|
+
user: "User: %{id}"
|
|
671
|
+
resolved: "Resolved"
|
|
672
|
+
notes_label: "Resolution Notes:"
|
|
673
|
+
# %{notes} is the user's own resolution comment, interpolated verbatim.
|
|
674
|
+
notes_tooltip: "Resolution Notes: %{notes}"
|
|
675
|
+
|
|
676
|
+
user_errors_table:
|
|
677
|
+
column_rank: "Rank"
|
|
678
|
+
column_user: "User"
|
|
679
|
+
column_error_type_count: "Different Error Types"
|
|
680
|
+
column_error_count: "Error Count"
|
|
681
|
+
column_percentage: "Percentage"
|
|
682
|
+
column_error_types: "Error Types"
|
|
683
|
+
column_actions: "Actions"
|
|
684
|
+
# %{count} distinct error types affected this user.
|
|
685
|
+
types:
|
|
686
|
+
one: "%{count} type"
|
|
687
|
+
other: "%{count} types"
|
|
688
|
+
# %{count} further error types beyond the ones listed.
|
|
689
|
+
more:
|
|
690
|
+
one: "+%{count} more"
|
|
691
|
+
other: "+%{count} more"
|
|
692
|
+
view_errors: "View Errors"
|
|
693
|
+
|
|
694
|
+
co_occurring:
|
|
695
|
+
title: "Co-occurring Errors"
|
|
696
|
+
badge: "Time Patterns"
|
|
697
|
+
# %{minutes} is the correlation window.
|
|
698
|
+
hint: "Errors that occur within %{minutes} minutes of this error"
|
|
699
|
+
column_error_type: "Error Type"
|
|
700
|
+
column_message: "Message"
|
|
701
|
+
column_platform: "Platform"
|
|
702
|
+
column_frequency: "Frequency"
|
|
703
|
+
column_avg_delay: "Avg Delay"
|
|
704
|
+
# %{count} co-occurrences.
|
|
705
|
+
times:
|
|
706
|
+
one: "%{count} time"
|
|
707
|
+
other: "%{count} times"
|
|
708
|
+
# %{duration} is a formatted duration. Whole phrases rather than a
|
|
709
|
+
# duration with a direction word appended — word order differs.
|
|
710
|
+
before: "%{duration} before"
|
|
711
|
+
after: "%{duration} after"
|
|
712
|
+
simultaneous: "simultaneous"
|
|
713
|
+
view: "View"
|
|
714
|
+
|
|
715
|
+
modals:
|
|
716
|
+
# The five action modals on the error detail page. "Cancel" and the
|
|
717
|
+
# close button's aria-label are shared across all of them.
|
|
718
|
+
cancel: "Cancel"
|
|
719
|
+
# The placeholder is an example name. Translators should substitute a
|
|
720
|
+
# name that reads as a placeholder in their language.
|
|
721
|
+
name_placeholder: "e.g., John Doe"
|
|
722
|
+
# Marks a required field. The asterisk is separate markup, so this is
|
|
723
|
+
# only the label text.
|
|
724
|
+
resolve:
|
|
725
|
+
title: "Mark Error as Resolved"
|
|
726
|
+
name_label: "Your Name"
|
|
727
|
+
name_hint: "Who is resolving this error?"
|
|
728
|
+
reference_label: "Reference (Optional)"
|
|
729
|
+
# JIRA, PR and GitHub are product names and stay as written.
|
|
730
|
+
reference_placeholder: "e.g., JIRA-123, PR #456, GitHub Issue #789"
|
|
731
|
+
reference_hint: "Link to ticket, PR, or issue"
|
|
732
|
+
notes_label: "Resolution Notes (Optional)"
|
|
733
|
+
notes_placeholder: "Describe what was done to fix this error..."
|
|
734
|
+
notes_hint: "What was done to resolve this error?"
|
|
735
|
+
submit: "Mark as Resolved"
|
|
736
|
+
assign:
|
|
737
|
+
title: "Assign Error"
|
|
738
|
+
label: "Assign To"
|
|
739
|
+
hint: "Who should investigate this error?"
|
|
740
|
+
submit: "Assign"
|
|
741
|
+
priority:
|
|
742
|
+
title: "Update Priority"
|
|
743
|
+
label: "Priority Level"
|
|
744
|
+
# %{value} is the current priority's label.
|
|
745
|
+
current: "Current: %{value}"
|
|
746
|
+
submit: "Update Priority"
|
|
747
|
+
snooze:
|
|
748
|
+
title: "Snooze Error"
|
|
749
|
+
label: "Snooze Duration"
|
|
750
|
+
hint: "Hide this error from active views"
|
|
751
|
+
reason_label: "Reason (Optional)"
|
|
752
|
+
reason_placeholder: "Why are you snoozing this error?"
|
|
753
|
+
reason_hint: "Reason will be added as a comment"
|
|
754
|
+
submit: "Snooze"
|
|
755
|
+
# Duration options. English writes the longer spans twice — "24 hours
|
|
756
|
+
# (1 day)". The two halves pluralize on different counts (24 and 1),
|
|
757
|
+
# so each is its own plural key and %{equivalent} composes them. A
|
|
758
|
+
# locale that does not use the parenthetical can ignore it.
|
|
759
|
+
hours:
|
|
760
|
+
one: "%{count} hour"
|
|
761
|
+
other: "%{count} hours"
|
|
762
|
+
days:
|
|
763
|
+
one: "%{count} day"
|
|
764
|
+
other: "%{count} days"
|
|
765
|
+
weeks:
|
|
766
|
+
one: "%{count} week"
|
|
767
|
+
other: "%{count} weeks"
|
|
768
|
+
hours_with_equivalent: "%{hours} (%{equivalent})"
|
|
769
|
+
mute:
|
|
770
|
+
title: "Mute Notifications"
|
|
771
|
+
# The channel names are products and stay as written.
|
|
772
|
+
description: "Muted errors still appear in the dashboard but will not trigger any notifications (Slack, email, Discord, PagerDuty, webhooks)."
|
|
773
|
+
name_label: "Your Name (Optional)"
|
|
774
|
+
reason_label: "Reason (Optional)"
|
|
775
|
+
reason_placeholder: "Why are you muting this error?"
|
|
776
|
+
reason_hint: "Reason will be added as a comment"
|
|
777
|
+
submit: "Mute Notifications"
|
|
778
|
+
|
|
779
|
+
request_context:
|
|
780
|
+
title: "Request Context"
|
|
781
|
+
# Table row labels. The trailing colon is part of the label so a locale
|
|
782
|
+
# can drop it — several scripts do not use one.
|
|
783
|
+
url: "Request URL:"
|
|
784
|
+
hostname: "Hostname:"
|
|
785
|
+
content_type: "Content Type:"
|
|
786
|
+
duration: "Request Duration:"
|
|
787
|
+
params: "Request Params:"
|
|
788
|
+
user_agent: "User Agent:"
|
|
789
|
+
ip_address: "IP Address:"
|
|
790
|
+
replay: "Replay Request:"
|
|
791
|
+
raw_user_agent: "Raw User Agent"
|
|
792
|
+
# %{value} is a number. The unit is inside the key so a locale can put
|
|
793
|
+
# a space (or nothing) between number and unit as its typography wants.
|
|
794
|
+
duration_seconds: "%{value}s"
|
|
795
|
+
duration_ms: "%{value}ms"
|
|
796
|
+
# "curl" and "RSpec" are tool names and stay as written in every locale.
|
|
797
|
+
copy_curl: "Copy as curl"
|
|
798
|
+
copy_curl_title: "Copy curl command to clipboard"
|
|
799
|
+
copy_rspec: "Copy as RSpec"
|
|
800
|
+
copy_rspec_title: "Copy RSpec request spec to clipboard"
|
|
801
|
+
|
|
802
|
+
similar_errors:
|
|
803
|
+
title: "Similar Errors"
|
|
804
|
+
badge: "Fuzzy Matching"
|
|
805
|
+
# %{threshold} is the similarity cut-off as a percentage. It is passed
|
|
806
|
+
# from the same local that drives the query, so the prose cannot drift
|
|
807
|
+
# from the threshold actually applied.
|
|
808
|
+
hint: "Errors with similar backtraces and messages (%{threshold}%+ similarity)"
|
|
809
|
+
column_similarity: "Similarity"
|
|
810
|
+
column_error_type: "Error Type"
|
|
811
|
+
column_message: "Message"
|
|
812
|
+
column_platform: "Platform"
|
|
813
|
+
column_occurrences: "Occurrences"
|
|
814
|
+
# %{count} occurrences. English shortens "times" to a trailing "x";
|
|
815
|
+
# that abbreviation is not universal, so it is a full plural form here.
|
|
816
|
+
occurrences:
|
|
817
|
+
one: "%{count}x"
|
|
818
|
+
other: "%{count}x"
|
|
819
|
+
view: "View"
|
|
820
|
+
|
|
821
|
+
source_code:
|
|
822
|
+
# %{host} is a repository host name (GitHub, GitLab, Bitbucket) — a
|
|
823
|
+
# brand name, not translated.
|
|
824
|
+
view_on: "View on %{host}"
|
|
825
|
+
view_source: "View Source"
|
|
826
|
+
# The coverage legend was assembled from coloured fragments
|
|
827
|
+
# ("green = executed, gray = not executed"). %{executed} and
|
|
828
|
+
# %{not_executed} arrive as pre-coloured <span>s, hence _html.
|
|
829
|
+
coverage_legend_html: "Coverage active — %{executed} = executed, %{not_executed} = not executed"
|
|
830
|
+
coverage_green: "green"
|
|
831
|
+
coverage_gray: "gray"
|
|
832
|
+
# %{message} is the underlying read error — diagnostic text, verbatim.
|
|
833
|
+
read_failed: "Could not read source: %{message}"
|
|
834
|
+
|
|
835
|
+
ai_help:
|
|
836
|
+
title: "AI Help"
|
|
837
|
+
# LLM provider display names. Brand names, so they are identical in
|
|
838
|
+
# every locale — but they are keys rather than titleize on the config
|
|
839
|
+
# value, which renders "openai" as "Openai". Neither that nor the bare
|
|
840
|
+
# identifier is how either company writes its own name.
|
|
841
|
+
providers:
|
|
842
|
+
openai: "OpenAI"
|
|
843
|
+
anthropic: "Anthropic"
|
|
844
|
+
close: "Close AI Help"
|
|
845
|
+
empty: "Ask about root cause, reproduction steps, likely fixes, or what to inspect next."
|
|
846
|
+
question_label: "Question"
|
|
847
|
+
question_placeholder: "What is the likely root cause?"
|
|
848
|
+
ask: "Ask"
|
|
849
|
+
|
|
850
|
+
sidebar:
|
|
851
|
+
title: "Metadata"
|
|
852
|
+
|
|
853
|
+
occurrence_count: "Occurrence Count"
|
|
854
|
+
# %{count} times. The badge above it shows "12x"; this is the sentence
|
|
855
|
+
# under it, shown only when the count is greater than one.
|
|
856
|
+
occurred_times:
|
|
857
|
+
one: "This error has occurred %{count} time"
|
|
858
|
+
other: "This error has occurred %{count} times"
|
|
859
|
+
|
|
860
|
+
first_seen: "First Seen"
|
|
861
|
+
last_seen: "Last Seen"
|
|
862
|
+
jump_to_timeline: "Jump to timeline"
|
|
863
|
+
|
|
864
|
+
severity_level: "Severity Level"
|
|
865
|
+
# %{severity} is a translated severity label.
|
|
866
|
+
view_all_severity: "View all %{severity} errors"
|
|
867
|
+
# Severity badges, stored already-uppercased. The English original
|
|
868
|
+
# hardcoded "CRITICAL"/"HIGH"/"MEDIUM"/"LOW" per branch; .upcase would
|
|
869
|
+
# be a Latin-alphabet assumption, so the casing lives in the value.
|
|
870
|
+
severity_badges:
|
|
871
|
+
critical: "CRITICAL"
|
|
872
|
+
high: "HIGH"
|
|
873
|
+
medium: "MEDIUM"
|
|
874
|
+
low: "LOW"
|
|
875
|
+
|
|
876
|
+
platform: "Platform"
|
|
877
|
+
# %{platform} is a platform name (iOS, Android, Web) and is not translated.
|
|
878
|
+
view_all_platform: "View all %{platform} errors"
|
|
879
|
+
|
|
880
|
+
user: "User"
|
|
881
|
+
view_user_errors: "View all errors for this user"
|
|
882
|
+
# %{id} is a user identifier.
|
|
883
|
+
user_id: "ID: %{id}"
|
|
884
|
+
user_id_label: "User ID: %{id}"
|
|
885
|
+
guest: "Guest / Unauthenticated"
|
|
886
|
+
|
|
887
|
+
# Shown when issue tracking owns status/assignment/priority. Two whole
|
|
888
|
+
# sentences rather than a stem plus two endings — the clause order is
|
|
889
|
+
# not universal.
|
|
890
|
+
#
|
|
891
|
+
# %{link} is a fully-built <a> element, NOT a bare URL. An _html key is
|
|
892
|
+
# html_safe, so interpolating the raw external_issue_url here would let
|
|
893
|
+
# a crafted URL break out of the href and inject an event handler. The
|
|
894
|
+
# tag is built with link_to in the view, which escapes it.
|
|
895
|
+
issue_tracking_linked_html: "Status, assignment, and priority are managed via your %{link}."
|
|
896
|
+
issue_tracking_link_text: "linked issue"
|
|
897
|
+
issue_tracking_unlinked: >-
|
|
898
|
+
Status, assignment, and priority are managed via your issue tracker.
|
|
899
|
+
Link an issue to see details.
|
|
900
|
+
|
|
901
|
+
workflow_status: "Workflow Status"
|
|
902
|
+
resolved: "Resolved"
|
|
903
|
+
unresolved: "Unresolved"
|
|
904
|
+
|
|
905
|
+
reopened: "Reopened"
|
|
906
|
+
|
|
907
|
+
assigned_to: "Assigned To"
|
|
908
|
+
assign: "Assign"
|
|
909
|
+
remove_assignment: "Remove assignment?"
|
|
910
|
+
|
|
911
|
+
priority: "Priority"
|
|
912
|
+
|
|
913
|
+
snooze: "Snooze"
|
|
914
|
+
snoozed: "Snoozed"
|
|
915
|
+
# %{time} is a <span class="local-time"> element from
|
|
916
|
+
# ApplicationHelper#local_time, so this key is _html.
|
|
917
|
+
snoozed_until_html: "Until %{time}"
|
|
918
|
+
unsnooze: "Unsnooze"
|
|
919
|
+
|
|
920
|
+
notifications: "Notifications"
|
|
921
|
+
muted: "Muted"
|
|
922
|
+
# %{name} is whoever muted it — free-form data, not translated.
|
|
923
|
+
muted_by: "By %{name}"
|
|
924
|
+
# %{time} is a <span class="local-time"> element, hence _html.
|
|
925
|
+
muted_since_html: "Since %{time}"
|
|
926
|
+
mute: "Mute"
|
|
927
|
+
unmute: "Unmute"
|
|
928
|
+
|
|
929
|
+
resolved_by: "Resolved By"
|
|
930
|
+
reference: "Reference"
|
|
931
|
+
resolution_notes: "Resolution Notes"
|
|
932
|
+
|
|
933
|
+
error_id: "Error ID"
|
|
934
|
+
copy_error_id: "Copy error ID"
|
|
935
|
+
|
|
936
|
+
environment:
|
|
937
|
+
title: "Environment"
|
|
938
|
+
hint: "Runtime context at error time"
|
|
939
|
+
app_version: "App Version:"
|
|
940
|
+
# %{version} is a version string.
|
|
941
|
+
view_all_version: "View all errors in %{version}"
|
|
942
|
+
git_sha: "Git SHA:"
|
|
943
|
+
rails: "Rails:"
|
|
944
|
+
ruby: "Ruby:"
|
|
945
|
+
environment: "Environment:"
|
|
946
|
+
server: "Server:"
|
|
947
|
+
database: "Database:"
|
|
948
|
+
key_gems: "Key Gems:"
|
|
949
|
+
|
|
950
|
+
health:
|
|
951
|
+
title: "System Health"
|
|
952
|
+
hint: "Runtime state when error fired"
|
|
953
|
+
|
|
954
|
+
# Metric labels. The values beside them are machine state rendered in
|
|
955
|
+
# <code> and stay English (see the glossary in TRANSLATIONS.md):
|
|
956
|
+
# close_wait, time_wait, enqueued, iseqs, adapter names and so on are
|
|
957
|
+
# diagnostic tokens developers search for, not prose.
|
|
958
|
+
memory_rss: "Memory (RSS):"
|
|
959
|
+
process_swap: "Process Swap:"
|
|
960
|
+
peak_rss: "Peak RSS:"
|
|
961
|
+
os_threads: "OS Threads:"
|
|
962
|
+
threads: "Threads:"
|
|
963
|
+
file_descriptors: "File Descriptors:"
|
|
964
|
+
load_average: "Load Average:"
|
|
965
|
+
system_memory: "System Memory:"
|
|
966
|
+
system_swap: "System Swap:"
|
|
967
|
+
tcp_connections: "TCP Connections:"
|
|
968
|
+
gc_live_objects: "GC Live Objects:"
|
|
969
|
+
major_gc_runs: "Major GC Runs:"
|
|
970
|
+
last_gc: "Last GC:"
|
|
971
|
+
connection_pool: "Connection Pool:"
|
|
972
|
+
puma_threads: "Puma Threads:"
|
|
973
|
+
# %{adapter} is the job backend's name (sidekiq, solid_queue) and is
|
|
974
|
+
# not translated.
|
|
975
|
+
job_queue: "Job Queue (%{adapter}):"
|
|
976
|
+
vm_cache_invalidations: "VM Cache Invalidations:"
|
|
977
|
+
vm_cache_misses: "VM Cache Misses:"
|
|
978
|
+
shape_cache_size: "Shape Cache Size:"
|
|
979
|
+
yjit_compiled: "YJIT Compiled:"
|
|
980
|
+
yjit_invalidations: "YJIT Invalidations:"
|
|
981
|
+
yjit_code_size: "YJIT Code Size:"
|
|
982
|
+
yjit_compile_time: "YJIT Compile Time:"
|
|
983
|
+
|
|
984
|
+
# %{count} is a Ruby thread count shown beside the OS thread count.
|
|
985
|
+
ruby_threads: "(Ruby: %{count})"
|
|
986
|
+
|
|
987
|
+
info:
|
|
988
|
+
new_badge: "NEW"
|
|
989
|
+
new_tooltip: "Error occurred within the last hour"
|
|
990
|
+
reopened: "Reopened"
|
|
991
|
+
# %{time} is a formatted timestamp.
|
|
992
|
+
reopened_tooltip: "Previously resolved, recurred %{time}"
|
|
993
|
+
copy_error_type: "Copy error type"
|
|
994
|
+
message_label: "Error Message:"
|
|
995
|
+
copy_message: "Copy error message"
|
|
996
|
+
copy: "Copy"
|
|
997
|
+
|
|
998
|
+
cause_chain:
|
|
999
|
+
title: "Exception Cause Chain"
|
|
1000
|
+
# The chain is a list; "Caused by:" labels one entry, and when there
|
|
1001
|
+
# is more than one the index is appended. Two keys rather than a
|
|
1002
|
+
# concatenated suffix, since the numbering may sit elsewhere in the
|
|
1003
|
+
# sentence.
|
|
1004
|
+
caused_by: "Caused by:"
|
|
1005
|
+
# %{index} is the 1-based position in the chain.
|
|
1006
|
+
caused_by_indexed: "Caused by (#%{index}):"
|
|
1007
|
+
backtrace: "Backtrace"
|
|
1008
|
+
|
|
1009
|
+
backtrace:
|
|
1010
|
+
label: "Backtrace:"
|
|
1011
|
+
# %{app} frames are the user's own code, %{framework} are gems/Rails.
|
|
1012
|
+
frame_counts: "(%{app} your code, %{framework} framework/gems)"
|
|
1013
|
+
# The button label and its tooltip differ in the original ("Copy Full
|
|
1014
|
+
# Backtrace" vs "Copy full backtrace"); kept as separate keys so a
|
|
1015
|
+
# translator can decide whether the distinction is worth keeping.
|
|
1016
|
+
copy_full: "Copy Full Backtrace"
|
|
1017
|
+
copy_full_title: "Copy full backtrace"
|
|
1018
|
+
your_code: "Your Code"
|
|
1019
|
+
framework_code: "Framework & Gem Code"
|
|
1020
|
+
# %{count} frames in the section.
|
|
1021
|
+
frames:
|
|
1022
|
+
one: "%{count} frame"
|
|
1023
|
+
other: "%{count} frames"
|
|
1024
|
+
click_to_expand: "(click to expand)"
|
|
1025
|
+
view_source: "View Source"
|
|
1026
|
+
none: "No backtrace available"
|
|
1027
|
+
|
|
1028
|
+
row:
|
|
1029
|
+
# Badge on an error first seen within the recent window.
|
|
1030
|
+
new_badge: "NEW"
|
|
1031
|
+
reopened: "Reopened"
|
|
1032
|
+
# %{user} is a user identifier — free-form data, never translated.
|
|
1033
|
+
view_user_errors: "View all errors for user %{user}"
|
|
1034
|
+
|
|
1035
|
+
# Workflow status labels. The status is a machine value ("in_progress");
|
|
1036
|
+
# it was previously displayed by tr('_', ' ') plus a CSS capitalize,
|
|
1037
|
+
# which is English morphology applied to an identifier. Each value now
|
|
1038
|
+
# has its own key, and an unrecognized value falls back to the raw text.
|
|
1039
|
+
status:
|
|
1040
|
+
unresolved: "unresolved"
|
|
1041
|
+
resolved: "resolved"
|
|
1042
|
+
in_progress: "in progress"
|
|
1043
|
+
investigating: "investigating"
|
|
1044
|
+
wont_fix: "wont fix"
|
|
1045
|
+
assigned: "assigned"
|
|
1046
|
+
snoozed: "snoozed"
|
|
1047
|
+
muted: "muted"
|
|
1048
|
+
|
|
1049
|
+
# The five stat cards above the error list. Rendered on the index and
|
|
1050
|
+
# re-rendered by ErrorBroadcaster#broadcast_stats over ActionCable, so
|
|
1051
|
+
# these labels must be translated in both paths, not just the request one.
|
|
1052
|
+
#
|
|
1053
|
+
# Each is a bare noun phrase standing over a number, not a sentence
|
|
1054
|
+
# fragment to be joined to one.
|
|
1055
|
+
stats:
|
|
1056
|
+
today: "Today"
|
|
1057
|
+
this_week: "This Week"
|
|
1058
|
+
unresolved: "Unresolved"
|
|
1059
|
+
resolved: "Resolved"
|
|
1060
|
+
reopened: "Reopened"
|
|
1061
|
+
|
|
1062
|
+
# Vocabulary shared by the diagnostic summary pages (deprecations, N+1,
|
|
1063
|
+
# swallowed exceptions, rate limits, diagnostic dumps). These pages have
|
|
1064
|
+
# one shape — title, day-range toggle, empty state with a "how it works"
|
|
1065
|
+
# list, stat tiles, a table, a footer tip — so the repeated labels are
|
|
1066
|
+
# named once rather than per page.
|
|
1067
|
+
pages:
|
|
1068
|
+
# Units rendered next to a number. They live in keys because both the
|
|
1069
|
+
# symbol and its spacing vary — several locales put a space before "%".
|
|
1070
|
+
# %{value} is the already-formatted number.
|
|
1071
|
+
percent: "%{value}%"
|
|
1072
|
+
column_errors: "Errors"
|
|
1073
|
+
column_occurrences: "Occurrences"
|
|
1074
|
+
column_last_seen: "Last Seen"
|
|
1075
|
+
total_occurrences: "Total Occurrences"
|
|
1076
|
+
affected_errors: "Affected Errors"
|
|
1077
|
+
# %{count} is how many more error links exist beyond the five shown.
|
|
1078
|
+
# English reads the same either way, but the form is selected properly
|
|
1079
|
+
# so a locale that distinguishes them can.
|
|
1080
|
+
more_errors:
|
|
1081
|
+
one: "+%{count} more"
|
|
1082
|
+
other: "+%{count} more"
|
|
1083
|
+
# %{days} is the selected day range.
|
|
1084
|
+
none_in_last_days: "No results were detected over the last %{days} days."
|
|
1085
|
+
# Byte-identical on the deprecations and N+1 pages; %{option} is the
|
|
1086
|
+
# config option name rendered as a <code> element.
|
|
1087
|
+
how_breadcrumbs_html: "Breadcrumbs must be enabled (%{option})"
|
|
1088
|
+
|
|
1089
|
+
deprecations_page:
|
|
1090
|
+
title: "Deprecation Warnings"
|
|
1091
|
+
empty_title: "No Deprecation Warnings Found"
|
|
1092
|
+
# %{days} is the selected day range.
|
|
1093
|
+
empty_body: "No deprecation warnings were detected in error breadcrumbs over the last %{days} days."
|
|
1094
|
+
how_title: "How deprecations are captured:"
|
|
1095
|
+
how_captured: "Rails deprecation warnings are automatically captured as breadcrumbs"
|
|
1096
|
+
how_appear: "Deprecations appear here when an error occurs during a request with deprecation warnings"
|
|
1097
|
+
unique_warnings: "Unique Warnings"
|
|
1098
|
+
all_title: "All Deprecation Warnings"
|
|
1099
|
+
column_warning: "Warning"
|
|
1100
|
+
column_source: "Source"
|
|
1101
|
+
|
|
1102
|
+
n_plus_one_page:
|
|
1103
|
+
title: "N+1 Query Patterns"
|
|
1104
|
+
empty_title: "No N+1 Query Patterns Found"
|
|
1105
|
+
# %{days} is the selected day range.
|
|
1106
|
+
empty_body: "No N+1 query patterns were detected in error breadcrumbs over the last %{days} days."
|
|
1107
|
+
how_title: "How N+1 detection works:"
|
|
1108
|
+
how_captured: "SQL queries are captured as breadcrumbs during requests that produce errors"
|
|
1109
|
+
# %{threshold} is the configured option name as a <code> element.
|
|
1110
|
+
how_threshold_html: "Queries with the same shape appearing >= %{threshold} times are flagged"
|
|
1111
|
+
# %{count} is the configured default, read from the configuration so the
|
|
1112
|
+
# prose cannot drift from the value actually applied.
|
|
1113
|
+
how_default:
|
|
1114
|
+
one: "Default threshold is %{count} repetition"
|
|
1115
|
+
other: "Default threshold is %{count} repetitions"
|
|
1116
|
+
unique_patterns: "Unique Patterns"
|
|
1117
|
+
all_title: "All N+1 Query Patterns"
|
|
1118
|
+
# column_query, column_total_time and eager_loading_guide are reused
|
|
1119
|
+
# from red.errors.n_plus_one — the detail panel already names them and
|
|
1120
|
+
# the strings are identical.
|
|
1121
|
+
# %{value} is a duration in milliseconds.
|
|
1122
|
+
duration_ms: "%{value} ms"
|
|
1123
|
+
# The method names are Ruby API calls and stay as written.
|
|
1124
|
+
footer_tip_html: "Use %{includes}, %{preload}, or %{eager_load} to fix N+1 queries."
|
|
1125
|
+
|
|
1126
|
+
swallowed_page:
|
|
1127
|
+
title: "Swallowed Exceptions"
|
|
1128
|
+
empty_title: "No Swallowed Exceptions Detected"
|
|
1129
|
+
# %{threshold} is the configured rescue-ratio percentage and %{days} the
|
|
1130
|
+
# selected day range.
|
|
1131
|
+
empty_body: "No exceptions with a rescue ratio above %{threshold}% were detected in the last %{days} days."
|
|
1132
|
+
how_title: "How swallowed exceptions are detected:"
|
|
1133
|
+
# TracePoint(:raise) and TracePoint(:rescue) are Ruby APIs.
|
|
1134
|
+
how_raise: "TracePoint(:raise) counts every exception raised"
|
|
1135
|
+
how_rescue: "TracePoint(:rescue) counts every exception rescued"
|
|
1136
|
+
how_ratio: "High rescue/raise ratio = likely swallowed (silently rescued)"
|
|
1137
|
+
# %{option} is a config option name as a <code> element; the Ruby
|
|
1138
|
+
# version is a literal.
|
|
1139
|
+
how_requires_html: "Requires Ruby 3.3+ and %{option}"
|
|
1140
|
+
swallowed_patterns: "Swallowed Patterns"
|
|
1141
|
+
total_rescues: "Total Rescues"
|
|
1142
|
+
total_raises: "Total Raises"
|
|
1143
|
+
all_title: "Swallowed Exception Patterns"
|
|
1144
|
+
column_exception_class: "Exception Class"
|
|
1145
|
+
column_raise_location: "Raise Location"
|
|
1146
|
+
column_rescue_location: "Rescue Location"
|
|
1147
|
+
column_raises: "Raises"
|
|
1148
|
+
column_rescues: "Rescues"
|
|
1149
|
+
column_ratio: "Ratio"
|
|
1150
|
+
# %{exception} is an exception class name and is never translated.
|
|
1151
|
+
view_unrescued: "View any unrescued %{exception} errors that leaked into error_log"
|
|
1152
|
+
footer_tip: "Swallowed exceptions are raised then silently rescued. They may hide real bugs."
|
|
1153
|
+
|
|
1154
|
+
rack_attack_page:
|
|
1155
|
+
title: "Rate Limit Events"
|
|
1156
|
+
missing_title: "Rack Attack Is Not Installed"
|
|
1157
|
+
# %{gem} is the gem name as a <code> element — a package name, not prose.
|
|
1158
|
+
missing_body_html: >-
|
|
1159
|
+
Tracking is enabled, but the %{gem} gem is not loaded in this
|
|
1160
|
+
application — so no events can be recorded. Add it to your Gemfile and
|
|
1161
|
+
configure at least one rule, then events will appear here.
|
|
1162
|
+
empty_title: "No Rate Limit Events Found"
|
|
1163
|
+
# %{days} is the selected day range.
|
|
1164
|
+
empty_body: "No Rack Attack throttle, blocklist, or track events were recorded over the last %{days} days."
|
|
1165
|
+
how_title: "How Rack Attack tracking works:"
|
|
1166
|
+
# %{option} is a config option name as a <code> element.
|
|
1167
|
+
how_enabled_html: "Rack Attack tracking must be enabled (%{option})"
|
|
1168
|
+
how_installed: "Rack Attack must be installed and configured in your app"
|
|
1169
|
+
how_recorded: "Throttle, blocklist, and track events are recorded whenever a rule matches — no error required"
|
|
1170
|
+
# %{seconds} is the configured flush interval.
|
|
1171
|
+
how_buffered: "Events are buffered and written every %{seconds}s, so allow a short delay before they appear"
|
|
1172
|
+
unique_rules: "Unique Rules"
|
|
1173
|
+
total_events: "Total Events"
|
|
1174
|
+
unique_ips: "Unique IPs"
|
|
1175
|
+
all_title: "Rate Limit Events by Rule"
|
|
1176
|
+
column_rule: "Rule"
|
|
1177
|
+
column_type: "Type"
|
|
1178
|
+
column_count: "Count"
|
|
1179
|
+
column_ips: "IPs"
|
|
1180
|
+
column_top_path: "Top Path"
|
|
1181
|
+
# Rack Attack match types. These are machine values the view also
|
|
1182
|
+
# compares by string equality, so the display is a lookup and the
|
|
1183
|
+
# comparison keeps the English literal.
|
|
1184
|
+
match_type:
|
|
1185
|
+
blocklist: "blocklist"
|
|
1186
|
+
throttle: "throttle"
|
|
1187
|
+
track: "track"
|
|
1188
|
+
footer_tip: "High counts may indicate abuse or misconfigured rules."
|
|
1189
|
+
docs: "Rack Attack Docs"
|
|
1190
|
+
|
|
1191
|
+
diagnostic_dumps_page:
|
|
1192
|
+
title: "Diagnostic Dumps"
|
|
1193
|
+
capture: "Capture Dump"
|
|
1194
|
+
empty_title: "No Diagnostic Dumps Yet"
|
|
1195
|
+
empty_body: "Capture an on-demand snapshot of your system state for debugging."
|
|
1196
|
+
how_title: "How diagnostic dumps work:"
|
|
1197
|
+
# %{button} is the capture button's label and %{command} the rake task,
|
|
1198
|
+
# both rendered as elements.
|
|
1199
|
+
how_capture_html: "Click %{button} above or run %{command}"
|
|
1200
|
+
how_captures: "Captures: environment, GC stats, threads, connection pool, memory, job queue"
|
|
1201
|
+
how_saved: "Each dump is saved to the database for historical comparison"
|
|
1202
|
+
how_use: "Use dumps to investigate production issues or verify system health"
|
|
1203
|
+
total_dumps: "Total Dumps"
|
|
1204
|
+
threads_latest: "Threads (Latest)"
|
|
1205
|
+
memory_latest: "Memory (Latest)"
|
|
1206
|
+
history_title: "Dump History"
|
|
1207
|
+
details: "Details"
|
|
1208
|
+
# PID is an acronym and stays as written. %{pid} is the process id.
|
|
1209
|
+
pid: "PID: %{pid}"
|
|
1210
|
+
# %{minutes} is the process uptime.
|
|
1211
|
+
uptime: "Uptime: %{minutes}m"
|
|
1212
|
+
section_environment: "Environment"
|
|
1213
|
+
section_system_health: "System Health"
|
|
1214
|
+
section_gc: "GC"
|
|
1215
|
+
section_job_queue: "Job Queue"
|
|
1216
|
+
# %{ruby} and %{rails} are version numbers; the language and framework
|
|
1217
|
+
# names are products.
|
|
1218
|
+
env_versions: "Ruby %{ruby} / Rails %{rails}"
|
|
1219
|
+
# %{value} is a memory figure in megabytes. MB is a unit symbol.
|
|
1220
|
+
memory_mb: "%{value} MB"
|
|
1221
|
+
# %{count} is a thread count.
|
|
1222
|
+
threads:
|
|
1223
|
+
one: "%{count} thread"
|
|
1224
|
+
other: "%{count} threads"
|
|
1225
|
+
# %{busy} and %{size} are connection-pool counts.
|
|
1226
|
+
pool: "Pool: %{busy}/%{size}"
|
|
1227
|
+
# %{live} is a heap slot count and %{major} a GC run count.
|
|
1228
|
+
gc_stats: "Live: %{live} / Major GC: %{major}"
|
|
1229
|
+
# %{count} is a failed job count.
|
|
1230
|
+
jobs_failed: "failed: %{count}"
|
|
1231
|
+
# Both are literal rake invocations and are never translated.
|
|
1232
|
+
footer_tip_html: "You can also capture dumps via: %{command}"
|
|
1233
|
+
footer_note_html: "Add a note: %{command}"
|
|
1234
|
+
unknown_short: "?"
|
|
1235
|
+
|
|
1236
|
+
storms_page:
|
|
1237
|
+
title: "Storm History"
|
|
1238
|
+
# storm_* is a config option prefix, rendered as a <code> element.
|
|
1239
|
+
intro_html: >-
|
|
1240
|
+
When the error rate spikes (a bad deploy, a dependency outage), storm
|
|
1241
|
+
protection limits the gem's own database writes so it never amplifies
|
|
1242
|
+
the incident. Occurrences are always counted exactly — only per-event
|
|
1243
|
+
detail is sampled. Thresholds are configurable per process via
|
|
1244
|
+
%{options} options.
|
|
1245
|
+
# %{time} is a formatted timestamp and %{rate} a per-minute rate.
|
|
1246
|
+
active_html: "%{label} since %{time} — peak rate %{rate}."
|
|
1247
|
+
active_label: "Storm in progress"
|
|
1248
|
+
empty_title: "No Storms Recorded"
|
|
1249
|
+
empty_body: >-
|
|
1250
|
+
Storm protection is standing by. If an error flood ever hits this app,
|
|
1251
|
+
episodes will appear here with exact counts of what was shed.
|
|
1252
|
+
column_started: "Started"
|
|
1253
|
+
column_duration: "Duration"
|
|
1254
|
+
column_peak_rate: "Peak Rate"
|
|
1255
|
+
column_mode: "Mode"
|
|
1256
|
+
column_counted: "Counted (exact)"
|
|
1257
|
+
column_overflow: "Overflow"
|
|
1258
|
+
column_top_errors: "Top Errors"
|
|
1259
|
+
active_badge: "active"
|
|
1260
|
+
# Storm modes. Machine states with their own keys rather than raw
|
|
1261
|
+
# values, so a locale can name them.
|
|
1262
|
+
mode_count_only: "count-only"
|
|
1263
|
+
mode_shedding: "shedding"
|
|
1264
|
+
# %{value} is a delimited number. "/min" is a rate unit.
|
|
1265
|
+
rate_per_minute: "%{value}/min"
|
|
1266
|
+
# %{count} is an occurrence count for one error class in a storm.
|
|
1267
|
+
occurrence_multiplier: "×%{count}"
|
|
1268
|
+
|
|
1269
|
+
overview_page:
|
|
1270
|
+
# The browser tab title and the page heading are deliberately different
|
|
1271
|
+
# strings: the tab says what the app is, the heading says what the page
|
|
1272
|
+
# is. One key for both would change the tab title.
|
|
1273
|
+
page_title: "Dashboard"
|
|
1274
|
+
title: "Overview"
|
|
1275
|
+
# %{time} is a <span class="local-time"> element, hence _html.
|
|
1276
|
+
last_updated_html: "Last updated: %{time}"
|
|
1277
|
+
# %{count} critical or high severity errors in the last hour.
|
|
1278
|
+
alert_banner:
|
|
1279
|
+
one: "%{count} Critical/High Error in Last Hour"
|
|
1280
|
+
other: "%{count} Critical/High Errors in Last Hour"
|
|
1281
|
+
# %{count} is an occurrence count.
|
|
1282
|
+
alert_occurrences:
|
|
1283
|
+
one: "%{count} occurrence"
|
|
1284
|
+
other: "%{count} occurrences"
|
|
1285
|
+
alert_view: "View"
|
|
1286
|
+
error_rate: "Error Rate"
|
|
1287
|
+
error_rate_hint: "Errors per hour today"
|
|
1288
|
+
unresolved: "Unresolved"
|
|
1289
|
+
unresolved_hint: "Pending resolution"
|
|
1290
|
+
resolution_rate: "Resolution Rate"
|
|
1291
|
+
# %{resolved} of %{total} errors are resolved. One phrase, not three
|
|
1292
|
+
# fragments — the order is not universal.
|
|
1293
|
+
resolution_hint: "%{resolved} of %{total} resolved"
|
|
1294
|
+
affected_users: "Affected Users (Today)"
|
|
1295
|
+
# %{count} is the change in affected users since yesterday.
|
|
1296
|
+
users_change: "%{count} from yesterday"
|
|
1297
|
+
avg_resolution: "Avg Resolution"
|
|
1298
|
+
avg_resolution_hint: "Mean time to resolution"
|
|
1299
|
+
# %{value} is a duration in hours. The "h" suffix is a unit.
|
|
1300
|
+
hours_short: "%{value}h"
|
|
1301
|
+
error_trend: "Error Trend"
|
|
1302
|
+
top_errors: "Top Errors by Impact"
|
|
1303
|
+
view_all: "View all →"
|
|
1304
|
+
# %{count} is a number of affected users.
|
|
1305
|
+
users:
|
|
1306
|
+
one: "%{count} user"
|
|
1307
|
+
other: "%{count} users"
|
|
1308
|
+
platform_health: "Platform Health"
|
|
1309
|
+
full_comparison: "Full comparison →"
|
|
1310
|
+
# %{score} is a stability score out of 100.
|
|
1311
|
+
stability_score_html: "%{score}/100"
|
|
1312
|
+
# One line summarising a platform's errors. Whole phrase rather than
|
|
1313
|
+
# three fragments joined by separators.
|
|
1314
|
+
platform_summary: "%{total} errors · %{critical} critical · %{unresolved} open"
|
|
1315
|
+
correlation_title: "Correlation Insights"
|
|
1316
|
+
full_analysis: "Full analysis →"
|
|
1317
|
+
problematic_releases: "Problematic Releases"
|
|
1318
|
+
# %{count} is an error count for one release.
|
|
1319
|
+
release_errors:
|
|
1320
|
+
one: "%{count} error"
|
|
1321
|
+
other: "%{count} errors"
|
|
1322
|
+
time_correlated: "Time-Correlated"
|
|
1323
|
+
# %{percent} is the correlation percentage inside its <strong>, hence
|
|
1324
|
+
# _html; %{strength} is a label from red.analytics.correlation_strength,
|
|
1325
|
+
# reused rather than duplicated.
|
|
1326
|
+
correlation_value_html: "%{percent} correlation (%{strength})"
|
|
1327
|
+
multi_error_users: "Multi-Error Users"
|
|
1328
|
+
# %{user} is a user identifier and %{count} how many distinct error
|
|
1329
|
+
# types they hit.
|
|
1330
|
+
user_types_html: "User %{user} · %{types}"
|
|
1331
|
+
types:
|
|
1332
|
+
one: "%{count} type"
|
|
1333
|
+
other: "%{count} types"
|
|
1334
|
+
|
|
1335
|
+
settings:
|
|
1336
|
+
title: "Settings"
|
|
1337
|
+
# %{version} is the gem version. The "v" prefix is a sigil, not a word.
|
|
1338
|
+
version: "v%{version}"
|
|
1339
|
+
# %{file} is the initializer path, rendered as a <code> element. The path
|
|
1340
|
+
# itself is never translated.
|
|
1341
|
+
intro_html: "Read-only view of current configuration. Edit via %{file} or environment variables."
|
|
1342
|
+
# %{count} is the number of options in a collapsed group.
|
|
1343
|
+
option_count:
|
|
1344
|
+
one: "%{count} option"
|
|
1345
|
+
other: "%{count} options"
|
|
1346
|
+
|
|
1347
|
+
plugins:
|
|
1348
|
+
title: "Active Plugins"
|
|
1349
|
+
column_name: "Plugin Name"
|
|
1350
|
+
column_version: "Version"
|
|
1351
|
+
column_description: "Description"
|
|
1352
|
+
column_status: "Status"
|
|
1353
|
+
active: "Active"
|
|
1354
|
+
inactive: "Inactive"
|
|
1355
|
+
empty: "No plugins are currently registered. You can create custom plugins to extend functionality."
|
|
1356
|
+
|
|
1357
|
+
test_error:
|
|
1358
|
+
title: "Test Notifications"
|
|
1359
|
+
# %{error_class} is RailsErrorDashboard::TestError as a <code> element,
|
|
1360
|
+
# so this key is _html. The channel names are products.
|
|
1361
|
+
description_html: >-
|
|
1362
|
+
Send a test error through the full capture and notification pipeline.
|
|
1363
|
+
This creates a %{error_class} in the error log and dispatches
|
|
1364
|
+
notifications to all configured channels (Slack, Discord, PagerDuty,
|
|
1365
|
+
email, webhooks). The test error is clearly marked and safe to resolve
|
|
1366
|
+
or delete.
|
|
1367
|
+
confirm: "This will create a test error and send notifications to all configured channels. Continue?"
|
|
1368
|
+
submit: "Send Test Error"
|
|
1369
|
+
|
|
1370
|
+
help:
|
|
1371
|
+
title: "Need to change these settings?"
|
|
1372
|
+
# Two whole sentences, rendered on separate lines. Each is one key with
|
|
1373
|
+
# its element interpolated rather than prose fragments assembled around
|
|
1374
|
+
# the markup — clause order is not universal.
|
|
1375
|
+
# %{file} is the initializer path and %{docs} the documentation link,
|
|
1376
|
+
# both pre-built elements, hence _html.
|
|
1377
|
+
edit_html: "Edit your configuration in %{file} and restart your application."
|
|
1378
|
+
docs_html: "See the %{docs} for more information."
|
|
1379
|
+
docs_link: "documentation"
|
|
1380
|
+
|
|
1381
|
+
# Group headings, keyed by a stable slug so the display text can change
|
|
1382
|
+
# without touching the view's structure.
|
|
1383
|
+
groups:
|
|
1384
|
+
core_features: "Core Features"
|
|
1385
|
+
multi_app: "Multi-App Support"
|
|
1386
|
+
user_integration: "User Integration"
|
|
1387
|
+
performance: "Performance Settings"
|
|
1388
|
+
notifications: "Notification Channels"
|
|
1389
|
+
analytics: "Advanced Analytics Features"
|
|
1390
|
+
source_code: "Source Code Integration"
|
|
1391
|
+
breadcrumbs: "Breadcrumbs"
|
|
1392
|
+
system_health: "System Health"
|
|
1393
|
+
enhanced_metrics: "Enhanced Metrics"
|
|
1394
|
+
issue_tracking: "Issue Tracking"
|
|
1395
|
+
deep_debugging: "Deep Debugging"
|
|
1396
|
+
event_tracking: "Event Tracking"
|
|
1397
|
+
advanced: "Advanced Configuration"
|
|
1398
|
+
internal_logging: "Internal Logging"
|
|
1399
|
+
|
|
1400
|
+
# Units appended to a numeric setting value. Plural forms because the
|
|
1401
|
+
# value drives them; English happens to show the plural in every default
|
|
1402
|
+
# but a locale cannot rely on that.
|
|
1403
|
+
units:
|
|
1404
|
+
lines:
|
|
1405
|
+
one: "%{count} line"
|
|
1406
|
+
other: "%{count} lines"
|
|
1407
|
+
minutes:
|
|
1408
|
+
one: "%{count} minute"
|
|
1409
|
+
other: "%{count} minutes"
|
|
1410
|
+
seconds:
|
|
1411
|
+
one: "%{count} second"
|
|
1412
|
+
other: "%{count} seconds"
|
|
1413
|
+
events:
|
|
1414
|
+
one: "%{count} event"
|
|
1415
|
+
other: "%{count} events"
|
|
1416
|
+
queries:
|
|
1417
|
+
one: "%{count} query"
|
|
1418
|
+
other: "%{count} queries"
|
|
1419
|
+
# The standard-deviation symbol is a unit sign, not a word.
|
|
1420
|
+
std_devs: "%{count}σ"
|
|
1421
|
+
|
|
1422
|
+
# Value badges rendered by settings/_value_badge. The five "absent"
|
|
1423
|
+
# phrasings are deliberately distinct — they mean different things
|
|
1424
|
+
# (unset vs. not found vs. unavailable vs. empty vs. undetectable) and
|
|
1425
|
+
# collapsing them would lose that distinction in translation.
|
|
1426
|
+
values:
|
|
1427
|
+
enabled: "Enabled"
|
|
1428
|
+
disabled: "Disabled"
|
|
1429
|
+
not_set: "Not set"
|
|
1430
|
+
not_found: "Not found"
|
|
1431
|
+
not_available: "Not available"
|
|
1432
|
+
empty: "Empty"
|
|
1433
|
+
unknown: "Unknown"
|
|
1434
|
+
set: "Set"
|
|
1435
|
+
auto_detected: "Auto-detected"
|
|
1436
|
+
# The parentheses are part of the English rendering; a locale may drop
|
|
1437
|
+
# them.
|
|
1438
|
+
configured: "(Configured)"
|
|
1439
|
+
items:
|
|
1440
|
+
one: "%{count} item"
|
|
1441
|
+
other: "%{count} items"
|
|
1442
|
+
rules:
|
|
1443
|
+
one: "%{count} rule"
|
|
1444
|
+
other: "%{count} rules"
|
|
1445
|
+
# %{count} selects the form; %{formatted} is the same number with
|
|
1446
|
+
# thousands delimiters, which is what should be displayed.
|
|
1447
|
+
users:
|
|
1448
|
+
one: "%{formatted} user"
|
|
1449
|
+
other: "%{formatted} users"
|
|
1450
|
+
days:
|
|
1451
|
+
one: "%{count} day"
|
|
1452
|
+
other: "%{count} days"
|
|
1453
|
+
rails_app_name_unavailable: "Rails app name unavailable"
|
|
1454
|
+
# %{name} is the database configuration's name — a config key, not
|
|
1455
|
+
# prose.
|
|
1456
|
+
separate_db: "Separate DB: %{name}"
|
|
1457
|
+
configured_but_not_found: "Configured but not found"
|
|
1458
|
+
# "primary" is the Rails database configuration key and stays literal.
|
|
1459
|
+
shared_db_primary: "Shared DB (primary)"
|
|
1460
|
+
shared_db: "Shared DB"
|
|
1461
|
+
unable_to_detect: "Unable to detect"
|
|
1462
|
+
no_user_model: "No User model detected"
|
|
1463
|
+
unable_to_query_count: "Unable to query count"
|
|
1464
|
+
manual_cleanup_required: "Manual cleanup required"
|
|
1465
|
+
keep_forever: "Keep Forever"
|
|
1466
|
+
no_automatic_deletion: "No automatic deletion"
|
|
1467
|
+
# These label a rake command rendered beside them. The command is never
|
|
1468
|
+
# translated.
|
|
1469
|
+
run_command: "Run:"
|
|
1470
|
+
to_cleanup: "To cleanup:"
|
|
1471
|
+
|
|
1472
|
+
# One description per config option, keyed by the option's own name so the
|
|
1473
|
+
# key stays greppable from the initializer. The option names themselves,
|
|
1474
|
+
# file paths, env vars, rake commands, Ruby APIs and product names inside
|
|
1475
|
+
# these sentences are never translated.
|
|
1476
|
+
options:
|
|
1477
|
+
enable_middleware: "Catches unhandled exceptions"
|
|
1478
|
+
enable_error_subscriber: "Subscribes to Rails error events"
|
|
1479
|
+
retention_days: "Manual cleanup only (run: rails error_dashboard:cleanup_resolved DAYS=90)"
|
|
1480
|
+
max_backtrace_lines: "Stack trace depth limit"
|
|
1481
|
+
sampling_rate: "Percentage of errors captured"
|
|
1482
|
+
application_name: "Name of this application (auto-detected if not set)"
|
|
1483
|
+
database: "Active database for error logs"
|
|
1484
|
+
use_separate_database: "Use dedicated DB for error logs"
|
|
1485
|
+
user_model: "Model name for user associations (auto-detected if not set)"
|
|
1486
|
+
total_users_for_impact: "For impact % calculation (auto-detected if not set)"
|
|
1487
|
+
async_logging: "Background job processing"
|
|
1488
|
+
async_adapter: "Job queue adapter"
|
|
1489
|
+
enable_rate_limiting: "Throttle API requests"
|
|
1490
|
+
rate_limit_per_minute: "Requests per minute per IP"
|
|
1491
|
+
enable_slack_notifications: "Real-time notifications"
|
|
1492
|
+
slack_webhook_url: "Slack webhook endpoint"
|
|
1493
|
+
enable_email_notifications: "Email alerts"
|
|
1494
|
+
notification_email_recipients: "Recipient addresses"
|
|
1495
|
+
notification_email_from: "Sender address"
|
|
1496
|
+
enable_discord_notifications: "Discord webhook notifications"
|
|
1497
|
+
discord_webhook_url: "Discord webhook endpoint"
|
|
1498
|
+
enable_pagerduty_notifications: "Critical error escalation"
|
|
1499
|
+
pagerduty_integration_key: "PagerDuty API key"
|
|
1500
|
+
enable_webhook_notifications: "Generic webhook endpoints"
|
|
1501
|
+
webhook_urls: "Custom webhook endpoints"
|
|
1502
|
+
enable_scheduled_digests: "Daily/weekly summary emails. Schedule via SolidQueue, Sidekiq, or cron"
|
|
1503
|
+
digest_frequency: "How often to send digest emails"
|
|
1504
|
+
digest_recipients: "Email addresses (falls back to notification recipients)"
|
|
1505
|
+
enable_similar_errors: "Find related errors by similarity"
|
|
1506
|
+
enable_co_occurring_errors: "Errors happening together"
|
|
1507
|
+
enable_error_cascades: "Parent→child error chains"
|
|
1508
|
+
enable_error_correlation: "Version/user/time analysis"
|
|
1509
|
+
enable_platform_comparison: "iOS vs Android analytics"
|
|
1510
|
+
enable_occurrence_patterns: "Cyclical/burst detection"
|
|
1511
|
+
enable_baseline_alerts: "Anomaly detection"
|
|
1512
|
+
baseline_alert_threshold_std_devs: "Standard deviations to trigger alert"
|
|
1513
|
+
baseline_alert_severities: "Severities to alert on"
|
|
1514
|
+
baseline_alert_cooldown_minutes: "Minutes between alerts for same error type"
|
|
1515
|
+
enable_source_code_integration: "Show code in backtrace"
|
|
1516
|
+
source_code_context_lines: "Lines before/after target line"
|
|
1517
|
+
enable_git_blame: "Show git blame info"
|
|
1518
|
+
source_code_cache_ttl: "Source code cache duration"
|
|
1519
|
+
only_show_app_code_source: "Hide gems/stdlib for security"
|
|
1520
|
+
git_branch_strategy: "Branch resolution strategy"
|
|
1521
|
+
enable_breadcrumbs: "Capture request activity trail"
|
|
1522
|
+
breadcrumb_buffer_size: "Max breadcrumbs per request"
|
|
1523
|
+
enable_n_plus_one_detection: "Detect repeated query patterns in breadcrumbs"
|
|
1524
|
+
n_plus_one_threshold: "Min repetitions to flag as N+1"
|
|
1525
|
+
enable_system_health: "Capture GC, memory, threads, connection pool at error time"
|
|
1526
|
+
app_version: "Current application version"
|
|
1527
|
+
git_sha: "Deployed commit"
|
|
1528
|
+
git_repository_url: "GitHub/GitLab repo URL"
|
|
1529
|
+
dashboard_base_url: "Base URL for dashboard links"
|
|
1530
|
+
enable_issue_tracking: >-
|
|
1531
|
+
GitHub/GitLab/Codeberg integration — one switch enables all: issue
|
|
1532
|
+
creation, auto-create, lifecycle sync, platform state mirroring,
|
|
1533
|
+
comment display. Replaces workflow controls with platform state.
|
|
1534
|
+
issue_tracker_token: "RED bot token (set RED_BOT_TOKEN env var)"
|
|
1535
|
+
issue_tracker_provider: "Auto-detected from git_repository_url"
|
|
1536
|
+
issue_tracker_repo: "Auto-detected from git_repository_url"
|
|
1537
|
+
issue_tracker_labels: "Labels added to new issues"
|
|
1538
|
+
issue_webhook_secret: "Set to enable two-way sync (HMAC verification)"
|
|
1539
|
+
enable_local_variables: "TracePoint(:raise) — capture locals at exception time"
|
|
1540
|
+
enable_instance_variables: "Capture self's ivars at exception time"
|
|
1541
|
+
detect_swallowed_exceptions: "TracePoint(:raise) + (:rescue) — detect silently rescued exceptions (Ruby 3.3+)"
|
|
1542
|
+
enable_diagnostic_dump: "On-demand system state snapshots"
|
|
1543
|
+
enable_crash_capture: "at_exit hook for unhandled crashes"
|
|
1544
|
+
enable_coverage_tracking: "Diagnostic mode — enable via dashboard to see executed lines in source view (Ruby 3.2+)"
|
|
1545
|
+
enable_rack_attack_tracking: "Record throttle/blocklist events to their own table"
|
|
1546
|
+
enable_actioncable_tracking: "Track WebSocket channel events as breadcrumbs"
|
|
1547
|
+
enable_activestorage_tracking: "Track uploads/downloads/deletes as breadcrumbs"
|
|
1548
|
+
custom_severity_rules: "Error type → severity mapping"
|
|
1549
|
+
ignored_exceptions: "Exceptions to ignore"
|
|
1550
|
+
enable_internal_logging: "Gem debugging output"
|
|
1551
|
+
log_level: "Verbosity level"
|
|
1552
|
+
|
|
1553
|
+
flash:
|
|
1554
|
+
locale:
|
|
1555
|
+
# Shown when a submitted language is one RED does not ship. The stored
|
|
1556
|
+
# value is cleared and the dashboard falls back to its configured
|
|
1557
|
+
# locale, so this is informational rather than an error.
|
|
1558
|
+
unavailable: "That language is not available. Using the default instead."
|
|
1559
|
+
|
|
1560
|
+
# Controller flash messages and the command result strings they wrap.
|
|
1561
|
+
#
|
|
1562
|
+
# The batch notice used to read "Successfully #{action_type}d N error(s)":
|
|
1563
|
+
# it conjugated English past tense by bolting a "d" onto the raw action
|
|
1564
|
+
# param and dodged pluralization with "(s)". No key can express that, so
|
|
1565
|
+
# each outcome is its own key with real plural forms. Never interpolate a
|
|
1566
|
+
# verb into a sentence — only data.
|
|
1567
|
+
batch:
|
|
1568
|
+
resolved:
|
|
1569
|
+
one: "Successfully resolved %{count} error"
|
|
1570
|
+
other: "Successfully resolved %{count} errors"
|
|
1571
|
+
muted:
|
|
1572
|
+
one: "Successfully muted %{count} error"
|
|
1573
|
+
other: "Successfully muted %{count} errors"
|
|
1574
|
+
unmuted:
|
|
1575
|
+
one: "Successfully unmuted %{count} error"
|
|
1576
|
+
other: "Successfully unmuted %{count} errors"
|
|
1577
|
+
deleted:
|
|
1578
|
+
one: "Successfully deleted %{count} error"
|
|
1579
|
+
other: "Successfully deleted %{count} errors"
|
|
1580
|
+
# %{reason} is a command's own error string.
|
|
1581
|
+
failed: "Batch operation failed: %{reason}"
|
|
1582
|
+
|
|
1583
|
+
issue:
|
|
1584
|
+
created: "Issue created successfully"
|
|
1585
|
+
linked: "Issue linked successfully"
|
|
1586
|
+
# %{reason} is a command's own error string.
|
|
1587
|
+
create_failed: "Failed to create issue: %{reason}"
|
|
1588
|
+
link_failed: "Failed to link issue: %{reason}"
|
|
1589
|
+
|
|
1590
|
+
# The "X is not enabled" notice was written out eleven times with only
|
|
1591
|
+
# the feature name changing. Two keys rather than one because English
|
|
1592
|
+
# agrees the verb and pronoun with the feature name: "Breadcrumbs are
|
|
1593
|
+
# not enabled. Enable them" but "System health is not enabled. Enable
|
|
1594
|
+
# it". A language with different agreement rules — or none — can give
|
|
1595
|
+
# both keys the same text. The initializer path is a path, not prose,
|
|
1596
|
+
# and is interpolated rather than translated.
|
|
1597
|
+
not_enabled: "%{feature} is not enabled. Enable it in %{file}"
|
|
1598
|
+
not_enabled_plural: "%{feature} are not enabled. Enable them in %{file}"
|
|
1599
|
+
# A few features name the exact options instead. %{options} is a list of
|
|
1600
|
+
# config option names — identifiers, never translated. "Set" is used when
|
|
1601
|
+
# the option needs an explicit value, "Enable" when naming it is enough.
|
|
1602
|
+
not_enabled_options: "%{feature} is not enabled. Enable %{options} in %{file}"
|
|
1603
|
+
not_enabled_set_options: "%{feature} is not enabled. Set %{options} in %{file}"
|
|
1604
|
+
# Feature names as they appear in those notices.
|
|
1605
|
+
features:
|
|
1606
|
+
platform_comparison: "Platform Comparison"
|
|
1607
|
+
error_correlation: "Error Correlation"
|
|
1608
|
+
breadcrumbs: "Breadcrumbs"
|
|
1609
|
+
system_health: "System health"
|
|
1610
|
+
swallowed_exceptions: "Swallowed exception detection"
|
|
1611
|
+
rack_attack: "Rack Attack tracking"
|
|
1612
|
+
actioncable: "ActionCable tracking"
|
|
1613
|
+
activestorage: "ActiveStorage tracking"
|
|
1614
|
+
diagnostic_dumps: "Diagnostic dumps"
|
|
1615
|
+
|
|
1616
|
+
diagnostic_dump:
|
|
1617
|
+
disabled: "Diagnostic dumps are not enabled."
|
|
1618
|
+
captured: "Diagnostic dump captured successfully."
|
|
1619
|
+
# %{message} is an exception message — diagnostic output, never
|
|
1620
|
+
# translated, only wrapped.
|
|
1621
|
+
failed: "Failed to capture diagnostic dump: %{message}"
|
|
1622
|
+
|
|
1623
|
+
coverage:
|
|
1624
|
+
not_enabled: "Coverage tracking is not enabled in configuration."
|
|
1625
|
+
enabled: "Code path coverage enabled. Reproduce the error, then view source code to see executed lines."
|
|
1626
|
+
disabled: "Code path coverage disabled."
|
|
1627
|
+
# The Ruby version requirement is a literal.
|
|
1628
|
+
unavailable: "Could not enable coverage. Requires Ruby 3.2+."
|
|
1629
|
+
|
|
1630
|
+
test_error:
|
|
1631
|
+
# The channel names are products.
|
|
1632
|
+
logged: "Test error logged successfully. Check your notification channels (Slack, Discord, email, etc.) to confirm delivery."
|
|
1633
|
+
# %{message} is an exception message and stays verbatim.
|
|
1634
|
+
failed: "Failed to log test error: %{message}"
|
|
1635
|
+
|
|
1636
|
+
# %{version} is the running Ruby version. "Ruby 3.3+" is a literal
|
|
1637
|
+
# requirement, not prose.
|
|
1638
|
+
swallowed_requires_ruby: "Swallowed exception detection requires Ruby 3.3+ (you have %{version}). Upgrade Ruby to use this feature."
|
|
1639
|
+
|
|
1640
|
+
# JSON error bodies for the AI help endpoint. The message is rendered in
|
|
1641
|
+
# the help panel, so it is translated; the HTTP status carrying it is the
|
|
1642
|
+
# machine-readable half and is untouched.
|
|
1643
|
+
ai_help:
|
|
1644
|
+
not_configured: "AI Help is not configured"
|
|
1645
|
+
blank_question: "Question cannot be blank"
|
|
1646
|
+
# %{limit} is the character cap, formatted with delimiters.
|
|
1647
|
+
question_too_long: "Question is too long. Keep it under %{limit} characters."
|
|
1648
|
+
|
|
1649
|
+
commands:
|
|
1650
|
+
# Strings returned by commands in their result hashes. They are not shown
|
|
1651
|
+
# on their own — a controller wraps each one in a flash message — but they
|
|
1652
|
+
# are the half of that sentence the command owns.
|
|
1653
|
+
#
|
|
1654
|
+
# Exception messages and class names returned alongside these are
|
|
1655
|
+
# diagnostic output and are never translated.
|
|
1656
|
+
no_error_ids: "No error IDs provided"
|
|
1657
|
+
invalid_action: "Invalid action type"
|
|
1658
|
+
issue:
|
|
1659
|
+
not_configured: "Issue tracking is not configured"
|
|
1660
|
+
# %{url} is the existing issue's URL.
|
|
1661
|
+
already_linked: "Error already has a linked issue: %{url}"
|
|
1662
|
+
url_required: "Issue URL is required"
|
|
1663
|
+
# %{id} is the requested error's id.
|
|
1664
|
+
error_not_found: "Error not found: %{id}"
|
|
1665
|
+
# %{count} errors could not be updated in a batch operation.
|
|
1666
|
+
batch_failed:
|
|
1667
|
+
mute:
|
|
1668
|
+
one: "Failed to mute %{count} error"
|
|
1669
|
+
other: "Failed to mute %{count} errors"
|
|
1670
|
+
unmute:
|
|
1671
|
+
one: "Failed to unmute %{count} error"
|
|
1672
|
+
other: "Failed to unmute %{count} errors"
|
|
1673
|
+
resolve:
|
|
1674
|
+
one: "Failed to resolve %{count} error"
|
|
1675
|
+
other: "Failed to resolve %{count} errors"
|
|
1676
|
+
|
|
1677
|
+
mailers:
|
|
1678
|
+
# Email is the one surface where a translation lands in someone else's
|
|
1679
|
+
# mail client rather than in the dashboard. Three rules follow from that:
|
|
1680
|
+
#
|
|
1681
|
+
# 1. The .text.erb parts use red_mail_t, not red_t. red_t escapes for
|
|
1682
|
+
# HTML, so an apostrophe would arrive as "'" in plain text.
|
|
1683
|
+
# 2. Error content — class names, messages, backtraces — is diagnostic
|
|
1684
|
+
# output and is NEVER translated. Only the chrome around it is.
|
|
1685
|
+
# 3. The fixed-width ASCII layout the text parts used to have has been
|
|
1686
|
+
# relaxed. Aligning labels to a column assumes every translation is
|
|
1687
|
+
# about as long as the English, which is false (German runs ~30%
|
|
1688
|
+
# longer). The templates now put label and value on the same line
|
|
1689
|
+
# with a single space, so nothing to break.
|
|
1690
|
+
shared:
|
|
1691
|
+
# Product name. Never translated — it is what the gem is called.
|
|
1692
|
+
product_name: "Rails Error Dashboard"
|
|
1693
|
+
unknown_application: "Unknown"
|
|
1694
|
+
|
|
1695
|
+
error_alert:
|
|
1696
|
+
# Subject line. The emoji is part of the English rendering; a locale
|
|
1697
|
+
# may drop it. %{application} is the host app's name, %{error_type} is
|
|
1698
|
+
# an exception class name and %{message} is its message — both are
|
|
1699
|
+
# verbatim error content and are not translated.
|
|
1700
|
+
subject: "🚨 [%{application}] %{error_type}: %{message}"
|
|
1701
|
+
heading: "🚨 Error Alert"
|
|
1702
|
+
labels:
|
|
1703
|
+
application: "Application"
|
|
1704
|
+
error_type: "Error Type"
|
|
1705
|
+
platform: "Platform"
|
|
1706
|
+
occurred_at: "Occurred At"
|
|
1707
|
+
user_id: "User ID"
|
|
1708
|
+
ip_address: "IP Address"
|
|
1709
|
+
request_url: "Request URL"
|
|
1710
|
+
message: "Message"
|
|
1711
|
+
error_id: "Error ID"
|
|
1712
|
+
# %{count} is how many backtrace lines are shown, not how many exist.
|
|
1713
|
+
stack_trace:
|
|
1714
|
+
one: "Stack Trace (first %{count} line)"
|
|
1715
|
+
other: "Stack Trace (first %{count} lines)"
|
|
1716
|
+
view_details: "View Full Details in Dashboard"
|
|
1717
|
+
view_details_text: "View full details in the dashboard:"
|
|
1718
|
+
footer: "This is an automated error notification from %{product}."
|
|
1719
|
+
|
|
1720
|
+
digest:
|
|
1721
|
+
# %{count} new errors in the period, %{period} is the period label
|
|
1722
|
+
# below. Both interpolate into the subject, which is why the plural
|
|
1723
|
+
# form lives here rather than being assembled in the mailer.
|
|
1724
|
+
subject:
|
|
1725
|
+
one: "RED Digest — %{count} new error (%{period})"
|
|
1726
|
+
other: "RED Digest — %{count} new errors (%{period})"
|
|
1727
|
+
heading: "RED Error Digest"
|
|
1728
|
+
# Digest period labels. They appear in the subject AND the body, so
|
|
1729
|
+
# they are keys rather than literals in DigestBuilder (P4-T2 REQ-4).
|
|
1730
|
+
periods:
|
|
1731
|
+
daily: "Last 24 hours"
|
|
1732
|
+
weekly: "Last 7 days"
|
|
1733
|
+
generated_at: "Generated"
|
|
1734
|
+
summary: "Summary"
|
|
1735
|
+
stats:
|
|
1736
|
+
new_errors: "New Errors"
|
|
1737
|
+
total_occurrences: "Occurrences"
|
|
1738
|
+
total_occurrences_text: "Total Occurrences"
|
|
1739
|
+
resolved: "Resolved"
|
|
1740
|
+
unresolved: "Unresolved"
|
|
1741
|
+
critical_high: "Critical/High"
|
|
1742
|
+
resolution_rate: "Resolution Rate"
|
|
1743
|
+
comparison:
|
|
1744
|
+
heading: "vs Previous Period"
|
|
1745
|
+
# %{period} is "daily"/"weekly" — the raw period, not its label.
|
|
1746
|
+
versus: "vs previous %{period}:"
|
|
1747
|
+
current: "Current"
|
|
1748
|
+
previous: "Previous"
|
|
1749
|
+
change: "Change"
|
|
1750
|
+
# %{delta} carries its own sign, e.g. "+12" or "-3".
|
|
1751
|
+
delta:
|
|
1752
|
+
one: "%{delta} error"
|
|
1753
|
+
other: "%{delta} errors"
|
|
1754
|
+
critical_unresolved: "Critical & High Unresolved"
|
|
1755
|
+
top_errors: "Top Errors by Count"
|
|
1756
|
+
columns:
|
|
1757
|
+
severity: "Severity"
|
|
1758
|
+
error: "Error"
|
|
1759
|
+
error_type: "Error Type"
|
|
1760
|
+
count: "Count"
|
|
1761
|
+
view: "View"
|
|
1762
|
+
open_dashboard: "Open Dashboard"
|
|
1763
|
+
view_dashboard_text: "View the full dashboard:"
|
|
1764
|
+
manage_settings: "Manage digest settings"
|
|
1765
|
+
footer: "Automated digest from RED (%{product})"
|
|
1766
|
+
|
|
1767
|
+
notifications:
|
|
1768
|
+
# Slack / Discord / PagerDuty field labels and button text.
|
|
1769
|
+
#
|
|
1770
|
+
# THE RULE HERE IS NARROWER THAN ELSEWHERE. Only values a human reads get
|
|
1771
|
+
# keys. Anything a receiving system parses stays English, because
|
|
1772
|
+
# translating it breaks the integration rather than localizing it:
|
|
1773
|
+
#
|
|
1774
|
+
# * Slack block "type" values (header, section, mrkdwn, actions,
|
|
1775
|
+
# button, plain_text) and "style"
|
|
1776
|
+
# * PagerDuty "event_action" ("trigger") and "severity" ("critical") —
|
|
1777
|
+
# these are API enums, not adjectives
|
|
1778
|
+
# * Every webhook JSON key AND its values. The whole webhook payload is
|
|
1779
|
+
# machine-readable by definition; it has no keys here at all.
|
|
1780
|
+
# * Discord "inline", "color", "timestamp"
|
|
1781
|
+
#
|
|
1782
|
+
# GitHub/GitLab/Linear issue bodies are also deliberately absent: they
|
|
1783
|
+
# are dev-facing, and the maintainer reading an issue may not share the
|
|
1784
|
+
# dashboard's locale.
|
|
1785
|
+
shared:
|
|
1786
|
+
# Product name, and the name RED gives itself as a PagerDuty client.
|
|
1787
|
+
# Never translated.
|
|
1788
|
+
product_name: "Rails Error Dashboard"
|
|
1789
|
+
unknown: "Unknown"
|
|
1790
|
+
not_available: "N/A"
|
|
1791
|
+
|
|
1792
|
+
error_alert:
|
|
1793
|
+
# Slack's fallback text, shown in notification previews.
|
|
1794
|
+
fallback: "🚨 New Error Alert"
|
|
1795
|
+
heading: "🚨 Error Alert"
|
|
1796
|
+
# %{error_type} is an exception class name — verbatim, not translated.
|
|
1797
|
+
discord_title: "🚨 New Error: %{error_type}"
|
|
1798
|
+
# PagerDuty incident summary. %{application}, %{error_type} and
|
|
1799
|
+
# %{platform} are all verbatim values.
|
|
1800
|
+
pagerduty_summary: "[%{application}] Critical Error: %{error_type} in %{platform}"
|
|
1801
|
+
labels:
|
|
1802
|
+
application: "Application"
|
|
1803
|
+
error_type: "Error Type"
|
|
1804
|
+
platform: "Platform"
|
|
1805
|
+
occurred: "Occurred"
|
|
1806
|
+
message: "Message"
|
|
1807
|
+
user: "User"
|
|
1808
|
+
ip_address: "IP Address"
|
|
1809
|
+
request_url: "Request URL"
|
|
1810
|
+
occurrences: "Occurrences"
|
|
1811
|
+
controller: "Controller"
|
|
1812
|
+
action: "Action"
|
|
1813
|
+
first_seen: "First Seen"
|
|
1814
|
+
location: "Location"
|
|
1815
|
+
# %{id} is the user's database id, shown when no email is available.
|
|
1816
|
+
user_fallback: "User #%{id}"
|
|
1817
|
+
view_details: "View Details"
|
|
1818
|
+
view_in_dashboard: "View in Error Dashboard"
|
|
1819
|
+
# %{id} is the error's database id.
|
|
1820
|
+
error_id: "Error ID: %{id}"
|
|
1821
|
+
|
|
1822
|
+
baseline_alert:
|
|
1823
|
+
fallback: "🚨 Baseline Anomaly Alert"
|
|
1824
|
+
heading: "🚨 Baseline Anomaly Detected"
|
|
1825
|
+
labels:
|
|
1826
|
+
severity: "Severity"
|
|
1827
|
+
std_devs: "Standard Deviations"
|
|
1828
|
+
threshold: "Threshold"
|
|
1829
|
+
baseline_type: "Baseline Type"
|
|
1830
|
+
baseline_info: "Baseline Info"
|
|
1831
|
+
# Anomaly levels. NOT the same vocabulary as red.common.severity —
|
|
1832
|
+
# an anomaly can be "elevated", an error cannot. Previously rendered
|
|
1833
|
+
# by .upcase on the raw symbol, which is English morphology applied to
|
|
1834
|
+
# a machine value.
|
|
1835
|
+
level:
|
|
1836
|
+
critical: "CRITICAL"
|
|
1837
|
+
high: "HIGH"
|
|
1838
|
+
elevated: "ELEVATED"
|
|
1839
|
+
unknown: "UNKNOWN"
|
|
1840
|
+
# %{value} is a rounded number of standard deviations.
|
|
1841
|
+
std_devs_above: "%{value}σ above baseline"
|
|
1842
|
+
# The alert threshold, in errors. %{value} is the displayed number
|
|
1843
|
+
# (a rounded float); %{count} is its integer form and only drives
|
|
1844
|
+
# plural selection, so it must not appear in the text.
|
|
1845
|
+
threshold_errors:
|
|
1846
|
+
one: "%{value} error"
|
|
1847
|
+
other: "%{value} errors"
|
|
1848
|
+
view_in_dashboard: "View in Dashboard"
|
|
1849
|
+
|
|
1850
|
+
storm:
|
|
1851
|
+
# The single "error storm in progress" message. %{application} is the
|
|
1852
|
+
# host app's name and %{started_at} an ISO8601 timestamp.
|
|
1853
|
+
detected: "Error storm detected in %{application} at %{started_at}."
|
|
1854
|
+
# Breaker state at notification time.
|
|
1855
|
+
mode:
|
|
1856
|
+
open: "count-only mode (occurrences tallied, detail paused)"
|
|
1857
|
+
shedding: "shedding mode (context sampling active)"
|
|
1858
|
+
# %{mode} is one of the two above.
|
|
1859
|
+
engaged: "Storm protection engaged — %{mode}."
|
|
1860
|
+
suppressed: "Per-error notifications are suppressed until the storm subsides; exact counts are preserved."
|
|
1861
|
+
# %{url} links to the storms page.
|
|
1862
|
+
dashboard: "Dashboard: %{url}"
|
|
1863
|
+
|
|
1864
|
+
time:
|
|
1865
|
+
# "%{duration} ago" as a single key. Never build this by concatenating a
|
|
1866
|
+
# duration and the word "ago" — word order differs across languages, and
|
|
1867
|
+
# several put the equivalent of "ago" first.
|
|
1868
|
+
ago: "%{duration} ago"
|
|
1869
|
+
|
|
1870
|
+
# strftime patterns, one per preset in ApplicationHelper#local_time.
|
|
1871
|
+
# These are per-locale on purpose: "%B %d, %Y" is a US ordering, not
|
|
1872
|
+
# merely English words. A German locale wants "%d. %B %Y".
|
|
1873
|
+
#
|
|
1874
|
+
# The same patterns are handed to the browser via data-format and
|
|
1875
|
+
# re-rendered by formatDateTime() in the dashboard layout, so any
|
|
1876
|
+
# directive used here must be one that function supports:
|
|
1877
|
+
# %Y %y %B %b %m %d %e %A %a %H %I %M %S %p %P
|
|
1878
|
+
formats:
|
|
1879
|
+
full: "%B %d, %Y %I:%M:%S %p"
|
|
1880
|
+
short: "%m/%d %I:%M%p"
|
|
1881
|
+
date_only: "%B %d, %Y"
|
|
1882
|
+
time_only: "%I:%M:%S %p"
|
|
1883
|
+
datetime: "%b %d, %Y %H:%M"
|
|
1884
|
+
|
|
1885
|
+
health:
|
|
1886
|
+
# Table column headers repeated on more than one health page.
|
|
1887
|
+
columns:
|
|
1888
|
+
error: "Error"
|
|
1889
|
+
last_seen: "Last Seen"
|
|
1890
|
+
|
|
1891
|
+
database:
|
|
1892
|
+
title: "Database Health"
|
|
1893
|
+
|
|
1894
|
+
stats:
|
|
1895
|
+
errors_with_pool: "Errors with Pool Data"
|
|
1896
|
+
peak_utilization: "Peak Utilization"
|
|
1897
|
+
total_dead: "Total Dead"
|
|
1898
|
+
total_waiting: "Total Waiting"
|
|
1899
|
+
|
|
1900
|
+
live:
|
|
1901
|
+
title: "Live Database Health"
|
|
1902
|
+
# %{adapter} is the detected AR adapter name (e.g. "mysql2") — a
|
|
1903
|
+
# machine identifier, not translated. NOT an _html key: the adapter
|
|
1904
|
+
# name comes from ActiveRecord::Base.connection.adapter_name, and a
|
|
1905
|
+
# custom/misbehaving adapter could return anything. Escaped via the
|
|
1906
|
+
# normal red_t path; the <strong> wrapper is built in the view.
|
|
1907
|
+
non_postgresql: "Non-PostgreSQL adapter detected (%{adapter})."
|
|
1908
|
+
non_postgresql_hint: >-
|
|
1909
|
+
Live table, index, and activity stats require PostgreSQL. Connection
|
|
1910
|
+
pool and historical data are still available below.
|
|
1911
|
+
pool_size: "Pool Size"
|
|
1912
|
+
busy: "Busy"
|
|
1913
|
+
idle: "Idle"
|
|
1914
|
+
dead: "Dead"
|
|
1915
|
+
waiting: "Waiting"
|
|
1916
|
+
|
|
1917
|
+
summary:
|
|
1918
|
+
total_db_size: "Total DB Size"
|
|
1919
|
+
tables: "Tables"
|
|
1920
|
+
unused_indexes: "Unused Indexes"
|
|
1921
|
+
active_connections: "Active Connections"
|
|
1922
|
+
|
|
1923
|
+
host_tables:
|
|
1924
|
+
title: "Host App Tables"
|
|
1925
|
+
gem_tables:
|
|
1926
|
+
title: "Error Dashboard Tables"
|
|
1927
|
+
unused_indexes:
|
|
1928
|
+
title: "Unused Indexes"
|
|
1929
|
+
column_index: "Index"
|
|
1930
|
+
column_table: "Table"
|
|
1931
|
+
column_size: "Size"
|
|
1932
|
+
activity:
|
|
1933
|
+
title: "Connection Activity"
|
|
1934
|
+
# %{count} connections total, currently.
|
|
1935
|
+
total_badge: "%{count} total"
|
|
1936
|
+
# %{count} of them waiting.
|
|
1937
|
+
waiting_badge: "%{count} waiting"
|
|
1938
|
+
column_state: "State"
|
|
1939
|
+
column_count: "Count"
|
|
1940
|
+
column_waiting: "Waiting"
|
|
1941
|
+
|
|
1942
|
+
# Shared table columns for the host/gem table listings.
|
|
1943
|
+
table_columns:
|
|
1944
|
+
table: "Table"
|
|
1945
|
+
est_rows: "Est. Rows"
|
|
1946
|
+
size: "Size"
|
|
1947
|
+
seq_scans: "Seq Scans"
|
|
1948
|
+
idx_scans: "Idx Scans"
|
|
1949
|
+
dead_tuples: "Dead Tuples"
|
|
1950
|
+
last_vacuum: "Last Vacuum"
|
|
1951
|
+
never_vacuumed: "Never"
|
|
1952
|
+
|
|
1953
|
+
pool_history:
|
|
1954
|
+
title: "Connection Pool by Error"
|
|
1955
|
+
empty_title: "No Connection Pool Data Found"
|
|
1956
|
+
# %{days} is the analysis window.
|
|
1957
|
+
empty_message_html: >-
|
|
1958
|
+
No connection pool stats were detected in system health snapshots over
|
|
1959
|
+
the last %{days} days. Enable <code>enable_system_health = true</code>
|
|
1960
|
+
to capture pool stats at error time.
|
|
1961
|
+
column_error: "Error"
|
|
1962
|
+
column_error_type: "Error Type"
|
|
1963
|
+
column_utilization: "Utilization"
|
|
1964
|
+
column_busy: "Busy"
|
|
1965
|
+
column_idle: "Idle"
|
|
1966
|
+
column_dead: "Dead"
|
|
1967
|
+
column_waiting: "Waiting"
|
|
1968
|
+
column_pool_size: "Pool Size"
|
|
1969
|
+
column_last_seen: "Last Seen"
|
|
1970
|
+
tip: >-
|
|
1971
|
+
High utilization during errors may indicate connection pool
|
|
1972
|
+
exhaustion or long-running queries.
|
|
1973
|
+
guide_link: "Database Guide"
|
|
1974
|
+
|
|
1975
|
+
llm:
|
|
1976
|
+
title: "LLM Health"
|
|
1977
|
+
|
|
1978
|
+
disabled:
|
|
1979
|
+
title: "LLM Observability Not Enabled"
|
|
1980
|
+
message: "To see per-model LLM stats here, enable LLM observability and breadcrumbs."
|
|
1981
|
+
enable_in_html: "Enable in <code>config/initializers/rails_error_dashboard.rb</code>:"
|
|
1982
|
+
|
|
1983
|
+
empty:
|
|
1984
|
+
title: "No LLM Calls Detected"
|
|
1985
|
+
# %{days} is the analysis window.
|
|
1986
|
+
message: >-
|
|
1987
|
+
No LLM API calls were captured in error breadcrumbs over the last
|
|
1988
|
+
%{days} days. Instrument LLM calls in one of three ways:
|
|
1989
|
+
tab_otel: "OpenTelemetry"
|
|
1990
|
+
tab_faraday: "Faraday / RubyLLM"
|
|
1991
|
+
tab_manual: "Manual"
|
|
1992
|
+
otel_hint: "Already running an OTel collector? Drop in this gem and we'll subscribe automatically."
|
|
1993
|
+
otel_requires_html: "Requires <code>enable_llm_observability = true</code>."
|
|
1994
|
+
faraday_hint: "Using <code>ruby_llm</code>, <code>openai</code>, <code>anthropic</code>, or any Faraday-based SDK? Insert the middleware once."
|
|
1995
|
+
faraday_note: "RED auto-detects provider/model and tokens from the request/response."
|
|
1996
|
+
manual_hint: "Direct <code>Net::HTTP</code>, gRPC, local inference, or anything else — instrument by hand."
|
|
1997
|
+
manual_note_html: "Cost is auto-estimated from tokens — payload can override with <code>cost_usd_estimate:</code>."
|
|
1998
|
+
|
|
1999
|
+
stats:
|
|
2000
|
+
calls: "LLM Calls"
|
|
2001
|
+
models: "Models"
|
|
2002
|
+
# %{rate} is the error-rate percentage cited in the same stat tile.
|
|
2003
|
+
errors_with_llm: "Errors with LLM (%{rate}%)"
|
|
2004
|
+
total_cost: "Total Cost"
|
|
2005
|
+
|
|
2006
|
+
by_model:
|
|
2007
|
+
title: "Performance by Model"
|
|
2008
|
+
column_provider_model: "Provider · Model"
|
|
2009
|
+
column_calls: "Calls"
|
|
2010
|
+
column_tools: "Tools"
|
|
2011
|
+
column_avg_tokens: "Avg tokens"
|
|
2012
|
+
column_avg_latency: "Avg latency"
|
|
2013
|
+
column_error_rate: "Error rate"
|
|
2014
|
+
column_cost: "Cost"
|
|
2015
|
+
column_top_error: "Top error"
|
|
2016
|
+
column_last_seen: "Last seen"
|
|
2017
|
+
avg_tokens_in: "in"
|
|
2018
|
+
avg_tokens_out: "out"
|
|
2019
|
+
# %{count} calls in this model failed.
|
|
2020
|
+
failed_count: "%{count} failed"
|
|
2021
|
+
# Contains a literal > entity, hence _html.
|
|
2022
|
+
tip_html: >-
|
|
2023
|
+
High error rates on a model often signal quota or rate-limit issues.
|
|
2024
|
+
Slow latency (>5s) suggests provider degradation.
|
|
2025
|
+
guide_link: "Instrumentation Guide"
|
|
2026
|
+
|
|
2027
|
+
cache:
|
|
2028
|
+
title: "Cache Health"
|
|
2029
|
+
|
|
2030
|
+
empty:
|
|
2031
|
+
title: "No Cache Activity Found"
|
|
2032
|
+
# %{days} is the analysis window.
|
|
2033
|
+
message: "No cache operations were detected in error breadcrumbs over the last %{days} days."
|
|
2034
|
+
how_it_works: "How cache tracking works:"
|
|
2035
|
+
step_breadcrumbs_html: "Breadcrumbs must be enabled (<code>enable_breadcrumbs = true</code>)"
|
|
2036
|
+
step_capture: "Cache reads and writes are captured as breadcrumbs during requests that produce errors"
|
|
2037
|
+
step_hit_status: "Hit/miss status is tracked for read operations"
|
|
2038
|
+
step_sort: "This page shows cache performance per-error, sorted worst-first"
|
|
2039
|
+
|
|
2040
|
+
stats:
|
|
2041
|
+
errors_with_cache: "Errors with Cache"
|
|
2042
|
+
avg_hit_rate: "Avg Hit Rate"
|
|
2043
|
+
total_ops: "Total Cache Ops"
|
|
2044
|
+
|
|
2045
|
+
table:
|
|
2046
|
+
title: "Cache Performance by Error"
|
|
2047
|
+
column_error: "Error"
|
|
2048
|
+
column_reads: "Reads"
|
|
2049
|
+
column_writes: "Writes"
|
|
2050
|
+
column_hit_rate: "Hit Rate"
|
|
2051
|
+
column_total_time: "Total Time"
|
|
2052
|
+
column_slowest_op: "Slowest Op"
|
|
2053
|
+
column_last_seen: "Last Seen"
|
|
2054
|
+
tip: "Low hit rates may indicate cache keys that expire too quickly or aren't being set properly."
|
|
2055
|
+
guide_link: "Rails Caching Guide"
|
|
2056
|
+
|
|
2057
|
+
job:
|
|
2058
|
+
title: "Job Health"
|
|
2059
|
+
|
|
2060
|
+
empty:
|
|
2061
|
+
title: "No Job Queue Data Found"
|
|
2062
|
+
# %{days} is the analysis window.
|
|
2063
|
+
message: "No job queue stats were detected in system health snapshots over the last %{days} days."
|
|
2064
|
+
how_it_works: "How job health tracking works:"
|
|
2065
|
+
step_enable_html: "System health must be enabled (<code>enable_system_health = true</code>)"
|
|
2066
|
+
step_capture: "Job queue stats are captured automatically when Sidekiq, SolidQueue, or GoodJob is detected"
|
|
2067
|
+
step_collected: "Stats are collected per-error at the time of capture"
|
|
2068
|
+
step_sort: "This page shows job queue health per-error, sorted by failed count"
|
|
2069
|
+
|
|
2070
|
+
stats:
|
|
2071
|
+
errors_with_jobs: "Errors with Job Data"
|
|
2072
|
+
total_failed: "Total Failed Jobs"
|
|
2073
|
+
adapters_detected: "Adapters Detected"
|
|
2074
|
+
|
|
2075
|
+
table:
|
|
2076
|
+
title: "Job Queue Health by Error"
|
|
2077
|
+
column_error: "Error"
|
|
2078
|
+
column_adapter: "Adapter"
|
|
2079
|
+
column_failed: "Failed"
|
|
2080
|
+
column_queued: "Queued"
|
|
2081
|
+
column_other_stats: "Other Stats"
|
|
2082
|
+
column_last_seen: "Last Seen"
|
|
2083
|
+
# Adapter-specific queue-depth labels. The adapter name itself
|
|
2084
|
+
# (sidekiq, solid_queue, good_job) is a machine value and stays
|
|
2085
|
+
# untranslated; only the noun after the count is a key.
|
|
2086
|
+
enqueued: "enqueued"
|
|
2087
|
+
ready: "ready"
|
|
2088
|
+
queued: "queued"
|
|
2089
|
+
# Adapter-specific "other stats" line, one whole phrase per adapter
|
|
2090
|
+
# rather than assembled labels — the label:value order and the
|
|
2091
|
+
# comma-separated layout are not universal.
|
|
2092
|
+
# %{dead}, %{retry}, %{workers} are raw counts.
|
|
2093
|
+
other_stats_sidekiq: "dead: %{dead}, retry: %{retry}, workers: %{workers}"
|
|
2094
|
+
# %{claimed}, %{blocked}, %{scheduled} are raw counts.
|
|
2095
|
+
other_stats_solid_queue: "claimed: %{claimed}, blocked: %{blocked}, scheduled: %{scheduled}"
|
|
2096
|
+
# %{finished} is a raw count.
|
|
2097
|
+
other_stats_good_job: "finished: %{finished}"
|
|
2098
|
+
tip: "High failed job counts during errors may indicate job queue saturation or upstream service issues."
|
|
2099
|
+
guide_link: "Active Job Guide"
|
|
2100
|
+
|
|
2101
|
+
actioncable:
|
|
2102
|
+
title: "ActionCable Health"
|
|
2103
|
+
|
|
2104
|
+
empty:
|
|
2105
|
+
title: "No ActionCable Events Found"
|
|
2106
|
+
# %{days} is the analysis window.
|
|
2107
|
+
message: >-
|
|
2108
|
+
No ActionCable channel actions, transmissions, or subscription events
|
|
2109
|
+
were detected in error breadcrumbs over the last %{days} days.
|
|
2110
|
+
how_it_works: "How ActionCable tracking works:"
|
|
2111
|
+
step_breadcrumbs_html: "Breadcrumbs must be enabled (<code>enable_breadcrumbs = true</code>)"
|
|
2112
|
+
step_tracking_html: "ActionCable tracking must be enabled (<code>enable_actioncable_tracking = true</code>)"
|
|
2113
|
+
step_configured: "ActionCable must be configured in your app"
|
|
2114
|
+
step_capture: "Channel actions, transmissions, and subscription events are captured as breadcrumbs during requests that produce errors"
|
|
2115
|
+
|
|
2116
|
+
stats:
|
|
2117
|
+
active_channels: "Active Channels"
|
|
2118
|
+
total_events: "Total Events"
|
|
2119
|
+
subscription_rejections: "Subscription Rejections"
|
|
2120
|
+
|
|
2121
|
+
table:
|
|
2122
|
+
title: "ActionCable Events by Channel"
|
|
2123
|
+
column_channel: "Channel"
|
|
2124
|
+
column_actions: "Actions"
|
|
2125
|
+
column_transmissions: "Transmissions"
|
|
2126
|
+
column_subscriptions: "Subscriptions"
|
|
2127
|
+
column_rejections: "Rejections"
|
|
2128
|
+
column_errors: "Errors"
|
|
2129
|
+
column_last_seen: "Last Seen"
|
|
2130
|
+
tip: "ActionCable events are captured when they coincide with errors. High rejection counts may indicate authentication or authorization issues."
|
|
2131
|
+
guide_link: "ActionCable Guide"
|
|
2132
|
+
|
|
2133
|
+
activestorage:
|
|
2134
|
+
title: "ActiveStorage Health"
|
|
2135
|
+
|
|
2136
|
+
empty:
|
|
2137
|
+
title: "No ActiveStorage Events Found"
|
|
2138
|
+
# %{days} is the analysis window.
|
|
2139
|
+
message: "No ActiveStorage service operations were detected in error breadcrumbs over the last %{days} days."
|
|
2140
|
+
how_it_works: "How ActiveStorage tracking works:"
|
|
2141
|
+
step_breadcrumbs_html: "Breadcrumbs must be enabled (<code>enable_breadcrumbs = true</code>)"
|
|
2142
|
+
step_tracking_html: "ActiveStorage tracking must be enabled (<code>enable_activestorage_tracking = true</code>)"
|
|
2143
|
+
step_configured: "ActiveStorage must be configured in your app"
|
|
2144
|
+
step_capture: "Uploads, downloads, and deletes are captured as breadcrumbs during requests that produce errors"
|
|
2145
|
+
|
|
2146
|
+
stats:
|
|
2147
|
+
storage_services: "Storage Services"
|
|
2148
|
+
total_operations: "Total Operations"
|
|
2149
|
+
errors_with_storage: "Errors with Storage Ops"
|
|
2150
|
+
|
|
2151
|
+
table:
|
|
2152
|
+
title: "Storage Operations by Service"
|
|
2153
|
+
column_service: "Service"
|
|
2154
|
+
column_uploads: "Uploads"
|
|
2155
|
+
column_downloads: "Downloads"
|
|
2156
|
+
column_deletes: "Deletes"
|
|
2157
|
+
column_exists: "Exists"
|
|
2158
|
+
column_total: "Total"
|
|
2159
|
+
column_avg_duration: "Avg Duration"
|
|
2160
|
+
column_slowest: "Slowest"
|
|
2161
|
+
column_errors: "Errors"
|
|
2162
|
+
column_last_seen: "Last Seen"
|
|
2163
|
+
tip: "Slow storage operations may indicate network issues, large file sizes, or service provider throttling."
|
|
2164
|
+
guide_link: "ActiveStorage Guide"
|
|
2165
|
+
|
|
2166
|
+
analytics:
|
|
2167
|
+
# Machine values shared across more than one analytics page. Stability
|
|
2168
|
+
# (release health) and trend direction (correlation) are each their own
|
|
2169
|
+
# small enum — not the same as red.common.severity — so they get their
|
|
2170
|
+
# own lookup tables rather than being force-fit into an existing one.
|
|
2171
|
+
stability:
|
|
2172
|
+
green: "Green"
|
|
2173
|
+
yellow: "Yellow"
|
|
2174
|
+
red: "Red"
|
|
2175
|
+
|
|
2176
|
+
trend:
|
|
2177
|
+
increasing_significantly: "increasing significantly"
|
|
2178
|
+
increasing: "increasing"
|
|
2179
|
+
stable: "stable"
|
|
2180
|
+
decreasing: "decreasing"
|
|
2181
|
+
decreasing_significantly: "decreasing significantly"
|
|
2182
|
+
|
|
2183
|
+
correlation_strength:
|
|
2184
|
+
strong: "Strong"
|
|
2185
|
+
moderate: "Moderate"
|
|
2186
|
+
weak: "Weak"
|
|
2187
|
+
|
|
2188
|
+
# Shared "N days" pill labels for the analytics overview's compact
|
|
2189
|
+
# time-range selector — visually distinct from red.common.days_filter's
|
|
2190
|
+
# "7 Days" button labels, so kept separate rather than force-fit.
|
|
2191
|
+
days_pill:
|
|
2192
|
+
"7": "7d"
|
|
2193
|
+
"14": "14d"
|
|
2194
|
+
"30": "30d"
|
|
2195
|
+
"60": "60d"
|
|
2196
|
+
"90": "90d"
|
|
2197
|
+
|
|
2198
|
+
overview:
|
|
2199
|
+
title: "Analytics"
|
|
2200
|
+
|
|
2201
|
+
stats:
|
|
2202
|
+
total_errors: "Total Errors"
|
|
2203
|
+
unresolved: "Unresolved"
|
|
2204
|
+
resolution_rate: "Resolution Rate"
|
|
2205
|
+
|
|
2206
|
+
# %{days} is the analysis window, cited in both the chart heading and
|
|
2207
|
+
# the query it drives.
|
|
2208
|
+
trend_chart:
|
|
2209
|
+
title: "Error Trend (Last %{days} Days)"
|
|
2210
|
+
|
|
2211
|
+
platform_chart:
|
|
2212
|
+
title: "Errors by Platform"
|
|
2213
|
+
quick_links: "Quick Links:"
|
|
2214
|
+
|
|
2215
|
+
type_chart:
|
|
2216
|
+
title: "Top 10 Error Types"
|
|
2217
|
+
|
|
2218
|
+
hour_chart:
|
|
2219
|
+
title: "Errors by Hour of Day"
|
|
2220
|
+
|
|
2221
|
+
top_users:
|
|
2222
|
+
title: "Top 10 Affected Users"
|
|
2223
|
+
|
|
2224
|
+
type_breakdown:
|
|
2225
|
+
title: "Error Type Breakdown"
|
|
2226
|
+
# %{days} is the analysis window.
|
|
2227
|
+
subtitle: "Last %{days} days"
|
|
2228
|
+
column_rank: "Rank"
|
|
2229
|
+
column_error_type: "Error Type"
|
|
2230
|
+
column_count: "Count"
|
|
2231
|
+
column_percentage: "Percentage"
|
|
2232
|
+
column_actions: "Actions"
|
|
2233
|
+
view_errors: "View Errors"
|
|
2234
|
+
|
|
2235
|
+
recurring:
|
|
2236
|
+
title: "Recurring Issues"
|
|
2237
|
+
high_frequency_title: "High Frequency Errors"
|
|
2238
|
+
column_error_type: "Error Type"
|
|
2239
|
+
column_total_occurrences: "Total Occurrences"
|
|
2240
|
+
column_duration: "Duration"
|
|
2241
|
+
column_first_seen: "First Seen"
|
|
2242
|
+
column_last_seen: "Last Seen"
|
|
2243
|
+
column_status: "Status"
|
|
2244
|
+
# %{days} is the duration a high-frequency error has recurred over.
|
|
2245
|
+
duration_days: "%{days} days"
|
|
2246
|
+
active: "Active"
|
|
2247
|
+
inactive: "Inactive"
|
|
2248
|
+
# %{days} is the analysis window.
|
|
2249
|
+
empty_high_frequency: "No high-frequency errors found in the last %{days} days."
|
|
2250
|
+
|
|
2251
|
+
persistent_title: "Persistent Unresolved Errors"
|
|
2252
|
+
persistent_hint: "These errors have been unresolved for more than 7 days."
|
|
2253
|
+
column_message: "Message"
|
|
2254
|
+
column_platform: "Platform"
|
|
2255
|
+
column_count: "Count"
|
|
2256
|
+
column_age: "Age"
|
|
2257
|
+
column_actions: "Actions"
|
|
2258
|
+
# %{days} is how long the error has been open.
|
|
2259
|
+
age_days: "%{days} days"
|
|
2260
|
+
view: "View"
|
|
2261
|
+
|
|
2262
|
+
releases:
|
|
2263
|
+
version_chart_title: "Errors by Release Version"
|
|
2264
|
+
comparison_title: "Latest vs Previous"
|
|
2265
|
+
latest_version: "Latest Version"
|
|
2266
|
+
# %{count} errors in the latest release.
|
|
2267
|
+
latest_errors:
|
|
2268
|
+
one: "%{count} error"
|
|
2269
|
+
other: "%{count} errors"
|
|
2270
|
+
# %{count} critical errors in the latest release.
|
|
2271
|
+
latest_critical:
|
|
2272
|
+
one: "%{count} critical"
|
|
2273
|
+
other: "%{count} critical"
|
|
2274
|
+
previous_version: "Previous Version"
|
|
2275
|
+
# %{count} errors in the previous release.
|
|
2276
|
+
previous_errors:
|
|
2277
|
+
one: "%{count} error"
|
|
2278
|
+
other: "%{count} errors"
|
|
2279
|
+
# %{count} critical errors in the previous release.
|
|
2280
|
+
previous_critical:
|
|
2281
|
+
one: "%{count} critical"
|
|
2282
|
+
other: "%{count} critical"
|
|
2283
|
+
change: "Change"
|
|
2284
|
+
empty: "Not enough release data for comparison."
|
|
2285
|
+
|
|
2286
|
+
problematic_title: "Problematic Releases Detected"
|
|
2287
|
+
# %{multiplier} is the deviation threshold (e.g. "2"), an integer
|
|
2288
|
+
# from the view — not user data. Contains a literal > entity,
|
|
2289
|
+
# hence _html.
|
|
2290
|
+
problematic_hint_html: "The following releases have significantly higher error rates (>%{multiplier}x average):"
|
|
2291
|
+
# %{count} errors, %{critical} of them critical, %{deviation}% above
|
|
2292
|
+
# the average — one sentence rather than three fragments, since the
|
|
2293
|
+
# clause order is not universal.
|
|
2294
|
+
problematic_entry: >-
|
|
2295
|
+
%{count} errors (%{critical} critical, +%{deviation}% from average)
|
|
2296
|
+
|
|
2297
|
+
mttr:
|
|
2298
|
+
title: "Resolution Performance (MTTR)"
|
|
2299
|
+
overall_title: "Overall MTTR"
|
|
2300
|
+
overall_hint: "Average resolution time"
|
|
2301
|
+
fastest_title: "Fastest"
|
|
2302
|
+
fastest_hint: "Best resolution time"
|
|
2303
|
+
slowest_title: "Slowest"
|
|
2304
|
+
slowest_hint: "Longest resolution time"
|
|
2305
|
+
total_resolved_title: "Total Resolved"
|
|
2306
|
+
# %{days} is the analysis window.
|
|
2307
|
+
total_resolved_hint: "In last %{days} days"
|
|
2308
|
+
|
|
2309
|
+
by_platform_title: "MTTR by Platform"
|
|
2310
|
+
|
|
2311
|
+
by_severity_title: "MTTR by Severity"
|
|
2312
|
+
column_severity: "Severity"
|
|
2313
|
+
column_avg_time: "Average Time to Resolution"
|
|
2314
|
+
column_actions: "Actions"
|
|
2315
|
+
# %{hours} is a formatted duration.
|
|
2316
|
+
hours: "%{hours} hours"
|
|
2317
|
+
view: "View"
|
|
2318
|
+
|
|
2319
|
+
trend_title: "MTTR Trend (Weekly)"
|
|
2320
|
+
|
|
2321
|
+
correlation:
|
|
2322
|
+
title: "Error Correlation Analysis"
|
|
2323
|
+
|
|
2324
|
+
trend_analysis:
|
|
2325
|
+
title: "Trend Analysis"
|
|
2326
|
+
current_period: "Current Period"
|
|
2327
|
+
previous_period: "Previous Period"
|
|
2328
|
+
change: "Change"
|
|
2329
|
+
# %{start} and %{end} are formatted dates.
|
|
2330
|
+
period_range: "%{start} - %{end}"
|
|
2331
|
+
|
|
2332
|
+
problematic_releases:
|
|
2333
|
+
title: "Problematic Releases"
|
|
2334
|
+
hint: "Versions with more than 2x the average error rate"
|
|
2335
|
+
column_version: "Version"
|
|
2336
|
+
column_error_count: "Error Count"
|
|
2337
|
+
column_deviation: "Deviation from Avg"
|
|
2338
|
+
column_critical: "Critical Errors"
|
|
2339
|
+
column_unique_types: "Unique Error Types"
|
|
2340
|
+
column_platforms: "Platforms"
|
|
2341
|
+
column_actions: "Actions"
|
|
2342
|
+
view: "View"
|
|
2343
|
+
|
|
2344
|
+
by_version:
|
|
2345
|
+
title: "Errors by App Version"
|
|
2346
|
+
column_version: "Version"
|
|
2347
|
+
column_errors: "Errors"
|
|
2348
|
+
column_types: "Types"
|
|
2349
|
+
column_critical: "Critical"
|
|
2350
|
+
|
|
2351
|
+
by_git_sha:
|
|
2352
|
+
title: "Errors by Git SHA"
|
|
2353
|
+
column_sha: "SHA"
|
|
2354
|
+
column_errors: "Errors"
|
|
2355
|
+
column_types: "Types"
|
|
2356
|
+
column_versions: "Versions"
|
|
2357
|
+
|
|
2358
|
+
multi_error_users:
|
|
2359
|
+
title: "Users Affected by Multiple Error Types"
|
|
2360
|
+
hint: "Users experiencing 2+ different error types"
|
|
2361
|
+
# %{shown} of %{total} users are listed.
|
|
2362
|
+
truncated: "Showing %{shown} of %{total} users"
|
|
2363
|
+
|
|
2364
|
+
time_correlated:
|
|
2365
|
+
title: "Time-Correlated Errors"
|
|
2366
|
+
hint: "Error types that occur at similar times of day"
|
|
2367
|
+
column_error_type_a: "Error Type A"
|
|
2368
|
+
column_error_type_b: "Error Type B"
|
|
2369
|
+
column_correlation: "Correlation"
|
|
2370
|
+
column_strength: "Strength"
|
|
2371
|
+
# %{shown} of %{total} correlated pairs are listed.
|
|
2372
|
+
truncated: "Showing %{shown} of %{total} correlated error pairs"
|
|
2373
|
+
|
|
2374
|
+
platform_specific:
|
|
2375
|
+
title: "Platform-Specific vs Cross-Platform Errors"
|
|
2376
|
+
# %{count} occurrences of this error.
|
|
2377
|
+
occurrences:
|
|
2378
|
+
one: "%{count} occurrence"
|
|
2379
|
+
other: "%{count} occurrences"
|
|
2380
|
+
platform_specific: "Platform-Specific"
|
|
2381
|
+
cross_platform: "Cross-Platform"
|
|
2382
|
+
# %{platforms} is a comma-joined list of platform names.
|
|
2383
|
+
also_on: "Also on: %{platforms}"
|
|
2384
|
+
|
|
2385
|
+
empty:
|
|
2386
|
+
title: "Not Enough Data for Correlation Analysis"
|
|
2387
|
+
message: "Correlation analysis requires more error data to identify patterns."
|
|
2388
|
+
needed_title: "What's needed:"
|
|
2389
|
+
needed_version: "App version tracking for release correlation"
|
|
2390
|
+
needed_user: "User tracking for user correlation"
|
|
2391
|
+
needed_types: "Multiple error types for time correlation"
|
|
2392
|
+
hint: "Check back once more errors have been logged."
|
|
2393
|
+
|
|
2394
|
+
platform_comparison:
|
|
2395
|
+
title: "Platform Health Comparison"
|
|
2396
|
+
|
|
2397
|
+
empty:
|
|
2398
|
+
title: "No Platform Data Available"
|
|
2399
|
+
# %{days} is the analysis window.
|
|
2400
|
+
message: "No errors were logged for the selected time period (%{days} days)."
|
|
2401
|
+
hint: "Try selecting a longer time period or check back later."
|
|
2402
|
+
|
|
2403
|
+
health_card:
|
|
2404
|
+
healthy: "Healthy"
|
|
2405
|
+
warning: "Warning"
|
|
2406
|
+
critical: "Critical"
|
|
2407
|
+
stability_score: "Stability Score"
|
|
2408
|
+
total_errors: "Total Errors:"
|
|
2409
|
+
critical_errors: "Critical:"
|
|
2410
|
+
unresolved: "Unresolved:"
|
|
2411
|
+
resolution_rate: "Resolution Rate:"
|
|
2412
|
+
error_velocity: "Error Velocity:"
|
|
2413
|
+
# %{platform} is a platform name (iOS, Android, Web) and is not
|
|
2414
|
+
# translated.
|
|
2415
|
+
view_errors: "View %{platform} Errors"
|
|
2416
|
+
|
|
2417
|
+
error_rate_chart:
|
|
2418
|
+
title: "Error Rate by Platform"
|
|
2419
|
+
|
|
2420
|
+
daily_trend_chart:
|
|
2421
|
+
title: "Daily Error Trends"
|
|
2422
|
+
|
|
2423
|
+
severity_distribution:
|
|
2424
|
+
title: "Severity Distribution"
|
|
2425
|
+
# %{label} is a translated red.common.severity label, %{count} a raw
|
|
2426
|
+
# count — used both as the bar's title= tooltip and the number shown
|
|
2427
|
+
# inside a wide-enough bar segment.
|
|
2428
|
+
severity_count: "%{label}: %{count}"
|
|
2429
|
+
# %{critical}, %{high}, %{medium}, %{low} are raw counts; the
|
|
2430
|
+
# "Critical:"/"High:"/etc. labels come from red.common.severity, not
|
|
2431
|
+
# from this key, so they translate along with everything else. One
|
|
2432
|
+
# sentence rather than four fragments joined with "|", since the
|
|
2433
|
+
# separator and ordering are not universal.
|
|
2434
|
+
breakdown_html: "%{critical} | %{high} | %{medium} | %{low}"
|
|
2435
|
+
empty: "No errors"
|
|
2436
|
+
|
|
2437
|
+
resolution_time_chart:
|
|
2438
|
+
title: "Average Resolution Time"
|
|
2439
|
+
|
|
2440
|
+
cross_platform:
|
|
2441
|
+
title: "Cross-Platform Errors"
|
|
2442
|
+
column_error_type: "Error Type"
|
|
2443
|
+
column_platforms: "Platforms"
|
|
2444
|
+
column_total_occurrences: "Total Occurrences"
|
|
2445
|
+
column_breakdown: "Breakdown"
|
|
2446
|
+
|
|
2447
|
+
top_errors:
|
|
2448
|
+
# %{platform} is a platform name and is not translated.
|
|
2449
|
+
title: "Top Errors - %{platform}"
|
|
2450
|
+
empty: "No errors found"
|
|
2451
|
+
|
|
2452
|
+
releases:
|
|
2453
|
+
title: "Releases"
|
|
2454
|
+
|
|
2455
|
+
empty:
|
|
2456
|
+
title: "No Release Data Found"
|
|
2457
|
+
# %{days} is the analysis window.
|
|
2458
|
+
message: "No version data was detected in errors over the last %{days} days."
|
|
2459
|
+
how_to_title: "How to enable release tracking:"
|
|
2460
|
+
# %{option} is a pre-formatted <code> element naming the config
|
|
2461
|
+
# option, hence _html.
|
|
2462
|
+
step_config_html: "Set %{option} in your initializer"
|
|
2463
|
+
# %{env_var} is a pre-formatted <code> element, hence _html.
|
|
2464
|
+
step_env_html: "Or set the %{env_var} environment variable"
|
|
2465
|
+
# %{git_sha}, %{heroku}, %{render} are pre-formatted <code>
|
|
2466
|
+
# elements naming env vars, hence _html.
|
|
2467
|
+
step_git_sha_html: "Git SHA is auto-detected from %{git_sha}, %{heroku}, or %{render}"
|
|
2468
|
+
step_captured: "Version and SHA are captured automatically when errors occur"
|
|
2469
|
+
|
|
2470
|
+
summary:
|
|
2471
|
+
releases: "Releases"
|
|
2472
|
+
current_release: "Current Release"
|
|
2473
|
+
avg_errors: "Avg Errors / Release"
|
|
2474
|
+
problematic: "Problematic Releases"
|
|
2475
|
+
|
|
2476
|
+
current_card:
|
|
2477
|
+
title: "Current Release:"
|
|
2478
|
+
live_badge: "Live"
|
|
2479
|
+
errors: "Errors"
|
|
2480
|
+
error_types: "Error Types"
|
|
2481
|
+
new_errors: "New Errors"
|
|
2482
|
+
stability: "Stability"
|
|
2483
|
+
git_sha: "Git SHA"
|
|
2484
|
+
vs_previous: "vs Previous"
|
|
2485
|
+
|
|
2486
|
+
timeline:
|
|
2487
|
+
title: "Release Timeline"
|
|
2488
|
+
column_version: "Version"
|
|
2489
|
+
column_git_sha: "Git SHA"
|
|
2490
|
+
column_time_range: "Time Range"
|
|
2491
|
+
column_errors: "Errors"
|
|
2492
|
+
column_types: "Types"
|
|
2493
|
+
column_new_errors: "New Errors"
|
|
2494
|
+
column_stability: "Stability"
|
|
2495
|
+
column_vs_previous: "vs Previous"
|
|
2496
|
+
current_badge: "Current"
|
|
2497
|
+
problematic_badge: "Problematic"
|
|
2498
|
+
# %{count} additional git SHAs beyond the first shown.
|
|
2499
|
+
more_shas: "+%{count}"
|
|
2500
|
+
# %{count} new error types first seen in this release.
|
|
2501
|
+
new_count:
|
|
2502
|
+
one: "%{count} new"
|
|
2503
|
+
other: "%{count} new"
|
|
2504
|
+
|
|
2505
|
+
footer_html: >-
|
|
2506
|
+
Stability: <span class="badge bg-success">Green</span> ≤ avg errors,
|
|
2507
|
+
<span class="badge bg-warning">Yellow</span> 1-2x avg,
|
|
2508
|
+
<span class="badge bg-danger">Red</span> > 2x avg.
|
|
2509
|
+
"New" errors are error types first seen in that release.
|
|
2510
|
+
|
|
2511
|
+
user_impact:
|
|
2512
|
+
title: "User Impact"
|
|
2513
|
+
|
|
2514
|
+
empty:
|
|
2515
|
+
title: "No User Impact Data"
|
|
2516
|
+
# %{days} is the analysis window.
|
|
2517
|
+
message: "No errors with user attribution were found in the last %{days} days."
|
|
2518
|
+
how_tracked_title: "How user impact is tracked:"
|
|
2519
|
+
# %{attribute} is a pre-formatted <code> element naming the
|
|
2520
|
+
# attribute, hence _html.
|
|
2521
|
+
step_user_id_html: "Errors must have a %{attribute} associated"
|
|
2522
|
+
# %{current_attributes} and %{current_user} are pre-formatted
|
|
2523
|
+
# <code> elements, hence _html.
|
|
2524
|
+
step_auto_html: "Auto-detected via %{current_attributes} or %{current_user}"
|
|
2525
|
+
# %{option} is a pre-formatted <code> element, hence _html.
|
|
2526
|
+
step_config_html: "Or set %{option} in your initializer"
|
|
2527
|
+
|
|
2528
|
+
summary:
|
|
2529
|
+
error_types: "Error Types with Users"
|
|
2530
|
+
total_users_affected: "Total Users Affected"
|
|
2531
|
+
most_impactful: "Most Impactful Error"
|
|
2532
|
+
total_users: "Total Users (for %)"
|
|
2533
|
+
|
|
2534
|
+
table:
|
|
2535
|
+
title: "Errors Ranked by User Impact"
|
|
2536
|
+
column_rank: "#"
|
|
2537
|
+
column_error_type: "Error Type"
|
|
2538
|
+
column_unique_users: "Unique Users"
|
|
2539
|
+
column_occurrences: "Occurrences"
|
|
2540
|
+
column_impact_percentage: "User Impact %"
|
|
2541
|
+
column_severity: "Severity"
|
|
2542
|
+
column_last_seen: "Last Seen"
|
|
2543
|
+
# %{count} unique users affected.
|
|
2544
|
+
users:
|
|
2545
|
+
one: "%{count} user"
|
|
2546
|
+
other: "%{count} users"
|
|
2547
|
+
# %{count} total occurrences.
|
|
2548
|
+
occurrences:
|
|
2549
|
+
one: "%{count}x"
|
|
2550
|
+
other: "%{count}x"
|
|
2551
|
+
footer: >-
|
|
2552
|
+
Ranked by unique users affected, not occurrence count. An error
|
|
2553
|
+
hitting 1000 users once is worse than hitting 1 user 1000 times.
|
|
2554
|
+
|
|
2555
|
+
# Strings handed to inline JavaScript via window.RED_I18N (P3-T1).
|
|
2556
|
+
#
|
|
2557
|
+
# This subtree is serialized into every dashboard page, so it is kept small
|
|
2558
|
+
# on purpose — only what the browser actually re-renders belongs here.
|
|
2559
|
+
# Server-rendered strings stay in their own namespaces and never ship twice.
|
|
2560
|
+
js:
|
|
2561
|
+
# Month and day names for formatDateTime()'s %B/%b/%A/%a directives.
|
|
2562
|
+
# Arrays, not numbered keys, because the JS indexes them directly by
|
|
2563
|
+
# Date#getMonth() and Date#getDay(). Order is fixed and must not be
|
|
2564
|
+
# rearranged when translating: January first, Sunday first.
|
|
2565
|
+
months:
|
|
2566
|
+
- "January"
|
|
2567
|
+
- "February"
|
|
2568
|
+
- "March"
|
|
2569
|
+
- "April"
|
|
2570
|
+
- "May"
|
|
2571
|
+
- "June"
|
|
2572
|
+
- "July"
|
|
2573
|
+
- "August"
|
|
2574
|
+
- "September"
|
|
2575
|
+
- "October"
|
|
2576
|
+
- "November"
|
|
2577
|
+
- "December"
|
|
2578
|
+
months_short:
|
|
2579
|
+
- "Jan"
|
|
2580
|
+
- "Feb"
|
|
2581
|
+
- "Mar"
|
|
2582
|
+
- "Apr"
|
|
2583
|
+
- "May"
|
|
2584
|
+
- "Jun"
|
|
2585
|
+
- "Jul"
|
|
2586
|
+
- "Aug"
|
|
2587
|
+
- "Sep"
|
|
2588
|
+
- "Oct"
|
|
2589
|
+
- "Nov"
|
|
2590
|
+
- "Dec"
|
|
2591
|
+
days:
|
|
2592
|
+
- "Sunday"
|
|
2593
|
+
- "Monday"
|
|
2594
|
+
- "Tuesday"
|
|
2595
|
+
- "Wednesday"
|
|
2596
|
+
- "Thursday"
|
|
2597
|
+
- "Friday"
|
|
2598
|
+
- "Saturday"
|
|
2599
|
+
days_short:
|
|
2600
|
+
- "Sun"
|
|
2601
|
+
- "Mon"
|
|
2602
|
+
- "Tue"
|
|
2603
|
+
- "Wed"
|
|
2604
|
+
- "Thu"
|
|
2605
|
+
- "Fri"
|
|
2606
|
+
- "Sat"
|
|
2607
|
+
# %p / %P. Many locales use a 24-hour clock and never render these; a
|
|
2608
|
+
# translation may legitimately be an empty string.
|
|
2609
|
+
meridian:
|
|
2610
|
+
am: "AM"
|
|
2611
|
+
pm: "PM"
|
|
2612
|
+
# BCP 47 tag handed to Intl for the timezone abbreviation. Separate from
|
|
2613
|
+
# the locale name because RED's locale set and the browser's need not
|
|
2614
|
+
# agree — an unsupported tag falls back to en-US in the JS.
|
|
2615
|
+
intl_locale: "en-US"
|
|
2616
|
+
|
|
2617
|
+
# Durations for formatRelativeTime(). These are the duration ALONE —
|
|
2618
|
+
# the JS wraps the result in red.time.ago, exactly as local_time_ago
|
|
2619
|
+
# does on the server, so both sides put "ago" wherever the language
|
|
2620
|
+
# wants it rather than assuming it trails.
|
|
2621
|
+
#
|
|
2622
|
+
# Plural forms, never a ternary on "s". A locale needing more categories
|
|
2623
|
+
# than English adds them here; one supplying only :other still renders,
|
|
2624
|
+
# because the JS selector falls back to :other for any missing category.
|
|
2625
|
+
duration:
|
|
2626
|
+
seconds:
|
|
2627
|
+
one: "1 second"
|
|
2628
|
+
other: "%{count} seconds"
|
|
2629
|
+
minutes:
|
|
2630
|
+
one: "1 minute"
|
|
2631
|
+
other: "%{count} minutes"
|
|
2632
|
+
hours:
|
|
2633
|
+
one: "1 hour"
|
|
2634
|
+
other: "%{count} hours"
|
|
2635
|
+
days:
|
|
2636
|
+
one: "1 day"
|
|
2637
|
+
other: "%{count} days"
|
|
2638
|
+
months:
|
|
2639
|
+
one: "1 month"
|
|
2640
|
+
other: "%{count} months"
|
|
2641
|
+
years:
|
|
2642
|
+
one: "1 year"
|
|
2643
|
+
other: "%{count} years"
|
|
2644
|
+
|
|
2645
|
+
# Batch-selection counter on the errors index. Lives here rather than in
|
|
2646
|
+
# ui_js because the count is only known once the user ticks a box, so the
|
|
2647
|
+
# browser selects the plural form — never count + " selected", which
|
|
2648
|
+
# assumes both the word order and the agreement of English.
|
|
2649
|
+
selected:
|
|
2650
|
+
one: "1 selected"
|
|
2651
|
+
other: "%{count} selected"
|
|
2652
|
+
|
|
2653
|
+
# Timestamp tooltips and the UTC suffix on the toggled-to view.
|
|
2654
|
+
# "UTC" itself is a standard abbreviation and stays as-is.
|
|
2655
|
+
titles:
|
|
2656
|
+
local_time: "Your local time (click to see UTC)"
|
|
2657
|
+
utc_time: "UTC time (click to see local time)"
|
|
2658
|
+
exact_time: "Click to see exact time"
|
|
2659
|
+
relative_time: "Click to see relative time"
|
|
2660
|
+
|
|
2661
|
+
# Strings the SERVER renders into inline <script> blocks (P3-T3).
|
|
2662
|
+
#
|
|
2663
|
+
# Separate from red.js on purpose. red.js ships to the browser in
|
|
2664
|
+
# window.RED_I18N on every page load and must stay small; these are
|
|
2665
|
+
# resolved by red_t at render time and the browser never looks them up,
|
|
2666
|
+
# so shipping them would be pure payload with no reader.
|
|
2667
|
+
#
|
|
2668
|
+
# The test is where the lookup happens, not what the string looks like:
|
|
2669
|
+
# if JS builds the text at runtime it belongs in red.js, and if ERB writes
|
|
2670
|
+
# it into the script body it belongs here.
|
|
2671
|
+
ui_js:
|
|
2672
|
+
# Transient button and status text the JS writes (P3-T3). Rendered by
|
|
2673
|
+
# the server into the script blocks, so these are red_t at render time,
|
|
2674
|
+
# not redT lookups — the pages that use them are ERB, not static assets.
|
|
2675
|
+
toast:
|
|
2676
|
+
loading: "Loading..."
|
|
2677
|
+
copied: "Copied!"
|
|
2678
|
+
copied_to_clipboard: "Copied to clipboard!"
|
|
2679
|
+
failed: "Failed"
|
|
2680
|
+
copy_failed: "Failed to copy to clipboard"
|
|
2681
|
+
downloaded: "Downloaded!"
|
|
2682
|
+
|
|
2683
|
+
# AI help panel status line.
|
|
2684
|
+
ai_help:
|
|
2685
|
+
question_required: "Enter a question first."
|
|
2686
|
+
streaming: "Streaming..."
|
|
2687
|
+
streaming_unsupported: "Streaming is not supported by this browser."
|
|
2688
|
+
request_failed: "Request failed."
|
|
2689
|
+
|
|
2690
|
+
# Section pills on the error detail page. Short by design — they sit in a
|
|
2691
|
+
# horizontally scrolling bar, so a translation that runs long will scroll
|
|
2692
|
+
# rather than wrap. "N+1" is the standard name for the pattern and stays
|
|
2693
|
+
# as-is, like the rest of the error-domain jargon in the glossary.
|
|
2694
|
+
sections:
|
|
2695
|
+
error: "Error"
|
|
2696
|
+
request: "Request"
|
|
2697
|
+
deprecations: "Deprecations"
|
|
2698
|
+
n_plus_one: "N+1"
|
|
2699
|
+
cache: "Cache"
|
|
2700
|
+
breadcrumbs: "Breadcrumbs"
|
|
2701
|
+
similar: "Similar"
|
|
2702
|
+
co_occurring: "Co-occurring"
|
|
2703
|
+
timeline: "Timeline"
|
|
2704
|
+
issue: "Issue"
|
|
2705
|
+
discussion: "Discussion"
|
|
2706
|
+
cascades: "Cascades"
|
|
2707
|
+
patterns: "Patterns"
|
|
2708
|
+
|
|
2709
|
+
# Chart.js axis titles and series labels. Chart.js renders these itself,
|
|
2710
|
+
# so they are values in a JS config object rather than page text.
|
|
2711
|
+
charts:
|
|
2712
|
+
axis_date: "Date"
|
|
2713
|
+
axis_hour: "Hour"
|
|
2714
|
+
axis_error_type: "Error Type"
|
|
2715
|
+
axis_count: "Count"
|
|
2716
|
+
axis_number_of_errors: "Number of Errors"
|
|
2717
|
+
axis_hours: "Hours"
|
|
2718
|
+
series_total_errors: "Total Errors"
|
|
2719
|
+
series_hours_to_resolve: "Hours to Resolve"
|