Vos logs passent la seconde avec ELK (ElasticSearch – Logstash – Kibana)

Les logs, éléments indispensables à toute application quelle qu'elle soit pour suivre, analyser et comprendre ce qui se passe et pouvoir intervenir en conséquence. Oui mais quand on a un éco-système d'applications assez riche, avec plusieurs environnements et que l'on veut consulter les logs voici le scénario qui peut parfois se produire :

  • Je veux consulter les logs de telle application développée par tel service, ok elles sont où les logs? Je vais demander à l'équipe qui a développé.
  • Bon j'ai le nom de la machine et le chemin, zut je ne peux pas me connecter avec mon compte et je n'ai pas les accès. Ok je vais re-demander.
  • Ok j'ai accès aux logs, je les consulte, et je me retrouve avec ça :

bash-lire-le-fichier-de-log-apache-access

  • Après il faut se battre à coups de grep, cut, sort...  pour rechercher ce que l'on souhaite pour au final se rendre compte que l'erreur vient d'une autre application tierce, et on recommence la recherche d'informations.

Résultat vous perdez un temps infini à rechercher la bonne information au bon endroit.

Maintenant on va voir une autre solution beaucoup moins stressante, beaucoup plus rapide et conviviale,  la stack ELK!

Si vous recherchez ELK sur un navigateur il se peut que vous arriviez sur ce résultat :

Bull-67_bugle-web

Je n'ai absolument rien contre nos amis les bêtes et je ne suis pas un partisan de la chasse, on parlera plutôt de ça :

Elasticsearch + Logstash +Kibana !

Présentation

La stack ELK est une solution open source, de la société elastic,composée de trois produits que sont Elasticsearch, Logstash et Kibana, qui permettent de parser, indexer et présenter de gros volumes de données issues de vos logs sous forme de dashbords et de faire des recherches au sein de vos logs comme vous pourriez le faire avec un moteur de recherche.

Schématiquement le processus de fonctionnement de la stask est le suivant :

Je vais présenter succinctement chaque élément sachant que vous pourrez avoir une description plus précise sur le site officiel elastic.

Elasticsearch

Elasticsearch-Logo-Color-V.jpg

Elasticsearch est un puissant moteur d'indexation qui se base sur le projet Apache Lucene mais qui en simplifie l'utilisation. Il permet via une API Rest d'indexer et d'interroger facilement à l'aide de requêtes au format JSON les documents stockés dans une base nosql adaptée pour traiter de très gros volumes de données suivant des critères d'indexation complètement paramétrables afin d'optimiser les recherches.

Logstash

Logstash est un très bon outil permettant de collecter, analyser, formater et redistribuer des flux de chaines de caractères, des logs par exemple, via des fichiers de configuration et des plugins. Les points d'entrée de logstash sont définis dans des fichiers de configuration, ils peuvent être de nature variée via des plugins, presque une cinquantaine (ex : jdbc, nosql, fichiers, flux http, streams twitter, csv, syslog...). Logstash parse les  lignes de données qui sont ensuite traitées par des filtres pour filtrer mais également transformer les entrants, via des plugins, afin de les restituer dans un format attendu par le consommateur qui le traitera. Là encore les possibilités de sorties, via des plugins, sont multiples, près d'une soixantaine  (ex :  elasticsearch, jira, websocket, cvs, nosql ...)

Kibana

Kibana est une interface web riche qui permet de présenter sous forme de dashboards des documents issus d'index Elastisearch. Kibana offre de nombreuses possibilités de représentations graphiques des données et cela de manière rapide et simple, pouvant être partagées avec l'ensemble des membres d'une équipe. Les données affichées peuvent être affinées en temps réel grâce à un système filtres et de requêtage.

En pratique

Pré-requis

Pour le bon déroulement de cet article  il vous faudra d'abord vous assurer que votre poste possède les éléments suivants :

  • jruby, nécessaire pour logstash
  • un jdk en version 7 minimum et la variable d'environnement JAVA_HOME de définie sur votre installation de JDK

Installation

Au moment où j'ai écrit cet article les versions des composant d'ELK sont :

Pour l'installation rien de plus simple, il vous suffit de décompresser chacune des archives.

Pour tester votre installation d'Elasticsearch, vous pouvez saisir la commande

%dossier_installation_elastisearch%/bin/elastisearch

puis dans un navigateur saisissez l'adresse http://localhost:9200 vous devriez avoir un résultat similaire :

elasticsearch_test_install

Pour tester votre installation de logstash, vous pouvez saisir la commande

%dossier_installation_logstash%/bin/logstash -e 'input { stdin { } } output { stdout {} }'

Une fois le message "Logstash startup completed" vous pouvez saisir dans la console un message de test, "Coucou logstash", et vous devriez voir s'afficher dans la console quelque chose comme ceci :

2016-03-16T12:46:40.283Z DavidBoujot-PC Coucou logstash

Enfin pour tester l'installation de Kibana vous pouvez saisir la commande

%dossier_installation_kibana%/bin/kibana

puis dans un navigateur saisissez l'adresse http://localhost:5601 vous devriez avoir un résultat similaire :

kibana_test_install

Exemple d'utilisation avec les logs d'Apache

Maintenant que notre stack est installée et opérationnel, nous allons la mettre en oeuvre pour lire et afficher les logs d'un serveur Apache. Si vous n'avez pas de serveur Apache sous la main vous pouvez le télécharger ici.

Configuration de Logstash

Comme expliqué dans la présentation de Logstash, ce dernier se base sur un fichier de configuration et des plugins pour parser, transformer et rediffuser des flux d'informations, dans le cas qui nous intéresse des fichiers des logs d'apache.

On va tout d'abord créer un fichier de configuration pour Logstash que l'on va nommer "apache_log.conf" et un fichier "apache_template.json" qui va nous permettre de créer notre index Elasticsearch dans lequel seront écrites les logs après transformation via les filtres de Logstash.

 

input {
    file {
        path => '\apache\logs\access.log'
    }
}
    
filter {
  grok {
    match => {
      "message" => '%{IPORHOST:clientip} %{USER:ident} %{USER:auth} \[%{HTTPDATE:timestamp}\] "%{WORD:verb} %{DATA:request} HTTP/%{NUMBER:httpversion}" %{NUMBER:response:int} (?:-|%{NUMBER:bytes:int}) %{QS:referrer} %{QS:agent}'
    }
  }

  date {
    match => [ "timestamp", "dd/MMM/YYYY:HH:mm:ss Z" ]
    locale => en
  }

  geoip {
    source => "clientip"
  }

  useragent {
    source => "agent"
    target => "useragent"
  }
}

output {
	stdout { 
		codec => plain {
							charset => "ISO-8859-1"
	   }

	}
	elasticsearch {
		index => "apache_log"
		template => "apache_template.json"
		template_name => "apache_log"
		template_overwrite => true
	}
}
apache_log.conf

Détaillons le contenu de ce fichier.

  • lignes 1 à 5 : on indique une entrée de type fichier qui pointe vers le fichier de log que l'on souhaite analyser. Attention au chemin de votre fichier de log Apache! Les entrées possibles sont décrites ici
  • lignes 7 à 27 : on déclare 4 filtres qui vont transformer les lignes de logs de notre fichier pour ensuite les servir à la sortie déclarée plus loin.
    1. grok : permet de parser des fichiers de log serveur et d'extraire facilement les données dont on a besoin à l'aide de mots clés. Sur la documentation de logstash vous trouverez une page dédiée à ce filtre et sa synthax. De plus vous pouvez valider vos expressions grok sur ce site.
    2. date : permet de stocker la date dans une propriété "timestamp" nous verrons plus tard à quoi elle va nous servir.
    3. geoip : retourne des données de géolocalisation en fonction de l'adresse IP de la personne qui s'est connectée.
    4. useragent : donne le nom du navigateur de l'utilisateur.
  • lignes 29 à 42 : la dernière partie du fichier de configuration indique où logstash doit envoyer les logs traitées. Nous lui demandons d'alimenter un index Elasticsearch qui nous servira pour créer nos gaphiques Kibana. La propriété "template" correspond au fichier json qui décrit notre index Elasticsearch. Attention au chemin de votre fichier, ici le fichier doit se trouver dans le répertoire bin de Logstash.
{

  "template": "apache_log",
  "settings": {
     "index.refresh_interval": "5s"
  },
  "mappings": {
     "_default_": {
        "dynamic_templates": [
           {
              "message_field": {
                 "mapping": {
                    "index": "analyzed",
                    "omit_norms": true,
                    "type": "string"
                 },
                 "match_mapping_type": "string",
                 "match": "message"
              }
           },
           {
              "string_fields": {
                 "mapping": {
                    "index": "analyzed",
                    "omit_norms": true,
                    "type": "string",
                    "fields": {
                       "raw": {
                          "index": "not_analyzed",
                          "ignore_above": 256,
                          "type": "string"
                       }
                    }
                 },
                 "match_mapping_type": "string",
                 "match": "*"
              }
           }
        ],
        "properties": {
           "geoip": {
              "dynamic": true,
              "properties": {
                 "location": {
                    "type": "geo_point"
                 }
              },
              "type": "object"
           },
           "@version": {
              "index": "not_analyzed",
              "type": "string"
           }
        },
        "_all": {
           "enabled": true
        }
     }
  }
}
apache_template.json

Je vais faire l'impasse sur le détail du fichier de mapping de l'index Elasticsearch et vous laisse le soin de vous documenter sur le sujet ;).

Exécution de Logstash

Voilà une bonne chose de faite, la configuration de Logstash est finie, maintenant GO POUR LE TEST!

Si votre Logstash est déjà en cours d'exécution, il faut l'arrêter et exécuter cette commande dans le répertoire "bin"

logstash -f apache_log.conf

NB : le fichier apache_log.conf doit également se trouver dans le répertoire "bin".

Si tout se passe bien, vous devriez avoir un résultat comme ceci :

Settings: Default pipeline workers: 4
Logstash startup completed

Maintenant si vous faites un hit dans votre serveur Apache vous devriez voir dans la console de Logstash une trace de ce type

2016-04-08T15:20:57.045Z D-CZC5072T5Y ::1 - - [08/Apr/2016:17:20:56 +0200] "GET/ HTTP/1.1" 304 -

Vérification dans Elasticsearch

Parfait nous avons notre Logstash qui tourne, qui visiblement consomme notre fichier de log Apache, mais qu'est-ce qui se passe dans notre index Elasticsearch, et bien il se remplit. Si vous tapez cette url dans un navigateur "http://localhost:9200/apache_log" vous devriez avoir un résultat similaire à ça :

{
	"took": 15,
	"timed_out": false,
	"_shards": {
		"total": 5,
		"successful": 5,
		"failed": 0
	},
	"hits": {
		"total": 2,
		"max_score": 1.0,
		"hits": [{
			"_index": "apache_log",
			"_type": "logs",
			"_id": "AVP2dj7VgyOMGOLqpVhC",
			"_score": 1.0,
			"_source": {
				"message": "::1 - - [08/Apr/2016:17:20:56 +0200] \"GET / HTTP/1.1\" 304 -\r",
				"@version": "1",
				"@timestamp": "2016-04-08T15:20:57.045Z",
				"path": "C:\\PERSO\\NETAPSYS\\BLOG\\ELK\\_TEST\\_SERVER\\apache\\logs\\access.log",
				"host": "D-CZC5072T5Y"
			}
		}, {
			"_index": "apache_log",
			"_type": "logs",
			"_id": "AVP2daM2gyOMGOLqpVhB",
			"_score": 1.0,
			"_source": {
				"message": "::1 - - [08/Apr/2016:17:20:16 +0200] \"GET / HTTP/1.1\" 200 37846\r",
				"@version": "1",
				"@timestamp": "2016-04-08T15:20:17.010Z",
				"path": "C:\\PERSO\\NETAPSYS\\BLOG\\ELK\\_TEST\\_SERVER\\apache\\logs\\access.log",
				"host": "D-CZC5072T5Y"
			}
		}]
	}
}

Où l'on voit qu'il y a eu 2 hists d'indexés et à chaque fois que vous allez faire un nouveau hit sur votre serveur Apache, il sera automatique dans votre index Elasticsearch. On est content oui mais... mais ça ne va pas être super intéressant de faire des graphiques à partir des logs générées par des appels à l'url "http://localhost" on va être très vite limité. Je vous propose donc de charger un fichier de logs Apache bien rempli.

Dans un premier temps on va effacer notre index Elasticsearch pour le refaire de zéro.

curl -XDELETE 'http://localhost:9200/apache_log/'
Commande de suppression de l'index Elasticsearch

Ensuite on stoppe notre serveur Apache, on N'ARRETE PAS Logstash, on remplace le fichier de logs Apache configuré dans Logstash par celui accessible via ce lien access.log et hop en quelques secondes notre fichier de logs est indexé dans Elasticsearch. Si vous saisissez cette adresse dans un navigateur "http://localhost:9200/apache_log/_count" vous devriez avoir cette réponse

{
	"count": 10000,
	"_shards": {
		"total": 5,
		"successful": 5,
		"failed": 0
	}
}

Voilà nous somme près à avoir de beaux graphiques avec des données exploitables.

Création de graphiques Kibana

Nous arrivons enfin à la partie qui va vous permettre d'en mettre plein la vue avec les graphiques de Kibana. Connectez-vous à la console Kibana via l'url "http://localhost:5601" . Cliquez ensuite sur le lien "Settings" puis "Indices"

Settings - Kibana

Il faut indiquer au moins un index Elasticsearch à Kibana pour que ce dernier puisse travailler.

Settings - Kibana2

Dans le champ "index name" il suffit de mettre le nom de notre index "apache_log" et par défaut Kibana sélectionne la propriété qui va servir de champ temporel, le fameux timestamp que nous avons configuré plus tôt dans Logstash, pour le rafraîchissement.

Settings - Kibana3

Voilà vous pouvez cliquer sur "Create" et vous allez arriver sur une page qui liste toutes les propriétés de votre index.

Pour créer un graphique, il faut cliquer sur le bouton "Vizualize" dans la barre de menu.

Création d'un graphique "Pie chart"

Nous allons créer un graphique de type "camembert" ou "pie chart" c'est selon les goûts, dans lequel ont va afficher la répartition des  navigateurs utilisés par pays. Donc dans le choix des graphiques vous cliquez sur "Pie Chart".

Dans le nouvel écran qui apparaît avec un énorme disque vert, vous avez à gauche la possibilité de sélectionner le type de "bucket" de votre graphique, vous cliquez sur "Split slices".

Visualize - Kibana

Dans la combo "Aggregation" qui s'affiche, vous sélectionnez "Terms" ce qui fait apparaître plusieurs champs dans "Fields" vous sélectionnez "useragent.name.raw" et vous n'avez plus qu'à cliquer sur ce bouton Visualize - Kibana3 pour actualiser le graphique et obtenir un résultat similaire à ça :

Visualize - Kibana2

On a les 5 navigateurs les plus utilisés selon les logs que nous avons indexées. Maintenant si on veut avoir la répartition géographique par pays pour chaque navigateur il suffit de cliquer sur le bouton "add sub-buckets" et nous retrouvons un formulaire similaire au précédent dans lequel vous allez saisir :

  • buckets type : Split slices
  • Sub aggregation : Terms
  • Field : geoip.country_name.raw
  • Size : 3

Voilà on clique sur ce bouton  Visualize - Kibana3 pour rafraîchir le graphique qui nous affiche par navigateur les 3 pays qui l'utilisent le plus :

Visualize - Kibana4

C'est beau! Vous pouvez même sauvegarder, icône "disquette" ou partager votre graphique, l'icône carré avec la flèche qui pointe vers le haut.

Visualize - Kibana5

Dernière petite chose, vous pouvez aussi affiner votre graphique avec le champs de saisie dans lequel vous pouvez par exemple saisir "france AND chrome" et automatiquement votre graphique est affiné.

Settings - Kibana7

Création d'un graphique "Histogram"

On refait la même manipulation que pour le graphique précédent mais cette fois on choisit comme type de graphique "Histogram" et on va afficher par jour la répartition des codes de réponse HTTP.

Visualize - Kibana8

Création d'un dashboard Kibana

Une fois vos graphiques créés et sauvegardés vous pouvez les inclure dans un dashboard ce qui vous  permettra d'avoir dans une seule et même vue tous les graphiques liés à un besoin.

Cliquez sur le bouton "Dashboard" dans la barre de menu en haut de la page. Dans le champ de saisie "Vizualization filter" vous pouvez retrouver les graphiques que vous avez sauvegardés ou utiliser les boutons de pagination. Cliquez sur les graphiques que vous souhaitez ajouter à votre dashboard, vous pouvez également changer leur disposition par drag and drop. Ensuite vous pouvez sauvegarder votre dashboard de la même façon que vous avez sauvegardé vos graphiques. Voici un exemple de dashboard avec les deux graphiques précédents :

Dashboard - Kibana

Sur la base des données que nous avons indexées vous pouvez aussi charger ce fichier de dashboard, en passant par le menu "Settings" puis le sous menu "Objects" et enfin le bouton "Import"

Import - Kibana

Une nouvelle entrée apparaît dans la liste des dashboards et si vous cliquez sur le bouton de visualisation en forme d’œil vous pourrez voir un super dashboard avec plein de graphiques et de métriques.

Sample Dashboard for Apache Logs - Dashboard - Kibana

 

Dernier petit point pour terminer sur les dashboards, comme nous l'avions vu pour les graphiques, vous pouvez utiliser le champ de saisie qui se trouve en haut du dashboard pour filtrer les résultats, par exemple avec  la requête : geoip.country_name.raw = 'spain'. Vous avez également dans la barre de menu en haut tout à droite un filtre sur la date :

FilterDate - Kibana

Quand vous cliquez dessus vous avez des propositions de tranches de dates pour filtrer les données affichées et vous avez aussi le libre choix de votre plage de dates de recherche.

Conclusion

Comme il faut bien terminer, je vous laisse découvrir toutes les autres possibilités de cette solution ELK. Vous l'aurez compris les possibilités sont très étendues de par les nombreuses entrées traitées par Logstah et les filtres applicables sur les données récoltées, les dashboards de Kibana, qui est à mon sens un très bon outil d'analyse de logs, avec là aussi des configurations très riches, qui donnent une vision rapide, claire de ce qui se passe sur les applications surveillées.

J'espère que cet article vous aura donné envie de vous intéresser d'un peu plus près à ELK, de consulter la documentation sur le site elastic. N'hésitez pas à me faire des retours sur cet article, à apporter des précisions ou des corrections, elles sont toujours les bienvenues et ne feront qu'enrichir ce post.

5 commentaires

  1. La centralisation des logs est un sujet qui devient de plus en plus important dans les entreprises. La stack ELK permet de mettre en place une centralisation très rapidement mais il y a quelques fonctionnalité qui ne sont pas disponible de base (en open source) : les alertes et la gestion des droits notamment.
    Une autre solution open-source – qui utilise Elasticsearch pour le stockage – est Graylog. Elle propose de nombreuses fonctionnalité mais pêche un peu sur la partie visualisation des données ou il y a moins de types de graphiques.

  2. Bonjour,

    Merci à toi pour ce tutoriel. Toutefois, malgré que tu nous laisse nous documenter sur le sujet concernant les templates JSON, pourrais-tu transmettre tes sources pour que je puisse voir comment construire un templates JSON qui soient correct stp ? (J’essaie de lire des logs format log4j)

  3. J’ai tout essayé, je n’ai jamais réussi à le faire fonctionner.
    En passant par les paquets debian, j’ai bien une redirection vers x.x.x.x/app/kibana mais page blanche qui tourne en boucle. Aucun log, aucune info, rien. Sur Windows en local, elastic search refuse de se lancer sous prétexte qu’il ne tourne qu’avec Java8 alors que je dispose du jdk1.8.0_131

    Bref, dommage pour moi.

Laisser un commentaire

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

Captcha *