Logfiles, zoals de Apache access logs, zijn niet alleen nuttig voor troubleshooting. Wil je trends op de lange termijn spotten? Met de Elastic Stack kun je data uit allerlei logfiles indexeren, analyseren en visualiseren. In deze workshop leggen we de basisprincipes uit.

Er bestaan al verschillende tools om logfiles te analyseren. Voor Apache is er bijvoorbeeld AWStats en voor syslog LogAnalyzer. Aan elk van die tools kleven wel enkele nadelen: ze zijn specifiek ontwikkeld voor één applicatie, tonen niet altijd realtime data, kunnen moeilijk met data van meerdere servers omgaan of zijn niet eenvoudig aan te passen aan jouw wensen. Elastic Stack is een erg krachtig en flexibel alternatief om alle mogelijke logfiles te analyseren. De configuratie neemt wel meer tijd in beslag, want de Elastic Stack bestaat uit verschillende componenten. In zijn eenvoudigste vorm heb je Elasticsearch, Logstash en Kibana nodig. Tot voor kort was de stack dan ook wel ekend als de ELK-stack, naar analogie met de bekende LAMP-stack (Linux, Apache, MySQL, PHP). Ook kwamen de versienummers van de verschillende componenten niet overeen met elkaar. Vanaf de release van Elasticsearch 5.0 krijgt elke component hetzelfde versienummer en spreekt men van de Elastic Stack. Let wel op als je online documentatie raadpleegt, want Elastic Stack is een vrij jong product en de ontwikkeling verloopt nog erg snel. Documentatie van oudere versies is daardoor niet altijd even bruikbaar!

Componenten

Een typische Elastic Stack bestaat uit twee tot vijf componenten. De volgende applicaties zijn het absolute minimum om aan de slag te gaan:

          Elasticsearch: om data uit logfiles te indexeren en nadien te doorzoeken;

          Kibana: om data uit Elasticsearch te visualiseren.

In zijn meest eenvoudige vorm schrijf je dus rechtstreeks data naar Elasticsearch om ze nadien via Kibana weer op te vragen. Zo bestaat er bijvoorbeeld een Elasticsearch output plugin voor rsyslog. Op die manier kun je (bepaalde) syslog-entries forwarden naar een Elasticsearch-installatie. Maar in de praktijk voegt men meestal nog een derde component toe: Logstash. Dat is als het ware een compatibiliteitslaag tussen de applicatie waarvan je data wilt inlezen en Elasticsearch. Logstash bevat een vijftigtal input plugins om data in te lezen via allerlei protocols, zoals bijvoorbeeld syslog of tekstbestanden. Via filters transformeer je die data (indien gewenst) in het juiste formaat en met de Elasticsearch output plugin forward je het resultaat naar Elasticsearch. Om data van verschillende servers te forwarden naar de Elastic Stack bestaan er eenvoudige agents, de zogenaamde Beats. Met de Filebeat-agent forward je bijvoorbeeld een logfile van een webserver naar Logstash op jouw Elastic-server. Tot slot wordt Kibana vaak verder beveiligd met een reverse proxy, zoals Apache of nginx.

Server en client(s)

Een Elastic Stack maak je zo eenvoudig of complex als je zelf wilt. Voor deze workshop werken we een typische Elastic Stack-installatie uit, zonder te diep in te gaan op allerlei configuratiedetails. Daarvoor werken we met twee servers:

          Een webserver, waarop we Filebeat installeren om de Apache access logs te forwarden.

          Een Elastic-server, waarop we Elasticsearch, Logstash en Kibana installeren. In Logstash configureren we een Filebeat input plugin en Elasticsearch output plugin.

Beide servers draaien Ubuntu 16.04 Server, maar op andere apt- of yum-gebaseerde distributies is de installatie even eenvoudig. Je kunt onze configuratie zo toepassen bij je thuis of zelfs in kleine(re) bedrijfsomgevingen. In dat laatste geval raden we je wel aan om de installatie voldoende te beveiligen. Zo dien je de Filebeat-communicatie tussen beide servers te encrypten en ook Kibana kun je beter voorzienvan TLS-encryptie (al dan niet via een reverse proxy). Tot slot schakel je gebruikersauthenticatie in voor Elasticsearch en Kibana om precies te bepalen wie welke data mag bekijken. Meer informatie over al die onderwerpen vind je in de uitstekende documentatie op www.elastic.co/guide.

Filebeat

Om te beginnen installeren we Filebeat op onze webserver. Daarvoor gebruiken we Elastic’s officiële apt-repository. Hoe je die precies configureert, lees je op http://bit.ly/2lL0Q3C (of http://bit.ly/2kmasoC voor de yum-repository). Installeer het filebeat-pakket en open vervolgens het bestand /etc/filebeat/filebeat.yml. Aan het begin staan de zogenaamde prospectors gedefinieerd, oftewel de bestanden die je wilt forwarden. Standaard zal Filebeat alle bestanden met .log-extensie onder /var/log forwarden, maar wij zijn enkel geïnteresseerd in /var/log/apache2/access.log. De standaardconfiguratie stuurt de data ook rechtstreeks naar Elasticsearch, terwijl wij kiezen om dit via Logstash te doen. Vervang daarom ook de output.elasticsearch-entry door een output.logstash-entry onder het kopje Outputs. Het resultaat van onze aanpassingen zie je in afbeelding 1 (192.168.1.46 is het ip-adres van onze Elasticsearch-server). Meer uitleg over de beschikbare parameters vind je in het bestand filebeat.full.yml. Start nu de filebeat-service:

systemctl enable filebeat

systemctl start filebeat

en bekijk de logfile /var/log/filebeat/filebeat. Daar krijg je een heleboel connection refused-fouten te zien. Dat is normaal, aangezien we Logstash nog niet geconfigureerd hebben.

Logstash

Activeer nu de Elasticsearch-repository op de Elasticsearch-server en installeer Java 8 (niet 9!) en het logstash-pakket. Voor Java mag je zowel Oracle’s versie als OpenJDK gebruiken (pakket openjdk-8-jre-headless in Ubuntu). Onder /etc/logstash vind je verschillende configuratiebestanden. Probeer je Logstash op te starten, dan zie je in de logfile (/var/log/logstash/logstash-plain.log), dat dit niet lukt voordat je extra configuratie toevoegt in de conf.d-directory. Logstash moet immers weten met welke input- en output-plugins het aan de slag moet. Maak dus een bestand input.conf aan met daarin de code uit afbeelding 2. Daarmee start Logstash een service, die luistert op poort 5044 voor inkomende Filebeat-verbindingen. Als output gebruiken we voorlopig een tekstbestand. Zo kunnen we de communicatie tussen Filebeat en Logstash al testen zonder Elasticsearch erbij te betrekken. De benodigde code daarvoor is erg eenvoudig en zie je in afbeelding 3. Tot slot vervang je 127.0.0.1 door het IP-adres van de Elastic-server bij de optie http.port in logstash.yml, bijvoorbeeld:

http.host: “192.168.1.46”

Doe je dat niet, dan kunnen enkel services op de Elastic-server zelf communiceren met Logstash en werkt onze Filebeat-verbinding niet.

Eerste test

Start vervolgens de logstash-service en houd de filebeat.log (op de webserver) en logstash-plain.log (op de Elastic-server) in het oog met tail -F. Is er ondertussen activiteit op je webserver, dan zou je verschillende entries in de logfiles moeten zien en maakt Logstash het outputbestand output-test.log aan. In dat bestand zie je de eigenlijke log entries uit Apache’s error log op de webserver. Elke entry bestaat uit meerdere velden. De oorspronkelijke tekst uit de access.log vind je in het message-veld. Zowel Filebeat als Logstash voegen extra velden toe met nuttige informatie, zoals timestamp, host, source of type. Op die velden kun je achteraf de data doorzoeken, sorteren of visualiseren in Kibana. Het is dus van groot belang om jouw data met de correcte velden in Elasticsearch te indexeren. Voorlopig is onze data nog niet erg doorzoekbaar, want alle relevante informatie zit samen in het message-veld. Dat moeten we nog even oplossen!

Filters

We hebben in Logstash reeds een input- en een outputplugin geconfigureerd, maar de belangrijkste hebben we nog niet vermeld: filter plugins. De laatste Logstash-versie bevat bijna vijftig verschillende filter plugins om de data te manipuleren. Zo kun je bijvoorbeeld timestamps of data in verschillende formaten omzetten, hostnames in IP-adressen omzetten (of omgekeerd) en GeoIP-informatie toevoegen. Een erg krachtig en vaakgebruikt filter is grok. Met behulp van reguliere expressies splitst grok één message-veld op in meerdere velden, die afzonderlijk doorzoekbaar zijn. Gelukkig zijn wij niet de eerste met dat idee. Er bestaan dan ook heel wat templates voor grok om logfiles van populaire open source software te interpreteren. Het volgende commando toont de directories op je systeem met voorgeïnstalleerde templates:

find /usr/share/logstash -type d -name patterns

Extra templates installeren is mogelijk, maar hoeft niet om Apache access logs in lezen. Plaats de code uit afbeelding 4 in het bestand /etc/logstash/conf.d/filter.conf om de data correct te indexeren. Herstart nu Logstash, controleer of logstash-plain.log geen foutmeldingen bevat en wacht tot er nieuwe entries verschijnen in output-test.log. Als alles correct geconfigureerd is, krijg je nu heel wat extra velden te zien: request, agent, referrer, response, enzovoorts. Tip: installeer het jq-pakket om de Logstash-output in JSON-formaat iets leesbaarder weer te geven in je terminal (zie afbeelding 5).

Elasticsearch

Intussen krijgen we onze access logs via Filebeat en Logstash in het correcte formaat op de Elastic-server. Maar ons output-test.log-bestand is natuurlijk nauwelijks eenvoudiger te doorzoeken dan het originele access.log-bestand! Dat probleem los je op door de data uit Logstash in Elasticsearch te bewaren. Installeer dus het Elasticsearch-pakket en start de Elasticsearch-service:

systemctl enable elasticsearch

systemctl start elasticsearch

Controleer ook of er geen foutmeldingen staan in /var/log/elasticsearch/elasticsearch.log. Voor de rest hoef je niets te wijzigen aan de Elasticsearch-configuratie: voor onze workshop volstaat de standaardconfiguratie. Open nu het bestand /etc/logstash/conf.d/output.conf en vervang de eerder geconfigureerde output door de code uit afbeelding 6. De Elasticsearch output-plugin bevat overigens erg veel opties, maar die hebben we hier (nog) niet nodig. Herstart nu Logstash en controleer wederom of er geen errors gelogd worden. Wacht even tot er nieuwe data in de Apache error logs verschijnt en voer dan het commando uit afbeelding 7 uit op de Elastic-server. Heeft Logstash data weggeschreven in Elasticsearch, dan zie je hier een index staan met de naam logstash-<datum>. Met die indexnaam kan je via curl individuele logentries opvragen, maar erg gebruiksvriendelijk is dat niet. In afbeelding 8 zie je bijvoorbeeld hoe we alle GET-requests opvragen. Maar aangezien we weten dat onze setup werkt, gaan we meteen over naar de laatste stap: de installatie van Kibana

Kibana

 

Na installatie van het Kibana-pakket moet je even de configuratie in /etc/kibana/kibana.yml nakijken. Zo is Kibana standaard enkel toegankelijk vanaf localhost. Dat werkt natuurlijk prima als je nog een reverse proxy zou installeren. Voor deze workshop gaat dat echter iets te ver, dus willen we rechtstreeks naar Kibana surfen. Daarvoor vul je het IP-adres van je Elastic-server in bij volgende parameter:

http.host: “192.168.1.46”

Start nu Kibana:

systemctl enable kibana

systemctl start kibana

en surf met je browser naar poort 5601 op je Elastic-server. Je komt nu terecht in het tabblad Management waar je een zogenaamd index pattern moet instellen. Als je geen gekke dingen gedaan hebt bij de configuratie van Logstash of Elasticsearch, mag je de standaardinstellingen aanvaarden door op Create te klikken. Kibana is nu klaar voor gebruik!

Zoeken

Via de navigatiebalk links krijg je toegang tot Kibana’s belangrijkste functies: Discover, Visualize en Dashboard. Met de Discover-functie zie je standaard alle logberichten van het laatste kwartier. De grafiek bovenaan toont meteen hoe die berichten in de tijd verdeeld zijn. Het zoekbereik pas je op verschillende manieren aan: door op één specifieke tijdsstip in de grafiek te klikken, door een bereik in de grafiek te selecteren om daarop in te zoomen of door op de knop ‘Last 15 minutes’ linksboven te klikken. Met die laatste optie stel je het gewenste bereik precies in, zowel relatief (bijvoorbeeld het laatste uur) als absoluut (bijvoorbeeld van 18/03 19:20 tot 18/03 20:50). Tot slot is het ook mogelijk om een auto refresh interval in te stellen van pakweg vijf of tien seconden. Dat is erg handig om in realtime logs op te volgen bij het troubleshooten van problemen.

Heb je het gewenste bereik afgebakend? Dan is het tijd om de berichten verder te filteren op basis van de verschillende velden. In de balk links klik je op het veld waarin je geïnteresseerd bent, bijvoorbeeld response (dat is de statuscode van Apache voor een http request). Kibana toont dan de vijf meest courante waardes voor dat veld. Klik vervolgens op het vergrootglas met het +-icoontje om enkel de berichten te tonen met die specifieke response waarde. Bovenaan verschijnt er nu een extra tekstvak met jouw filter. Zodra je de muis boven dat vak houdt, zie je een aantal kleine knopjes om het filter uit te schakelen, te verwijderen of aan te passen. Herhaal die procedure voor andere velden als je op zoek bent naar berichten met een combinatie van verschillende eigenschappen, bijvoorbeeld een response code van 404 voor een request van de url /admin. Wil je niet alle velden van de gevonden berichten zien? Selecteer dan de gewenste velden in de balk links en klik op de add-knop om de weergave van de zoekresultaten aan te passen. 

Visualiseren

Filters voor zoekopdrachten vormen het startpunt om data te visualiseren. Bewaar daarom jouw filter via de Save-knop rechtsboven en ga vervolgens naar het tabblad Visualize. Daar krijg je de keuze uit een tiental visualisatietypes, zoals een staaf-, lijn- of taartdiagram, een tag cloud of een tabel. Selecteer vervolgens de eerder bewaarde zoekopdracht en configureer het gekozen visualisatietype. Wil je bijvoorbeeld een taartdiagram maken met de meest courante waardes van een bepaald veld? Daarvoor moet je een sub bucket toevoegen, kies je bij Aggregation voor Terms en selecteer je het gewenste veld (zie afbeelding 10). Voor meer informatie kun je het beste Kibana’s online documentatie raadplegen. Zodra je tevreden bent met jouw visualisatie, bewaar je ze via de Save-knop rechtsboven.

De laatste stap om jouw data inzichtelijk te maken in Kibana is het configureren van een eigen dashboard. Een dashboard bevat één of meerdere bewaarde zoekopdrachten of visualisaties. Zo zie je in één oogopslag een samenvatting van alle essentiële informatie in jouw logfiles. Uiteraard kun je ook meerdere dashboards bewaren, bijvoorbeeld om achteraf op te roepen als je specifieke problemen wilt troubleshooten. In afbeelding 11 zie je een voorbeeld van een eenvoudig dashboard. 

Conclusie

De Elastic Stack is een erg krachtige oplossing om logfiles te doorzoeken, te analyseren en te visualiseren. De installatie van de verschillende componenten is in de basis niet zo moeilijk. In deze workshop hebben we wel een aantal stappen achterwege gelaten, met name op het gebied van security. Voor een goed beveiligde installatie in een zakelijke omgeving is de procedure dus iets complexer. Het correct configureren van de filter plugins in Logstash kan ook behoorlijk tijdrovend zijn. Gelukkig vind je voor heel wat software kant-en-klare templates om je snel op weg te helpen.

Tot slot kost ook het uitwerken van aangepaste zoekopdrachten en visualisaties in Kibana wel wat tijd en moeite. Het resultaat mag er echter zijn: één centrale tool voor alle logfiles van al jouw systemen, met filters en visualisaties waarop zelfs de verstokte commandline-fanatiekeling jaloers is. De Elastic Stack is wat ons betreft dus een absolute aanrader voor systeem- of applicatiebeheerders, die een beter zicht willen krijgen op hun logfiles.