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
- http://bryanw.tk/2013/geoip-in-logstash-kibana
- http://elasticsearch-users.115913.n3.nabble.com/need-count-of-terms-using-facets-taking-space-into-account-td3956699.html
- https://gist.github.com/deverton/2970285
- http://untergeek.com/2012/09/20/using-templates-to-improve-elasticsearch-caching-with-logstash/
Commentaire
26 réponses pour " Logstash, ElasticSearch, Kibana – S01E02 – Analyse orientée business de vos logs applicatifs "
Published by Ismail , 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
Published by Vincent Spiewak , 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
Published by Ismail , 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
Published by linda , 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.
Published by Vincent Spiewak , 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
Published by Clément HELIOU , 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.
Published by Vincent Spiewak , 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
Published by Clément H , 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,
Published by Vincent Spiewak , Il y a 9 ans
Bonjour Clément,
Une manière simple de purger vos données est de préciser un ttl (Time To Live).
(cf. http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/mapping-ttl-field.html)
Vous pouvez le préciser dans la template de mapping comme ceci:
{
« template » : « logstash-* »,
« mappings » : {
« _default_ » : {
« _ttl » : { « enabled » : true }
}
}
}
Published by Clément H , Il y a 9 ans
Bonjour Vincent,
Merci pour cette réponse.
Bien cordialement,
Published by Phil G , 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
Published by Vincent Spiewak , 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
Published by Christian , 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.
Published by Vincent Spiewak , 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
Published by HelloKitty , Il y a 9 ans
Bonjour
Comment réagit grok en cas de stacktrace dans les logs?
Published by Vincent Spiewak , 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
Published by Fabi , 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.
Published by Vincent Spiewak , 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
Published by Vincent Spiewak , 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
Published by Robert , 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
Published by Vincent Spiewak , 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
Published by Anthony , 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
Published by Techno : ELK (Elasticsearch, Logstach, Kibana ) | Un regard sur le cloud computing , Il y a 8 ans
[…] Xebia : Logstash, ElasticSearch, Kibana – S01E02 – Analyse orientée business de vos logs applic… […]
Published by DIDI , 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
Published by Othmane , 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
Published by Alison T. , 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.