Beliebte Suchanfragen
//

Log Management für Spring Boot Applikationen mit Logstash, Elasticsearch and Kibana

29.10.2014 | 5 Minuten Lesezeit

In diesem Blogartikel gebe ich eine kleine Einführung, wie man sehr schnell mit dem bekannten ELK Stack (Elasticsearch-Logstash-Kibana) eine Log Management Lösung für Spring Boot basierte Microservices aufsetzt. Ich werde zwei Methoden zeigen, wie man die Anwendungslogdateien einliest und zu der zentralen Elasticsearch Instanz transportiert. Grundsätzlich ist dies auch interessant für Anwender, die nicht Spring Boot einsetzen, aber bekannte Logging Frameworks, wie z.B. Logback, Log4J o.ä. verwenden.

Dieser Artikel geht nicht konkret auf die verwendeten Technologien ein und beschreibt sie von Grund auf. Im Netz gibt es dazu jedoch genügend Informationen. Falls noch kein Vorwissen besteht, sollte man sich vorher etwas über Elasticsearch, Logstash und Kibana informieren, bevor man hier startet. Eine gute Informationsquelle ist die Webseite von Elasticsearch , wo einige interessante Webinare und Dokumentationen zu finden sind. Meine Kollegen von codecentric haben ebenfalls schon über Themen im Zusammenhang mit Elasticsearch geblogged . Der Grund warum ich mich für Spring Boot als Beispiel entschieden habe ist, dass wir dieses Framework aktuell in einigen Projekten einsetzen. Ich glaube fest dran, dass Spring Boot dabei helfen wird den nächsten großen Schritt im Bereich der Enterprise Java Architekturen zu gehen. Bei der Einführung von Microservices wird jedoch auch eine größere Menge an Logdateien anfallen, so dass man hier auf jeden Fall eine gute Lösung braucht, um den Überblick zu behalten.

Zuerst klonen wir das Beispiel Git Repository und wechseln in dieses Verzeichnis.

1git clone http://github.com/denschu/elk-example
2cd elk-example

Die Spring Boot Beispielanwendung ist ein einfacher Batchjob und liegt in dem Verzeichnis „loggging-example-batch“. Die JVM wird mit folgenden Kommandos gestartet:

1cd loggging-example-batch/
2mvn spring-boot:run

In der Datei „/tmp/server.log“ sollten nun schon einige Logeinträge zu finden sein, die so ähnlich aussehen, wie diese hier:

12014-10-10 17:21:10.358  INFO 11871 --- [           main] .t.TomcatEmbeddedServletContainerFactory : Server initialized with port: 8090
22014-10-10 17:21:10.591  INFO 11871 --- [           main] o.apache.catalina.core.StandardService   : Starting service Tomcat
32014-10-10 17:21:10.592  INFO 11871 --- [           main] org.apache.catalina.core.StandardEngine  : Starting Servlet Engine: Apache Tomcat/7.0.55
42014-10-10 17:21:10.766  INFO 11871 --- [ost-startStop-1] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
52014-10-10 17:21:10.766  INFO 11871 --- [ost-startStop-1] o.s.web.context.ContextLoader            : Root WebApplicationContext: initialization completed in 2901 ms
62014-10-10 17:21:11.089  INFO 11322 [main] --- s.b.c.e.t.TomcatEmbeddedServletContainer : Tomcat started on port(s): 8090/http

Die Frage ist nun, wie man diese Datei einliest und weitertransportiert. Dazu setzen wir den ELK Stack nun auf und probieren zwei Varianten aus, wie man die Logdateien mit Logstash verarbeiten kann.

Vorbereitung

Elasticsearch

Dazu öffnen wir eine neue Shell und laden Elasticsearch zunächst herunter. Danach kann die Instanz ohne weitere Anpassungen gestartet werden.

1curl -O https://download.elasticsearch.org/elasticsearch/elasticsearch/elasticsearch-1.1.1.tar.gz
2tar zxvf elasticsearch-1.1.1.tar.gz
3./elasticsearch-1.1.1/bin/elasticsearch

Kibana

In einer weitere Shell wird dann das Webfrontend Kibana installiert. Das zu entpackende Archiv enthält ein JavaScript-basiertes Dashboard, welches mit jedem beliebigen HTTP Server ausgeliefert werden kann. In diesem Beispiel wird der mitgelieferte Webserver von Python verwendet.

1curl -O https://download.elasticsearch.org/kibana/kibana/kibana-3.1.0.tar.gz
2tar zxvf kibana-3.1.0.tar.gz
3cd kibana-3.1.0/
4python -m SimpleHTTPServer 8087

Bitte jetzt zunächst prüfen, ob das vorinstallierte Logstash Dashboard sich korrekt mit dem laufenden Elasticsearch Server verbindet. Als default verwendet Kibana hier die URL „http://localhost:9200“ (siehe config.js).

1http://localhost:8087/index.html#/dashboard/file/logstash.json

Logstash Agent

Für das Einlesen und den Transport der Logdateien werden so genannte Logstash Agenten verwendet. In einer neuen Shell wird dieser Agent ins Zielverzeichnis entpackt.

1curl -O https://download.elasticsearch.org/logstash/logstash/logstash-1.4.2.tar.gz
2tar zxvf logstash-1.4.2.tar.gz

Methode 1: Verarbeitung der Logdateien mit Grok

Die am häufigsten verwendete Methode zum verarbeiten der Dateien ist die Benutzung von Grok Filtern . Mit Hilfe von Patterns ist Grok in der Lage die relevanten Informationen aus den Logstatements zu extrahieren. Für unsere Spring Boot Beispielanwendung bzw. die dort verwendete Logback Konfiguration habe ich bereits einen Grok Filter erstellt, den wir nun direkt verwenden können:

1input {
2  stdin {}
3  file {
4    path =>  [ "/tmp/server.log" ]
5  }
6}
7filter {
8   multiline {
9      pattern => "^(%{TIMESTAMP_ISO8601})"
10      negate => true
11      what => "previous"
12   }
13   grok {
14      # Do multiline matching with (?m) as the above mutliline filter may add newlines to the log messages.
15      match => [ "message", "(?m)^%{TIMESTAMP_ISO8601:logtime}%{SPACE}%{LOGLEVEL:loglevel} %{SPACE}%{NUMBER:pid}%{SPACE}%{SYSLOG5424SD:threadname}%{SPACE}---%{SPACE}%{JAVACLASSSHORT:classname}%{SPACE}:%{SPACE}%{GREEDYDATA:logmessage}" ]
16   }
17}
18output {
19  elasticsearch { host => "localhost" }
20}

Damit die verkürzten Klassennamen (z.b. „o.s.web.context.ContextLoader“) korrekt eingelesen werden, muss noch ein zusätzliches Pattern (JAVACLASSSHORT) in Logstash registriert werden:

1cp custompatterns logstash-1.4.2/patterns/

Logstash Agent

Starte nun den Logstash Agenten mit der Spring Boot Konfiguration von oben. Diese Konfiguration befindet sich bereits im Beispielprojekt unter logstash-spring-boot.conf.

1./logstash-1.4.2/bin/logstash agent -v -f logstash-spring-boot.conf

Mit cURL bzw. einem HTTP POST Request wird der Job nun gestartet, damit auch Logstatements erzeugt werden.

1curl --data 'jobParameters=pathToFile=classpath:partner-import.csv' localhost:8090/batch/operations/jobs/flatfileJob

In dem vorkonfigurierten Logstash Dashboard in Kibana sollten nun die ersten Logeinträge zu sehen sein.

1http://localhost:8087/index.html#/dashboard/file/logstash.json

Methode 2: JSON Logback Encoder

Ein Nachteil von Methode 1 ist, dass es manchmal nicht so einfach ist ein voll funktionsfähiges Grok Pattern zu erstellen, dass alle Besonderheiten des Formats der Logeinträge berücksichtigt. Gerade mehrzeilige Logeinträge sind hier oft problematisch. Das in Spring Boot verwendete Log Format ist hier noch ein sehr gutes Beispiel, da größtenteils fixe Spaltengrößen verwendet werden. Eine Alternative dazu ist die direkte Erzeugung der Logeinträge im JSON-Format. Dazu wird nur ein weitere Maven Artefakt in der pom.xml benötigt (Dies ist bereits in der Beispiel Applikation eingetragen!).

1<dependency>
2    <groupId>net.logstash.logback</groupId>
3    <artifactId>logstash-logback-encoder</artifactId>
4    <version>2.5</version>
5</dependency>

… und noch ein spezieller Logstash Encoder in der Logback Konfigurationsdatei „logback.xml“, der letztendlich für die Erzeugung des JSON-Formats zuständig ist (Ebenfalls schon im Beispiel enthalten!).

1<encoder class="net.logstash.logback.encoder.LogstashEncoder"/>

Die neue Logstash Konfiguration (logstash-json.conf) ist nun viel kleiner und einfacher zu lesen:

1input {
2  file {
3    path =>  [ "/tmp/server.log.json" ]
4    codec =>   json {
5      charset => "UTF-8"
6    }
7  }
8}
9 
10output {
11  elasticsearch { host => "localhost" }
12}

Alternative Log Transporter

Der Logstash Agent benötigt leider etwas mehr Speicher (bis zu 1GB) und ist somit nicht so optimal für kleinere Server (z.b. EC2 Micro Instances) geeignet. Für unsere Demo hier spielt das zwar keine große Rolle, aber insbesondere im Umfeld von Microservice-Umgebungen ist es empfehlenswert auf einen anderen Log Shipper zu setzen, wie z.B. den Logstash Forwarder (aka Lumberjack). Weitere Informationen dazu sind hier zu finden. Und für die JavaScript-Kollegen gibt es natürlich auch eine Implementierung für Node.JS .

Zusammenfassend lässt sich sagen, dass der ELK Stack (Elasticsearch-Logstash-Kibana) eine gute Kombination ist, um ein komplettes Log Management ausschließlich mit Open Source Technologien durchzuführen. Bei größeren Umgebungen mit einer sehr großen Menge an Logdateien sollte man ggf. noch ein zusätzlichen Transport (z.B. Redis) nutzen, um die einzelnen Komponenten (Log Server, Log Shipper) voneinander zu entkoppeln. In der nächsten Zeit werde ich noch weitere Themen im Zusammenhang mit Microservices beleuchten. Also seid gespannt und ich freu mich natürlich immer über Feedback :-).

Beitrag teilen

//

Weitere Artikel in diesem Themenbereich

Entdecke spannende weiterführende Themen und lass dich von der codecentric Welt inspirieren.

//

Gemeinsam bessere Projekte umsetzen.

Wir helfen deinem Unternehmen.

Du stehst vor einer großen IT-Herausforderung? Wir sorgen für eine maßgeschneiderte Unterstützung. Informiere dich jetzt.

Hilf uns, noch besser zu werden.

Wir sind immer auf der Suche nach neuen Talenten. Auch für dich ist die passende Stelle dabei.