Das Sammeln und die Auswertung von Log-Dateien sowie Feedback von Nutzern in Produktionsumgebungen sind entscheidende Elemente bei der kontinuierlichen Verbesserung von Software. Log-Dateien dienen nicht nur dazu, Fehler zu protokollieren, sondern auch als wertvolle Quelle, um tiefergehende Einsichten in das Verhalten der Nutzer zu erhalten. Ein klarer Vorteil einer präzisen und gut strukturierten Log-Dokumentation ist, dass sie zur Fehlerbehebung beitragen kann. Doch wie präzise und hilfreich sind die Log-Dateien wirklich, und wie können diese effektiv genutzt werden, um die Software zu testen und weiterzuentwickeln?

Oft wird das Log-Management nicht über das bloße Incident-Management hinaus genutzt, was zu einer unzureichenden Ausnutzung der Log-Daten führt. In einem konkreten Fall konnte durch die Analyse von Produktions-Logs festgestellt werden, dass eine Vielzahl ähnlicher Fehlermeldungen auftrat. Nach eingehender Untersuchung stellte sich heraus, dass Benutzer sich daran gewöhnt hatten, einen Button doppelt zu klicken, weil ein Fehler in der Anwendung verhinderte, dass der erste Klick funktionierte. Der erste Klick erzeugte eine Ausnahme, die nur in den Logs sichtbar war. Solche Erkenntnisse können nur durch eine sorgfältige und regelmäßige Analyse von Log-Daten gewonnen werden.

Matthew Skelton empfiehlt, Logging als ein Mittel zur besseren Testbarkeit verteilter Systeme zu nutzen. Besonders wichtig dabei sind drei grundlegende Aspekte: Erstens sollten Ereignisse, die wir erwarten, im Log-Stream korrekt erscheinen. Zweitens müssen Transaktionskennzeichen (auch als Korrelations-IDs bekannt) korrekt durch den Log-Stream fließen. Drittens sollten Ereignisse auf dem richtigen Log-Level (z. B. Info, Error, Debug) aufgezeichnet werden, wenn konfigurierbare Log-Level verwendet werden. Diese Praktiken sind besonders relevant in komplexen Systemarchitekturen, in denen eine einzige Nutzeraktion von mehreren Systemen verarbeitet wird. Ohne ein solches vernetztes Logging kann es schwierig sein, Anomalien zu erkennen.

Die Verwaltung von Log-Dateien ist ebenso von Bedeutung. Besonders bei großen Log-Dateien stellt sich oft das Problem, dass diese unhandlich werden und schwer zu durchsuchen sind. Eine durchdachte Log-Rotation und Aufbewahrungspolitik hilft, dieses Problem zu umgehen. Große Log-Dateien verbrauchen zu viel Festplattenspeicher und erschweren den Austausch von Daten. Eine Möglichkeit, diesem Problem zu begegnen, ist die Archivierung der Logs, sobald sie eine bestimmte Größe erreicht haben, und das Löschen von Logs, die ein bestimmtes Alter überschreiten. Dabei sollte immer geprüft werden, ob archivierte Logs bei Bedarf wiederhergestellt werden können. Je nach Implementierung kann es auch notwendig sein, die Log-Management-Lösung selbst zu testen.

Neben den Logs spielen Feedback-Kanäle eine wesentliche Rolle. Ob es sich um eine einfache E-Mail-Adresse „Kontaktieren Sie uns“, ein eingebettetes Feedback-Formular oder eine Echtzeit-Chat-Applikation handelt – alle diese Kanäle ermöglichen es Nutzern, ihre Erfahrungen und Probleme zu teilen. Auch Support-Teams, die über ein Call-Center oder ein Ticketsystem agieren, können wertvolle Informationen liefern. Diese Rückmeldungen sind eine Quelle qualitativen Feedbacks, das oft die Schwächen eines Produkts aufzeigt, die in den analytischen Daten nicht sofort erkennbar sind.

Feedback aus der Nutzerperspektive gibt den Entwicklern oft eine tiefergehende Einsicht, die durch rein quantitative Analysen nicht erfasst werden kann. Es gibt jedoch auch Herausforderungen bei der Verarbeitung dieses Feedbacks. Oftmals handelt es sich um Reaktionen auf eine Emotion oder einen temporären Frustrationspunkt, die nicht notwendigerweise eine sofortige Änderung des Produkts erfordern. Es ist wichtig, Feedback zu sammeln, zu analysieren und daraufhin nicht immer sofort Änderungen vorzunehmen, sondern es zunächst als eine Form der Wahrnehmung der Nutzer und der Marktstimmung zu verstehen.

Im Kontext von DevOps ist das Testen in der Produktion eine wichtige Praxis, die über die traditionelle Testphase hinausgeht. Hierbei wird das Feedback kontinuierlich in den Entwicklungsprozess eingespeist und dient als Grundlage für die weiteren Iterationen des Softwareprodukts. Dies unterscheidet sich grundlegend von klassischen Entwicklungsmodellen, in denen nach einem großen Release nur noch selten Tests in der Produktionsumgebung durchgeführt werden. In einer DevOps-Welt jedoch kann das Testen in Produktion als regelmäßiger Bestandteil des Entwicklungsprozesses angesehen werden, um sofortiges Feedback zu generieren, das die kommenden Softwareversionen beeinflusst.

Zu den gängigsten Testpraktiken in der Produktion gehören A/B-Tests, Beta-Tests und das Monitoring als Testmethode. A/B-Tests ermöglichen es, zwei Varianten einer Software in einer kontrollierten Umgebung zu testen, um herauszufinden, welche Version die bevorzugte Wahl der Nutzer darstellt. Ein Beispiel hierfür wäre die Überprüfung einer neuen Version eines Abonnieren-Buttons, bei dem verschiedene Textformulierungen getestet werden. Ziel eines A/B-Tests ist es nicht, Fehler zu finden, sondern zu validieren, ob die entwickelte Lösung die gewünschte Wirkung erzielt.

Das Testen von A/B-Experimenten erfordert eine klare Zielsetzung: Welche Metriken sollen gemessen werden? Wie lange soll der Test laufen? Welche Auswirkungen erwarten wir auf das Geschäft? Wichtig ist, dass der Test mit einer statistisch signifikanten Anzahl von Nutzern durchgeführt wird, um sicherzustellen, dass die Ergebnisse nicht zufällig oder verzerrt sind. Eine frühzeitige Entscheidung für eine der getesteten Varianten kann zu falschen Schlussfolgerungen führen, wenn nicht genügend Daten gesammelt wurden.

Insgesamt zeigt sich, dass die richtige Handhabung von Log-Dateien und Feedback-Kanälen ein unverzichtbares Element bei der kontinuierlichen Verbesserung von Software darstellt. Sie bieten nicht nur Fehlerdiagnosen, sondern auch tiefere Einblicke in das Verhalten und die Wünsche der Nutzer. Ein durchdachter Umgang mit diesen Quellen und eine enge Verzahnung von Entwicklung und Test in der Produktionsumgebung können den Unterschied zwischen mittelmäßiger und herausragender Software ausmachen.

Wie ein DevOps-Bug-Filter die Qualität der Software sicherstellt

In einer DevOps-Umgebung ist es entscheidend, die Qualität von Software kontinuierlich zu überwachen und Fehler frühzeitig zu erkennen. Ein Modell, das sich hierfür gut eignet, ist der DevOps-Bug-Filter. Dieser Filter besteht aus sechs Schichten, die sich in zwei Hauptkategorien unterteilen lassen: Tests, die in der Entwicklungsumgebung durchgeführt werden, und Informationen, die in der Produktionsumgebung gesammelt werden, um Bugs zu identifizieren und die Produktqualität zu bewerten.

Die oberen drei Schichten des Filters beziehen sich auf Tests im Entwicklungsumfeld. Diese umfassen Unit-Tests, Integrationstests und End-to-End-Tests. Die unteren drei Schichten hingegen beziehen sich auf das Sammeln von Informationen in der Produktionsumgebung: Alarmierung, Monitoring und Logging. Wenn man sich diesen Bug-Filter als eine Art Sieb vorstellt, dann sind Unit-Tests und Logging die feinmaschigsten, um auch die kleinsten Fehler zu erfassen. Integrationstests und Monitoring haben ein etwas gröberes Netz, und End-to-End-Tests sowie Alarmierungen sind die größten Filter, die nur die schwerwiegenden Probleme auffangen.

Man kann sich diese Bugs als Schmetterlinge vorstellen, die sich in verschiedenen Lebensstadien durch den Filter bewegen. Die Unit-Tests fangen die Eier auf – die Fehler, bevor sie sich zu einem relevanten Problem entwickeln. Integrationstests fangen die Raupen auf, die entweder aus einem Ei stammen, das in den integrierten Umgebungen geschlüpft ist, oder die aus einem externen System in die eigene Plattform gelangt sind. End-to-End-Tests schließlich fangen die Schmetterlinge, die die ausgereiften Fehler darstellen. Diese Metapher verdeutlicht, dass der obere Teil des Filters nicht hermetisch abgedichtet ist. Selbst bei 100 % Testabdeckung können Fehler nicht vollständig verhindert werden, da die zugrunde liegende Infrastruktur und die Systeme, mit denen wir interagieren, sich im Laufe des Entwicklungsprozesses ändern. Fehler können aus unerwarteten Quellen in diesen Schichten auftauchen, weshalb die Filtermaschen im Verlauf immer größer werden.

Einmal in der Produktionsumgebung angekommen, funktioniert der Filter wie ein Blockfilter. Die verschiedenen Schichten sind jetzt abgedichtet, und die oberste Schicht fängt die größten Probleme auf, bis hinunter zur untersten Schicht, die die kleineren Fehler abfängt. An diesem Punkt gibt es keine neuen Fehler mehr zwischen den Schichten, da wir lediglich in die Details der Produktionsumgebung eintauchen.

Dieser DevOps-Bug-Filter bietet ein nützliches Modell für Gespräche über eine umfassende Teststrategie. Die Tests, die im Entwicklungsteam implementiert werden, sowie die Daten, die in der Produktionsumgebung gesammelt werden, bilden das Netz des DevOps-Filters. Wenn die Testabdeckung unzureichend ist, wird das Netz Lücken aufweisen. Wo diese Lücken existieren, können Fehler durchrutschen und sich zu größeren Problemen entwickeln. Fehlt beispielsweise die Deckung in den Unit-Tests, werden mehr Raupen in die Integrationsschicht gelangen, und so weiter. Wenn die Testabdeckung unvollständig ist, könnten sich mehr Fehler in der Software verstecken.

In einigen Fällen kann es eine strategische Entscheidung sein, Fehler später im Prozess zu erfassen. Vielleicht lässt sich ein bestimmter Integrationsservice nicht unabhängig testen oder ein Unit-Test ist schwierig zu isolieren und wird daher zu einer späteren Testreihe hinzugefügt. Es lohnt sich, solche strategischen Entscheidungen zu besprechen, um Missverständnisse zu vermeiden. Lücken im Testnetz können auch auftreten, wenn das Entwicklungsteam entscheidet, dass ein Testfehler den Release nicht aufhalten soll. In solchen Fällen kann es sinnvoll sein, die Software mit bekannten Fehlern in der Produktion zu veröffentlichen, die später durch Alarmierung, Monitoring oder Logging erkannt werden. Ein Teil von DevOps ist es, zu hinterfragen, an welchem Punkt im Prozess das Risiko am besten gemildert werden kann, und nur die notwendige Automatisierung hinzuzufügen.

Das Modell eines DevOps-Stundenglases bietet eine einfache Möglichkeit, die Teststrategie zu visualisieren, insbesondere wenn das Bug-Filter-Modell zu komplex wird. Hierbei können Alarmierung, Monitoring und Logging als Spiegelbild der ursprünglichen Testpyramide betrachtet werden. Dies ist eine schnelle Möglichkeit, die traditionelle Diskussion über Tests in den DevOps-Kontext zu erweitern. Eine Frage, die sich hier stellt, ist, ob die Teststrategie auch die Informationen umfasst, die durch Operations-Teams bereitgestellt werden.

Die Automatisierung von Tests geht jedoch über funktionale Tests hinaus und umfasst auch nicht-funktionale Aspekte wie Sicherheit, Performance und Usability. Durch den Einsatz von Testautomatisierung in der Entwicklung und das Sammeln von Metriken in der Produktion lassen sich auch diese Bereiche effizient abdecken.

Es ist jedoch wichtig zu verstehen, dass in einer DevOps-Umgebung Explorations-Tests weiterhin eine entscheidende Rolle spielen. Diese Tests ermöglichen es, Softwarefunktionen zu entdecken, die außerhalb der ursprünglichen Anforderungen liegen. In DevOps-Umgebungen kann es schwierig sein, Explorations-Tests zu rechtfertigen, besonders wenn der Fokus auf Geschwindigkeit liegt. Explorations-Tests neigen dazu, an den Rand des Entwicklungsprozesses gedrängt zu werden – sie finden entweder in der lokalen Entwicklungsumgebung vor dem Zusammenführen von Code oder nach der Veröffentlichung statt, wenn Benutzer mit der Software interagieren. Die Automatisierung bietet hier weniger Raum für Exploration.

Ein weiteres Modell, das oft verwendet wird, um den Testansatz in einer DevOps-Umgebung zu visualisieren, ist das Pendel-Modell. Stell dir ein Pendel vor, das in Ruhe ist. Der Raum, in dem das Pendel schwingen kann, ist der Testansatz. Am linken Apex gehen wir zu tief in den Testprozess, am rechten Apex bleiben wir zu oberflächlich. Zu Beginn eines neuen Projekts befindet sich das Pendel in der Mitte und bewegt sich erst nach links (shallow testing), da das Testerteam zunächst nur begrenztes Wissen hat. Mit zunehmender Erfahrung des Teams wird das Pendel mehr nach rechts schwingen und das Testing intensivieren. Das Pendel bewegt sich zwischen diesen beiden Extremen und hilft dabei, den richtigen Mittelweg zu finden. Dabei spielen Indikatoren wie die Anzahl der Fehler, das Feedback des Teams und das Feedback des Managements eine wesentliche Rolle. Wenn zu viele Fehler gefunden werden, die nicht behoben werden, oder wenn nur wenige Fehler in der Produktion gemeldet werden, könnte dies darauf hinweisen, dass der Testansatz entweder zu tief oder zu oberflächlich ist.

Ein weiterer wichtiger Punkt ist die Balance zwischen automatisierten und explorativen Tests, und die Flexibilität des Teams, den Testansatz je nach Bedarf anzupassen.