Les journaux systèmes, aka les logs
Les applications ont besoin de raconter ce qu'elles font, en temps normal (quand ça marche) et en temps de crise (quand ça ne marche pas). Traditionnellement, on écrit tout ça dans des fichiers plats qui seront tournés par logrotate ou dans syslog , le service historique pour déporter les logs. Déporter les logs rend impossible leur modification même si la machine est compromise. Centraliser les logs permet d'accéder aux messages d'un service, sans se soucier de l'endroit où il tourne (comme dans un cluster ou des conteneurs).
Centraliser et explorer
ELK ( Elasticsearch Logstash Kibana ) est le premier produit open source permettant de centraliser et d'explorer des logs agréablement. ELK a été pionnier, mais il a oublié de normaliser le protocole pour faire transiter efficacement des logs. Ils fournissent maintenant un émetteur (filebeat) et un récepteur (logstash), mais sans aucune spécification pour leur protocole, lumberjack.
source -> enrichissement, filtrage, routage -> stockage
Fluentd (mélange de C et de Ruby), une alternative à Logstash (mélange de Java et de Jruby), lui, a fourni les spécifications de son protocole : Fluent forward protocol . Fluentd est prévu pour être le hub traitant un ensemble de flux. Il est relativement gourmand en ressources, mais il est épaulé par Fluentbit , qui lui est minimaliste, codé en C, sans lib externe et suffisamment discret pour être installé sur chacun des nœuds.
Protocole
Un bon protocole d'échange de message doit permettre un bon débit, un traitement simple et du routage efficace.
La première étape est d'éradiquer les formats plats qui seront lus par des expressions régulières trop compliquées. La notion de clef/valeur permet d'avoir des filtres simples et une indexation pour avoir de la recherche efficace. Il est tout à fait légitime d'avoir un champ contenant du texte libre, mais il est indispensable de pouvoir étiqueter simplement une ligne de log. Fluent choisit msgpack , plus dense et moins ambigu que JSON, mais c'est un format binaire.
La seconde étape d'optimisation du transport de log est l'envoi par lots. Fluent permet d'envoyer des évènements un par un, par lot, et choix ultime, par lot compressé. De toute façon, en face, le stockage, qui ressemblera à du orienté colonne, immuable, est tellement plus efficace en gros qu'au détail.
Le client ne doit pas bloquer l'application, même quand le serveur de destination n'est pas disponible. L'astuce de l'UDP et des messages perdus n'est plus une option raisonnable. Avec un langage gérant les threads ou de l'asynchrone, il est possible de bufferiser les messages et de retenter l'envoi de lot de messages en cas d'incident de transport. Il est toujours conseillé de compléter la configuration avec un client simple, en relai local, qui profitera de la fiabilité de localhost. Fluentbit est conçu pour être ce relai local.
le protocole prévoit de l'authentification (une clef partagée ou un couple login/password) et l'usage de TLS pour le chiffrage, et même de l'authentification avec un certificat côté client.
Norme
Fluentd et Fluentbit , sont adoubés par le CNCF , recommandés par les gros du Cloud (qui contribuent au code) et les offres SAAS.
Docker sait utiliser fluentd pour router les flots de logs de ses conteneurs.
Fluent fournit une bibliothèque officielle pour une floppée de langage :
Attention, Fluent fournit un driver pour plein de langages, mais rarement un connecteur à l'API standard de log du langage. Les librairies standards de logging sont souvent antérieures à la notion de log structuré, il faudra donc choisir une abstraction de log, hors stdlib : flogger , logrus ,etc. Il sera toujours possible de bricoler un output fluentd pour une lib de log traditionnel, que ce soit dans le code, ou même simplement avec Fluentbit depuis l'extérieur.
Les libs suivent les bonnes pratiques pour ne pas bloquer l'application, ce qui est plus facile quand le langage gère correctement les threads ou l'asynchrone. Pour ne pas bloquer ni remplir la RAM, les libs proposent un tampon circulaire, qui va conserver n messages, puis commencer à écraser les vieux si le tampon est plein. Mais pas de panique hein, la bonne pratique est d'avoir un ambassadeur en localhost, fluentibit qui devra être plus fiable que votre base de données, ou même que le proxy de votre APM préféré, sujet maîtrisé depuis longtemps.
Fluentbit propose lui aussi sa ribambelle d'input comme tail, STDIN, journald ou syslog. Fluentbit peut parser les messages dans des formats comme du JSON ou même lire avec des regexp .
Côté réception, le choix est large.
- Logstash .
- Fluentd sera capable d'enrichir les messages avant de le confier à une solution de stockage.
- Fluentbit, de manière plus simple et économe, pourra lui aussi filtrer et rediriger vers du stockage.
Les solutions de stockage pourront être par exemple Elasticsearch, Loki, Clickhouse comme produits opensource, ou bien des offres SAAS.
Usages
Fluent permet de gérer proprement ses logs, que ce soit des logs historiques, avec l'aide de fluentbit, ou des logs métiers, qualifiés avec élégance.
Fluent n'assure que la partie transport/qualification/routage. À vous de choisir ce qu'il se passera en aval.
Fluent se positionne comme un complément aux métriques (statsd, Prometheus ), aux traces ( jaeger ) et à la gestion d'erreurs ( Sentry ).