From 90346a2da15eeebfac1e680af4057bc360f51c69 Mon Sep 17 00:00:00 2001 From: Jared Vititoe Date: Tue, 10 Feb 2026 13:00:50 -0500 Subject: [PATCH] Replace fragile column-index LXC storage parsing with regex Use regex pattern matching instead of split()[N] indexing for parsing pct df output. This is more robust against variations in column formatting and whitespace. Resolves https://code.lotusguild.org/LotusGuild/hwmonDaemon/issues/11 Co-Authored-By: Claude Opus 4.6 --- hwmonDaemon.py | 46 ++++++++++++++++++++++++++-------------------- 1 file changed, 26 insertions(+), 20 deletions(-) diff --git a/hwmonDaemon.py b/hwmonDaemon.py index bd30e19..3753229 100644 --- a/hwmonDaemon.py +++ b/hwmonDaemon.py @@ -3454,32 +3454,38 @@ class SystemHealthMonitor: if not fs_line.strip() or 'MP' in fs_line: continue - # Fix: Use fs_line instead of line, and columns consistently - columns = fs_line.split() - - if len(columns) >= 6: - try: - # Skip excluded mounts by checking the first column - if columns[0].startswith('appPool:') or '/mnt/pve/mediaf' in columns[1]: + # Parse df output using regex for reliable column extraction + match = re.match( + r'(\S+)\s+(\S+)\s+(\S+)\s+(\S+)\s+(\S+)\s+(\d+\.?\d*)%?\s+(.*)', + fs_line.strip() + ) + if not match: + logger.debug(f"Could not parse filesystem line: {fs_line}") + continue + + pool, device_col, total_str, used_str, avail_str, percent_str, mountpoint = match.groups() + + try: + # Skip excluded mounts + if pool.startswith('appPool:') or '/mnt/pve/mediaf' in device_col: continue - - # Get the mountpoint (last column) - mountpoint = columns[-1] - + + mountpoint = mountpoint.strip() + # Skip excluded mountpoints if self._is_excluded_mount(mountpoint): logger.debug(f"Skipping excluded mount: {mountpoint}") continue - - # Parse size values safely - use correct column indices - total_space = self._parse_size(columns[2]) # 3rd column - used_space = self._parse_size(columns[3]) # 4th column - available_space = self._parse_size(columns[4]) # 5th column - - # Parse percentage safely + + # Parse size values from named regex groups + total_space = self._parse_size(total_str) + used_space = self._parse_size(used_str) + available_space = self._parse_size(avail_str) + + # Parse percentage from regex group try: - usage_percent = float(columns[5].rstrip('%')) # 6th column - except (ValueError, IndexError): + usage_percent = float(percent_str) + except ValueError: # Calculate percentage if parsing fails usage_percent = (used_space / total_space * 100) if total_space > 0 else 0