Artikel

Statistiken, die nur ich sehe

Nicht für Nutzer, sondern für den Betrieb: Wie viele Befehle laufen, wie lange dauert das, wo sind Fehlerhäufungen. Eine Übersicht für eine einzige Person — und was sie beantworten muss.

BlackZackBlackzack

990 Wörter · 5 Min. Lesezeit

  • daten
  • betrieb
  • werkzeuge

Vor drei Jahren habe ich eine Statistikseite für Nutzer gebaut, die niemand benutzt hat. Diese hier ist das Gegenteil: Sie hat genau einen Nutzer, und der bin ich.

Der Anlass war eine Frage, die ich nicht beantworten konnte: Ist der Bot in den letzten Wochen langsamer geworden? Mein Gefühl sagte ja. Meine Daten sagten gar nichts, weil ich keine hatte.

Was ich messe

Bewusst wenig, und jedes davon beantwortet eine Frage, die ich tatsächlich habe.

Befehlsaufrufe pro Stunde, nach Befehl. Beantwortet: Was wird benutzt, und gibt es plötzliche Ausschläge?

Dauer je Befehl, als Mittelwert und als oberer Bereich. Der Mittelwert allein ist irreführend — wenn neun Aufrufe zwanzig Millisekunden dauern und einer vier Sekunden, sieht der Durchschnitt harmlos aus. Interessant ist der langsamste Zehntel.

Fehler je Befehl. Nicht die Fehlermeldungen selbst, sondern die Zahl. Eine Häufung ist das Signal.

Datenbankdauer je Vorgang. Damit sehe ich, ob eine Verlangsamung von der Datenbank kommt oder von etwas anderem.

Ereignisverzögerung. Zeit zwischen Eingang eines Ereignisses und Beginn der Verarbeitung. Der Wert, der als Erster steigt, wenn ein Prozess überlastet ist.

Wie ich es speichere

Nicht als Einzelereignisse. Das war die Lehre aus der alten Statistikseite: Rohdaten aufzubewahren ist teuer, langsam und datenschutzrechtlich unangenehm.

Stattdessen Verdichtung im Speicher, einmal pro Minute geschrieben:

CREATE TABLE metrik_minute (
  zeitpunkt   DATETIME NOT NULL,
  bereich     VARCHAR(40) NOT NULL,   -- z. B. befehl:stats
  aufrufe     INT NOT NULL,
  fehler      INT NOT NULL,
  dauer_summe INT NOT NULL,           -- für den Mittelwert
  dauer_max   INT NOT NULL,
  PRIMARY KEY (zeitpunkt, bereich)
);

Minutenwerte werden nach einer Woche zu Stundenwerten zusammengefasst, Stundenwerte nach drei Monaten zu Tageswerten. Damit bleibt die Tabelle klein und die Historie erhalten — nur eben gröber, je weiter man zurückgeht. Das entspricht genau der Art, wie man solche Daten benutzt.

Infobox

Der entscheidende Punkt bei dieser Art von Messung: Es dürfen keine personenbezogenen Daten anfallen. In meinen Metriken steht kein Nutzer, keine Server-ID, kein Inhalt. Nur Bereich, Zeit und Zahlen. Damit ist die Frage nach Aufbewahrungsfristen und Löschansprüchen erledigt, bevor sie sich stellt.

Die Ansicht

Eine einzelne Seite, ohne Anmeldung über die öffentliche Adresse nicht erreichbar. Sie zeigt:

  • Zustand aller Prozesse, mit Zeitpunkt des letzten Lebenszeichens
  • Aufrufe und Fehler der letzten 24 Stunden als einfache Kurve
  • Die zehn langsamsten Befehle der letzten Woche
  • Wann zuletzt gesichert wurde und wie groß die Sicherung war
  • Belegter Speicherplatz mit Hochrechnung

Der vorletzte Punkt ist der, der mich am häufigsten gerettet hat. Eine Sicherung, die seit vier Tagen nicht mehr läuft, sieht man in einem Protokoll nicht — auf einer Übersichtsseite fällt sie sofort auf, weil das Datum falsch aussieht.

Was ich damit tatsächlich gefunden habe

Einen Befehl, der zehnmal langsamer war als alle anderen. Eine Auswertung, die eine Rangliste über alle Mitglieder berechnete, ohne den passenden Index. Vier Sekunden im oberen Bereich. Vorher unauffällig, weil niemand sich beschwert hat — man wartet halt kurz.

Eine Fehlerhäufung nach einem Update. Ein Befehl, der plötzlich in zwei Prozent der Fälle scheiterte. Zwei Prozent bemerkt kein Mensch, aber die Kurve.

Eine langsame Erhöhung der Ereignisverzögerung über mehrere Wochen. Ursache war eine Liste im Speicher, die nie aufgeräumt wurde. Ohne die Messung hätte ich das erst gemerkt, wenn der Prozess an den Speichergrenzen gestorben wäre.

Diese drei Funde rechtfertigen den ganzen Aufwand — und keiner davon wäre über Nutzerbeschwerden aufgefallen.

Wie ich die Werte einsammle

Der Aufbau ist bewusst so einfach, dass er selbst nicht ausfallen kann.

Zählen im Speicher, schreiben im Takt. Jeder Prozess führt für die laufende Minute Zähler in einer Map und schreibt sie einmal pro Minute in eine Zeile. Damit erzeugt eine Messung fast keine Last — es gibt keinen Schreibvorgang pro Ereignis.

Verlorene Werte sind hinnehmbar. Wenn ein Prozess mitten in einer Minute stirbt, fehlt diese Minute. Für eine Betriebsübersicht ist das kein Problem, und die Alternative — jede Messung sofort schreiben — wäre deutlich teurer.

Kein eigener Dienst. Die Werte liegen in derselben Datenbank wie alles andere. Ein Messsystem, das eine eigene Infrastruktur braucht, ist für diesen Umfang unangemessen.

Verdichtung als Zeitplan. Minutenwerte zu Stundenwerten, Stundenwerte zu Tageswerten. Ohne diese Verdichtung wächst die Tabelle unbegrenzt, und Abfragen über längere Zeiträume werden langsam.

Was ich mit den Zahlen nicht mache

Es gibt eine Verlockung, aus Messwerten Ziele zu machen. Der wöchentliche Blick auf steigende Aufrufzahlen fühlt sich gut an.

Ich habe mich dagegen entschieden, und zwar bewusst: Diese Zahlen dienen dem Betrieb, nicht der Bewertung. Sie beantworten „läuft alles normal?" und „was hat sich verändert?", nicht „bin ich erfolgreich?".

Der Grund ist eine Beobachtung aus einem anderen Zusammenhang: Sobald eine Zahl zum Ziel wird, verändert sich das Verhalten in ihre Richtung — auch das eigene. Ich würde anfangen, Dinge zu bauen, die Aufrufe erzeugen, statt Dinge, die nützlich sind.

Für ein Projekt, das nebenbei läuft und keinen Wachstumszwang hat, wäre das ein schlechter Tausch.

Der Wert, der am meisten gebracht hat

Von allen Kennzahlen ist eine deutlich wertvoller als die anderen: die Ereignisverzögerung — also die Zeit zwischen dem Eintreffen einer Aufgabe und dem Beginn ihrer Bearbeitung.

Der Grund ist, dass sie vor allem anderen ansteigt. Wenn ein Prozess an seine Grenzen kommt, wird nicht sofort etwas langsamer und nichts stürzt ab. Zuerst stauen sich Ereignisse.

Antwortzeiten steigen erst danach. Fehler kommen noch später. Beschwerden ganz zum Schluss.

Eine Kennzahl, die früh reagiert, ist mehr wert als eine genaue. Und diese hier hat mir zweimal einen Hinweis gegeben, bevor jemand etwas gemerkt hat — einmal bei einer Liste im Speicher, die nie aufgeräumt wurde, und einmal bei einer Datenbankabfrage ohne passenden Index.

Wenn ich nur eine Kennzahl haben dürfte, wäre es diese.

Was ich weggelassen habe

Keine Warnungen aus den Metriken. Ich habe überlegt, bei Ausschlägen zu benachrichtigen. Dagegen spricht meine eigene Erfahrung mit Meldungsmüdigkeit: Schwellwerte auf Kennzahlen erzeugen Fehlalarme, und Fehlalarme entwerten alle anderen Meldungen. Die Übersicht schaue ich mir an, wenn ich etwas untersuche — geweckt werde ich nur von Zustandsprüfungen.

Keine fremden Dienste. Es gibt gute Werkzeuge für Metriken. Für fünf Kennzahlen aus drei Prozessen auf einer Maschine ist eine Tabelle und eine Seite die angemessene Größe. Der Punkt, an dem ich wechseln würde: mehrere Maschinen, oder wenn ich anfange, komplizierte Auswertungen von Hand zu bauen.