mirror of
https://github.com/MacRimi/ProxMenux.git
synced 2026-04-30 19:36:24 +00:00
Update health monitor
This commit is contained in:
@@ -179,6 +179,66 @@ def get_full_health():
|
|||||||
except Exception as e:
|
except Exception as e:
|
||||||
return jsonify({'error': str(e)}), 500
|
return jsonify({'error': str(e)}), 500
|
||||||
|
|
||||||
|
@health_bp.route('/api/health/cleanup-orphans', methods=['POST'])
|
||||||
|
def cleanup_orphan_errors():
|
||||||
|
"""
|
||||||
|
Clean up errors for devices that no longer exist in the system.
|
||||||
|
Useful when USB drives or temporary devices are disconnected.
|
||||||
|
"""
|
||||||
|
import os
|
||||||
|
import re
|
||||||
|
try:
|
||||||
|
cleaned = []
|
||||||
|
# Get all active disk errors
|
||||||
|
disk_errors = health_persistence.get_active_errors(category='disks')
|
||||||
|
|
||||||
|
for err in disk_errors:
|
||||||
|
err_key = err.get('error_key', '')
|
||||||
|
details = err.get('details', {})
|
||||||
|
if isinstance(details, str):
|
||||||
|
try:
|
||||||
|
import json as _json
|
||||||
|
details = _json.loads(details)
|
||||||
|
except Exception:
|
||||||
|
details = {}
|
||||||
|
|
||||||
|
device = details.get('device', '')
|
||||||
|
base_disk = details.get('disk', '')
|
||||||
|
|
||||||
|
# Try to determine the device path
|
||||||
|
dev_path = None
|
||||||
|
if base_disk:
|
||||||
|
dev_path = f'/dev/{base_disk}'
|
||||||
|
elif device:
|
||||||
|
dev_path = device if device.startswith('/dev/') else f'/dev/{device}'
|
||||||
|
elif err_key.startswith('disk_'):
|
||||||
|
# Extract device from error_key
|
||||||
|
dev_name = err_key.replace('disk_fs_', '').replace('disk_', '')
|
||||||
|
dev_name = re.sub(r'_.*$', '', dev_name) # Remove suffix
|
||||||
|
if dev_name:
|
||||||
|
dev_path = f'/dev/{dev_name}'
|
||||||
|
|
||||||
|
if dev_path:
|
||||||
|
# Also check base disk (remove partition number)
|
||||||
|
base_path = re.sub(r'\d+$', '', dev_path)
|
||||||
|
if not os.path.exists(dev_path) and not os.path.exists(base_path):
|
||||||
|
health_persistence.resolve_error(err_key, 'Device no longer present (manual cleanup)')
|
||||||
|
cleaned.append({'error_key': err_key, 'device': dev_path})
|
||||||
|
|
||||||
|
# Also cleanup disk_observations for non-existent devices
|
||||||
|
try:
|
||||||
|
health_persistence.cleanup_orphan_observations()
|
||||||
|
except Exception:
|
||||||
|
pass
|
||||||
|
|
||||||
|
return jsonify({
|
||||||
|
'success': True,
|
||||||
|
'cleaned_count': len(cleaned),
|
||||||
|
'cleaned_errors': cleaned
|
||||||
|
})
|
||||||
|
except Exception as e:
|
||||||
|
return jsonify({'error': str(e)}), 500
|
||||||
|
|
||||||
@health_bp.route('/api/health/pending-notifications', methods=['GET'])
|
@health_bp.route('/api/health/pending-notifications', methods=['GET'])
|
||||||
def get_pending_notifications():
|
def get_pending_notifications():
|
||||||
"""
|
"""
|
||||||
|
|||||||
@@ -2093,7 +2093,21 @@ class HealthMonitor:
|
|||||||
# Check if the device still exists. If not, auto-resolve
|
# Check if the device still exists. If not, auto-resolve
|
||||||
# the error -- it was likely a disconnected USB/temp device.
|
# the error -- it was likely a disconnected USB/temp device.
|
||||||
dev_path = f'/dev/{base_disk}' if base_disk else device
|
dev_path = f'/dev/{base_disk}' if base_disk else device
|
||||||
if not os.path.exists(dev_path):
|
|
||||||
|
# Also extract base disk from partition (e.g., sdb1 -> sdb)
|
||||||
|
if not base_disk and device:
|
||||||
|
# Remove /dev/ prefix and partition number
|
||||||
|
dev_name = device.replace('/dev/', '')
|
||||||
|
base_disk = re.sub(r'\d+$', '', dev_name) # sdb1 -> sdb
|
||||||
|
if base_disk:
|
||||||
|
dev_path = f'/dev/{base_disk}'
|
||||||
|
|
||||||
|
# Check both the specific device and the base disk
|
||||||
|
device_exists = os.path.exists(dev_path)
|
||||||
|
if not device_exists and device and device != dev_path:
|
||||||
|
device_exists = os.path.exists(device)
|
||||||
|
|
||||||
|
if not device_exists:
|
||||||
health_persistence.resolve_error(
|
health_persistence.resolve_error(
|
||||||
err_key, 'Device no longer present in system')
|
err_key, 'Device no longer present in system')
|
||||||
continue
|
continue
|
||||||
|
|||||||
@@ -1765,6 +1765,47 @@ class HealthPersistence:
|
|||||||
except Exception as e:
|
except Exception as e:
|
||||||
print(f"[HealthPersistence] Error marking removed disks: {e}")
|
print(f"[HealthPersistence] Error marking removed disks: {e}")
|
||||||
|
|
||||||
|
def cleanup_orphan_observations(self):
|
||||||
|
"""
|
||||||
|
Dismiss observations for devices that no longer exist in /dev/.
|
||||||
|
Useful for cleaning up after USB drives or temporary devices are disconnected.
|
||||||
|
"""
|
||||||
|
import os
|
||||||
|
import re
|
||||||
|
try:
|
||||||
|
conn = self._get_conn()
|
||||||
|
cursor = conn.cursor()
|
||||||
|
|
||||||
|
# Get all active (non-dismissed) observations
|
||||||
|
cursor.execute('''
|
||||||
|
SELECT id, device_name, serial FROM disk_observations
|
||||||
|
WHERE dismissed = 0
|
||||||
|
''')
|
||||||
|
observations = cursor.fetchall()
|
||||||
|
|
||||||
|
dismissed_count = 0
|
||||||
|
for obs_id, device_name, serial in observations:
|
||||||
|
# Check if device exists
|
||||||
|
dev_path = f'/dev/{device_name}'
|
||||||
|
# Also check base device (remove partition number)
|
||||||
|
base_dev = re.sub(r'\d+$', '', device_name)
|
||||||
|
base_path = f'/dev/{base_dev}'
|
||||||
|
|
||||||
|
if not os.path.exists(dev_path) and not os.path.exists(base_path):
|
||||||
|
cursor.execute('''
|
||||||
|
UPDATE disk_observations SET dismissed = 1
|
||||||
|
WHERE id = ?
|
||||||
|
''', (obs_id,))
|
||||||
|
dismissed_count += 1
|
||||||
|
|
||||||
|
conn.commit()
|
||||||
|
conn.close()
|
||||||
|
print(f"[HealthPersistence] Cleaned up {dismissed_count} orphan observations")
|
||||||
|
return dismissed_count
|
||||||
|
except Exception as e:
|
||||||
|
print(f"[HealthPersistence] Error cleaning orphan observations: {e}")
|
||||||
|
return 0
|
||||||
|
|
||||||
|
|
||||||
# Global instance
|
# Global instance
|
||||||
health_persistence = HealthPersistence()
|
health_persistence = HealthPersistence()
|
||||||
|
|||||||
Reference in New Issue
Block a user