Prédire l'épuisement de l'espace disque dans qtile avec un widget personnalisé
Les développeurs de qtile peuvent intégrer le widget DiskSpaceAlert pour anticiper l'épuisement de l'espace disque à l’aide d’une régression linéaire. Il analyse les tendances de l’espace libre sur les systèmes de fichiers réels — en excluant les systèmes virtuels — et déclenche une alerte lorsque la limite zéro est atteinte dans les 24 heures. Le widget hérite de InLoopPollText, qui interroge toutes les 5 secondes via /proc/mounts et os.statvfs, en utilisant un deque pour conserver les données historiques.
Le code fonctionne sans dépendance externe, ce qui le rend idéal pour les environnements de bureau sans Prometheus. La première alerte s’est déclenchée sur /tmp (ext2 sur zram, 16 Go) : des logs en arrière-plan ont rempli la partition, provoquant une panne silencieuse d’un outil Bash.
Filtrer les points de montage
Le widget ignore les systèmes de fichiers virtuels et les chemins système, se concentrant uniquement sur les disques physiques. Des constantes définissent les exclusions :
DISK_SPACE_SKIP_FS = {
'sysfs', 'proc', 'devtmpfs', 'devpts', 'tmpfs', 'securityfs',
'cgroup', 'cgroup2', 'pstore', 'debugfs', 'hugetlbfs', 'mqueue',
'configfs', 'fusectl', 'efivarfs', 'binfmt_misc', 'autofs',
'fuse.portal', 'nsfs', 'tracefs', 'bpf', 'ramfs', 'rpc_pipefs',
'nfsd', 'overlay', 'fuse.gvfsd-fuse',
}
DISK_SPACE_SKIP_PREFIXES = ('/sys/', '/proc/', '/dev/', '/run/')
La fonction get_mountpoints lit /proc/mounts, en ignorant les entrées par type de système de fichiers ou préfixe de chemin. Pour tmpfs sur zram, le filtre n’est pas appliqué — permettant ainsi de détecter des scénarios critiques.
def get_mountpoints(self):
mounts = []
try:
with open('/proc/mounts') as f:
for line in f:
parts = line.split()
if len(parts) < 3:
continue
mountpoint, fstype = parts[1], parts[2]
if fstype in DISK_SPACE_SKIP_FS:
continue
if any(mountpoint.startswith(p)
for p in DISK_SPACE_SKIP_PREFIXES):
continue
mounts.append(mountpoint)
except OSError:
pass
return mounts
Régression linéaire pour la prédiction
La prédiction utilise la méthode des moindres carrés ordinaires (OLS) sans NumPy. Elle modélise l’espace libre selon y(t) = a·t + b, calculant le temps jusqu’à y=0. Les formules sont :
a = (n∑(t_i y_i) - ∑t_i ∑y_i) / (n∑t_i² - (∑t_i)²)b = (∑y_i - a ∑t_i) / n
Temps restant : -b / a moins la durée écoulée. Si la pente ≥ 0 ou seconds_left ≤ 0, retourne None.
@staticmethod
def _predict_exhaustion(history, now):
n = len(history)
t = [h[0] - history[0][0] for h in history]
y = [h[1] for h in history]
sum_t = sum(t)
sum_y = sum(y)
sum_tt = sum(ti * ti for ti in t)
sum_ty = sum(ti * yi for ti, yi in zip(t, y))
denom = n * sum_tt - sum_t * sum_t
if denom == 0:
return None
slope = (n * sum_ty - sum_t * sum_y) / denom
intercept = (sum_y - slope * sum_t) / n
if slope >= 0:
return None
time_to_zero = -intercept / slope
elapsed = now - history[0][0]
seconds_left = time_to_zero - elapsed
if seconds_left > 0:
return seconds_left / 3600
return None
Une fenêtre glissante de maxlen=120 (10 minutes à intervalles de 5 secondes) atténue les bruits causés par les fichiers temporaires.
Indication de couleur et logique d’alerte
Deux niveaux d’alerte :
- Rouge (#FF0000) : consommation active (espace libre en baisse au cours des 30 dernières secondes) ou moins de 10 % disponible.
- Orange (#FF8800) : épuisement prévu dans les 24 heures, mais la tendance s’est stabilisée.
La méthode _set_color met à jour self.foreground et self.layout.colour efficacement, évitant les redessins inutiles. Texte de l’étiquette : DISK /tmp : 8%libre, 2h restantes.
def _set_color(self, color):
self.foreground = color
if self.layout:
self.layout.colour = color
L'historique est vidé pour les systèmes de fichiers démontés.
— Editorial Team
Aucun commentaire pour le moment.