Logovanie z webových aplikácií cez `logstash` do ElasticSearchu

Ukážeme si, ako možno logovať z webovej aplikácie rovno do ElasticSearchu, nad ktorým možno potom fulltextovo vyhľadávať.

Ingrediencie do receptu:

  • Maven
  • Spring Boot
  • SLF4j a Logback
  • Logstash
  • ElasticSearch

Maven: POM + Spring Boot (+ slf4j + Logback)

Vytvoríme pom.xml, v ktorom nadeklarujeme závislosť na Spring Boot.

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>sk.upjs.ics.novotnyr</groupId>
    <artifactId>spring-logstash-es-demo</artifactId>
    <version>0.0.1-SNAPSHOT</version>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.1.4.RELEASE</version>
    </parent>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
    </dependencies>
</project>

V rámci Spring Boot automaticky dostaneme závislosť na slf4j i na Logbacku.

Spring Boot

Vytvoríme kontrolér, v ktorom budeme logovať požiadavky cez slf4j.

package sk.upjs.ics.novotnyr.sled;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@EnableAutoConfiguration
public class MainController {

    private static final Logger logger = LoggerFactory.getLogger(MainController.class);

    @RequestMapping("/")
    public String handle() {
        logger.info("Handling a request");
        return "OK";
    }

    public static void main(String[] args) {
        SpringApplication.run(MainController.class);
    }
}

Spustíme to!

Spusťme

mvn spring-boot:run

a navštívme

http://localhost:8080/

Uvidíme nápis OK.

Logstash: agent zbierajúci dáta

  • Stiahnime logstash z http://logstash.net/
  • Rozbaľme ho do vhodného adresára (C:\java\logstash)

Agenta Logstash zatiaľ nespúšťame, potrebujeme dokonfigurovať naše demo.

Logstash: prepojenie Logbacku a Logstashu

Teraz nastavíme appendery Logbacku tak, aby posielali dáta cez súbor do agenta Logstashu.

  • Poobdivujeme projekt Logstash-Logback-Encoder
  • Do pom.xml dodáme deklaráciu:

    <dependency>
      <groupId>net.logstash.logback</groupId>
      <artifactId>logstash-logback-encoder</artifactId>
      <version>3.0</version>
    </dependency>
    
  • Vytvoríme logback.xml. V ňom vytvoríme appender, ktorý bude logovať do súboru (s dennou rotáciou) vo formáte, ktorému bude rozumieť agent Logstashu. Dosiahneme to použitím encodera LogstashEncoder v tradičnom súborovom appenderi.

    <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
        <encoder>
            <Pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</Pattern>
        </encoder>
    </appender>
    
    <appender name="LOGSTASH"
        class="ch.qos.logback.core.rolling.RollingFileAppender">
        <File>/var/log/sled/sled.log</File>
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <fileNamePattern>/var/log/sled/sled-%d{yyyy-MM-dd}.log</fileNamePattern>
        </rollingPolicy>
        <encoder class="net.logstash.logback.encoder.LogstashEncoder" />
    </appender> 
    
    <root level="INFO">
        <appender-ref ref="CONSOLE" />
    </root>
    
    <logger name="sk.upjs.ics.novotnyr.sled" level="DEBUG">
        <appender-ref ref="LOGSTASH" />
    </logger>
    

Popri tom vytvoríme druhý appender, ktorý bude logovať na štandardný výstup (inak by sme v konzole toho veľa neuvideli, a museli by sme obdivovať len logstashovský súbor).

Ďalej definujeme dva loggery: koreňový logger bude logovať len hlášky úrovne INFO a vyššej do konzoly, a logger pre aplikáciu začne posielať DEBUG a významnejšie hlášky jednak do konzoly a jednak do Logstashu (kumuláciu appenderov zabezpečuje aditivita appenderov).

Spustíme to!

Spusťme mvn spring-boot:run, navštívme http://localhost:8080/ a uvidíme, ako prebieha logovanie v JSONovskom formáte. Ukážková hláška vyzerá nasledovne (s formátovaním):

{
    "@timestamp": "2014-08-06T10:47:16.236+02:00",
    "@version": 1,
    "message": "Handling a request",
    "logger_name": "sk.upjs.ics.novotnyr.sled.MainController",
    "thread_name": "http-nio-8080-exec-1",
    "level": "INFO",
    "level_value": 20000,
    "HOSTNAME": "RN-PC"
}

Logstash: agent zbierajúci dáta a jeho konfigurácia

Konfigurák

V našom deme vytvoríme konfigurák pre logstash: src\main\resources\logstash.conf. Logstash bude obdivovať súbor sled.log v duchu unixovského tailu, a novopríchodzie hlášky bude posielať na konzoli.

Obsahom nech je:

input {
  file {
    type => "sled-dev"
    path => "C:/var/log/sled/sled.log"
    codec => "json"
  }
}

output { 
    stdout {}
}

Pokiaľ ste na Windowse, musíte do atribútu path uviesť absolútnu cestu, s normálnymi lomkami / a veľkým písmenom jednotky (C:). V opačnom prípade bude Logstash protestovať, že

Error: Neither current working directory (null) nor pathname (/var/log/sled/sled.log) led to an absolute path {:level=>:error}←[0m

Príčinou je chyba LOGSTASH-430.

Spustenie Logstashu

C:\Projects\spring-logstash-es-demo>C:\java\logstash\bin\logstash agent -f src/main/resources/logstash.conf

Logstash sa spustí:

←[33mUsing milestone 2 input plugin 'file'. This plugin should be stable, but if you see strange behavior, please let us know! For more information on plugin milestones, see http://logstash.net/docs/1.4.2/plugin-milestones {:level=>:warn}←[0m

Loggovod

Ak začneme obnovovať stránku v prehliadači, Logstash začne logovať do svojej konzoly:

2014-08-06T08:58:51.831+0000 RN-PC Handling a request

ElasticSearch

Logstash vie logovať do ElasticSearchu, kde vieme radostne vyhľadávať v logoch, koľko sa zažiada.

Rozbehanie ElasticSearch

  • Stiahneme ElasticSearch a rozbalíme napr. do C:\java\elasticsearch
  • Stiahneme plugin elasticsearch-head, vďaka ktorému dostaneme prehľadné používateľské rozhranie pre dopytovanie sa nad ES.

    C:\java\elasticsearch\bin\plugin -install mobz/elasticsearch-head
    
  • Spustíme ElasticSearch

    C:\java\elasticsearch\bin\elasticsearch
    
  • Otvoríme GUI:

    explorer http://localhost:9200/_plugin/head/
    

ElasticSearch + Logstash + Demo

Upravíme náš logstash.conf, kde dodáme logovanie do Elasticu. Je to jednoduché: do output sekcie dodáme klauzulu pre elasticsearch:

output { 
    elasticsearch { 
        host => localhost 
    }
    stdout {}
}

Reštartnime Logstash.

Obdivujme hlášky

Vojdime do elasticsearch-head. Na karte Browser uvidíme zoznam všetkých indexov a uvidíme, že Logstash automaticky vytvoril nový index. Kliknime naň a uvidíme zoznam hlášok, ktoré vieme obdivovať.

elasticsearch-head

Ak chceme, môžeme sa nad nimi dopytovať pomocou elasticsearchovského jazyka: môžeme nájsť len

{
  "query": {
    "ids": {
      "values": [
        "vT9xRynhRp2Hj4_6LBEXRw", "69sa2wTbSWC23anZK_TNaw"
      ]
    }
  }
}

To je všetko!

Veľmi rýchlo a elegantne sme skombinovali asi sedemnásť technológií :-) Logovacia hláška zo springovského kontroléra putuje cez:

  1. slf4j,
  2. Logback,
  3. súbor,
  4. Logstash až do
  5. ElasticSearchu,

… kde nad ňou môžeme vykonávať všakovaké dopyty.

Zdroják projektu

Zdroják projektu sa nachádza na GitHube.

4 thoughts on “Logovanie z webových aplikácií cez `logstash` do ElasticSearchu

  1. Ahoj, ak by si nad to všetko dal ešte kibanu bolo by to uno-tutti. Cez kibanu to vieš krásne prezerať :)

  2. A pri troche stastia by si to vedel nasypat priamo do ELK. Niekde som to cital a vypadalo to fajn. Tym Padom by si nepotreboval Logstash co sluzi iba na transport :)

Pridaj komentár

Vaša e-mailová adresa nebude zverejnená. Vyžadované polia sú označené *