Sonntag, 16. Dezember 2007

Forensik

Wenn ein System mal nicht so läuft wie geplant und der Kunde meldet einen Fehler, so ist aus der Fehlermeldung alleine meist nicht klar, was passiert ist. Nun beginnt die mühsame Suche nach Spuren, die auf das eigentliche Problem hinweisen. Im Gegensatz zu Kriminalfällen hat der Entwickler es aber selbst in der Hand, für geeignete Spuren zu sorgen. Im Gegensatz zu Kriminellen ist es sogar in seinem eigenen Interesse, möglichst brauchbare Spuren zu hinterlassen.

Welche Möglichkeiten gibt es, Fehler zu analysieren?

Speicherauszug

Unix-Benutzer kennen sicher die dump-Dateien, die übrigbleiben, wenn ein Prozeß unerwartet abstürzt. Diese Speicherauszüge können mit dem Systemdebugger untersucht werden, als ob das Programm an dieser Stelle auf einen Unterbrechungspunkt gelaufen wäre. Wenn man hängende Prozesse untersuchen will, so kann man einen Speicherauszug auch durch das kill-Kommando provozieren.

Ein Speicherauszug beantwortet sofort die Frage, wo der Fehler aufgetreten ist. Nicht immer ist aber klar, wie das Programm da hingekommen ist.

Unter Java gibt es übrigens das Tool jstack mit dem ein Stackdump aller in einer JVM laufenden Threads erzeugt werden kann. So läßt sich feststellen, wo ein Programm hängt.

Logs

Ein seit je her beliebtes Verfahren, Probleme analysierbar zu machen, sind Logs. Hier werden Informationen über den Programmablauf laufend gespeichert, meist in Textdateien. In der Vergangenheit gab es immer wieder Probleme mit dem Loggen aus parallellaufenden Threads oder mit unvollständigen Ausgaben, da Puffer nicht rechtzeitig auf die Platte geschrieben wurden. Die Stabilität sollte heute mit der Verfügbarkeit von Bibliotheken wie log4j kein Problem mehr sein. Allerdings bedeutet umfangreiches Loggen immer noch ein Performanceproblem, insbesondere wenn Dateien benutzt werden. Eine Datei kann zu einer Zeit nur von einem Thread verwendet werden. Häufiges Schreiben blockiert die Festplatte für andere Nutzer. Wird seltener geschrieben, werden die letzten Einträge vor einem Absturz wahrscheinlich nicht mehr abgespeichert.

In vielen Projekten werden die Ausgaben ad hoc von den Entwicklern formuliert. Dies führt dazu, daß sie sehr uneinheitlich und unterschiedlicher Qualität sind. Eine automatische Auswertung ist in der Regel nicht möglich. Für einen effizienten Umgang mit Log-Informationen ist es notwendig, daß ein einheitliches Log-Format vorgegeben wird. Eine Umsetzung dieser Idee findet sich z.B. in den Common Base Events. Eclipse bietet Werkzeuge zum Umgang mit auf dieser Spezifikation erfolgenden Logs. Ein Ziel, das hier verfolgt wird, ist es, eine serviceübergreifende Ablaufverfolgung in einer SOA-Umgebung zu ermöglichen.

Häufig wird Information in einer Log-Meldung benötigt, die sowieso in der Datenbank verfügbar ist. Um den Log nicht übermäßig aufzublähen, empfiehlt es sich, nicht die Information auszugeben sondern nur eine Referenz auf die Datenbank (Schlüssel). Ein logische Schlußfolgerung aus dieser Vorgehensweise ist es, direkt in eine Datenbanktabelle zu loggen. Dann kann die vollständige Information durch eine geeignete Abfrage angezeigt werden. Die Datenbank ist das ideale Ziel von Logs. Das Schreiben ist in der Regel wesentlich effizienter und die Werkzeuge zur Auswertung sind auch vorhanden. Eine Strukturierung der Information ergibt sich aus dem Design der Logtabelle.

Datenhistorie

In Geschäftsanwendungen wird häufig eine Revisionssicherheit der Daten gefordert. Dies bedeutet, das Daten nicht geändert oder gar gelöscht werden, sondern immer neu eingefügt werden. Die aktuellen Daten werden am Einfügezeitpunkt erkannt, der mitgeführt werden muß. Dies erfordert zwar eine Menge zusätzlichen Speicherplatz, der heutzutage aber kaum etwas kostet, und etwas zusätzlichen Entwicklungsaufwand. Jedoch lassen sich so Vorgänge optimal rekonstruieren. Auch wenn es nicht direkt gefordert ist, sollte beim Systemdesign darüber nachgedacht werden, ob eine Historie zumindest für die wichtigsten Daten nicht machbar ist.



Keine Kommentare: