From af1121e3d92179fa6330112ad19815e1ef562927 Mon Sep 17 00:00:00 2001 From: Jared Vititoe Date: Mon, 12 May 2025 15:47:14 -0400 Subject: [PATCH] Updated drive ticket creation --- hwmonDaemon.py | 185 +++++++++++++++++++++++++------------------------ 1 file changed, 94 insertions(+), 91 deletions(-) diff --git a/hwmonDaemon.py b/hwmonDaemon.py index 8d50415..f16f631 100644 --- a/hwmonDaemon.py +++ b/hwmonDaemon.py @@ -467,110 +467,113 @@ class SystemHealthMonitor: - Possible drive failure! """ - if "Drive" in issue: - device = re.search(r'/dev/[a-zA-Z0-9]+', issue).group(0) if '/dev/' in issue else None - drive_info = next((d for d in health_report['drives_health']['drives'] if d['device'] == device), None) - drive_details = self._get_drive_details(device) + if "Drive" in issue and "/dev/" in issue: + try: + device = re.search(r'/dev/[a-zA-Z0-9]+', issue).group(0) if '/dev/' in issue else None + drive_info = next((d for d in health_report['drives_health']['drives'] if d['device'] == device), None) + + if drive_info: + drive_details = self._get_drive_details(device) - smart_data = { - 'attributes': drive_info.get('smart_attributes', {}), - 'performance_metrics': drive_info.get('performance_metrics', {}), - 'last_test_date': drive_info.get('last_test_date', 'N/A') - } + smart_data = { + 'attributes': drive_info.get('smart_attributes', {}), + 'performance_metrics': drive_info.get('performance_metrics', {}), + 'last_test_date': drive_info.get('last_test_date', 'N/A') + } - power_on_hours = smart_data['attributes'].get('Power_On_Hours', 'N/A') - last_test_date = smart_data.get('last_test_date', 'N/A') - age = f"{int(power_on_hours/24/365) if isinstance(power_on_hours, (int, float)) else 'N/A'} years" if power_on_hours != 'N/A' else 'N/A' + power_on_hours = smart_data['attributes'].get('Power_On_Hours', 'N/A') + last_test_date = smart_data.get('last_test_date', 'N/A') + age = f"{int(power_on_hours/24/365) if isinstance(power_on_hours, (int, float)) else 'N/A'} years" if power_on_hours != 'N/A' else 'N/A' - description += """ -┏━ DRIVE SPECIFICATIONS ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓ -┃ Device Path │ {:<60} ┃ -┃ Model │ {:<60} ┃ -┃ Serial │ {:<60} ┃ -┃ Capacity │ {:<60} ┃ -┃ Type │ {:<60} ┃ -┃ Firmware │ {:<60} ┃ -┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛ - """.format( - device, - drive_details['model'], - drive_details['serial'], - drive_details['capacity'], - drive_details['type'], - drive_details['firmware'] - ) - - if drive_info: - perf_metrics = { - 'read_speed': drive_info.get('performance_metrics', {}).get('read_speed', 'N/A'), - 'write_speed': drive_info.get('performance_metrics', {}).get('write_speed', 'N/A'), - 'access_time': drive_info.get('performance_metrics', {}).get('access_time', 'N/A'), - 'iops': drive_info.get('performance_metrics', {}).get('iops', 'N/A') - } - - description += """ -┏━ DRIVE TIMELINE ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓ -┃ Power-On Hours │ {:<56} ┃ -┃ Last SMART Test │ {:<56} ┃ -┃ Drive Age │ {:<56} ┃ -┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛ - """.format( - f"{power_on_hours} hours" if power_on_hours != 'N/A' else 'N/A', - last_test_date, - age - ) - - for drive in health_report.get('drives_health', {}).get('drives', []): - if drive['device'] == device: description += """ -┏━ SMART STATUS ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓ -┃ Status │ {:<60} ┃ -┃ Temperature │ {:<60} ┃ -┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛ - """.format( - drive['smart_status'], - f"{drive.get('temperature')}°C" if drive.get('temperature') else 'N/A' + ┏━ DRIVE SPECIFICATIONS ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓ + ┃ Device Path │ {:<60} ┃ + ┃ Model │ {:<60} ┃ + ┃ Serial │ {:<60} ┃ + ┃ Capacity │ {:<60} ┃ + ┃ Type │ {:<60} ┃ + ┃ Firmware │ {:<60} ┃ + ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛ + """.format( + device, + drive_details.get('model', 'N/A'), + drive_details.get('serial', 'N/A'), + drive_details.get('capacity', 'N/A'), + drive_details.get('type', 'N/A'), + drive_details.get('firmware', 'N/A') + ) + + if drive_info: + perf_metrics = { + 'read_speed': drive_info.get('performance_metrics', {}).get('read_speed', 'N/A'), + 'write_speed': drive_info.get('performance_metrics', {}).get('write_speed', 'N/A'), + 'access_time': drive_info.get('performance_metrics', {}).get('access_time', 'N/A'), + 'iops': drive_info.get('performance_metrics', {}).get('iops', 'N/A') + } + + description += """ + ┏━ DRIVE TIMELINE ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓ + ┃ Power-On Hours │ {:<56} ┃ + ┃ Last SMART Test │ {:<56} ┃ + ┃ Drive Age │ {:<56} ┃ + ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛ + """.format( + f"{power_on_hours} hours" if power_on_hours != 'N/A' else 'N/A', + last_test_date, + age + ) + + description += """ + ┏━ SMART STATUS ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓ + ┃ Status │ {:<60} ┃ + ┃ Temperature │ {:<60} ┃ + ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛ + """.format( + drive_info.get('smart_status', 'N/A'), + f"{drive_info.get('temperature')}°C" if drive_info.get('temperature') else 'N/A' ) - if drive.get('smart_attributes'): + if drive_info.get('smart_attributes'): description += "\n┏━ SMART ATTRIBUTES " + "━" * 48 + "┓\n" - for attr, value in drive['smart_attributes'].items(): + for attr, value in drive_info['smart_attributes'].items(): description += "┃ {:<25} │ {:<37} ┃\n".format( attr.replace('_', ' '), value ) description += "┗" + "━" * 71 + "┛\n" - if drive.get('partitions'): - for partition in drive['partitions']: - usage_percent = partition['usage_percent'] - blocks = int(usage_percent / 5) # 20 blocks total = 100% - usage_meter = '█' * blocks + '░' * (20 - blocks) - - description += """ -┏━ PARTITION [{:<60}] ━┓ -┃ Filesystem │ {:<60} ┃ -┃ Usage Meter │ [{:<58}] ┃ -┃ Total Space │ {:<60} ┃ -┃ Used Space │ {:<60} ┃ -┃ Free Space │ {:<60} ┃ -┃ Usage │ {:<60} ┃ -┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛ - """.format( - partition['mountpoint'], - partition['fstype'], - usage_meter, - partition['total_space'], - partition['used_space'], - partition['free_space'], - f"{usage_percent}%" - ) + if drive_info.get('partitions'): + for partition in drive_info['partitions']: + usage_percent = partition.get('usage_percent', 0) + blocks = int(usage_percent / 5) # 20 blocks total = 100% + usage_meter = '█' * blocks + '░' * (20 - blocks) + + description += """ + ┏━ PARTITION [{:<60}] ━┓ + ┃ Filesystem │ {:<60} ┃ + ┃ Usage Meter │ [{:<58}] ┃ + ┃ Total Space │ {:<60} ┃ + ┃ Used Space │ {:<60} ┃ + ┃ Free Space │ {:<60} ┃ + ┃ Usage │ {:<60} ┃ + ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛ + """.format( + partition.get('mountpoint', 'N/A'), + partition.get('fstype', 'N/A'), + usage_meter, + partition.get('total_space', 'N/A'), + partition.get('used_space', 'N/A'), + partition.get('free_space', 'N/A'), + f"{usage_percent}%" + ) - firmware_info = self._check_disk_firmware(device) - if firmware_info['is_problematic']: - description += "\n┏━ FIRMWARE ALERTS " + "━" * 48 + "┓\n" - for issue in firmware_info['known_issues']: - description += "┃ ⚠ {:<67} ┃\n".format(issue) - description += "┗" + "━" * 71 + "┛\n" + firmware_info = self._check_disk_firmware(device) + if firmware_info['is_problematic']: + description += "\n┏━ FIRMWARE ALERTS " + "━" * 48 + "┓\n" + for issue in firmware_info['known_issues']: + description += "┃ ⚠ {:<67} ┃\n".format(issue) + description += "┗" + "━" * 71 + "┛\n" + except Exception as e: + description += f"\nError generating drive details: {str(e)}\n" if "Temperature" in issue: description += """