A la découverte de Graylog

David Sarrio
BeTomorrow
Published in
8 min readSep 5, 2017

--

De nos jours, quand vous recherchez une solution pour centraliser les logs de vos applications, il y en a une qui revient très souvent dans les réponses : la stack Elastic (anciennement connue sous le nom de stack ELK). Pour ceux qui ne la connaissent pas, en voici un rapide aperçu : elle se compose de différents outils et applications et permet d’ingérer, formatter, stocker et indexer des données comme les logs pour ensuite effectuer des recherches complexes et présenter les résultats sous formes de graphes et tableaux de bords. La grande force de cette stack réside d’une part dans les fonctionnalités offertes mais aussi dans ses capacités de scaling qui permettent de gérer d’énormes quantités de données avec des coûts de mise en place et maintenance faibles. Et pas des moindres, le tout est open source et gratuit !

Les éléments de la stack sont les suivants :

  • Elasticsearch: moteur de recherche et d’indexation basé sur Apache Lucene.
  • Logstash: outil du style “pipeline” qui permet de recevoir les données, de les transformer avant de les envoyer au système de stockage.
  • Kibana: outil de visualisation et présentation des données.

Maintenant, même si la mise en place et l’administration de la stack est simple, il n’en reste pas moins que certaines opérations doivent être faites soit en ligne de commande, soit via des fichiers de configuration à éditer manuellement comme par example les règles d’extractions et transformations de Logstash.

Et Graylog dans tout ça ?

On y vient justement ! Graylog est une solution open source alternative de centralisation de logs basée sur Elasticsearch. L’outil reprend à sa façon les fonctionnalités offertes par Logstash et Kibana et permet de gérer la plateforme directement via son interface web.

Pour démarrer il faut déjà déployer l’outil : de nombreuses options s’offrent à vous et la documentation vous guide pour chacune d’elles que ce soit sur Windows, sur Linux, dans une vm ou dans le cloud, via Chef, Ansible ou encore Docker.
Dans le cadre de l’article nous nous contenterons d’un setup local via Docker. On a donc besoin des images Elasticsearch, MongoDB (utilisé pour stocker tout ce qui n’est pas des logs comme la configuration, les utilisateurs, etc.) et Graylog. Pour vous simplifier la mise en place voici le docker-compose qui permet de lancer le tout.

Il suffit donc de faire un docker-compose up -d dans le dossier qui contient votre docker-compose.yml et de se rendre ensuite sur l’adresse http://localhost:9000 pour accéder à Graylog (le compte est admin:passw).

Ecran d’acceuil au 1er lancement

Inputs

Une fois l’outil en place, il est maintenant question de lui envoyer des données. Le modèle principal est sur du push, c’est à dire que les logs arrivent de l’extérieur. Mais il est également possible dans une moindre mesure de faire en sorte que Graylog aille récupérer des infos, par example en questionnant une api REST, mais ce sont là des cas isolés que je ne détaillerai pas ici.

Un certain nombre de types d’entrées sont disponibles, on trouve par exemple des entrées en format brut, Syslog, Beats ou encore Gelf qui est le format de logs créé par Graylog et pour lequel des intégrations sont disponibles pour de nombreux languages et frameworks. A noter aussi que toutes les entrées sont disponibles via TCP, UDP, Kafka ou encore AMQP. Bref, de quoi satisfaire la plupart des besoins et existants !

Pour tester rapidement d’injecter des données, rendez-vous dans System > Input. Et choisissez d’ajouter un input “Random HTTP Message generator” qui comme son nom l’indique permet d’ajouter des logs http fictifs.

Ajout d’un input fictif

Après quelques secondes, des logs vont être ajoutés au système et vous pourrez les consulter depuis l’onglet “Search”. Ici l’interface s’apparente quelque peu à celle de Kibana : la section du haut vous permet de rechercher et filtrer les logs, la section de gauche de choisir les champs à afficher ou à grapher, et celle de droite présente le graph demandé ainsi que la liste des logs filtrés avec le message brut et les champs extraits. Concernant la barre de recherche, la syntaxe utilisée est proche de celle de Lucene (voir ici).

L’interface de recherche de Graylog

Extraction des champs et transformations

Pour pouvoir indexer convenablement les données et faciliter les recherches, il est nécessaire de pouvoir extraire d’une ligne de log des valeurs et de les identifier. De base les logs Gelf et syslog de par leur nature clef/valeur sont traités et extraits directement par l’outil mais par example dans un log de serveur web dans le format non-standard suivant :

2017–06–15T10:51:14.450Z [200] [20ms] [Chrome:4.2] GET /news/4534221

Si on souhaite pouvoir rechercher en fonction de la date, du code de retour, par api ou encore même par numéro de news, il faut indiquer à Graylog comment extraire les champs voulus pour qu’il puisse les renseigner dans Elasticsearch. Pour cela il est possible de rajouter des “Extractors” custom.

On commence donc par ajouter un input “Raw/Plaintext TCP” pour pouvoir envoyer nous même des logs (attention de conserver le port 5555 ou alors assurez-vous que celui choisi est bien forward par docker).

Création d’un input raw tcp

Une fois l’input lancé, il est prêt à ingérer tout ce qu’on va lui envoyer. Attention : l’input étant en raw, Graylog ne s’attend pas à recevoir de requêtes http ou autre, et il faut donc utiliser des outils comme netcat ou telnet. Pour ma part j’ai juste fait un petit script rapide pour avoir une date cohérente et différente à chaque requête: ./send.sh "[200] [20ms] [Chrome:4.2] GET /news/4534221"

send.sh

On peut ensuite voir dans la recherche de Graylog que notre ligne a bien été ajoutée, mais en revanche si on regarde plus en détails en cliquant sur la ligne on se rend compte que, hormis la date, aucun des champs n’a été extrait. Il est donc très difficile de faire une recherche fiable pour trouver les requêtes ayant retournées une erreur 404 par exemple.

Les seuls champs extraits sont message, source et la date

Attachons-nous maintenant à créer un extracteur pour traiter correctement notre format de log. Pour cela revenez à la liste des inputs et sélectionnez “Manage extractors” pour votre input (dans mon cas je l’ai appelé “My raw input”) puis “Get started” dans la section “Add extractor”. On commence par charger un message depuis l’input qui nous servira de base de travail et de modèle, Graylog vous propose de prendre le dernier reçu ou bien de renseigner un message bien précis via son id.

Chargement d’un message pour l’ajout d’un extractor

L’étape suivante est d’ajouter un extractor sur le champ message. Notre but est de le parser et de le convertir en plusieurs champs, à savoir response_code, response_latency, referer, method, et enfin path. Il existe différentes façon d’extraire les champs, les plus classiques étant par expressions régulières ou par grok patterns, mais il est aussi possible d’extraire des champs depuis un json, ou même d’appliquer une série de transformations à un message pour extraire in fine les valeurs voulues (Pipelines). Dans notre example nous utiliserons simplement des grok patterns qui permettent de simplifier l’écriture. D’autant plus que de nombreux pattern sont déjà présents dans l’outil et il vous est bien évidement possible d’en rajouter. Voici la règle utilisée ainsi que la configuration complète de l’extractor :

.* \[%{NUMBER:code}\] \[%{NUMBER:latency}ms\] \[%{DATA:referer}\] %{WORD:method} %{URIPATHPARAM:path}
Configuration de l’extractor.

L’outil de Graylog est bien fait dans le sens où il est possible de tester nos expressions directement sur le message cible et de voir le résultat. Une fois l’extracteur créé vous pouvez envoyer de nouveau un fichier de log pour voir que les champs auront cette fois-ci été extraits correctement et qu’il est donc possible à présent de rechercher précisément et simplement sur les valeurs ou champs voulus.

Les logs sont maintenant correctement ingérés.

Quoi de plus que la stack ELK ?

La question mérite d’être posée effectivement. Il faut bien avouer que si on regarde strictement du coté des fonctionnalités de base, il n’y a pas énormément de choses en plus. Par example la gestion de la visualisation n’a pas été abordée ici mais, bien que très simple et parfaitement fonctionnelle, elle n’apporte pas vraiment plus que Kibana. À l’inverse, certaines options de customisation des dashboards et graphs font cruellement défaut.

Les principaux atouts de Graylog résident dans les fonctionnalités de gestion :

  • La possibilité est offerte de gérer des utilisateurs et des permissions. C’est pourtant quelque chose de classique et de récurrent mais qui malheureusement dans la stack Elastic, n’existe uniquement que via un pack payant.
  • Elasticsearch n’est pas intégré directement dans l’outil, il est donc possible de mutualiser son cluster avec d’autres outils et applications. De plus Graylog permet via son interface de gérer automatiquement les index en réglant le niveau de rétention comme on le souhaite (roulement sur n-index, durée de rétention, quantité, etc.) là ou il faudrait s’y prendre plus ou moins manuellement avec la stack Elastic.
  • Une chose intéressante, est la notion de “Content packs”. Il vous est possible de packager un sous-ensemble de vos configurations (inputs, extractors, collectors, grok patterns, etc.) dans un pack pour le sauvegarder, le versioner ou surtout, le partager avec la communauté.

Conclusion

Graylog est une solution simple et évolutive de centralisation des logs. À ce titre, peu de différences avec la stack Elastic. Mais son déploiement simple, son interface graphique et la vulgarisation faite autour de la gestion et de l’exploitation en font une alternative très intéressante.
De plus, le fait d’être basé sur Elasticsearch et que les extractors suivent une syntaxe très proche de Logstash font qu’il est relativement simple de passer d’une solution à l’autre si besoin est.

--

--