Published by

Il y a 9 ans -

Temps de lecture 20 minutes

Logstash, ElasticSearch, Kibana – S01E02 – Analyse orientée business de vos logs applicatifs

Les logs d’une application sont utilisés le plus souvent afin d’analyser un incident en production.
Ces lignes parfois trop complexes, même pour un développeur, sont générées par Go voir Tera toutes les heures, suivant votre infrastructure.
Elles sont trop souvent sous-exploitées au regard du nombre d’informations précieuses disponibles.

Nous allons voir comment mettre à profit nos logs applicatifs afin de faire de l’analyse orientée "business" grâce à Logstash, ElasticSearch et Kibana.
Dans ce billet de blog, nous serons à la tête d’un site fictif de vente en ligne, et essaierons de répondre aux questions suivantes :

  • Quel est le ratio recherches / ventes ?
  • Quels sont les critères de recherches les plus utilisés ?
  • Quels sont les produits les plus consultés ?
  • Quels sont les produits les plus vendus (iPhone 5S, Galaxy S4) ?
  • Quels sont les modèles les plus vendus (iPod Shuffle Bleu, iPhone 5S 64 Go Argent) ?
  • Qui sont mes plus fidèles clients ? Où sont-ils (géo)localisés ?
  • Quelle est la proportion homme / femme de mes acheteurs ?
  • Où nous situons-nous par rapport à nos objectifs de ventes ?
  • etc…

Format des logs

Ce paragraphe vous présente le format des logs que nous allons exploiter.

Vous pouvez utiliser l’application log-generator disponible sur Github afin de générer des logs facilement.
Voici un exemple permettant de générer 10 logs, puis 100 logs toutes les secondes sur 2 threads :

git clone https://github.com/vspiewak/log-generator.git
cd log-generator
mvn clean package
java -jar target/log-generator-0.0.1-SNAPSHOT.jar -n 10
java -jar target/log-generator-0.0.1-SNAPSHOT.jar -n 100 -r 1000 -t 2

Voici quelques exemples de recherches/visites d’un produit :

08-10-2013 16:33:46.585 [pool-2-thread-1] INFO com.github.vspiewak.loggenerator.SearchRequest - id=1,ip=92.90.16.222,category=Portable
08-10-2013 16:33:47.627 [pool-1-thread-1] INFO com.github.vspiewak.loggenerator.SearchRequest - id=12,ip=90.33.93.13,category=Mobile,brand=Samsung
08-10-2013 16:33:49.628 [pool-1-thread-1] INFO com.github.vspiewak.loggenerator.SearchRequest - id=35,ip=82.121.185.168,category=Portable,brand=Apple,options=Ecran 11|Disque 128Go
08-10-2013 16:33:49.629 [pool-1-thread-1] INFO com.github.vspiewak.loggenerator.SearchRequest - id=41,ip=157.55.34.94,brand=Apple,name=iPhone 5C,model=iPhone 5C - Blanc - Disque 16Go,category=Mobile,color=Blanc,options=Disque 16Go,price=599.0

Dans l’exemple ci-dessus, les logs représentent respectivement :

  • une requête (id 1) de recherche sur la catégorie "Portable", venant de l’ip 92.90.16.222
  • une requête (id 12) de recherche sur la catégorie "Mobile" et la marque "Samsung", venant de l’ip 90.33.93.13
  • une requête (id 35) de recherche sur la catégorie "Portable" et la marque "Apple", avec un écran 11 pouces et un disque 128 Go, venant de l’ip 82.121.185.168
  • une visite (id 41) du produit "iPhone 5C", modèle blanc avec une capacité de 16Go, au prix de 599 €, venant de l’ip 157.55.34.94

Voici un exemple de log d’une vente :

08-10-2013 16:33:50.586 [pool-2-thread-1] INFO com.github.vspiewak.loggenerator.SellRequest - id=53,ip=193.248.203.28,email=client16@gmail.com,sex=F,brand=Google,name=Nexus 10,model=Nexus 10 - Disque 16Go,category=Tablette,options=Disque 16Go,price=399.0

Ici, le log nous informe que notre cliente a acheté une Tablette Nexus 10 de capacité 16Go au prix de 399€.

Logstash

Logstash est un pipe permettant de collecter, parser, et stocker des logs à l’aide d’entrées, de filtres et de sorties (input, filter, output).
La phase de parsing permet d’ajouter de la sémantique à notre événement, en ajoutant, modifiant ou supprimant des champs, des tags, des types, etc…

Cet article utilise la version 1.2.1 de Logstash, qui comporte entre autres :

  • 37 types d’entrée
  • 39 filtres
  • 51 types de sortie

De quoi vous brancher à pas mal de systèmes au sein de votre SI…
Le JAR est disponible à cette adresse : https://download.elasticsearch.org/logstash/logstash/logstash-1.2.1-flatjar.jar

Configuration minimale

 Créez un fichier de configuration minimaliste nommé "logstash-logback.conf" :

input {
  stdin {} 
}

output {
  stdout { debug => true }
}

Lancez Logstash avec cette configuration :

java -jar logstash-1.2.1-flatjar.jar agent -f logstash-logback.conf

Copiez/collez dans l’entrée standard une ligne de log :

02-10-2013 14:26:27.724 [pool-10-thread-1] INFO com.github.vspiewak.loggenerator.SearchRequest - id=9205,ip=217.109.49.180,cat=TSHIRT

Logstash affichera alors sa représentation au moment de la réception :

{
       "message" => "02-10-2013 14:26:27.724 [pool-10-thread-1] INFO com.github.vspiewak.loggenerator.SearchRequest - id=9205,ip=217.109.49.180,cat=TSHIRT",
    "@timestamp" => "2013-10-02T14:08:52.356Z",
      "@version" => "1",
          "host" => "D-CZC1444LWN-LX"
}

Le champ message contient la ligne de log brute, @timestamp contient la date de l’événement.

Un œil averti aura remarqué que le champ @timestamp n’est pas le même que la ligne originale.
Logstash a en effet pris la date d’insertion ne sachant pas quel "bout" de log utiliser.

Le premier travail va consister à parser le log à l’aide d’une regex…

Ajout de sémantique avec le filtre Grok

Le filtre grok va nous permettre de parser les lignes de logs et leur donner de la sémantique.

Logstash vient avec plus d’une centaine d’expressions régulières prédéfinies (disponibles ici : https://github.com/logstash/logstash/tree/master/patterns).
Par exemple, le pattern "COMBINEDAPACHELOG" du fichier grok-patterns permet de matcher les lignes de logs d’un serveur Apache.

Vous pouvez utiliser 2 syntaxes :

  • %{SYNTAX:SEMANTIC} ou %{SYNTAX:SEMANTIC:TYPE}
  • (?<field_name>the pattern here)

La première syntaxe réutilise un pattern Logstash (ex: MONTHDAY, NOTSPACE, LOGLEVEL, …), SEMANTIC étant le nom du champ à mapper.
Vous pouvez aussi préciser le type du champ (integer, float, String) via le paramètre TYPE.
La deuxième syntaxe vous permet de définir un pattern customisé avec ou sans l’aide de plusieurs patterns "logstash".

Voici une configuration permettant de parser nos logs :

input {
  stdin {} 
}

filter {
   grok {
      match => ["message","(?<log_date>%{MONTHDAY}-%{MONTHNUM}-%{YEAR} %{HOUR}:%{MINUTE}:%{SECOND}.[0-9]{3}) \[%{NOTSPACE:thread}\] %{LOGLEVEL:log_level} %{NOTSPACE:classname} - %{GREEDYDATA:msg}"]
   }
}

output {
  stdout { debug => true }
}

Si vous relancez Logstash, et copiez/collez la première ligne, vous devriez obtenir une sortie similaire :

02-10-2013 14:26:27.724 [pool-10-thread-1] INFO com.github.vspiewak.loggenerator.SearchRequest - id=9205,ip=217.109.49.180,cat=TSHIRT
{
       "message" => "02-10-2013 14:26:27.724 [pool-10-thread-1] INFO com.github.vspiewak.loggenerator.SearchRequest - id=9205,ip=217.109.49.180,cat=TSHIRT",
    "@timestamp" => "2013-10-02T14:13:50.357Z",
      "@version" => "1",
          "host" => "D-CZC1444LWN-LX",
      "log_date" => "02-10-2013 14:26:27.724",
        "thread" => "pool-10-thread-1",
     "log_level" => "INFO",
     "classname" => "com.github.vspiewak.loggenerator.SearchRequest",
           "msg" => "id=9205,ip=217.109.49.180,cat=TSHIRT"
}

On remarque que Logstash a parsé les champs log_date, thread, log_level, classname et msg.

Lorsque Grok échoue, il ajoute le tag "_grokparsefailure" à votre évènement :

This line will fail obviously...
{
       "message" => "This line will fail obviously...",
    "@timestamp" => "2013-10-02T13:36:53.290Z",
      "@version" => "1",
          "host" => "D-CZC1444LWN-LX",
          "tags" => [
        [0] "_grokparsefailure"
    ]
}
Dossier de patterns

Plutôt que d’utiliser une longue expression régulière dans votre configuration, définissez un fichier contenant vos patterns personnalisés.

Créez un dossier "patterns" dans votre répertoire courant.
Créez un fichier "logback" dans le dossier "patterns" contenant :

LOG_DATE %{MONTHDAY}-%{MONTHNUM}-%{YEAR} %{HOUR}:%{MINUTE}:%{SECOND}.[0-9]{3}
#LOGBACK_LOG %{LOG_DATE:log_date} [%{NOTSPACE:thread}] %{LOGLEVEL:log_level} %{NOTSPACE:classname} - %{GREEDYDATA:msg}

Indiquez ensuite à Grok le dossier contenant vos fichiers de patterns via l’attribut "patterns_dir".

La configuration Losgstash devient :

input { 
   stdin {} 
}

filter { 
   grok {
      patterns_dir => "./patterns"
      match => [ "message", "%{LOG_DATE:log_date} \[%{NOTSPACE:thread}\] %{LOGLEVEL:log_level} %{NOTSPACE:classname} - %{GREEDYDATA:msg}"]
   }
}

output {
   stdout { debug => true }
}

Le bon @Timestamp avec le filtre date

Le filtre date est l’un des filtre les plus importants. Il permet en effet de parser une date et de l’utiliser pour le champ @timestamp.
Cette étape est cruciale (souvenez-vous du panel "timepicker" dans Kibana…).

Vous pouvez spécifier les 4 formats de date suivants :

  • "ISO8601" :  timestamp ISO8601 (ex: 2011-04-19T03:44:01.103Z)
  • "UNIX" : temps écoulé depuis epoch en secondes
  • "UNIX_MS" : temps écoulé depuis epoch en millisecondes
  • "TAI64N"
  • un pattern au format org.joda.time.format.DateTimeFormat

Dans notre configuration, nous allons utiliser un pattern au format Joda :

input { 
   stdin {} 
}

filter { 
   grok {
      patterns_dir => "./patterns"
      match => [ "message", "%{LOG_DATE:log_date} \[%{NOTSPACE:thread}\] %{LOGLEVEL:log_level} %{NOTSPACE:classname} - %{GREEDYDATA:msg}"]
   }
}

filter {
   date {
      match => ["log_date","dd-MM-YYYY HH:mm:ss.SSS"]
   }
}

output {
  stdout { debug => true }
}

Le champ @timestamp utilise enfin la date de notre log :

02-10-2013 14:26:27.724 [pool-10-thread-1] INFO com.github.vspiewak.loggenerator.SearchRequest - id=9205,ip=217.109.49.180,cat=TSHIRT
{
  "@timestamp" => "2013-10-02T12:26:27.724Z",
    "@version" => "1",
   "classname" => "com.github.vspiewak.loggenerator.SearchRequest",
       "datas" => "id=9205,ip=217.109.49.180,cat=TSHIRT",
        "host" => "0:0:0:0:0:0:0:1:55773",
   "log_level" => "INFO",
     "logdate" => "02-10-2013 14:26:27.724",
     "message" => "02-10-2013 14:26:27.724 [pool-10-thread-1] INFO com.github.vspiewak.loggenerator.SearchRequest - id=9205,ip=217.109.49.180,cat=TSHIRT",
      "thread" => "pool-10-thread-1",
        "type" => "ibay"
}

Vous pouvez le vérifier en copiant/collant plusieurs fois la même ligne de log, Logstash devrait utiliser le même timestamp.

Parsing d’un champ avec le filtre kv

Le filtre kv s’avère très utile lorsque vous voulez parser un champ de type foo=bar comme par exemple une requête HTTP.

Ajoutez le filtre kv pour notre example :

filter {
   kv {
      field_split => ","
      source => "msg"
   }
}

Logstash parse maintenant notre ligne de vente et ajoute automatiquement les champs category, brand, name, model, color, options et price :

{
  "@timestamp" => "2013-10-08T14:33:49.629Z",
    "@version" => "1",
       "brand" => "Apple",
    "category" => "Mobile",
   "classname" => "com.github.vspiewak.loggenerator.SearchRequest",
       "color" => "Blanc",
        "host" => "0:0:0:0:0:0:0:1:60860",
          "id" => "41",
          "ip" => "157.55.34.94",
   "log_level" => "INFO",
     "logdate" => "08-10-2013 16:33:49.629",
     "message" => "08-10-2013 16:33:49.629 [pool-1-thread-1] INFO com.github.vspiewak.loggenerator.SearchRequest - id=41,ip=157.55.34.94,brand=Apple,name=iPhone 5C,model=iPhone 5C - Blanc - Disque 16Go,category=Mobile,color=Blanc,options=Disque 16Go,price=599.0",
       "model" => "iPhone 5C - Blanc - Disque 16Go",
         "msg" => "id=41,ip=157.55.34.94,brand=Apple,name=iPhone 5C,model=iPhone 5C - Blanc - Disque 16Go,category=Mobile,color=Blanc,options=Disque 16Go,price=599.0",
        "name" => "iPhone 5C",
     "options" => "Disque 16Go",
       "price" => "599.0",
      "thread" => "pool-1-thread-1",
        "type" => "ibay"
}

Conditions

Logstash permet d’utiliser des conditions via la syntaxe :

if EXPRESSION {
  ...
} else if EXPRESSION {
  ...
} else {
  ...
}

Les expressions peuvent contenir :

  • une égalité, comparaison : == != < > <= >=
  • un pattern : =~ !~
  • une inclusion : in  not in
  • un opérateur booléen : and, or, nand, xor
  • un opérateur unaire : !

Filtre mutate

Ajout d’un tag

Le filtre mutate est un filtre "couteaux suisses" permettant une multitude de modifications.

Nous allons ajouter un tag à nos logs afin de différencier les recherches des ventes :

filter {
   if [classname] =~ /SellRequest/ {
      mutate { add_tag => "sell" }
   } else if [classname] =~ /SearchRequest$/ {
      mutate { add_tag => "search" }
   }
}
Conversion de type

Le filtre mutate permet de convertir certains champs en entier, flottant ou string.

Nous ajoutons à notre configuration la conversion des champs id et price :

filter {
  mutate {
    convert => [ "id", "integer" ]  
  }  
  mutate {
    convert => [ "price", "float" ]  
  }   
}
Suppression d’un champ

Toujours avec le filtre mutate, nous allons supprimer le champ "msg".
Nous avons en effet parsé ce champ avec le filtre kv et n’avons plus besoin de ce doublon d’information.

Ajoutez à la suite du dernier bloc de filtre :

filter { 
  mutate {
    remove_field => [ "msg" ]  
  }  
}
Split d’un champ

Pour finir avec le filtre mutate, nous allons splitté notre champ "options" afin d’avoir un tableau d’options.

filter {
   mutate {
      split => [ "options", "|" ]
   }
}

Au final, l’utilisation du filtre mutate nous a permis d’obtenir la sortie suivante :

08-10-2013 16:33:48.586 [pool-2-thread-1] INFO com.github.vspiewak.loggenerator.SellRequest - id=16,ip=78.250.209.114,email=client17@gmail.com,sex=M,brand=Apple,name=Macbook Air,model=Macbook Air - Ecran 13 - Disque 128Go,category=Portable,options=Ecran 13|Disque 128Go,price=1099.0
{
  "@timestamp" => "2013-10-08T14:33:48.586Z",
    "@version" => "1",
       "brand" => "Apple",
    "category" => "Portable",
   "classname" => "com.github.vspiewak.loggenerator.SellRequest",
       "email" => "client17@gmail.com",
        "host" => "macbookpro",
          "id" => 16,
          "ip" => "78.250.209.114",
    "log_date" => "08-10-2013 16:33:48.586",
   "log_level" => "INFO",
     "message" => "08-10-2013 16:33:48.586 [pool-2-thread-1] INFO com.github.vspiewak.loggenerator.SellRequest - id=16,ip=78.250.209.114,email=client17@gmail.com,sex=M,brand=Apple,name=Macbook Air,model=Macbook Air - Ecran 13 - Disque 128Go,category=Portable,options=Ecran 13|Disque 128Go,price=1099.0",
       "model" => "Macbook Air - Ecran 13 - Disque 128Go",
        "name" => "Macbook Air",
     "options" => [
    [0] "Ecran 13",
    [1] "Disque 128Go"
  ],
       "price" => 1099.0,
         "sex" => "M",
        "tags" => [
    [0] "sell"
  ],
      "thread" => "pool-2-thread-1"
}

GeoIP

Le filtre geoip permet d’ajouter des informations de géolocalisation via une adresse ip (ou hostname).
Logstash utilise la base de donnée GeoLite de Maxmind sous license CCA-ShareAlike 3.0. 

Ici j’utilise une version de GeoLite City (format Binary / GZip) téléchargée au préalable sur le site Maxmind plutôt que la version embarquée dans Logstash :

filter {
   geoip {
      source => "ip"
      database => "./GeoLiteCity.dat"
   }
}

Logstash ajoute un champ geoip contenant les précieuses informations de géolocalisations :

"geoip" => {
    "ip" => "217.***.***.180",
    "country_code2" => "FR",
    "country_code3" => "FRA",
    "country_name" => "France",
    "continent_code" => "EU",
    "region_name" => "A8",
    "city_name" => "Paris",
    "postal_code" => "",
    "latitude" => 48.86670000000001,
    "longitude" => 2.3333000000000084,
    "dma_code" => nil,
    "area_code" => nil,
    "timezone" => "Europe/Paris",
    "real_region_name" => "Ile-de-France"
}

GeoIP et Bettermap

Le panel Bettermap de Kibana requiert un champ contenant les coordonnées GPS au format Geo_JSON (format : [ longitude, latitude ]).

Nous allons ajouter un champ "geoip.lnglat" contenant le tableau de coordonnées via le "hack" suivant :

filter {

 # 'geoip.lnglat' will be kept, 'tmplat' is temporary.
 # Both of these new fields are strings.
 mutate {
  add_field => [ "[geoip][lnglat]", "%{[geoip][longitude]}",
                 "tmplat", "%{[geoip][latitude]}" ]
 }

 # Merge 'tmplat' into 'geoip.lnglat'
 mutate {
  merge => [ "[geoip][lnglat]", "tmplat" ]
 }

 # Convert our new array of strings back to float
 # Delete our temporary latitude field
 mutate {
  convert => [ "[geoip][lnglat]", "float" ]
  remove => [ "tmplat" ]
 }

}

Configuration Logstash finale

 Pour rappel, voici le contenu final du fichier de configuration de Logstash :

input {
  stdin {} 
  file {
     path => "/tmp/logstash/*.log"  
  }
}

filter {
   grok {
      patterns_dir => "./patterns"
      match => ["message","%{LOG_DATE:log_date} \[%{NOTSPACE:thread}\] %{LOGLEVEL:log_level} %{NOTSPACE:classname} - %{GREEDYDATA:msg}"]
   }
}

filter {
   date {
      match => ["log_date","dd-MM-YYYY HH:mm:ss.SSS"]
   }
}

filter {
   kv {
      field_split => ","
      source => "msg"
   }
}

filter {
   if [classname] =~ /SellRequest$/ {
      mutate { add_tag => "sell" }
   } else if [classname] =~ /SearchRequest$/ {
      mutate { add_tag => "search" }
   }
}

filter {
   mutate {    
      remove_field => [ "msg" ]
   }  
}

filter {
   mutate {
      convert => [ "id", "integer" ]
   }
   mutate {
      convert => [ "price", "float" ]
   }
}

filter {
   mutate {
      split => [ "options", "|" ]
   }
}

filter {
   geoip {
      source => "ip"
      database => "./GeoLiteCity.dat"
   }
}

filter {
 mutate {
  add_field => [ "[geoip][lnglat]", "%{[geoip][longitude]}", "tmplat", "%{[geoip][latitude]}" ]
 }
 mutate {
  merge => [ "[geoip][lnglat]", "tmplat" ]
 }
 mutate {
  convert => [ "[geoip][lnglat]", "float" ]
  remove_field => [ "tmplat" ]
 }
}

output {
  stdout { debug => true }
  elasticsearch { }
}
08-10-2013 16:33:48.586 [pool-2-thread-1] INFO com.github.vspiewak.loggenerator.SellRequest - id=16,ip=78.250.209.114,email=client17@gmail.com,sex=M,brand=Apple,name=Macbook Air,model=Macbook Air - Ecran 13 - Disque 128Go,category=Portable,options=Ecran 13|Disque 128Go,price=1099.0
{
  "@timestamp" => "2013-10-08T14:33:48.586Z",
    "@version" => "1",
       "brand" => "Apple",
    "category" => "Portable",
   "classname" => "com.github.vspiewak.loggenerator.SellRequest",
       "email" => "client17@gmail.com",
       "geoip" => {
           "area_code" => nil,
           "city_name" => "Paris",
      "continent_code" => "EU",
       "country_code2" => "FR",
       "country_code3" => "FRA",
        "country_name" => "France",
            "dma_code" => nil,
                  "ip" => "78.250.209.114",
            "latitude" => 48.86670000000001,
              "lnglat" => [
      [0] 2.3333000000000084,
      [1] 48.86670000000001
    ],
           "longitude" => 2.3333000000000084,
         "postal_code" => "",
    "real_region_name" => "Ile-de-France",
         "region_name" => "A8",
            "timezone" => "Europe/Paris"
  },
        "host" => "macbookpro",
          "id" => 16,
          "ip" => "78.250.209.114",
    "log_date" => "08-10-2013 16:33:48.586",
   "log_level" => "INFO",
     "message" => "08-10-2013 16:33:48.586 [pool-2-thread-1] INFO com.github.vspiewak.loggenerator.SellRequest - id=16,ip=78.250.209.114,email=client17@gmail.com,sex=M,brand=Apple,name=Macbook Air,model=Macbook Air - Ecran 13 - Disque 128Go,category=Portable,options=Ecran 13|Disque 128Go,price=1099.0",
       "model" => "Macbook Air - Ecran 13 - Disque 128Go",
        "name" => "Macbook Air",
     "options" => [
    [0] "Ecran 13",
    [1] "Disque 128Go"
  ],
       "price" => 1099.0,
         "sex" => "M",
        "tags" => [
    [0] "sell"
  ],
      "thread" => "pool-2-thread-1"
}

La configuration finale de logstash parsera tous les logs générés dans le dossier /tmp/logstash. Vous pouvez lancer la génération de logs via la commande :

java -jar target/log-generator-0.0.1-SNAPSHOT.jar -n 10 -r 1000 -t 2 > /tmp/logstash/app.log

Elasticsearch

Nous allons installer Elasticsearch ainsi que le plugin head afin de stocker nos logs. Nous utiliserons ici la version 0.90.3, comme recommandé dans la documentation Logstash (pour les sorties elasticsearch & elasticsearch_http):

curl -O https://download.elasticsearch.org/elasticsearch/elasticsearch/elasticsearch-0.90.3.zip
unzip elasticsearch-0.90.3.zip
cd elasticsearch-0.90.3/
 
bin/plugin --install mobz/elasticsearch-head

Il ne nous reste plus qu’à lancer Elasticsearch :

./bin/elasticsearch -f
[2013-11-24 20:22:49,444][INFO ][node                     ] [Red Skull II] version[0.90.3], pid[4986], build[5c38d60/2013-08-06T13:18:31Z]
[2013-11-24 20:22:49,445][INFO ][node                     ] [Red Skull II] initializing ...
[2013-11-24 20:22:49,450][INFO ][plugins                  ] [Red Skull II] loaded [], sites []
[2013-11-24 20:22:51,356][INFO ][node                     ] [Red Skull II] initialized
[2013-11-24 20:22:51,357][INFO ][node                     ] [Red Skull II] starting ...
[2013-11-24 20:22:51,448][INFO ][transport                ] [Red Skull II] bound_address {inet[/0:0:0:0:0:0:0:0:9300]}, publish_address {inet[/192.168.1.5:9300]}
[2013-11-24 20:22:54,478][INFO ][cluster.service          ] [Red Skull II] new_master [Red Skull II][SBR_oXvoTySk0ubW8zX2ow][inet[/192.168.1.5:9300]], reason: zen-disco-join (elected_as_master)
[2013-11-24 20:22:54,498][INFO ][discovery                ] [Red Skull II] elasticsearch/SBR_oXvoTySk0ubW8zX2ow
[2013-11-24 20:22:54,508][INFO ][http                     ] [Red Skull II] bound_address {inet[/0:0:0:0:0:0:0:0:9200]}, publish_address {inet[/192.168.1.5:9200]}
[2013-11-24 20:22:54,508][INFO ][node                     ] [Red Skull II] started
[2013-11-24 20:22:54,522][INFO ][gateway                  ] [Red Skull II] recovered [0] indices into cluster_state

Vous pouvez visualiser votre cluster Elasticsearch via le plugin head à l’adresse : http://localhost:9200/_plugin/head
Par défaut, Logstash enverra vos logs dans des indices Elasticsearch nommés "logstash-YYYY-MM-DD".

Template de mapping Elasticsearch

Elasticsearch ne nécessite aucune configuration particulière pour fonctionner avec Logstash. Cependant, pour cet exemple, nous allons désactiver l’analyseur utilisé sur certains champs. Cela s’avère utile pour notre dashboard Kibana qui utilise notamment des panels de type "terms".

curl -XPUT http://localhost:9200/_template/logstash_per_index -d '{             
    "template" : "logstash*",
                  
    "mappings" : {           
        "_default_" : {
           "_all" : {"enabled" : false},
           "properties" : {
              "@timestamp": { "type": "date", "index": "not_analyzed" },
              "ip": { "type" : "ip", "index": "not_analyzed" }, 
              "name": { "type" : "string", "index": "not_analyzed" },
              "model": { "type" : "string", "index": "not_analyzed" },
              "options": { "type" : "string", "index": "not_analyzed" },
              "email": { "type" : "string", "index": "not_analyzed" }

            }             
        }
   }
}'

Cette requête désactive l’analyseur pour les champs "ip", "name", "model", "options" et "email". Cela vous évitera des écueils lors de l’affichage des "top clients" ou "top produits":

Kibana

Pour installer Kibana, il vous faut également un serveur web. L’exemple est donné pour une installation standard d’Apache, mais tout autre serveur web capable de servir des fichiers statiques fera l’affaire.

curl -O https://download.elasticsearch.org/kibana/kibana/kibana-3.0.0milestone4.zip
unzip kibana-3.0.0milestone4.zip
sudo mv kibana-3.0.0milestone4 /var/www/kibana

Vous pouvez désormais accéder à Kibana à l’adresse : http://localhost/kibana

Un dashboard pré-configuré est disponible en téléchargement ici : dashboard.json
Il ne vous reste plus qu’à charger le dashboard via le menu Load > Advanced > Local File.

Sur cette capture d’écran, nous remarquons notamment que :

  • Il y a 20% de ventes, et 80% de recherches
  • 35% des clients sont des femmes
  • 39% des produits vendus sont des baladeurs
  • 254 iPod Touch ont été vendus pour la période de temps sélectionnée
  • 3 requêtes (recherche ou vente) viennent des Etats-Unis

Pour aller plus loin

Des filtres peuvent être créés dynamiquement en cliquant sur les différents éléments du dashboard (notamment les petites loupes). Ils apparaissent dans le panel filtering sous forme de boîtes. En quelques clics, vous pouvez restreindre les résultats de vos queries sur un modèle, une option particulière, ou tout autre champ disponible. Vous aurez notamment la possibilité de suivre l’évolution des achats de téléphone Nexus 4 (modèle 16 Go, couleur Blanc) effectués par des femmes habitant sur Paris pour la période du 15 novembre au 25 décembre.

Sources

Published by

Publié par Vincent Spiewak

Vincent est un consultant passionné ayant rejoint Xebia en Mai 2013. Il aime concevoir des projets innovants dans un cadre Agile. Son expérience tourne autour du monde Java / EE, WOA, et de la conduite du changement. (@vspiewak)

Commentaire

26 réponses pour " Logstash, ElasticSearch, Kibana – S01E02 – Analyse orientée business de vos logs applicatifs "

  1. Published by , Il y a 9 ans

    Bonjour,

    En suivant les étapes sur EC2, jusqu’a l’installation d ES, je lance la commande : $ java -jar logstash-1.2.1-flatjar.jar agent -f logstash-logback.conf
    et là j’ai des erreurs :

    Using 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.2.1/plugin-milestones {:level=>:warn}
    Using milestone 2 filter plugin ‘kv’. 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.2.1/plugin-milestones {:level=>:warn}
    Using milestone 1 filter plugin ‘geoip’. This plugin should work, but would benefit from use by folks like you. Please let us know if you find bugs or have suggestions on how to improve this plugin. For more information on plugin milestones, see http://logstash.net/docs/1.2.1/plugin-milestones {:level=>:warn}
    log4j, [2013-12-27T11:27:16.279] WARN: org.elasticsearch.discovery: [MN-E (Ultraverse)] waited for 30s and no initial state was set by the discovery

    Exception in thread « elasticsearch[MN-E (Ultraverse)][generic][T#3] » org.elasticsearch.discovery.MasterNotDiscoveredException: waited for [30s]
    at org.elasticsearch.action.support.master.TransportMasterNodeOperationAction$3.onTimeout(TransportMasterNodeOperationAction.java:176)
    at org.elasticsearch.cluster.service.InternalClusterService$NotifyTimeout.run(InternalClusterService.java:435)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
    at java.lang.Thread.run(Thread.java:724)

    Avez vous déja eu ce problème,
    En regardant sur le net j’ai vi qu’il faudra installer le plugin bin/plugin -install elasticsearch/elasticsearch-cloud-aws/1.16.0 , mais même avec ça, le problème persiste.

    MERCI

  2. Published by , Il y a 9 ans

    Bonjour,

    l’affichage des warnings est un comportement normal.
    Ils signalent l’utilisation de plugins en Milestone 0, 1 ou 2, versions moins « stable ».
    (cf. http://logstash.net/docs/1.2.1/plugin-milestones)

    L’exception MasterNotDiscoveredException à déjà été rencontrée par un Xebian.
    Utilisez-vous Logstash 1.2.1 conjointement avec Elasticsearch 0.90.3 ?
    En effet, le plugin de sortie Elasticsearch est sensible à la version comme précisé ici:
    http://logstash.net/docs/1.2.1/outputs/elasticsearch

    Une alternative possible est d’utiliser la sortie elasticsearch_http
    (cf. http://logstash.net/docs/1.2.1/outputs/elasticsearch_http)

    Cet article tourne sur Amazon EC2 sans nécessiter l’utilisation du plugin elasticsearch-cloud-aws.

    Bon courage

  3. Published by , Il y a 9 ans

    Bonjour,

    J’utilise bien ES 0.90.3 :
    [ec2-user@ES-Kibana elasticsearch-0.90.3]$ bin/elasticsearch -f
    [2013-12-30 04:53:04,853][INFO ][node ] [Emplate] version[0.90.3], pid[2040], build[5c38d60/2013-08-06T13:18:31Z]
    [2013-12-30 04:53:04,854][INFO ][node ] [Emplate] initializing …
    [2013-12-30 04:53:04,865][INFO ][plugins ] [Emplate] loaded [], sites [head]
    [2013-12-30 04:53:08,727][INFO ][node ] [Emplate] initialized
    [2013-12-30 04:53:08,727][INFO ][node ] [Emplate] starting …
    [2013-12-30 04:53:08,857][INFO ][transport ] [Emplate] bound_address {inet[/0:0:0:0:0:0:0:0:9300]}, publish_address {inet[/10.190.89.180:9300]}
    [2013-12-30 04:53:11,905][INFO ][cluster.service ] [Emplate] new_master [Emplate][co9OfJx_T2OgDvTxGjCRfw][inet[/10.190.89.180:9300]], reason: zen-disco-join (elected_as_master)
    [2013-12-30 04:53:11,968][INFO ][discovery ] [Emplate] elasticsearch/co9OfJx_T2OgDvTxGjCRfw
    [2013-12-30 04:53:11,992][INFO ][http ] [Emplate] bound_address {inet[/0:0:0:0:0:0:0:0:9200]}, publish_address {inet[/10.190.89.180:9200]}
    [2013-12-30 04:53:11,992][INFO ][node ] [Emplate] started
    [2013-12-30 04:53:12,014][INFO ][gateway ] [Emplate] recovered [0] indices into cluster_state

    et Logstash 1.2.1 :
    [ec2-user@logstash workshop]$ java -jar logstash-1.2.1-flatjar.jar agent -f logstash-logback.conf
    Using 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.2.1/plugin-milestones {:level=>:warn}
    Using milestone 2 filter plugin ‘kv’. 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.2.1/plugin-milestones {:level=>:warn}
    Using milestone 1 filter plugin ‘geoip’. This plugin should work, but would benefit from use by folks like you. Please let us know if you find bugs or have suggestions on how to improve this plugin. For more information on plugin milestones, see http://logstash.net/docs/1.2.1/plugin-milestones {:level=>:warn}
    log4j, [2013-12-30T05:02:04.329] WARN: org.elasticsearch.discovery: [Bloom, Astrid] waited for 30s and no initial state was set by the discovery
    Exception in thread « elasticsearch[Bloom, Astrid][generic][T#3] » org.elasticsearch.discovery.MasterNotDiscoveredException: waited for [30s]
    at org.elasticsearch.action.support.master.TransportMasterNodeOperationAction$3.onTimeout(TransportMasterNodeOperationAction.java:176)
    at org.elasticsearch.cluster.service.InternalClusterService$NotifyTimeout.run(InternalClusterService.java:435)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
    at java.lang.Thread.run(Thread.java:724)

    Quand j’utilise la sortie elasticsearch_http j’ai eu cette exception :
    [2013-12-30 05:12:47,219][WARN ][http.netty ] [Rancor] Caught exception while handling client http traffic, closing connection [id: 0xad808186, /10.73.21.182:34109 => /10.190.89.180:9200]
    java.lang.NumberFormatException: For input string: «  »
    at java.lang.NumberFormatException.forInputString(NumberFormatException.java:65)
    at java.lang.Integer.parseInt(Integer.java:504)
    at org.elasticsearch.common.netty.handler.codec.http.HttpMessageDecoder.getChunkSize(HttpMessageDecoder.java:621)

    J’ai par la suite autorisé tous les ports TCP sur Security Groups , avec la sortie elasticsearch et ça marche bien :)
    [ec2-user@ES-Kibana ~]$ curl -s http://127.0.0.1:9200/_status?pretty=true | grep logstash
    « logstash-2013.12.30 » : {
    « index » : « logstash-2013.12.30 »
    « index » : « logstash-2013.12.30 »
    « index » : « logstash-2013.12.30 »
    « index » : « logstash-2013.12.30 »
    « index » : « logstash-2013.12.30 »

    MERCI .

    Rem : dans http://xebia-france.github.io/workshop-kibana/groups/io.html la version présenté de ES est 0.90.5 avec Logstash 1.2.1 .

    Cordialement

  4. Published by , Il y a 9 ans

    Bonjour,

    Merci pour ce tuto!! il se trouve que dans mon projet j’aurai besoin d’un gestionnaire de log, la recherche sur google m’a conduit vers ce tuto!
    au faite je voudrai extraire de l’info de 3 fichier log différents (appli1.log, appli2.log, appli3.log). de ces trois fichiers je voudrai extraire l’adresse ip, le login et le mot de passe.
    les infos ainsi extraits je voudrai les mettre dans un fichier texte classique.
    ma question est la suivante:

    en suivant les étapes dans votre tuto j’ai bien réussit à extraires les data! mon problème est le fichier output qui n’est pas bien structuré. Alors y’a t’il un moyen de bien structuré le fichier output?

    merci.

  5. Published by , Il y a 9 ans

    Bonjour,

    en l’état je ne peux vous répondre ne connaissant pas:
    – le format d’entrée
    – le format de sortie souhaité
    – la configuration logstash

    De plus, qu’entendez-vous par bien ou mal structuré ?

    Cordialement

  6. Published by , Il y a 9 ans

    Bonjour Vincent,

    Merci pour cette série sur logstash/elasticsearch/kibana/.
    Les exemples sont pertinents et la clarté est de mise; c’est idéal pour débuter sur ces outils.
    Je ne manquerai pas d’en faire la publicité ;)

    Par ailleurs, pouvez-vous m’indiquer pourquoi avoir fait usage de GeoLiteCity dans votre exemple?
    Cela vous oblige au petit « hack » pour Bettermap alors que filtre geoip propose le bon format par défaut (dans le champ « location »).

    Merci d’avance de votre réponse.

  7. Published by , Il y a 9 ans

    Bonjour Clément,

    je suis ravi de savoir que ces billets de blog vous ont plu :)

    L’utilisation du filtre geoip (et de la base GeoLiteCity) permet d’obtenir des informations de géolocalisation depuis une adresse IP.
    Le « hack » est nécessaire si vous utilisez une version de Logstash inférieure à 1.3.0.
    En effet, depuis cette version, le filtre produit un champ geoip.location au format GeoJSON, compatible avec Bettermap.
    (cf. http://logstash.net/docs/1.3.0/filters/geoip)

    Cordialement

  8. Published by , Il y a 9 ans

    Bonjour Vincent,

    Merci pour votre réponse.
    Une autre question me vient à l’esprit mais est à mon avis, plus liée à l’utilisation d’ElasticSearch.

    Que ce soit dans avec des logs ou des tweets, les indexes ont tendances à grossir très rapidement dans ES. Quelle stratégie technique adoptez-vous en production pour purger ces données?

    Je suppose que, fonctionnellement, ces purges dépendent de la profondeur d’historique souhaitée.

    Bien cordialement,

  9. Published by , Il y a 9 ans

    Bonjour Vincent,

    Merci pour cette réponse.

    Bien cordialement,

  10. Published by , Il y a 9 ans

    Bonjour et encore merci pour cet excellent tutorial
    Je regarde comment utiliser Logstash+ES+kibana dans le cadre de mes logs
    jai des records de logs qui enregistrent le traffic ip sortant du style
    record1 –> …..,WANtraffic=500,……
    record2 –> …..,WANtraffic=750, …..
    record3 –> …..,WANTraffic=1500, ….
    record3 –> …..,WANTraffic=1500, ….

    je voudrais afficher via l’objet graphique Trend les variations du traffic
    toutes les N sec ou tout les N records
    ( ex entre 750 –> 500 variation +50%,
    entre 1500 –> 750 variation +100%
    entre 1500 -> 1500 variation 0% )
    et afficher a interval regulier dans le dashboard kibana la trend …

    je me demandais si kibana ( via le setting des widgets du dashboard, ou logstash en manipulant les records via grok ) permettait d’arriver a ces resultats …?

    cordialement
    philippe

  11. Published by , Il y a 9 ans

    Bonjour Philippe,
    merci pour vos retours :)

    Vous pouvez avoir la différence dans l’histogramme via « Chart Value » > « mean » (pour la valeur plutôt que le count) et cocher la case « Derivative ».
    Il me semble que le pourcentage de la différence n’est pas possible facilement.

    Pour tout ce qui concerne les metriques hardware (CPU, I/O, Network, etc…),
    je vous insiste à utiliser le plugin Collectd de Logstash
    (cf. http://www.elasticsearch.org/blog/logstash-collectd-input-plugin).

    Cordialement

  12. Published by , Il y a 9 ans

    Bonjour!
    Merci encore pour ce tuto détaillé.
    J’utilise « logstash-1.1.9-monolithic.jar » et « elasticsearch-0.90.2.jar ».
    Voici 3 sources distinctes de log :
    [1:session ssh] Feb 18 13:41:06 machine1 sshd[19047]: pam_unix(sshd:session): session opened for user nagios by (uid=0)
    [2:log apache] Feb 18 13:55:32 machine1 log_mod_jk 2014/02/18 13:55:30,432 [INFO ] [270 : InterpreteurMessageEDI.java ] : Message EDI traité
    [3:log jboss] Feb 17 17:06:25 machine1 log_server 2014-02-17 17:06:20,813 INFO [fr.maclasse.InterpreteurMessageEDI] (WorkManager(2)-56) Message EDI traité

    Machine1 envoie les logs via Rsyslog vers un serveur. Sur ce serveur, Rsyslog réceptionne les messages et les renvoie sur le port 5544. Logstash (sur le même serveur) prend en entrée le flux TCP sur le port 5544 puis envoie l’ensemble des logs vers Elasticsearch. Tout ceci fonctionne parfaitement.
    Voici mon config de logstash

    input{
    tcp {
    port => 5544
    type => syslog
    }
    }

    filter {
    grok {
    match => [« message », « %{SYSLOGTIMESTAMP:syslog_timestamp} %{SYSLOGHOST:syslog_hostname} %{DATA:syslog_program}(?:\[%{POSINT:syslog_pid}\])?: %{GREEDYDATA:syslog_message} » ]
    add_field => [ « received_at », « %{@timestamp} » ]
    add_field => [ « received_from », « %{host} » ]
    }
    date {
    match => [« syslog_timestamp », »dd-MM-YYYY HH:mm:ss.SSS »]
    }
    }

    output {
    stdout { debug => true}
    elasticsearch {
    type => « syslog »
    embedded => false
    host => « localhost »
    cluster => « syslog »
    }
    }

    J’ai deux problèmes.
    1.)
    Pour chaque message (donc chaque log reçu), le filtre « grok » échoue.
    Je ne comprends pas pourquoi.
    Auriez-vous une idée et pourriez-vous m’aider à écrire un bon filtre qui match bien mes logs ?

    2.)
    Pourquoi j’ai toujours l’espèce de devant chaque log ? J’ai bien constaté et c’est logstash qui les rajoute. Quand je rédirige vers un fichier ce que Rsyslog doit renvoyer, il n’y a pas ces caractères. Mais lorsque Rsyslog les renvoie en TCP vers le port 5544 et que logstash lis le flux TCP sur le port 5544, j’ai bien ces caractères. J’en déduis donc que c’est logstash qui les rajoute. Est-ce normal ?

    Merci.

  13. Published by , Il y a 9 ans

    Bonjour Christian,

    1) Vos logs ne comportent pas tout le temps le caractère « : » à la suite du pattern ‘%{DATA:syslog_program}(?:\[%{POSINT:syslog_pid}\])?’.
    Le pattern qui match le nom du programme ainsi que sont PID est disponible dans grok via SYSLOGPROG.

    Ainsi vous obtenez:

    input{ stdin {} }

    filter {
    grok {
    match => ["message", "%{SYSLOGTIMESTAMP:timestamp} %{SYSLOGHOST:logsource} %{SYSLOGPROG}(?:[:])? %{GREEDYDATA:syslog_message}" ]
    }
    }

    output { stdout { debug => true } }

    2) Les espaces en début de lignes ne perturberons pas grok ;)

    Cordialement

  14. Published by , Il y a 9 ans

    Bonjour

    Comment réagit grok en cas de stacktrace dans les logs?

  15. Published by , Il y a 9 ans

    Bonjour « Hello Kitty »,

    Logstash par défaut traite chaque ligne comme un message.
    Ainsi, votre stacktrace Java sera vu comme n messages (n lignes).

    Pour remédier à cela, Logstash vous propose le filtre multiline afin de regrouper plusieurs lignes en un seul message.
    (cf. http://logstash.net/docs/1.3.3/filters/multiline)

    Exemple:

    # stacktrace java as one message
    multiline {
    #type => "all" # no type means for all inputs
    pattern => "(^.+Exception: .+)|(^\s+at .+)|(^\s+... \d+ more)|(^\s*Caused by:.+)"
    what => "previous"
    }

    Cordialement

  16. Published by , Il y a 9 ans

    Bonsoir Vincent,

    Tout d’abord merci pour cet excellent article!

    Je m’intéresse au trio logstash/elasticSearch/Kibana pour analyser des logs téléphoniques mais:
    1/ ils sont au format .CSV, est-ce que je peux utiliser ce format de fichier directement?
    2/ j’ai déjà tout un historique à disposition, ce n’est donc pas un flux de données auquel je veux me « brancher » mais à un fichier déjà existant, est-ce possible?

    Merci par avance de vos réponses.

    Cordialement,

    Fabien.

  17. Published by , Il y a 9 ans

    Bonjour Fabien,

    1) Je vous invite à utiliser le filtre CSV prévu à cet effet

    2) Vous pouvez utiliser l’entrée ‘file’ en utilisant la valeur ‘beginning’ pour le champ ‘start_position’

    Cordialement

  18. Published by , Il y a 9 ans

    Bonjour,

    Vous pouvez configurer plusieurs inputs dans le même fichier de configuration:

    input {
    file {
    path => "/var/log/app1/*.log"
    }
    file {
    path => "/var/log/app2/*.log"
    }
    }

    Vous pouvez merger différents events si ils se suivent via le filtre: http://logstash.net/docs/1.4.2/filters/multiline

    Cordialement

  19. Published by , Il y a 8 ans

    Bonjour Vincent et Merci pour le tutorial. En ce moment, Je suis nouveau avec ELK et j aimerais savoir si c est possible d envoyer le contenu d un fichier complet a Logstash. Aussi j aimerais specifier que le fichier text contient plusieur ligne et chaque ligne a un timestamp et d autre information. Comment pourrais faire pour l envoyer et m assurer que l information est visible par kibana.

    Merci d avance

    Cordialement

  20. Published by , Il y a 8 ans

    Vous pouvez utiliser l’entrée ‘file’ en utilisant la valeur ‘beginning’ pour le champ ‘start_position’:
    Exemple:

    input {
    file {
    path => "/path/to/your/file.log"
    start_position => "beginning"
    }
    }

    Cordialement

  21. Published by , Il y a 8 ans

    Bonjour Vincent,

    Tout d’abord un grand merci pour ce tuto très clair.
    Je suis sous:
    elasticsearch: 1.4.2
    logstash: 1.4.2
    kibana: 4.0.0-beta3

    J’ai un petit souci pour faire fonctionner Geoip dans kibana4.

    J’ai bien lors de l’insertion dans elasticsearch via logstash le champ:

    « geoip »: {
    « lnglat »: [
    [0] 2.65,
    [1] 48.85
    ]
    }

    Sous kibana 3.1.2 avec bettermap cela fonctionne bien
    Mais sous kibana4 , impossible de trouver le moyen d’utiliser geoip.lnglat pour l’afficher sur une carte géographique.

    Si tu as une solution je suis preneur.

    Encore merci pour ce Tuto

    Anthony

  22. Published by , Il y a 7 ans

    Salut, j’ai une question : pour l’instant j’utilise pour entrés et sorties que des fichiers.
    Le problème se pose sur la fait que le fichier d’entrée n’est pas prise en compte, à l’inverse du fichier en sortie. Aussi le chemin jusqu’aux fichiers sont bon ( ils sont dans le même dossier).
    Le fichier de sortie se remplie avec le résultat souhaité seulement si je passe en console une ligne du fichier log par exemple.
    D’où peut venir le problème ?? Merci d’avance

    input {
    stdin {}
    file {
    path => « /Users/dma/Documents/MA/LOGSTASH/logstash-2.1.1/bin/Test/*.log »
    }

    }

    filter {
    grok {
    match => [« message », »(?%{MONTHDAY}-%{MONTHNUM}-%{YEAR} %{HOUR}:%{MINUTE}:%{SECOND}.[0-9]{3}) \[%{NOTSPACE:thread}\] %{LOGLEVEL:log_level} %{NOTSPACE:classname} – %{GREEDYDATA:msg} »]
    }
    }

    filter {
    date {
    match => [« log_date », »dd-MM-YYYY HH:mm:ss.SSS »]
    }
    }

    output {
    file {
    path => « /Users/dma/Documents/MA/LOGSTASH/logstash-2.1.1/bin/Test/result1.txt »
    }
    stdout {}
    }
    execution
    dma$ java -jar logstash-1.2.1-flatjar.jar agent -f logstash1.conf
    //Using 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.2.1/plugin-milestones {:level=>:warn}
    //Using milestone 2 output 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.2.1/plugin-milestones {:level=>:warn}
    02-10-2014 14:26:27.724 [pool-10-thread-1] INFO com.github.vspiewak.loggenerator.SearchRequest – id=9205,ip=217.109.49.180,cat=TSHIRT
    2014-10-02T12:26:27.724+0000 kusturica.ubiqube.com 02-10-2014 14:26:27.724 [pool-10-thread-1] INFO com.github.vspiewak.loggenerator.SearchRequest – id=9205,ip=217.109.49.180,cat=TSHIRT

  23. Published by , Il y a 7 ans

    Bonjour ,
    Tout d’abord j’aimerais vous féliciter pour votre travail que je trouve assez instructif.
    Alors, je viens de découvrir la pile ELK et je débute la dessus car je trouve que ce sont des technologies intéressantes pour le pilotage et le suivie de ce qui se passe sur un serveur.
    Je voulais savoir si vous avez un exemple complet de A à Z , car j’ai deja installer les 3 logiciels mais je sais toujours pas comment je peux les mettre en pratique sur un exemple concret.
    NT : je suis débutant c’est la première fois que j’utilise ELK

    si vous avez des exemples pour moi je vous serez tres reconnaissant.

    merci d’avance

  24. Published by , Il y a 6 ans

    Bonjour Vincent,

    Merci encore pour ce superbe tutoriel. Il permet de voir plus clair l’intérêt des 3 outils présentés.

    J’aimerais vous solliciter concernant l’erreur que j’ai rencontré dans Kibana. En effet, j’ai ce message « Oops! SearchPhaseExecutionException[Failed to execute phase [initial], No indices / shards to search on, requested indices are [_all]] » qui apparaît lorsque je suis sur le Dashboard.

    Je vous remercie pour votre réponse.

    Cordialement.

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *

Nous recrutons

Être un Sapient, c'est faire partie d'un groupe de passionnés ; C'est l'opportunité de travailler et de partager avec des pairs parmi les plus talentueux.