Introduction

Je commence un nouveau projet sur lequel je compte effectuer des publications progressives. J'avais un AWstats qui tournait depuis quelques années mais je n'étais pas très satisfait par ses capacités limitées aux logs Apache. Cela faisait quelques années que je cherchais à exploiter les logs de mon seveur public qui héberge de nombreux services exposés sur Internet.

Lire les logs, c'est fastidieux. On peut faire de grands coups de regexp mais ce n'est jamais très visuel. De plus, pour avoir déjà trempé dans le monde la Businness Intelligence et du reporting, on a souvent envie d'avoir de bons outils pour "faire parler les données". Après tout, un log est une donnée à lui seul. J'ai toujours cherché des solutions légères qui peuvent tourner sur une machine aux capacités limitées (Sheevaplug) mais je n'ai jamais rien trouvé d'adéquat. J'ai même commencé à imaginer un système basé sur du SQLite et sur la bibliothèque d3js pour faire des rendus graphiques intéressants.

La mise en place d'un tel système se révèle assez lourd car il faut pratiquement tout coder à partir de rien. Après quelques années, j'ai refais un tour des différentes solutions disponibles et force a été de constater qu'en 2014, il existe des implémentations de référence (c'est à dire qu'on peut mettre en production) qui font ce travail de manière intelligente. Les deux outils qui ont retenus mon attention sont graylog2 et ELK dont le sigle signifie Elastic Search, Logstash, Kibana, le nom des 3 logiciels qui composent la suite d'analyse de logs.

Ces deux outils sont en Java ce qui exclu de pouvoir les déposer sur mon Sheevaplug. Néanmoins, je dispose d'une station de travail avec pas mal de capacités. Je me suis dit que je pouvais installer une instance d'un de ces outils sur cette machine et procéder régulièrement et le plus automatiquement possible à l'import des logs de mon serveur public.

Pour ce travail, j'ai donné ma préférence à ELK qui semble être l'application du moment et surtout dont l'interface de visualisation me semble la plus adaptée à ce que j'attends.

ELK, c'est quoi ?

ELK est une "suite" logicielle composée des trois outils dont voici quelques présentations:

  • Elastic Search est une base de données indexée permettant des requêtes rapides via plusieurs API (dont une qui communique sur HTTP). Elle est basée sur le moteur de recherche Lucene. Bien sûr, c'est du Java un peu lourdingue.
  • Logstash est un dispatcheur de logs. Il va piocher ses informations dans des fichiers, des bases de données, ou via d'autres instances logstash qui lui injecte des données. Ces informations sont ensuite filtrées puis envoyées en sortie vers des "entités" capable d'accueillir le résultat. Parmi ces sorties, il y a bien évidemment les DB Elastic Search. Logstash est fait en Ruby (déjà c'est mal ;-)) qui plus est empaqueté dans du Java (via JRuby) et ça, c'est vraiment le mal ! Mais bon, ça tourne (et ça bouffe plus de RAM et de CPU qu'un simple rsyslog)... De toute façon, vous ne savez pas quoi faire de vos VM ! Attention, Logstash ne remplace pas syslog: il n'est pas capable de gérer les appels systèmes de ce dernier. Je dois, enfin, noter que le JRuby n'est pas une si mauvaise idée que ça pour faire des tests: vous avez vraiment envie d'installer toute la pile de paquets pour Ruby ainsi que les bibliothèques nécéssaires à l'installation de Logstash ?
  • Kibana est une application Web qui s'occupe de l'affichage des données. Elle est codée en Javascript côté client et en NodeJS pour la partie serveur. Elle s'exécute dans un simple navigateur Web. Comme Elastic Search a une API HTTP, Kibana peut faire des requêtes Lucene sur Elastic Search. Bon bien sûr, si vous avez un client Web qui date un peu, votre machine sera à genoux (ça à beau être du Javascript, ça doit quand même manipuler parfois beaucoup de données d'un seul coup). Mais je dois avouer que de facto, Kibana semble graphiquement bien évolué et qu'on peut faire de beaux graphiques comme le suggère l'impression d'écran qui suit:

kibana beautiful.png

Voici un schéma possible (le plus simple sans doute) de l'organisation du flux de données:

| Syslog |------->| Logstash |---------------->| Elastic Search |------------------>| Kibana |--------> | User |

On voit bien que tout commence par Logstash. Donc pourquoi parler de ELK au lieu de L(ogstash)E(lasticSearch)K(ibana) ? En fait, ELK correspond à l'ordre dans lequel vous devez installer votre configuration pour commencer à voir des choses. C'est ce que nous allons voir tout de suite.

Installation de test

Introduction

Quand on décrouvre de nouveaux logiciels, il est toujours bon de réaliser une installation basique qui permet de se familiariser avec les concepts avant d'aller plus loin. Nous allons donc installer la suite ELK dans l'ordre requis à savoir:

  • Elastic Search
  • puis Logstash car ce dernier doit disposer d'un noeud ElasticSearch actif pour pouvoir se lancer correctement.
  • enfin, Kibana qui fera la visualisation finale.

En préambule, sachez que par défaut, tout ce petit monde n'est PAS sécurisé. En effet, tout est ouvert par défaut et si vous avez une adresse publique sur votre station de travail (ce qui arrive parfois quand vous avez la chance d'avoir accès à Internet en IPv6), tout le monde pourra vous pourrir votre instance Elastic Search et consulter vos logs. Donc, travaillez plutôt dans un environnement déconnecté. C'est ce que nous allons rapidement mettre en place.

Installation minimaliste d'Elastic Search

Bon, Elastic Search très basiquement, c'est simple à déployer. On peut faire des clusters mais dans notre cas, ça ne sert à rien de faire des choses compliquées. Sachez que par défaut, rien n'est sécurisé dans Elastic Search: n'importe qui peut injecter n'importe quoi dedans, il n'y a pas d'authentification, pas de chiffrement des communications, on ne définit même pas où stocker les fichiers !

Commencez par télécharger le binaire d'Elastic Search sur le site approprié.

Pour ma part, je décharge le tout dans un répertoire de projets (après tout, on est en mode découverte !): ~/projects/ELK

$ mkdir -p ~/projects/ELK && cd ~/projects/ELK
$ cp /tmp/elasticsearch-1.7.1.tar.gz .
$ tar -xzf elasticsearch-1.7.1.tar.gz
$ ln -s elasticsearch-1.7.1 elasticsearch

Une fois que le binaire est décompressé, on peut créer un fichier de configuration minimaliste. Ce fichier est situé dans config/elasticsearch.yml. Dans mon cas, je me contente d'indiquer que le noeud Elastic Search n'est disponible que sur localhost. Pour cela, modifiez les paramètres suivants:

...
node.name: "Trick Node"
...
network.bind_host: 127.0.0.1
network.publish_host: 127.0.0.1
network.host: localhost
...

Une fois votre noeud/cluster configuré, un simple:

bin/elasticsearch

suffit pour lancer le cluster. Quand ce dernier est vide, le démarrage se fait assez rapidement.

Installation minimaliste de Logstash

Commencez par télécharger le binaire de Logstash sur le site approprié.

Pour ma part, je décharge le tout dans notre répertoire de projets: ~/projects/ELK

$ cd ~/projects/ELK
$ cp /tmp/logstash-1.5.4.tar.gz .
$ tar -xzf logstash-1.5.4..tar.gz
$ ln -s logstash-1.5.4 logstash

Le fichier de configuration se trouvera dans le répertoire config (que vous devez créer) dans l'arborescence logstash. Je le nomme logstash.conf et voici un contenu minimal:

# Fichier de configuration de Logstash

# Les entrées
input {
  # Un fichier de logs Apache2
  file {
      # Ici on précise l'emplacement du fichier
      path => "/home/medspx/projects/ELK/data/apache2/test.log"
      # On indique qu'on commence à le lire à partir du début.
      # C'est essentiel pour les fichiers sinon Logstash se comporte comme tail -f
      start_position => beginning
      # Le champ type est ajouté à toutes les lignes lues par logstash.
      # Ce champ sera disponible dans ElasticSearch
      type => "apache"
  }
}

# Les filtres
filter {
  grok {
      match => { "message" => "%{COMBINEDAPACHELOG}" }
  }
  date {
      match => [ "timestamp", "dd/MMM/yyyy:HH:mm:ss Z" ]
  }
}

# Les sorties
output {
  elasticsearch {
        host => "localhost"
        protocol => "http"
  }
}

Logstash se configure assez simplement. On lui indique quelles sont les entrées. Dans notre cas, il s'agit d'un fichier de log Apache, dans la partie input.

Ensuite, on indique comment manipuler les données dans la partie dédiée aux filtres. Par défaut, Logstash lit ce qui vient en entrée et place la ligne dans le champ "message". Ensuite, on utilise différentes directives pour travailler sur les champs détectés. La première directive: grok permet de récupérer ce qui vous intéresse selon un motif prédéfini. Dans notre cas, nous voulons récupérer des valeurs issues du champ message. Le motif utilisé est COMBINEDAPACHELOG qui un motif interne de Logstash dont la valeur complète est la suivante:

COMMONAPACHELOG %{IPORHOST:clientip} %{USER:ident} %{USER:auth} \[%{HTTPDATE:timestamp}\] "(?:%{WORD:verb} %{NOTSPACE:request}(?: HTTP/%{NUMBER:httpversion})?|%{DATA:rawrequest})" %{NUMBER:response} (?:%{NUMBER:bytes:int}|-)

Le principe d'un filtre grok est assez simple: on utilise un motif prédéfini (par exemple USER) et on lui affecte un champ qui sera accessible depuis Elasticsearch (ici auth). Le motif prédéfini de USER est en fait une expression rationnelle:

USER [a-zA-Z0-9._-]+

Ensuite, on trouve la directive date. Cette dernière permet de "tagguer" la date précise de l'évènement lu par logstash et d'affecter le champ timestamp. Sans ce filtre, Logstash utilise la date de lecture de l'évènement comme timestamp.

Enfin, on trouve la partie dédiée à la sortie (output). Cette partie permet d'indiquer à Logstash vers où balancer les résultats des filtres. Dans notre cas, on utilise un cluster Elasticsearch accessible sur localhost via l'API HTTP.

Pour lancer votre instance Logstash, il suffit de faire comme suit (à partir du répertoire ~/projects/ELK/logstash):

bin/logstash -f config/logstash.conf

Kibana

Pour l'installation, on procède à la même logique que pour Elasticsearch et Logstash. Vous pouvez télécharger le binaire de Kibana ici

$ cd ~/projects/ELK
$ cp /tmp/kibana-4.1.1-linux-x64.tar.gz .
$ tar -xzf kibana-4.1.1-linux-x64.tar.gz
$ ln -s kibana-4.1.1 kibana

Le fichier de configuration est ultrasimpliste et se trouve dans ./config/kibana.yml. Voici quelques directives à indiquer pour faire fonctionner Kibana avec votre noeud Elasticsearch:

# Kibana is served by a back end server. This controls which port to use.
port: 5601

# The host to bind the server to.
host: "localhost"

# The Elasticsearch instance to use for all your queries.
elasticsearch_url: "http://localhost:9200"

# preserve_elasticsearch_host true will send the hostname specified in `elasticsearch`. If you set it to false,
# then the host you use to connect to *this* Kibana instance will be sent.
elasticsearch_preserve_host: true

# Kibana uses an index in Elasticsearch to store saved searches, visualizations
# and dashboards. It will create a new index if it doesn't already exist.
kibana_index: ".kibana"
...

Ensuite, un simple:

bin/kibana

suffit à lancer l'instance Kibana. Rendez-vous ensuite sur http://localhost:5601 pour voir le contenu. Pour vous servir de Kibana, le mieux est de lire l'introduction en ligne.

Après avoir exploré, vous devriez être capable de faire quelques diagrammes. Néanmoins, il est bon de savoir dès le départ que Kibana 4 ne peut PAS vous permettre de gérer vos propres couleurs. Et ça, en 2015, c'est un manque de fonctionnalité quasi-inacceptable ! En effet, lorsque je représente des choses qui doivent m'alerter, il vaut mieux employer une palette qui contient du rouge et affecter cette dernière couleur au point qui pose problème. Au lieu de ça, Kibana vous gratifiera d'une palette de couleurs par défaut qui joue bien son rôle mais qui ne pourra pas vraiment mettre en valeur vos résultats. Donc, oubliez la couleur. Peut-être que ça viendra mais pour l'instant, il faut faire sans.

Documentations de référence

Si vous voulez aller plus loin, je vous recommande de lire les documentations de chacun des produits explorés:

Conclusions

En quelques décompressions de binaire et avec un minimum de configuration, vous devriez être capable de faire de beaux diagrammes. Mais je vous propose une série d'articles qui vous permettront, pas à pas, d'aller plus loin en étudiant, domaine par domaine, comment faire parler vos logs: