Skip to content

Aide mémoire – Collecter des données avec logstash

Posted in GNU/Linux

Un petit aide mémoire

Logstash est un collecteur de données. Il permet de récupérer par exemple des logs ou d’autres types de données (dans une base, un autre collecteur), il peut ensuite les filtrer ou les retravailler pour enfin les fournir en sortie à une autre application. Cela me fait penser un peu au travail d’un ETL.

Avant de débuter, sachez que logstash bien que développé principalement en ruby fait appel à Jruby. A chaque lancement, il faut donc démarrer une JVM ce qui plombe un peu le système … des fois il faut peut être refaire la roue. Habituellement l’utilisation de Elasticsearch et de kibana est associée à Logstash. A la fin de l’article on indique comment faire fonctionner le trio.

Installation de logstash : En pré requis il faut java, openjdk sur debian wheezy est suffisant.

1) Récupérez et décompressez les sources sur le site de Logstash (http://logstash.net/):

$ curl -O https://download.elasticsearch.org/logstash/logstash/logstash-1.4.2.tar.gz
$ tar xzvf logstash-1.4.2.tar.gz

2) Accédez au répertoire et faites un premier test :

$ cd logstash-1.4.2/ $ bin/logstash -e 'input { stdin { } } output { stdout {} }'
test
2015-02-12T13:11:49.278+0000 pyrbur test

Ici on dit à Logstash de collecter ce qui est fournit à l’entrée standard et de pousser les infos récupérées vers la sortie standard. Pour arrêter le process un Ctrl-C suffit. On peut maintenant ajouter un “codec” pour avoir une sortie verbeuse :

$ bin/logstash -e 'input { stdin { } } output { stdout { codec =  rubydebug } }'
coucou les copains
{ "message" =  "coucou les copains",
  "@version" =  "1",
  "@timestamp" =  "2015-02-12T13:25:17.961Z",
  "host" =  "pyrbur"
}

Évidemment la conf fournie à logstash peut être inscrite dans un fichier qui sera joué.
Par exemple :

$ echo 'input { stdin { } } output { stdout { codec =  rubydebug } }'  > conf1.cfg
$ bin/logstash -f conf1.cfg

Maintenant que l’on a compris le principe, il ne reste plus qu’à jouer avec. On peut changer les entrées pour collecter les entrées d’un fichier de log ou d’une base nosql, filtrer ces données et les renvoyer vers une sortie comme une base de données ou bien sûr vers elasticsearch.

Une mise en pratique de logstash :

Je vous propose d’écrire une conf permettant de collecter les données de logs apache pour les charger dans une base nosql mongodb.
Je pars du principe que les installation d’apache et de mongodb sont déjà réalisée.

Pour pouvoir utiliser mongodb en sortie, il faut installer d’abord les contrib-plugin, pour cela nous allons exécuter la commande suivante :

$ bin/plugin install contrib

Ensuite il faut démarrer une instance mongodb et où nous allons créer une base et une collection qui recevra nos données.

Ici je crée la base apachedb et la collection logs :

$ mongo
  MongoDB shell version: 2.0.6
  connecting to: test
   > use apachedb
    switched to db apachedb
   > db.createCollection('logs2')
    { "ok" : 1 }

On écrit ensuite le fichier de conf logstash ci dessous. La syntaxe parle d’elle même. Remarquez juste que l’on peut mettre plusieurs sorties (idem pour les entrées). Nous avons une sortie vers la sortie standard et une autre vers mongodb.

Fichier apache.cfg : 
input {
  file {
    path =  "/var/log/apache2/access.log"
    start_position =  beginning
	}
}
output {
    stdout {
    codec =  rubydebug
}
mongodb {
    collection =  "logs"
    database =  "apachedb"
    uri =  "mongodb://localhost:27017"
   }
}

On va pouvoir maintenant lancer logstash. Attention, il faut que votre user bénéficie des droits nécessaires pour lire les logs.

$ bin/logstash -f apache.cfg
Using milestone 2 input plugin 'file'. This plugin should be stable,....
Using milestone 2 input plugin 'mongodb'. This plugin should be stable,....

{"message" =  "127.0.0.1 - - [12/Feb/2015:18:17:10 +0100] \"GET /~bouba/ HTTP/1.1\" 200 1246 \"-\" \"Mozilla/5.0 (X11; Linux i686; rv:31.0) Gecko/20100101 Firefox/31.0 Iceweasel/31.4.0\"",
 "@version" =  "1",
 "@timestamp" =  "2015-02-12T17:27:19.975Z",
 "host" =  "pyrbur",
 "path" =  "/var/log/apache2/access.log"
}
....

Comme nous avons mis stdout { codec = rubydebug }, l’affichage est réalisé aussi sur la sortie standard.

Vérifions que nous avons bien nos données dans mongo avec, par exemple, un

> db.logs.find()

qui permet d’afficher la collection.

Évidemment c’est vraiment minimaliste. Cette conf peut être améliorée pour exploiter plus facilement vos données. Pour cela vous pouvez utiliser les filtres et les conditions (if/else). Vous trouverez plus d’infos ici : http://logstash.net/docs/1.4.2/configuration

Charger les données dans Elasticsearch et les exploiter avec Kibana :

Il faut bien entendu installer ces deux outils.

Traitons l’installation d’Elasticserach d’abord.

$ curl -O https://download.elasticsearch.org/elasticsearch/elasticsearch/elasticsearch-1.0.1.tar.gz
$ tar xzvf elasticsearch-1.0.1.tar.gz

Installer le plugin suivant :

$ cd elasticsearch-1.0.1/
$ bin/plugin -install lmenezes/elasticsearch-kopf

Nous allons maintenant installer Kibana.

Kibana est une interface web écrite en javascript qui permet de réaliser des tableaux de bords sur la base de données présentes dans Elasticsearch (ES).

Téléchargez les sources :

$ curl -O https://download.elasticsearch.org/kibana/kibana/kibana-3.1.2.tar.gz

Décompressez, renommez le dossier kibana et placez le tout dans votre /var/www. (Pour utiliser Kibana il faut bien entendu disposer d’un serveur web. Ici nous utilisons /var/www comme répertoire racine root d’apache)

$ tar xzvf kibana-3.1.2.tar.gz
$ mv kibana-3.1.2 /var/www/kibana

Vous pouvez maintenant ouvrir un navigateur et vous rendre sur la page http://localhost/kibana/.

Si vous n’avez pas démarré ES vous allez obtenir une erreur. Continuons donc … 😉

Revenons maintenant à notre commande logstash pour y ajouter une sortie vers ES.

input {
  file {
  path =  "/var/log/apache2/access.log"
  start_position =  beginning
  }
}
output {
  elasticsearch {
  host =  localhost
}
stdout {
  codec =  rubydebug
}
mongodb {
  collection =  "logs"
  database =  "apachedb"
  uri =  "mongodb://localhost:27017"
 }
}

Démarrons ES :

$ bin/elasticsearch

Faisons un petit test …

curl http://localhost:9200/_status?pretty=true

Normalement si vous avez fait tout depuis le début, il y a du monde …

Démarrons Logstash :

$ bin/logstash -f apache2.cfg

Et relancez Kibana

http://localhost/kibana/

Vous pouvez maintenant vous amuser notamment en jetant un coup d’oeil à http://localhost/kibana3/index.html#/dashboard/file/guided.json

Un dernier exemple permettant de charger un fichier CSV

J’ai fait des tests de collectes sur des données contenu dans un csv. Le fichier était assez volumineux car il était lui même l’aggregation de différente bases. Je n’ai gardé ici que 5 champs pour que cela soit compréhensible :

input {
  file {
  codec =  plain{
  charset =  "UTF-8"
  }
  path =  ["/home/bouba/travail/logstash/ressources/fichier.csv"]
  sincedb_path =  "/data/.sincedb_path"
  start_position =  "beginning"
 }
 }
filter {
  if [message] =~ /^"Refnom","Nom","Prenom","Piece","Tel_labo"/ {
  drop { }
}
csv {
  columns =  ["Refnom","Nom","Prenom","Piece","Tel_labo"]
  separator =  ","
  source =  message
  #remove_field =  ["message","host","path","@version","@timestamp"]
 }
}
output {
  elasticsearch {
  embedded =  false
  host =  "localhost"
  cluster =  "elasticsearch"
  node_name =  "localhost"
  index =  "index"
  index_type =  "type"
}
stdout { codec =  rubydebug }
}