meowtrics ist ein kleines Tray-Symbol, das auf den Zustand deines Rechners reagiert. Wenn die CPU heiß ist, schwitzt es. Wenn das System idlet, döst es. Wenn die Festplatte voll ist, sieht es nervös aus. Wenn ein Update verfügbar ist, schaut es erwartungsvoll. Es ist explizit kein Monitoring-Werkzeug, und das README ist deutlich darin. Du sollst nicht aus dem Augenwinkel auf das Emoji starren, um zu wissen, ob dein Server stirbt. Es ist eine Quelle gelegentlicher Heiterkeit, sonst nichts.
Es ist auch das Projekt, an dem ich am meisten gelernt habe, und das war eine Überraschung. Animierte Tray-Symbole, die sich an den Systemzustand binden, klingen nach drei Stunden Arbeit. In Wahrheit braucht es Vorsicht, damit es nicht jeden Sensor zwanzig Mal pro Sekunde liest, jede Tray-Implementierung kaputt macht oder Speicher verliert.
Der gesamte Trick liegt im Debouncing. Eine naive Implementierung liest CPU-Auslastung, Temperatur, Festplatte, Netzwerk, RAM und ein paar weitere Werte alle paar hundert Millisekunden, mappt das Tupel auf einen Stimmungs-Identifier und tauscht das Tray-Icon entsprechend aus. Das tut zwei schlechte Dinge auf einmal. Es flackert das Symbol jedes Mal, wenn die CPU für einen Moment auf 70 % springt und sofort wieder zurück. Und es weckt sysfs alle paar hundert Millisekunden auf einer ansonsten idle-en Maschine.
Stattdessen läuft jeder Sensor mit seiner eigenen Frequenz, und alle haben einen Hysterese-Schwellenwert. Die Stimmung wechselt nur, wenn der gleitende Mittelwert eine andere Stufe für einen anhaltenden Zeitraum erreicht. Eine kurze CPU-Spitze ändert nichts. Ein lang andauernder Workload schon. Das ist nicht clever, aber das Endergebnis ist ein Symbol, das interessant zu beobachten ist statt anstrengend.
Der zweite Stolperstein war die Tray-Spec selbst. Auf X11 gibt es libappindicator und SNI (StatusNotifierItem). Auf Wayland gibt es im Prinzip nur SNI, aber die Compositor-Unterstützung schwankt. KDE Plasma rendert SNI direkt. GNOME hat die Tray-Unterstützung in der Standardinstallation entfernt und braucht eine Extension. Sway, Hyprland, dwl und Co. nutzen entweder waybar oder ihre eigenen Status-Bars und sprechen mit SNI über D-Bus.
Das bedeutet, ein Tray-Symbol auszuliefern, das überall funktioniert, ist eine Übung in Tray-Backend-Detection und behutsamen Fehlermeldungen, wenn keines da ist. meowtrics versucht zur Laufzeit drei Backends in der Reihenfolge: SNI über D-Bus, libappindicator als Wrapper für ältere Shells, und ein simpler Notification-Fallback, der einfach nichts in den Tray tut, wenn keins davon erreichbar ist – statt das Programm einfach zu beerdigen.
Rust war hier weniger eine ideologische Wahl als eine pragmatische. Das Programm muss klein sein, eng integrieren, lange laufen, und es darf nichts leaken. Ein langlebiges Tray-Programm, das alle paar Sekunden Sensoren liest, ist die ideale Stelle, um eine eigene C++-Implementierung zu vergessen, sich um RAII zu kümmern und an irgendeinem System zu sterben, das ich nicht teste. Rust gibt mir hier zwei Garantien gratis: keine Use-after-free, keine wilden Ressourcenleaks, weil es keinen Faden gibt, der irgendetwas anderes tut als das, was ich modelliert habe.
Die Stimmungen sind keine fest verdrahteten Strings. Sie sind Zeilen in einer kleinen SQLite-Datenbank, die mit dem Paket ausgeliefert wird. Jede Stimmung hat einen Schlüssel, ein Pfad zu einem Symbol-Asset, einen Triggerpfad (Sensor + Schwellenwert) und einen optionalen Tooltip. Wenn du eine eigene Stimmung hinzufügen willst, fügst du eine Zeile hinzu. Wenn du dir das Verhalten ansehen willst, schaust du in die DB. Es gibt kein YAML-Schema, keinen Reload-Hook, keine Hot-Reload-Tricks. Du startest das Programm neu, und es liest die DB beim Start.
SQLite war übertrieben für etwa vierzig Zeilen Konfigurations-Daten, aber es bringt Constraints, Tooling, eine bekannte Lese-Story und null Zeilen Parser-Code. Das ist die beste Art Übertreibung.
Der Disclaimer ist nicht kosmetisch. meowtrics zeichnet keine Daten auf, schickt nichts irgendwohin und beobachtet keine Schwellen, die du behalten musst. Wenn ein Sensor zwei Stunden lang im roten Bereich war und du das Symbol gerade nicht angeschaut hast, hat sich das Symbol möglicherweise beruhigt, bevor du es bemerkt hast. Es ist Stimmung, kein Alarm. Wenn deine Festplatte gleich vollläuft, hör auf, das Emoji zu beobachten, und installier ein echtes Monitoring-System.
Spielzeuge sind oft ehrlicher mit dir, was Engineering-Aufwand wirklich bedeutet, als ernsthafte Tools. Bei einem ernsthaften Tool kannst du Komplexität hinter Constraints verstecken: das ist Compliance, das ist eine Audit-Anforderung, das ist die Art, wie unsere Kunden konfigurieren. Bei einem Spielzeug gibt es keine Constraints. Wenn du am Ende drei Tray-Backends, ein Hysterese-System und eine SQLite-DB hast, weil das Symbol sonst zucken oder krachen würde, dann lehrt dich das, wo die echte Arbeit lag. Hat sie nichts mit dem schwitzenden Katzengesicht zu tun. Sie hat damit zu tun, was zwischen einem Sensor-Wert und einem Pixel auf deinem Tray steht.
