Cat | tail | grep – nierzadko jest to dla wielu osób podstawowy zestaw komend do wyszukiwania pewnych informacji w logach. Rozwijając jakąkolwiek aplikację, tworzymy pewien ekosystem składający się wielu usług, generujących własne pliki rejestru zdarzeń w różnych formatach. Na przykład w pierwszej lepszej aplikacji którą rozwijałem informacje rejestrowane są przez:
- serwer proxy – NGINX
- serwer http – Tomcat
- bazę danych – PostgrteSQL
- no i aplikację.
Już przy tak podstawowym zestawie usług, generowanych informacji jest ogrom. Przegląd i analiza takich logów jest dosyć problematyczna. Jeszcze pół biedy, gdy wszystkie z tych danych znajdują się na jednym serwerze.
Jak nad tym zapanować? W tym artykule przedstawię open source’owy zestaw narzędzi służących zarządzania logami ELK Stack w skład którego wchodzą:
- Elasticsearch – silnik wyszukiwania pełnotekstowego oparty na Apache Lucene.
- Logstash – narzędzie przetwarzające, filtrujące, normalizujące i wysyłające gdzieś logi (w naszym przypadku do Elasticsearch’a).
- Kibana – interfejs, aplikacja webowa do przeglądania i wizualizacji logów w czasie rzeczywistym.
W poniższym artykule zaprezentuję przykład aplikacji wykorzystującej Javovy Log4J wysyłającej do Logstasha logi za pomocą SocketAppendera (na potrzeby wpisu w Windowsie 10).
Zaczynajmy, jak zwykle bez zbędnego rozpisywania się.
Instalujemy zestaw narzędzi
Ze strony www.elastic.co pobieramy opisywane wyżej trzy narzędzia:
Konfiguracja Elasticsearcha
Ustawienia znajdują się w pliku /config/elasticsearch.yml. Na potrzeby tego wpisy nie było konieczne wprowadzania w nim jakichkolwiek zmian.
Uruchamiamy silnik:
1 |
bin/elasticsearch.bat |
Sprawdzamy status uruchamiając przeglądarkę przechodząc pod adres: http://localhost:9200/.
Przykładowa odpowiedź:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
{ "name" : "h4uYFHH", "cluster_name" : "elasticsearch", "cluster_uuid" : "R55eUPevSS-nswbtNYvE1g", "version" : { "number" : "5.1.1", "build_hash" : "5395e21", "build_date" : "2016-12-06T12:36:15.409Z", "build_snapshot" : false, "lucene_version" : "6.3.0" }, "tagline" : "You Know, for Search" } |
Konfiguracja Logstasha
Tworzymy nowy plik konfiguracji: config/logstash.conf ustawiając serwer do odbioru danych z log4j na porcie 3456:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
input { log4j { mode => "server" host => "localhost" port => 3456 type => "log4j" } } output { elasticsearch { hosts => ["localhost:9200"] } stdout { codec => rubydebug } } |
Jeśli będziemy w aplikacji wykorzystywać bibliotekę log4j w wersji 1.2.17, musimy w pliku \logstash-core\lib\logstash-core_jars.rb zakomentować jedną linię:
1 |
# require_jar( 'org.apache.logging.log4j', 'log4j-1.2-api', '2.6.2' ) |
W przeciwnym wypadku logi nie będą poprawnie odbierane.
Uruchamiamy:
1 |
bin\logstash --debug -f config\logstash.conf |
Konfiguracja Kibany
Uruchamiamy:
1 |
bin\kibana |
W przeglądarce przechodzimy pod adres: http://localhost:5601/
Na pierwszym ekranie klikamy w przycisk „Create” aby dodać pole @timestamp.
Konfiguracja Log4J i SocketAppendera
Tworzymy przykładowy plik konfiguracyjny log4j.properties:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
log4j.rootLogger=DEBUG, stdout, socket log4j.appender.stdout=org.apache.log4j.ConsoleAppender log4j.appender.stdout.Target=System.out log4j.appender.stdout.layout=org.apache.log4j.PatternLayout log4j.appender.stdout.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %-5p %c{1}:%L - %m%n log4j.appender.socket=org.apache.log4j.net.SocketAppender log4j.appender.socket.Port=3456 log4j.appender.socket.RemoteHost=localhost log4j.appender.socket.ReconnectionDelay=10000 log4j.appender.socket.layout=org.apache.log4j.PatternLayout log4j.appender.socket.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %-5p %c{1}:%L - %m%n |
A następnie przykładową klasę wysyłającą komunikaty:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
package net.krzysztofjelonek.elktest; import java.net.URL; import org.apache.log4j.Logger; import org.apache.log4j.PropertyConfigurator; /** * * @author Krzysiek */ public class ELKTest { static Logger logger = Logger.getLogger(ELKTest.class); public static void main(String[] args) throws Exception { PropertyConfigurator.configure(new URL("file:/e:\\Software\\ELK\\logstash-5.1.1\\config\\log4j.properties")); long logCounter = 1; while (true) { logger.info("Testowy log " + logCounter++); Thread.sleep(1000); if (logCounter % 10 == 0) { logger.error("Testowy error log", new Exception()); } } } } |
Co 10 sekund zostanie zarejestrowany log error ze stack trace’em.
Zobaczmy
Uruchamiamy kolejno Elasticsearcha, Logstasha, Kibanę i naszą przykładową aplikację wysyłającą logi.
Przechodzimy do zakładki Discover w Kibanie i widzimy w czasie rzeczywistym wszystkie zdarzenia:
Możemy zdefiniować własne kolumny przeglądu wybierając je z listy po lewej stronie:
Bardzo szybko wyszukujemy interesujące nas zdarzenia. Po wpisaniu w polu wyszukiwania np. wartości: *Exception*, zobaczymy wszystkie wyjątki aplikacji.
Po rozwinięciu danej pozycji uzyskujemy szczegółowe informacje:
Panele i wizualizacja danych
Jednak najlepszą sprawą jest możliwość dowolnego konfigurowania dashboardów, dzięki którym możemy mieć szybki dostęp do poglądu sytuacji. Zobaczcie kilka przykładów:
Podsumowanie
Cały zestaw ELK Stack daje nam ogromnie możliwości przetwarzania logów wytwarzanych przez różne aplikacje takie jak np. Apache, NGINX, Tomcat, czy wszystkie silniki bazodanowe. Jako dane wejściowe do Logstasha możemy podpiąć nawet zwykłe pliki tekstowe, które zostaną odpowiednio znormalizowane i wysłane do Elasticsearcha.
Świetna sprawa, polecam.
Rabat na zestaw książek z serii R.C. Martina
Jest zniżka w Helionie na must have każdego programisty – zestaw od R.C. Martina: „Czysty kod”, „Mistrz czystego kodu” i wydany w tym roku „Software Craftsman” 🙂 3 ebooki za 84 zł, w druku 115 zł.
Trzeba przejść trochę niżej – do zakładki „Kup w zestawie”.
Podsumowując: cały zestaw w druku 115 zł lub 84 zł gdy wolimy ebooki.
ELK jest świetny, używam w pracy i jestem bardzo zadowolony. Jedyne co moim zdaniem bywa ciężkie to właściwa konfiguracja dashboardów, tak aby pokazywały to co chcesz zobaczyć. U mnie w zespole wielu się z tym zmaga. Na ogół pewnie jedna osoba może stworzyć jeden ogólny dashboard z wszystkimi wykresami a potem inni mogą sobie ewentulanie dodawać filtry. Jeśli jednak chcesz stworzyć dashboard to na ogół musisz spędzić nad tym kilka godzin. Może mógłbyś napisać kiedyś jakiś tutorial na ten temat?
Dodam jeszcze, że pisanie konfiguracji logstasha też może wymagać troche trudu jeśli masz swoją aplikacje, która produkuje logi w jakimś tam formacie ustalonym przez kogoś kiedyś a nie pasującym do domyślnych pluginów.
Aha i dosyć irytujące bywa zmaganie się z różnymi wersjami ElasticSearch czy Kibany. Te projekty idą dosyć szybko i jest dużo breaking changes pomiędzy wersjami, konfiguracja dashboardów też się zmienia i trzeba się praktycznie na nowo tego uczyć przy każdej nowej kibanie.