Transkript

Logging und Metrics

Moderne Ansätze zur Überwachung von verteilten Systemen

In der zwanzigsten Folge unseres Podcasts spricht Tammo van Lessen mit Stefan Tilkov über modernes Logging und Monitoring. Durch DevOps ist einige Bewegung in die Welt des verteilten Monitorings von Anwendungen gekommen. Aus dem Hashtag #monitoringsucks wurde dank neuer Werkzeuge recht schnell #monitoringlove. Tammo stellt einige dieser Ansätze und Tools für gutes Logging und die Erfassung von Metriken in verteilten Umgebungen vor.

Zurück zur Episode

Transkript

Tammo van Lessen: Hallo Stefan.

Stefan Tilkov: Wie immer muss ich die Standardfrage stellen: wer bist du und was tust du bei uns?

Tammo van Lessen: Ich bin Tammo. Ich bin jetzt schon drei Jahre bei der innoQ. Meine Schwerpunkte sind eigentlich eher so bei SOA und Geschäftsprozessmanagement. Da komme ich auch her.

Stefan Tilkov: Das ist das Thema, mit dem wir uns heute nicht befassen, was ein bisschen schräg ist. Worüber, wie ist der Querbezug dazu? Wieso sagst du, dass du eigentlich was mit dem Thema BPM zu tun hast und wir reden aber über Metrics, Logging und Monitoring?

Tammo van Lessen: Richtig, es gibt natürlich eine Menge Querbezüge. Bei den BPM-Themen spricht man gerne von Business Activity Monitoring. Das ist ein bisschen sperriges Wort. Das Ziel da ist aber, dass man der Fachabteilung die Möglichkeit gibt, rein in die Prozesse zu gucken, zu verstehen, was da los ist und da gibt es eben eine große Überschneidung zu Metrics und Monitoring, weil genau das will man ja in den traditionellen Anwendungen auch machen. Und da haben wir bei Kundenprojekten häufig große Schmerzen, wenn wir an Logs oder Metrikdaten kommen wollen. Häufig sind wir da im Blindflug.

Stefan Tilkov: Jetzt ist das, jetzt klingt das auf den ersten Blick nicht wie ein Thema, dass irgendwie gerade total heiß wäre oder wahnsinnig neu, aber da hat sich doch irgendwie etwas getan in letzter Zeit, oder?

Tammo van Lessen: Ja genau. Also mit der DevOps-Bewegung gab es da einfach viel mehr Schmerzen und die wurden addressiert beispielsweise über das Twitter Hashtag (1)(https://twitter.com/hashtag/monitoringsucks). Darüber haben die Leute wirklich Luft abgelassen, weil man eben lange Zeit lang keine guten Tools hatte. Also das kennen wahrscheinlich die meisten von uns. Wenn man Probleme im Betrieb hat, dann lässt man sich eine Log-File schicken und hantiert dann mit grep oder less dadrüber und versucht, bestimmte Dinge zu finden. Oder auch das Monitoring von ganzen Systemen macht man mit Nagios oder Icinga, aber so richtig schön und sexy ist das nicht. Und diese #monitoringsucks-Bewegung hat eben dazu geführt, dass neue Tools auf den Markt gekommen sind und deswegen ist das ein sehr spannender Bereich im Moment.

Stefan Tilkov: Ok. Lass uns doch vielleicht die Begriffe mal ein bisschen definieren. Also du hast gesagt, wir reden über Metrics und Logging. Wie würdest du das denn gegen einadner abgrenzen?

Tammo van Lessen: Ja, das ist eine gute Frage. Es gibt auch viele Leute, die das gerne mischen oder miteinander vermengen. Beim Logging ist es ja so, dass ich meine Anwendung instrumentiere mit Log-Statements. Aber meistens mache ich mir da noch keine Gedanken dadrüber, dass ich daraus irgendwelche Werte oder Statistiken ableiten möchte, sondern es geht mir nur dadrum, sozusagen einen Event-Stream zu erzeugen, der mir hilft, zu verstehen, was die Anwendung zu einem bestimmten Zeitpunkt getan hat. Das heißt, ich kann das nachvollziehen am Ende. Bei Metriken geht es eher dadrum, einen Blick in den Zustand der Anwendung zu bekommen. Also ein aggregiertes Bild.

Stefan Tilkov: Ok. Jetzt erklär' einem alten Mann wie mir, was man bei Logging denn heute so macht. Also man benutzt ein Log4j und schreibt da irgendwas raus. Also gibt es irgendwas Neues, hat sich irgendwas geändert an der Art und Weise, wie man das macht? Also man benutzt ein Logging-Framework und erzeugt auf stdout oder stderr irgendwelche Textnachrichten oder schickt die auf syslog. Was gibt es da Neues?

Tammo van Lessen: Ja, genau so macht man das und so macht man das auch naiv. Das hat aber einige Probleme, weil man dann immer sehr an die Struktur dieser Log-Nachrichten gebunden ist. Da gibt es jetzt einen relativ neuen Trend oder es ist jedenfalls etwas, was ich immer empfehle, was sich aber noch nicht so wirklich durchsetzt. Ich hoffe, das wird jetzt mehr, dass man eben nicht mehr in Textdateien schreibt oder weiterhin in Textdateien schreibt, aber nicht durch diese – normalerweise ist das ja über so ein Log-Pattern definiert, was wo steht und es ist oft auch auf bestimmte Zeichenlängen beschränkt. Viel besser geeignet ist natürlich sowas wie JSON, dass ich pro Log-Eintrag einen strukturierten Hash raus schreiben kann, in dem ich bestimmte Daten maschinenlesbar unterbringen kann. Das macht es natürlich schwieriger dann da mit less drin zu lesen, macht es aber für maschinen besser auswertbar und dafür gibt’s dann auch Tools. Was aber auch eben sehr wichtig ist, ist, dass man sich Gedanken darüber macht, insbesondere in verteilten Anwendungen, dass man ja auch Korrelationen hinbekommen muss. Und da geben die Log-Frameworks schon Mittel, die interessanterweise kaum Verwendung finden. Also wir haben zu dem Thema schon ein paar Vorträge gehalten und erkundigen uns immer gerne, welche Features vom Publikum so genutzt werden. Und Log4j oder SLF4J als Fassade bieten einem die Möglichkeit, sogenannte Map-Diagnostic-Contexts zu definieren. Das ist sowas, wie eine Thread-local Variable, in die ich Kontextwerte rein speichern kann, die dann im weiteren Verlauf in allen Log-Statement zur Verfügung stehen. Es kann also beispielsweise im Login-Handler oder in einem Filter von einem Servlet passieren, dass ich da schon den Username mit in so einen Kontext schreibe und der wird bei jeder Log-Nachricht mitgegeben. Und wenn ich das dann im strukturierten Log-Format rausschreibe, beispielsweise in JSON, dann ist eben jede Log-Nachricht mit diesem Benutzernamen anotiert. Darüber kann ich gut die Korrelationen hinbekommen. Oder halt z. B. im Web-Service Umfeld haben wir oft so correlation ids und die kann man dann über so eine ganze Anwendungslandschaft hinweg nachverfolgen und kann darüber auch die Log-Daten aus verschiedenen System wieder zusammen führen, um so den ganzen Fluß der Nachrichten durch so eine Anwendungslandschaft nachverfolgen zu können.

Stefan Tilkov: Der Bezug zur Verteilung ist, wenn ich jetzt ein hochverteiltes System habe, dann ist es natürlich noch schwieriger nachzuvollziehen, was da gerade wozu gehört und was richtig ist. Aber diese Dinge sind doch nichts Neues. Die gibt es doch schon ewig, oder? Ist es wirklich nur, dass die Leute das einfach nicht benutzen?

Tammo van Lessen: Es ist in vielen Fällen wirklich so, dass die Leute das nicht benutzen. Vielleicht haben sie auch die Schmerzen noch nicht gehabt. Es ist aber jetzt auch so, dass dadurch, dass man ein verteiltes Log-Aufarbeiten ermöglicht, mit neuen Tools wie beispielsweise Logstash, man die Daten auch viel einfacher zusammenführen kann. Als es diese Tools noch nicht gab, hat man, glaube ich, häufig das einfach so in Kauf genommen oder für selbstverständlich angenommen, dass man eben zuerst in der einen Log-Datei nachguckt und dann auf die andere Maschine geht und in der anderen Log-Datei sucht, wo da die Zusammenhänge sind, ja.

Stefan Tilkov: Kannst du kurz was zu Logstash sagen? Was ist das?

Tammo van Lessen: Ja. Also Logstash ist ein Open Source Tool, was darauf spezialisiert ist, Log-Daten in verschiedenen strukturierten oder unstrukturierten Formaten anzunehmen, aufzubereiten, möglicherweise zu annotieren mit Zusatzinformationen wie Geokoordinaten oder sowas, die anhand einer IP-Adresse nachgeschlagen werden, und dann wiederum in verschiedenen Formaten auszugeben. Standardmäßig kann es natürlich so ein spezielles JSON-Format einlesen, das ist dann schön, wenn die Log-Werkzeuge die schon direkt erzeugen. Man kann aber auch mit Grok – das ist sowas wie Regex on Speed – versuchen, unstrukturierte Log-Dateien so zu parsen, dass man da wieder die nötigen Informationen raus bekommt und kann die dann von Logstash weiter verarbeiten lassen. Und das spannendste Ausgabeformat von Logstash ist eigentlich neben so Sachen – man kann sich eine Nachricht auf den Pager schicken lassen, wenn eine bestimmte Log-Nachricht kommt oder solche Dinge. Aber das wirklich spannende ist, wenn man diese ganzen strukturierten Log-Daten dann – die werden sozusagen durch Logstash harmonisiert, kann man sagen – dann in ElasticSearch speichert und dann visualisiert.

Stefan Tilkov: Lass mich kurz fragen. Also Logstash ist noch nicht verteilt, oder? Ist Logstash eine verteilte Umgebung in irgendeiner Form?

Tammo van Lessen: Nein, Logstash ist erstmal nicht verteilt. Aber man kann es gut verteilen oder es verteilt nutzen. Also die Idee ist schon, dass man an einer Stelle so einen zentralen Logstash-Server hat. Aber weil eben diese Eingabeformate sehr unterschiedlich sein können – es muss eben nicht sein, dass es aus einer Datei gelesen wird, sondern kann auch über einen Socket z. B. eingelesen werden oder über Redis – kann man eben sehr leicht darüber so eine verteilte Architektur aufbauen. Also das typische verteilte Szenario wäre, dass man auf den verschiedenen Einzelsystemen sogenannte Logstash-Shipper hat. Das sind aber auch, also das kann man mit Logstash machen, das kann man aber auch mit anderen Tools machen, die etwas leicht gewichtiger sind. Die diese Logs erstmal entgegen nehmen, in dieses harmonisierte Format übertragen und dann per Redis z. B. beispielsweise zu dem zentralen Logstash-Server schickt, der das dann wiederum in das ElasticSearch speichert.

Stefan Tilkov: Das heißt, es gibt auch andere Clients außer diesem Logstash-Shipper, die mit dem Logstash-Server sprechen und das richtige Format produzieren und das dann über einen Socket dahin, über TCP dahin schicken oder so.

Tammo van Lessen: Genau.

Stefan Tilkov: Ok. Warum über Redis? Also was hat – Redis spielt dann was für eine Rolle? Mit Publish-Subscribe oder so? Weil Redis ist ja eigentlich eine NoSQL-Datenbank.

Tammo van Lessen: Genau, das kann ich jetzt auch nicht so genau erklären, das ist aber das von Logstash vorgeschlagene Szenario, Redis zu verwenden für die Interaktion zwischen dem Shipper und dem Server.

Stefan Tilkov: Ok, gut. ElasticSearch kennt jetzt vielleicht der ein oder andere als Suchmaschine. Das heißt, man hat jetzt den Logstash-Server, der die ganzen Dinge entgegen nimmt und harmonisiert, aber offensichtlich nicht vorhält, richtig? Also der hat jetzt keine durchsuchbare Datenbank oder irgendwas in der Art.

Tammo van Lessen: Genau.

Stefan Tilkov: Sondern, wenn ich dich richtig verstanden habe, schiebt man das ganze aus dem Logstash raus oder verbindet den Logstash so, dass er einfach alles, was da durch kommt, ins ElasticSearch, also in eine große Suchmaschine, reinpackt.

Tammo van Lessen: Genau. Das ist ja so ein bisschen ein Hybrid zwischen Dokumentendatenbank und Suchmaschine. Und genau dieser hybride Ansatz wird da im Grunde genommen auch genutzt. Das heißt, man kann sich jeden Log-Eintrag in diesem harmonisierten Format wieder da raus holen, man kann aber auch da drüber aggregieren und suchen. Weil das aber mühsam ist, das selber zu machen, gibt es dafür Kibana. Das ist so eine, ich glaube, AngularJS basierte Anwendung, die per Javascript einfach nur direkt mit ElasticSearch interagiert. Da ist also keine zusätzliche Komponente auf der Serverseite für nötig. Und das hilft einem, so Dashboards zusammen zu bauen. Also erstmal, wenn man das einfach nur so raus holt, dann zeigt es einem diesen Event-Stream an im Grunde. Man kann filtern über bestimmte Zeiträume, bestimmte Log-Typen. Das wäre wiederum was, was man auf der Logstash-Seite macht, dass man schon so eine Klassifikation vornimmt. Also welche Log-Daten kommen von welchem Server, kann man z. B. da rein taggen. Oder von welchem Komponententyp, beispielsweise. Und dann kann man darüber dann eben filtern in Kibana. Und das eben per Klick. Also es ist wirklich eine sehr angenehme Benutzeroberfläche, um mit einem Klick die Suche einzuschränken.

Stefan Tilkov: Und diese Kombination aus ElasticSearch, Logstash und Kibana ist so üblich, dass es schon einen Namen hat, nämlich den ELK-Stack.

Tammo van Lessen: Genau.

Stefan Tilkov: Richtig, das ist der Begriff, den man da hört. Ok, wie macht man jetzt die Verteilung? Also verteilt man dann typischerweise den Logstash-Server und die Logstash-Shipper – muss ich mal kurz überlegen, was ich da eigentlich fragen möchte. Also der Logstash-Server, von dem gibt es eine Instanz oder ist der auch so geclustert, dass ich von dem da mehrere Dinger nebeneinander stelle und dann Load-Balancing dazwischen mache oder wie tue ich das?

Tammo van Lessen: Das hängt natürlich sehr vom Log-Volumen ab. Also da darf man sich auch keine Illusion machen, wenn man auf diese Art und Weise loggt, dann verzehnfacht sich mit unter der Speicherplatzaufwand. Und dementsprechend, also das kriegt man natürlich nicht geschenkt und auch so ein ElasticSearch muss dann natürlich geclustert werden, wenn man entsprechend hohes Log-Volumen hat. Also das ist natürlich was, wenn man das in so einem Umfang macht, tritt man sofort auch selber in Konkurrenz zu kommerziellen Tools, die sich das ja auch sehr hochpreisig bezahlen lassen. Das sollte man immer im Hinterkopf halten, wenn man selber sowas baut.

Stefan Tilkov: Ein kommerziellen Tool wäre sowas wie Splunk zum Beispiel.

Tammo van Lessen: Exakt, ja.

Stefan Tilkov: Ok. Gut, das heißt, man skaliert den Logstash-Server, man skaliert dahinter das ElasticSearch und dann geht man mit dem Kibana dadrauf, um das ganze auszuwerten.

Tammo van Lessen: Genau.

Stefan Tilkov: Ok. Das war jetzt nach deiner Aufteilung, wenn ich dich richtig verstanden habe, der Logging-Aspekt, richtig?

Tammo van Lessen: Ja.

Stefan Tilkov: Oder fehlt uns da noch was zum Thema Logging? Klingt so, als wäre das so ein bisschen wie früher, nur halt mit vielen schicken Extra-Tools, mit denen man das ganze noch aggregiert und auswertbar macht und mit dem man einfach schöner die Log-Files durchsuchen kann, als sich per ssh auf dem Server anzumelden und mit grep nach den passenden Mustern zu suchen.

Tammo van Lessen: Genau. Und was ich da beobachte, ist, dass man halt plötzlich die Hürde zwischen – oder diesen Graben zwischen Betrieb und Entwicklung etwas minimieren kann, weil ein SSH-Zugang auf das Produktivsystem zu bekommen, da stellt sich ein Betrieb oft quer, aber vielleicht einen lesenden Zugang zu den Log-Dateien, je nachdem was man da loggt – manchmal sind ja sensible Daten drin, das ist dann immer ein bisschen schwierig, aber es ist teilweise ein bisschen einfacher, dann auch an Log-Daten zu kommen.

Stefan Tilkov: Was natürlich nochmal verstärkt wird, wenn man jetzt anfängt, gemischte Daten darein zu packen. Man könnte ja durchaus auch Log-Files von irgendeinem – weiß ich nicht – irgendeinem Apache-Server oder irgendeinem Mail-Server oder sonst irgendwas mit darein packen und mit korrelieren und darüber dann eine gemeinsame Auswertung über solche Dinge machen, was dann vielleicht bedeutet, dass Betrieb und Entwicklung dieselben Werkzeuge benutzen, was ja perfekt wäre.

Tammo van Lessen: Absolut ja. Das wäre eigentlich das ultimative Ziel, ja.

Stefan Tilkov: Ok.

Tammo van Lessen: Auch gerade verschiedene Log-Quellen zusammenzuführen, um dann über die Korrelation möglicherweise Zusammenhänge bei Problemen identifizieren zu können.

Stefan Tilkov: Ok. Wenn wir jetzt über Logging gesprochen haben und uns jetzt Metrics nähern wollen, sind Metrics dann einfach – tja, weiß ich auch nicht – alle herausgefilterten Fehlermeldungen einer bestimmten Kategorie aus dem Logging? Ist das, was sich hinter Metrics verbirgt?

tk: Das kann man natürlich so machen. Also gerade Logstash gibt einem auch die Möglichkeiten, das zu machen. Und es spricht auch gar nichts dagegen, das z. B. bei einem Apache-Log so zu machen, dass man da die Anzahl der 500er-Fehler oder der falschen Logins oder sowas direkt aus den Log-Dateien erfasst und in so Metrik-Datenbanken vorhält. Problematisch wird es aber, wenn man auf die Log-Dateien, die Entwickler in ihren Code schreiben, geht, denn dann hat man natürlich plötzlich, baut man eine Kopplung ein zwischen den Log-Daten, die man in dieser Anwendung schreibt, wo sich vielleicht nur ein Entwickler gedacht hat „Och, ich schreibe mal kurz raus, die Variable X ist jetzt 5.“, bindet sich dadrauf und da den Überblick zu behalten oder es ist ja quasi so eine Art Governance, die man einführen muss, dass die Entwickler ihre Log-Statements nicht mehr korrigieren dürfen …

Stefan Tilkov: Weil es wie ein API ist, dann auf einmal, oder?

Tammo van Lessen: Exakt. Und genau da wird es dann problematisch. Und da hatten wir wohl auch Kundenprojekte, die damit Probleme hatten, dass plötzlich ein Alert los ging, weil eine Anwendung plötzlich anders geloggt hat, als vorher oder als von irgendjemandem angenommen.

Stefan Tilkov: Ok, also beim Apache wäre das kein Problem, weil das Log-Format vom Apache ist ziemlich stabil. Das gilt schon seit 20 Jahren und das weiß man auch normalerweise, wie das Common Log-Format da aussieht. Was macht man denn dann, wenn man jetzt diese Variante nicht hat. Also wenn man kein stabiles Log-Format hat und trotzdem solche Metriken haben will.

Tammo van Lessen: Genau, dafür gibt es natürlich auch Tools und Werkzeuge.

Stefan Tilkov: Klar.

Tammo van Lessen: Wäre ja auch komisch, wenn nicht. Auch da gibt es verschiedene Ansätze. Also der Ansatz, der mir am besten gefällt, ist, dass man seinen Code selber instrumentiert. Da gibt es eine schöne Bibliothek von Coda Hale, die aus dem Drop – ich glaube, die ist bei Yammer mal entstanden und gehört inzwischen zu dem Dropwizard Projekt. Und das bietet einem die Möglichkeit …

Stefan Tilkov: Moment, die Bibliothek heißt wie?

Tammo van Lessen: Metrics.

Stefan Tilkov: Die heißt Metrics.

Tammo van Lessen: Genau.

Stefan Tilkov: Die ist für Metrics und heißt Metrics.

Tammo van Lessen: Es kann sein, dass sie inzwischen Dropwizard Metrics heißt, ja.

Stefan Tilkov: Ok.

Tammo van Lessen: Aber wenn man diese Begriffe da geordnet bei Google eingibt – ich glaube, wir haben aber auch noch Speaker Notes.

Stefan Tilkov: Ja, Shownotes, machen wir auf jeden Fall.

Tammo van Lessen: Ja. Genau. Was an der Bibliothek schön ist, die hat eine schöne API, es gibt so eine Metrics Registry, die einem dabei hilft, gute Namen für die Metriken zu finden. Und eine ganz schöne Abstraktion. Also man unterscheidet Gauges, das sind so – im Grunde wir da eine Funktion aufgerufen, die man selber implementiert, die dann einen Wert zurück liefert. Damit kann man also beispielsweise auch mal gegen eine Datenbank gehen und irgendwie die Anzahl der Einträge oder sowas raus holen.

Stefan Tilkov: Ein Gauge ist so ein Zeigerinstrument für irgendwas.

Tammo van Lessen: Genau. Dann gibt es Counter, die man so inkrementieren oder dekrementieren kann. Und dann geht das aber hoch bis Timer, die Zeiten erfassen und Histogramme. Ich glaube, ein Timer ist sogar ein Histogramm über die Zeit, mit der man dann eine ganz gute statistische Auswertung bekommen kann über die Werte, die man da erfasst. Also auch da muss man dran denken, das frisst natürlich Ressourcen. Aber da hat Coda Hale sich viele Gedanken gemacht, dass die Ressourcen-Verwaltung nicht so teuer ist, sodass die Devise eigentlich ist, möglichst viele Metriken zu erfassen in der Anwendung.

Stefan Tilkov: Muss ich nochmal kurz nachfragen, was du damit meinst „Das frisst Ressourcen“. Also du meinst jetzt Speicher für die Verwaltung dieser Werte.

Tammo van Lessen: Klar. Also wenn ich so ein Histogramm erfasse, muss ich natürlich so ein Sampling-Reservoir vorhalten. Und das soll natürlich möglichst auch noch über einen längeren Zeitraum statistisch repräsentativ sein. Und trotzdem soll die Stichprobe möglichst klein sein und ich meine, dass der, der relativ abgefahrene Algorithmen implementiert, dass der mit einer größe von 1024 auskommt. Und trotzdem muss man natürlich im Hinterkopf halten, wenn ich meine Anwendung jetzt durchinstrumentiere und überall diese Timer oder Histogramme einbaue, dass auch mein Speicherbedarf steigt. Aber es ist vielleicht auch heutzutage einfach nicht mehr so relevant.

Stefan Tilkov: Ich wollte grad sagen. Also das ist jetzt, wir reden jetzt von Dingen, die in-process passieren mit meiner eigentlich Anwendung. Also Metrics ist eine Java-Bibliothek, also wenn ich eine JVM-Anwendung habe, dann habe ich sowieso da alle möglichen Dinge, die ich anlege, alle möglichen Objekte, die ich verwalte, ob es da noch drauf ankommt, dass ich ein paar Metrics extra verwalte, weiß ich nicht. Wahrscheinlich würde ich ja Metrics dadrin verwalten, die mir auch was bringen, also die sind es wahrscheinlich auch wert, dass ich ein paar Bytes RAM oder ein paar Megabytes RAM dafür verballere.

Tammo van Lessen: Genau. Aber man muss sich halt darüber im klaren sein, dass es nicht for free ist. Umgekehrt sagt Coda Hale aber auch selber, es gab da mal eine Diskussion auf seiner Mailingliste dazu, ob man wie bei Log4j so einen Guard einführen kann. So isMetricsEnabled, dann erfasse die Metriken überhaupt. Und er sagt das ist Quatsch. Also entweder man erfasst Metriken oder man lässt es halt bleiben. Und sie haben sehr viele Metriken in Produktionscode und da stören sie nicht. Und selbst wenn sie stören würden, ist es das immernoch wert, dass sie überhaupt wissen, was die Anwendung macht.

Stefan Tilkov: Es ist vielleicht auch noch ein größerer Unterschied zum Thema Logging. Also beim Logging schreibe ich halt in der Regel auf irgendwas I/O mäßiges. Ich schreibe auf einen Socket oder ich schreibe ins Filesystem. Das kostet halt wirklich Zeit. Das ist ja wirklich echt, das belastet mich in der Performance, wenn ich zu viel logge, tatsächlich gewaltig.

Tammo van Lessen: Exakt.

Stefan Tilkov: Wohingegen im Hauptspeicher jetzt ein paar Dinger zu verwalten ist wahrscheinlich wirklich mit dem ganzen Rest, den ich mache, absolut lächerlich vom Zeitverbrauch her.

Tammo van Lessen: Ja.

Stefan Tilkov: Was passiert denn dann? Also die Metriken, die sind dann in meinem JVM-Prozess, in diesem konkreten Fall, irgendwo im Hauptspeicher drin. Wer holt die denn jetzt da ab oder wer macht jetzt irgendwas damit?

Tammo van Lessen: Ja, genau. Die werden da auch, also zumindest in dieser Bibliothek, voraggregiert dann. Und werden dann über sogenannte Reporter weitergegeben. Daher kommt der zur Out-of-the-box kann man das auf die Konsole schreiben oder in eine CSV-Datei schreiben. Das ist aber eigentlich alles uninteressant, weil spannend ist es, das jetzt einfach in die nächste Stufe von so einer Pipeline zu schieben. Und zwar in die Persistenz-Schicht. Da gibt es auch eine Menge von Tools, die sich sehr überlappen. Ich glaube der Platzhirsch im Moment, muss man sagen, ist Graphite. Das orientiert sich aber auch sehr an diesen Round-Robin Datenbanken, die es ja schon seit Hundert Jahren gefühlt gibt. Die Grundidee davon ist eigentlich, dass man verschiedene Buckets in verschiedenen Größen – insbesondere Zeitauflösung – hat. So hat man beispielsweise einen Bucket, der sagt „Ich erfasse jetzt mal die Daten von zwei Stunden in einer Auflösung von drei Sekunden“. Und wenn dieser Bucket voll ist, dann aggregiere ich die Daten und lege die in den nächsten Bucket und da halte ich dann die Daten vielleicht vor für einen ganzen Tag und dann danach für eine Woche und für ein Jahr. Auf die Art und Weise ist es möglich, relativ effizient eine ganze Historie der Entwicklung der Metriken festzuhalten, ohne natürlich immer diese hohe Auflösung beizubehalten. Aber trotzdem kann man in der Vergangenheit dann gucken und sehen, wie sich die Performance der Anwendung verändert hat.

Stefan Tilkov: Unter der Annahme, dass mich, je weiter ich in die Vergangenheit gucke, jeweils umso weniger Details interessieren. Also da möchte ich noch wissen, wie es insgesamt war, aber nicht mehr, was genau in dieser Sekunde oder in der dritten, im dritten Prozent der Stunde da passiert ist.

Tammo van Lessen: Ganz genau. Das ist die Annahme. Das ist vielleicht auch nochmal ein ganz interessanter Unterschied zum Logging, weil da will ich das möglicherweise. Also es ist, wir haben das teilweise im Betrieb, dass die sagen, da wird so viel geloggt, wir schmeißen die Log-Dateien nach einem Tag weg.

Stefan Tilkov: Ja. Super.

Tammo van Lessen: Und dann haben wir aber halt – das ist total super, weil meistens bis so eine Fehlermeldung bei uns angekommen ist, sind zwei Wochen durch First- und Second-Level-Support vergangen und dann steht man dann da und würde jetzt gerne wissen „Was war jetzt genau da an der Stelle passiert?“

Stefan Tilkov: Was jetzt deutlich sagt, dass dein aktuelles Projekt ein bisschen schneller sein könnte bei solchen Dingen. Aber egal, lass uns das auslassen.

Tammo van Lessen: Genau. Aber man kommt ja, durch den Leidensdruck kommt man zu solchen Themen und dann kann man ja auch wieder die Verbesserung suchen, ja.

Stefan Tilkov: Ok. Also ist Graphite jetzt nur diese Persistenz oder was verbirgt sich dahinter?

Tammo van Lessen: Ne, Graphite ist zum einen diese Persistenz, hat aber auch noch eine Visualisierung davon. Und man kann es sich so ein bisschen vorstellen, wie so eine Art Charting-as-a-Service Anwendung. Also das heißt, es gibt so eine UI, da kann man sagen „Jetzt ziehe mir doch mal folgende Metriken in folgender Auflösung in einen Balken- oder in ein Liniendiagramm und stell mir das als PNG oder als JSON-Sample zur Verfügung.“ Und dann kann ich da natürlich mir ein Dashboard draus bauen, indem ich entweder die Bilder da einbaue oder irgendwelche von den fancy Javascript Plotting-Bibliotheken dagegen binde und das dann visualisiere.

Stefan Tilkov: Was meinst du jetzt mit „as a Service“ Lösung?

Tammo van Lessen: Naja, dass ich halt in Graphite komponieren kann, wie das Chart aussehen soll und dann spuckt er mir aber am Ende eine URL aus und deswegen kann ich es einbinden. Also es ist kein …

Stefan Tilkov: Ich wollte grad sagen, also es ist keine externe, keine Cloud-Lösung oder sowas.

Tammo van Lessen: Exakt.

Stefan Tilkov: So war es nicht gemeint.

Tammo van Lessen: Genau.

Stefan Tilkov: Ok, verstehe. Das heißt, ich habe dann im Prinzip etwas, wo ich mir das abholen kann. Das ist für mich als Interface relativ einfach, weil ich einfach eine URL mir zusammenkonfiguriere. Oder ich konfiguriere mir etwas, was dann unter einer URL verfügbar ist, woran ich dann wiederum ganz ganz viele verschiedene Werkzeuge bauen kann.

Tammo van Lessen: Genau.

Stefan Tilkov: Und meinen großen 65" Bildschirm in den Flur hänge, wo dann all diese Dinge aggregiert werden.

Tammo van Lessen: Genau.

Stefan Tilkov: Ok. Gibt es jetzt einen Zusammenhang zwischen sowas wie Metrics, das ich in meiner Java-Anwendung habe und dem Graphite auf der einen Seite und dem ELK-Stack auf der anderen Seite? Verknüpfe ich die noch in irgendeiner Form oder sind das einfach zwei unterschiedliche Use Cases für unterschiedliche Zielgruppen?

Tammo van Lessen: Eigentlich sind das unterschiedliche Use Cases, ich kann aber natürlich aus meinem Logstash Daten dann in mein Graphite reinschicken. Also beispielsweise die aggregierten 500er-Fehlermeldungen würde ich dann darüber in Graphite rein bringen.

Stefan Tilkov: Ok.

Tammo van Lessen: Es gibt zum Beispiel noch ein anderes System, was man vor Graphite setzen kann. Das ist statsd. Das lauscht einfach einfach auf einem UDP-Port und nimmt so Triple an: Timestamp, Wert, Name. Und das kann man ja wirklich aus jeder Anwendung dann da rein pushen als Metrik. Wofür sowas manchmal ganz praktisch ist …

Stefan Tilkov: Sekunde. Also das statsd sitzt dann als ein Lieferant von Daten vor dem Graphite …

Tammo van Lessen: Exakt.

Stefan Tilkov: … und schiebt die Daten ins Graphite rein und ich kommuniziere mit dem statsd über die UDP-Pakete.

Tammo van Lessen: Genau so ist das, ja.

Stefan Tilkov: Ok.

Tammo van Lessen: Und das ist aber halt eine sehr, sehr simple API. Die kann man ja auch mit einem Netcat aus einem Shell-Skript beispielsweise verwenden. Und das ist dann sehr nett, wenn man so eine Continuous Delivery oder sowas hat, dass man so Deployment Marker setzen kann. Dann weiß auch das Graphite „Jetzt habe ich eine neue Version von meinem Service X ausgerollt.“ Und dann sehe ich …

Stefan Tilkov: Und dann kann ich die Metrik sehen.

Tammo van Lessen: Genau.

Stefan Tilkov: Schick.

Tammo van Lessen: Dann sehe ich einen Strich in meinem Diagramm und sehe dann auch „Aha, ab jetzt ist alles viel besser oder viel schlechter geworden.“

Stefan Tilkov: Ok. Was sind denn gute Beispiele für Metriken?

Tammo van Lessen: Ja, da muss man natürlich sehr differenzieren. Ich unterteile da gerne drei Kategorien. Und zwar die fachlichen Metriken, Anwendungsmetriken und Systemmetriken. Also fachliche Metriken sind tatsächlich Fragen, die oder Metriken, die Fragen des Fachbereichs beantworten können. Also beispielsweise „Wie viele Bücher habe ich heute verkauft über die Plattform?“ Oder „Wie lange sind die Durchlaufzeiten von so einem Prozess, der da durchläuft?“

Stefan Tilkov: „Wie viele Benutzer haben sich heute registriert und wie viele haben abgebrochen?“ und so.

Tammo van Lessen: Genau. Oder vielleicht auch sicherheitskritische Sachen „Wie viele failed logins haben wir?“ Das ist ja auch wichtig, wenn man da plötzlich so ein Peak hat, dann ist es meistens wahrscheinlich schon zu spät, aber man hat ihn dann vielleicht wenigstens mitbekommen.

Dem gegenüber stehen dann Anwendungsmetriken, also das heißt Interna aus der Anwendung, wie z. B. die Sättigung vom Thread-Pool oder dem DB-Pool. Oder auch die Anzahl von Requests oder „Wie oft ist mein ‚Sowieso‘-Controller aufgerufen worden?“ damit ich da so ein bisschen verstehen kann, wie wird meine Anwendung überhaupt genutzt oder auch wie sind die Durchlaufzeiten, wo wird die meiste Zeit verbrannt?

Und dann noch die Systemmetriken. Das ist halt sowas wie „Wie voll ist die Festplatte?“, „Wie viel RAM verbraucht meine Anwendung oder ist noch frei?“, CPU-Auslastung und sowas. Wenn man das alles zusammen erfasst und auch versucht, das in einer aggregierten Form zu visualisieren, dann hat man ein viel besseres Verständnis darüber, warum möglicherweise irgendwo was kracht. Also gerade in so einer verteilten Umgebung kann es eben sein, wir haben eine neue Version deployt, wir merken plötzlich, die Performance bricht ein und das hängt dann vielleicht damit zusammen, dass irgendein abhängiger Service seine Thread-Pools falsch konfiguriert hat oder die Datenbank-Pools voll sind und deswegen einfach die Performance in der ganzen Kette runter geht. Das würde man nicht erkennen können, wenn man diese Daten nicht so überlagern kann.

Stefan Tilkov: Von der Gesamtsicht her, das klingt so, als wäre das so eine sehr bewusst auf maximale Transparenz entworfene Umgebung, in der man möglichst viel darüber sieht. Hast du ein Gefühl dafür, wie viel Aufwand man in sowas rein steckt? Also ist das heute, mit dem Tooling, was man hat, eine Sache von ein paar Tagen, sowas aufzubauen? Oder ist das immernoch eine sehr aufwendige Sache, das ganze Zeug aufzusetzen und zu aggregieren und zu konfigurieren und die ganzen Appender und die ganzen Integrationen und das alles zu machen?

Tammo van Lessen: Also es ist natürlich ein signifikater Anteil. Die versuchen oder man merkt, dass die Bestrebungen dahin gehen, das alles einfacher zu machen. Also Graphite zu installieren war immer sehr mühsam und da tun jetzt so diese ganzen Entwicklungen mit Virtualisierung und Docker und so vereinfacht das alles ein bisschen. Aber auch da gibt es neue Tools, wie InfluxDB, die versuchen das zu vereinfachen oder andere Backends – oder ne, das sind eigentlich, es ist eher – doch, es ist ein Backend für Graphite, was die Daten in Charts speichern kann. Da ist eine Menge im Fluss, ich habe aber das Gefühl, man sollte das ein bisschen in das Projektsetup mit aufnehmen. Also so wie man am Anfang sich hinsetzt und irgendwie ein Maven-Build erstmal bootstrapt und sich ein CI-Server aufbaut und so eine Continuous Delivery Pipeline versucht zu konstruieren, sollte man sich auch gleich Gedanken machen, wie kann man die Metriken erfassen, dass das schon mit der Anwendung wachsen kann.

Stefan Tilkov: Eine Diskussion, die man häufig führt, ist die, ob nicht das, was in einem Java-Application-Server ist, vielleicht einfach schon ausreicht. Also wenn ich so ein WebLogic oder WebSphere oder JBoss oder was auch immer als JavaEE-App-Server habe, dann ist doch da alles schon erledigt und da gibt es schon Monitoring. Und wieso fange ich jetzt mit irgendwelchen alternativen Werkzeugen da rum zu fummeln? Hast du darauf eine Antwort?

Tammo van Lessen: Klar. Das ist natürlich ein bisschen ein anderer Ansatz zu dem selber Instumentieren. Das kann man erstmal sagen. Auch das ist irgendwo einen validen Ansatz. Auch dafür gibt es Tools, die das jenseits von den Application-Servern machen. Die instumentieren einfach alles, was sie so in die Finger kriegen oder unter Kontrolle haben. Was jetzt in unserem Setup daran nicht so spannend ist, ist, dass man übergreifende Aspekte dann nicht nachverfolgen kann. Klar kann man irgendwie den App-Server abfragen, ob alles in Ordnung ist, die APIs sind natürlich ein bisschen altmodisch aus heutiger Sicht. Auch die Abfrage. Ich habe auch keine Lust mich in verschiedene Tools einzuloggen, um mir die Metriken anzeigen zu lassen, sondern ich möchte das in einer aggregierten Form haben. Aber heutzutage hat man ja wirklich viel mehr verteilte Anwendungen über App-Server übergreifend oder man hat einen Varnish vorne dran und man möchte auch die Metriken davon in so eine konsolidierte Sicht mit rein bekommen. Das kann ein App-Server eben nicht leisten. Plus, dass ich diesem Ansatz auch immer ein bisschen unterstelle, wenn der versucht, aus allem Metriken rauszuextrahieren – also es gibt z. B. dieses Apache Sirona Projekt, was so einen Ansatz fährt, durch so eine Java-Agent Instrumentierung die Daten direkt rauszuziehen. Dass der halt möglicherweise Dinge misst, die ich gar nicht messen will, aber dafür einen negativen Impact auf die Performance hat. Deswegen präferiere ich den Ansatz, selber zu entscheiden, was möchte ich eigentlich messen. Und das dann in einer konsolidierten Sicht daraus zu leiten.

Stefan Tilkov: Gut, jetzt haben wir ungefähr eine halbe Stunde gesprochen. Ich glaube, wir haben das Thema nicht abschließend und vollständig behandelt.

Tammo van Lessen: Nein.

Stefan Tilkov: Hast du noch ein paar gute Tips an Ressourcen, derer man sich bedienen kann, wenn man mehr wissen will?

Tammo van Lessen: Ja. Also wir halten natürlich auch eine Menge Vorträge zu dem Thema. Wir haben auch Artikel dazu, auch von verschiedenen Autoren von der innoQ. Was immer nochmal eine Empfehlung wert ist, ist der Vortrag von Coda Hale. Ich glaube der heißt „Metrics, metrics, everywhere“, wo er auch wirklich nochmal betont, dass man so viele Metriken messen und erfassen sollte, wie mögliche, weil man ja oft vorher gar nicht weiß, welche man am Ende braucht. Das ist noch so eine Empfehlung.

Stefan Tilkov: Irgendwelche anderen Tools oder so, die wir nicht erwähnt haben? Kann ich mir kaum vorstellen.

Tammo van Lessen: Ja, wir haben natürlich ganz viele Tools ausgelassen. Vielleicht muss man eins noch erwähnen, was wirklich sehr spannend ist, weil es geht ja dann am Ende auch um die Frage „Wie geht es dann weiter, wenn ich die Metriken erfasst habe?“ Dann will ich Dashboards haben, ich will aber vielleicht auch ein Alerting haben. Ich will vielleicht auch eine Prediction haben oder eine Anomalie Detection. Das ist ja Unsinn, nachts um drei den Pager vom Admin gehen zu lassen, weil der Festplattenplatz jetzt aufgebraucht ist, obwohl der halt so ganz langsam ansteigt. Also wenn der Schwellwert halt nachts um drei erreicht wird, wird der nachts um drei erreicht. Es würde aber auch vollkommen ausreichen, das am nächsten Tag einfach zu machen. Also solche Aspekte. Und da könnte man vielleicht noch Riemann wirklich nennen. Das ist so eine Art neumodische CEP-Engine in Clojure geschrieben.

Stefan Tilkov: Complex Event Processing Engine.

Tammo van Lessen: Ah ja, Verzeihung. Und das ist so ein bisschen dieses fehlende Glied dadrinnen aus Metriken, vielleicht auch aus Log-Daten wieder eine Aggregation hinzukriegen, so eine Art höherwertigen Event. Ein schönes Beispiel, wofür man das z. B. verwenden kann, sind so Heartbeats. Also das haben wir auch in Projekten ab und zu mal, dass aus irgendeinem Grund die API ihren Zustand nicht mitteilen kann. Das heißt, wir müssen immer pollen. Wir kriegen quasi immer die Information „Service ist da“, „Service ist da“, „Service ist da“. Aber wir kriegen nie die Information „Service ist weg“. Und das kann man mit Riemann ganz schön modellieren, indem man einfach sagt „Du machst da so ein sliding time window auf“ und wenn die Events jetzt plötzlich über zwei Slots weg bleiben, dann erzeuge ein neues Event, was sagt „Service ist jetzt weg“. Und wenn man das – könnte man wahrscheinlich komplett nochmal drüber sprechen – aber wenn man das so mit in dieses Bild noch einnimmt, dann schließt sich der Kreis so ein bisschen.

Stefan Tilkov: Ok. Tammo, vielen Dank. Fand ich sehr informativ und sehr kurzweilig. Und danke für deine Zeit.

Tammo van Lessen: Danke dir auch, Stefan.


  1. monitoringsucks  ↩