Update notification service

This commit is contained in:
MacRimi
2026-03-05 19:49:35 +01:00
parent 5af51096d8
commit 260870ad8a
3 changed files with 50 additions and 6 deletions

View File

@@ -2432,9 +2432,30 @@ def api_storage_summary():
return jsonify(storage_data)
except Exception as e:
return jsonify({'error': str(e)}), 500
# END OF CHANGE FOR /api/storage/summary
# END OF CHANGE FOR /api/storage/summary
def get_interface_type(interface_name):
@app.route('/api/storage/observations', methods=['GET'])
@require_auth
def api_storage_observations():
"""Get disk observations (permanent error history) for a specific disk or all disks."""
try:
device = request.args.get('device', '')
serial = request.args.get('serial', '')
# Strip /dev/ prefix if present
if device.startswith('/dev/'):
device = device[5:]
observations = health_persistence.get_disk_observations(
device_name=device or None,
serial=serial or None
)
return jsonify({'observations': observations})
except Exception as e:
return jsonify({'observations': [], 'error': str(e)}), 500
def get_interface_type(interface_name):
"""Detect the type of network interface"""
try:
# Skip loopback
@@ -6515,6 +6536,21 @@ def api_health():
'version': '1.0.2'
})
@app.route('/api/health/acknowledge', methods=['POST'])
@require_auth
def api_health_acknowledge():
"""Acknowledge/dismiss a health error by error_key."""
try:
data = request.get_json()
error_key = data.get('error_key', '')
if not error_key:
return jsonify({'error': 'error_key is required'}), 400
result = health_persistence.acknowledge_error(error_key)
return jsonify({'success': True, 'result': result})
except Exception as e:
return jsonify({'error': str(e)}), 500
@app.route('/api/prometheus', methods=['GET'])
@require_auth
def api_prometheus():

View File

@@ -973,10 +973,10 @@ class HealthMonitor:
zfs_error_key = f'zfs_pool_{real_pool}'
zfs_reason = f'ZFS pool {real_pool}: {pool_info["reason"]}'
try:
if not health_persistence.is_error_active(zfs_error_key, category='zfs'):
if not health_persistence.is_error_active(zfs_error_key, category='disks'):
health_persistence.record_error(
error_key=zfs_error_key,
category='zfs',
category='disks',
severity=pool_info.get('status', 'WARNING'),
reason=zfs_reason,
details={
@@ -1102,7 +1102,12 @@ class HealthMonitor:
for sl in (issue.get('smart_lines') or [])[:3]:
smart_details_parts.append(sl)
detail_text = '; '.join(smart_details_parts[:3]) if smart_details_parts else 'SMART warning in journal'
checks['smart_health'] = {'status': 'WARNING', 'detail': detail_text}
checks['smart_health'] = {
'status': 'WARNING',
'detail': detail_text,
'dismissable': True,
'error_key': 'smart_health_journal',
}
else:
checks['smart_health'] = {'status': 'OK', 'detail': 'No SMART warnings in journal'}
if self.capabilities.get('has_zfs') and 'zfs_pools' not in checks:
@@ -3907,6 +3912,8 @@ class HealthMonitor:
'io_lines': unique_io[:5],
'sample': sample_line,
'source': 'journal',
'dismissable': True,
'error_key': f'smart_{disk_name}',
}
# Record as disk observation for the permanent history

View File

@@ -480,7 +480,8 @@ class HealthPersistence:
('updates', 'pending_updates'), ('updates', 'kernel_pve'),
('security', 'security_'),
('pve_services', 'pve_service_'), ('vms', 'vmct_'), ('vms', 'vm_'), ('vms', 'ct_'),
('disks', 'disk_'), ('logs', 'log_'), ('network', 'net_'),
('disks', 'disk_'), ('disks', 'smart_'), ('disks', 'zfs_pool_'),
('logs', 'log_'), ('network', 'net_'),
('temperature', 'temp_')]:
if error_key == prefix or error_key.startswith(prefix):
category = cat