Fix ticket ASCII art alignment, Ceph classification, and cleanup

- Fix all 9 box sections to produce exactly 80-char lines
- Add Ceph/OSD keyword detection to _get_issue_type()
- Make _get_impact_level() recognize HEALTH_WARN/HEALTH_ERR/DOWN
- Remove unused make_box() method
- Fix wrong Gitea URL (10.10.10.110 → 10.10.10.63) in README

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-02-06 19:08:56 -05:00
parent 509603843b
commit 70b02de104
2 changed files with 33 additions and 35 deletions

View File

@@ -37,7 +37,7 @@ sudo systemctl start hwmon.timer
### One liner (run as root)
```bash
curl -o /etc/systemd/system/hwmon.service http://10.10.10.110:3000/LotusGuild/hwmonDaemon/raw/branch/main/hwmon.service && curl -o /etc/systemd/system/hwmon.timer http://10.10.10.110:3000/LotusGuild/hwmonDaemon/raw/branch/main/hwmon.timer && systemctl daemon-reload && systemctl enable hwmon.timer && systemctl start hwmon.timer
curl -o /etc/systemd/system/hwmon.service http://10.10.10.63:3000/LotusGuild/hwmonDaemon/raw/branch/main/hwmon.service && curl -o /etc/systemd/system/hwmon.timer http://10.10.10.63:3000/LotusGuild/hwmonDaemon/raw/branch/main/hwmon.timer && systemctl daemon-reload && systemctl enable hwmon.timer && systemctl start hwmon.timer
```
## Manual Execution

View File

@@ -1081,12 +1081,6 @@ class SystemHealthMonitor:
return drive_details
def make_box(self, title: str, content: str, content_width: int = 70) -> str:
"""Create a formatted box with title and content."""
return f"""
┏━ {title} {'' * (content_width - len(title) - 3)}
{content}
{'' * content_width}"""
def _get_issue_type(self, issue: str) -> str:
"""Determine issue type from issue description."""
@@ -1094,6 +1088,8 @@ class SystemHealthMonitor:
return "SMART Health Issue"
elif "Drive" in issue:
return "Storage Issue"
elif any(kw in issue for kw in ["Ceph", "OSD", "ceph"]):
return "Ceph Cluster Issue"
elif "ECC" in issue:
return "Memory Issue"
elif "CPU" in issue:
@@ -1104,9 +1100,10 @@ class SystemHealthMonitor:
def _get_impact_level(self, issue: str) -> str:
"""Determine impact level from issue description."""
if "CRITICAL" in issue or "UNHEALTHY" in issue:
issue_upper = issue.upper()
if "CRITICAL" in issue_upper or "UNHEALTHY" in issue_upper or "HEALTH_ERR" in issue_upper:
return "🔴 Critical - Immediate Action Required"
elif "WARNING" in issue:
elif "WARNING" in issue_upper or "HEALTH_WARN" in issue_upper or "DOWN" in issue_upper:
return "🟡 Warning - Action Needed Soon"
return "🟢 Low - Monitor Only"
@@ -1116,17 +1113,18 @@ class SystemHealthMonitor:
timestamp = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
priority = "⚠ HIGH" if "CRITICAL" in issue else "● MEDIUM"
# Standard box width for all sections (80 chars total)
# Box width: all lines are exactly 80 chars
# border lines: ┏ + 78 ━ + ┓ = 80
# content lines: prefix + field_width + ┃ = 80
box_width = 78
field_width = 62 # Width for value fields after label
banner = f"""
{'' * box_width}
{' HARDWARE MONITORING ALERT TICKET '.center(box_width)}
{'' * box_width}
┃ Host : {hostname:<{box_width - 15}}
┃ Generated : {timestamp:<{box_width - 15}}
┃ Priority : {priority:<{box_width - 15}}
┃ Host : {hostname:<{box_width - 14}}
┃ Generated : {timestamp:<{box_width - 14}}
┃ Priority : {priority:<{box_width - 14}}
{'' * box_width}"""
issue_type = self._get_issue_type(issue)
@@ -1134,8 +1132,8 @@ class SystemHealthMonitor:
executive_summary = f"""
┏━ EXECUTIVE SUMMARY {'' * (box_width - 20)}
┃ Issue Type │ {issue_type:<{field_width}}
┃ Impact Level │ {impact_level:<{field_width}}
┃ Issue Type │ {issue_type:<60}
┃ Impact Level │ {impact_level:<60}
{'' * box_width}"""
description = banner + executive_summary
@@ -1179,12 +1177,12 @@ class SystemHealthMonitor:
description += f"""
┏━ DRIVE SPECIFICATIONS {'' * (box_width - 23)}
┃ Device Path │ {device_safe:<{field_width}}
┃ Model │ {model_safe:<{field_width}}
┃ Serial │ {serial_safe:<{field_width}}
┃ Capacity │ {capacity_safe:<{field_width}}
┃ Type │ {type_safe:<{field_width}}
┃ Firmware │ {firmware_safe:<{field_width}}
┃ Device Path │ {device_safe:<61}
┃ Model │ {model_safe:<61}
┃ Serial │ {serial_safe:<61}
┃ Capacity │ {capacity_safe:<61}
┃ Type │ {type_safe:<61}
┃ Firmware │ {firmware_safe:<61}
{'' * box_width}
"""
@@ -1202,9 +1200,9 @@ class SystemHealthMonitor:
description += f"""
┏━ DRIVE TIMELINE {'' * (box_width - 17)}
┃ Power-On Hours │ {power_on_safe:<{field_width - 4}}
┃ Last SMART Test │ {last_test_safe:<{field_width - 4}}
┃ Drive Age │ {age_safe:<{field_width - 4}}
┃ Power-On Hours │ {power_on_safe:<56}
┃ Last SMART Test │ {last_test_safe:<56}
┃ Drive Age │ {age_safe:<56}
{'' * box_width}
"""
@@ -1215,8 +1213,8 @@ class SystemHealthMonitor:
description += f"""
┏━ SMART STATUS {'' * (box_width - 15)}
┃ Status │ {smart_status_safe:<{field_width}}
┃ Temperature │ {temp_safe:<{field_width}}
┃ Status │ {smart_status_safe:<62}
┃ Temperature │ {temp_safe:<62}
{'' * box_width}
"""
@@ -1225,7 +1223,7 @@ class SystemHealthMonitor:
for attr, value in drive_info['smart_attributes'].items():
attr_safe = str(attr).replace('_', ' ') if attr else 'Unknown'
value_safe = str(value) if value is not None else 'N/A'
description += f"{attr_safe:<27}{value_safe:<{field_width - 14}}\n"
description += f"{attr_safe:<27}{value_safe:<46}\n"
description += f"{'' * box_width}\n"
if drive_info.get('partitions'):
@@ -1247,11 +1245,11 @@ class SystemHealthMonitor:
description += f"""
┏━ PARTITION: {mountpoint_display} {'' * (box_width - 14 - len(mountpoint_display))}
┃ Filesystem │ {fstype_safe:<{field_width}}
┃ Usage Meter │ {usage_meter} {usage_pct_str:>5}
┃ Total Space │ {total_space_safe:<{field_width}}
┃ Used Space │ {used_space_safe:<{field_width}}
┃ Free Space │ {free_space_safe:<{field_width}}
┃ Filesystem │ {fstype_safe:<61}
┃ Usage Meter │ {usage_meter} {usage_pct_str:>10}
┃ Total Space │ {total_space_safe:<61}
┃ Used Space │ {used_space_safe:<61}
┃ Free Space │ {free_space_safe:<61}
{'' * box_width}
"""
@@ -1260,7 +1258,7 @@ class SystemHealthMonitor:
description += f"\n┏━ FIRMWARE ALERTS {'' * (box_width - 18)}\n"
for issue_item in firmware_info['known_issues']:
issue_safe = str(issue_item) if issue_item else 'Unknown issue'
description += f"┃ ⚠ {issue_safe:<{box_width - 5}}\n"
description += f"┃ ⚠ {issue_safe:<{box_width - 4}}\n"
description += f"{'' * box_width}\n"
except Exception as e:
description += f"\nError generating drive details: {str(e)}\n"