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
+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",