i18n: localize health degradation alerts

This commit is contained in:
VAIO73
2026-09-17 13:31:58 +02:00
parent 2f8197eb97
commit 10a69947dc
11 changed files with 111 additions and 8 deletions
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+1
View File
@@ -1531,6 +1531,7 @@ def _health_collector_loop():
'count': str(len(degraded)),
'title': title,
'reason': body,
'health_degraded': {'categories': degraded},
'_journal_context': journal_context,
},
source='health_monitor',
@@ -663,6 +663,75 @@ def _format_app_update_available(data: Dict[str, Any],
return title, "\n\n".join([lead, *sections])
_CPU_SUSTAINED_REASON = re.compile(
r'^CPU >(?P<threshold>[0-9.]+)% sustained for (?P<duration>\d+)s$'
)
def _format_health_degraded(data: Dict[str, Any],
language: str = 'en') -> Tuple[str, str]:
"""Render Monitor-generated health degradations in the chosen locale."""
payload = data.get('health_degraded')
if not isinstance(payload, dict):
return str(data.get('title') or ''), str(data.get('reason') or '')
categories = payload.get('categories')
if not isinstance(categories, list) or not categories:
return str(data.get('title') or ''), str(data.get('reason') or '')
def category_label(item: Dict[str, Any]) -> str:
category = str(item.get('key') or '')
return (
runtime_message(f'healthDegraded.categories.{category}', language)
or str(item.get('category') or category)
)
def severity_label(item: Dict[str, Any]) -> str:
severity = str(item.get('status') or data.get('severity') or 'WARNING').lower()
return (
runtime_message(f'healthDegraded.severity.{severity}', language)
or str(item.get('status') or data.get('severity') or 'WARNING')
)
def localized_reason(item: Dict[str, Any]) -> str:
reason = str(item.get('reason') or '')
if str(item.get('key') or '') == 'cpu':
match = _CPU_SUSTAINED_REASON.fullmatch(reason)
if match:
return runtime_message(
'healthDegraded.reasons.cpuSustained', language,
threshold=match.group('threshold'), duration=match.group('duration'),
) or reason
return reason
hostname = str(data.get('hostname') or _get_hostname())
if len(categories) == 1:
item = categories[0] if isinstance(categories[0], dict) else {}
title = runtime_message(
'healthDegraded.singleTitle', language,
hostname=hostname, severity=severity_label(item), category=category_label(item),
)
entity = str(item.get('entity') or '').strip()
if entity:
title = f'{title}{entity}'
return title, localized_reason(item)
title = runtime_message(
'healthDegraded.multipleTitle', language,
hostname=hostname, count=len(categories),
)
lines = []
for item in categories:
if not isinstance(item, dict):
continue
lines.append(runtime_message(
'healthDegraded.multipleLine', language,
severity=severity_label(item), category=category_label(item),
reason=localized_reason(item),
))
return title, '\n'.join(line for line in lines if line)
# ─── Severity Icons ──────────────────────────────────────────────
SEVERITY_ICONS = {
@@ -735,6 +804,7 @@ TEMPLATES = {
'label': 'Health check degraded',
'group': 'health',
'default_enabled': True,
'formatter': '_format_health_degraded',
},
# ── VM / CT events ──
@@ -294,6 +294,38 @@ class RuntimeCatalogTests(unittest.TestCase):
self.assertIn("Vitajte", body)
self.assertIn("profilovú fotografiu", caption)
def test_monitor_generated_cpu_health_degradation_is_slovak(self):
data = {
"hostname": "HomeLAB_2",
"severity": "CRITICAL",
"title": "HomeLAB_2: Health CRITICAL - CPU Usage & Temperature",
"reason": "CPU >95.0% sustained for 296s",
"health_degraded": {
"categories": [{
"key": "cpu",
"status": "CRITICAL",
"reason": "CPU >95.0% sustained for 296s",
"entity": "",
}],
},
}
rendered = notification_templates.render_template(
"health_degraded", data, language="sk",
)
self.assertEqual(
rendered["title"],
"HomeLAB_2: Kritický stav Využitie CPU a teplota",
)
self.assertEqual(rendered["body"], "CPU je nad 95.0 % už 296 s.")
self.assertNotIn("Health CRITICAL", rendered["title"])
self.assertNotIn("sustained", rendered["body"])
enriched_title, _body = notification_templates.enrich_with_emojis(
"health_degraded", rendered["title"], rendered["body"],
{**data, "_notification_language": "sk"},
)
self.assertTrue(enriched_title.startswith("⚠️ "))
def test_batch_app_updates_render_from_every_runtime_catalog(self):
data = {
"hostname": "HOST-ŽILINA",