Expédier les logs de façon fiable : plugins de sortie et mise en tampon
Installez un plugin de sortie, routez différentes sources vers différentes destinations et configurez la mise en tampon pour qu'un backend en panne ne fasse pas perdre de données.
Collecter et analyser les logs n’est que la moitié du pipeline ; les amener quelque part d’utile, de façon fiable, même quand cette destination est temporairement injoignable, en est l’autre moitié. Ce guide couvre l’installation d’un plugin de sortie, le routage de plusieurs sources vers leurs propres destinations, et la configuration de mise en tampon qui rend la livraison réellement fiable plutôt que « au mieux ».
Installer un plugin de sortie
Les sorties intégrées de Fluentd couvrent les bases (file, stdout, forward vers une autre instance de Fluentd), mais la plupart des vraies destinations, Elasticsearch, un stockage cloud, une plateforme de logs SaaS, sont des plugins séparés que l’on installe avec fluent-gem, l’enveloppe gérée par Fluentd autour de RubyGems :
sudo fluent-gem install fluent-plugin-elasticsearch
Utiliser fluent-gem plutôt qu’un simple gem install est important : il installe dans l’environnement Ruby que Fluentd utilise réellement, plutôt que dans le Ruby par défaut du système, ce qui est une source fréquente de confusion du type « j’ai installé le plugin mais Fluentd dit toujours qu’il est introuvable ». Si vous exécutez Fluentd en conteneur, installez le plugin lors de la construction de votre propre image, bâtie sur l’image officielle, plutôt que de l’installer à la main dans un conteneur en cours d’exécution, afin qu’il soit réellement présent au prochain démarrage de ce conteneur.
Configurer la sortie
Une fois installée, une destination Elasticsearch n’est qu’un bloc <match> de plus :
<match apache.access>
@type elasticsearch
host elasticsearch
port 9200
index_name fluentd-apache
</match>
Router différentes sources vers différentes destinations
Rien n’oblige toutes les sources à aboutir au même endroit. Plusieurs blocs <match>, chacun limité à un tag différent, envoient des données différentes vers des destinations différentes au sein d’une même configuration :
<match apache.access>
@type elasticsearch
host elasticsearch
port 9200
index_name fluentd-apache
</match>
<match docker.**>
@type elasticsearch
host elasticsearch
port 9200
index_name fluentd-docker
</match>
<match app.**>
@type forward
<server>
host aggregator.internal
port 24224
</server>
</match>
Les logs applicatifs vont vers un index, les logs de conteneurs vers un autre, et une troisième source est transférée vers une instance Fluentd entièrement distincte pour un traitement ultérieur, le tout dans le même pipeline. C’est aussi ainsi qu’une même source peut être envoyée vers plusieurs destinations à la fois : définissez deux blocs <match> distincts correspondant au même tag (ou utilisez une section <copy>), car un pipeline Fluentd n’est pas limité à une seule sortie par source.
La mise en tampon : ce qui rend vraiment la livraison fiable
Par défaut, un plugin met en tampon en mémoire avant d’écrire vers sa destination, ce qui est rapide, mais signifie qu’un plantage ou un redémarrage de Fluentd perd tout ce qui n’avait pas encore été vidé. Pour tout cas où perdre des données de log en transit est gênant, configurez à la place un tampon fichier explicite, afin que les entrées mises en tampon soient persistées sur disque et survivent à un redémarrage :
<match apache.access>
@type elasticsearch
host elasticsearch
port 9200
index_name fluentd-apache
<buffer>
@type file
path /var/log/fluent/buffer/apache
flush_interval 5s
retry_max_times 10
retry_wait 5s
</buffer>
</match>
C’est le comportement que l’on décrit souvent par « Fluentd ne perd pas de données s’il redémarre », mais il faut être précis : c’est vrai grâce à un tampon fichier configuré, pas automatiquement. Avec un tampon mémoire, un plantage en plein vidage perd quand même ce qui était en file d’attente. Si une livraison fiable compte pour une destination donnée, configurez-lui explicitement le tampon fichier plutôt que de supposer que la valeur par défaut suffit.
Gérer une destination temporairement indisponible
La même configuration de mise en tampon est ce qui gère proprement un backend en panne. Si Elasticsearch (ou quelle que soit la destination) devient injoignable, les entrées s’accumulent dans le tampon au lieu d’être perdues, et Fluentd retente la livraison selon le calendrier que définissent retry_wait et retry_max_times, les données en tampon étant entre-temps stockées en sécurité sur disque si vous avez configuré un tampon fichier. Une fois la destination de nouveau joignable, Fluentd rattrape son retard à partir de là où il s’était arrêté. C’est ce qui fait d’une brève coupure réseau ou d’un redémarrage du backend un non-événement plutôt qu’un trou dans vos logs.
Masquer et enrichir avant la sortie finale
Un <filter> s’exécute toujours avant la sortie correspondante, quel que soit son emplacement entre la source et le match, si bien que les données sensibles peuvent être retirées juste avant d’atteindre la destination :
<filter apache.access>
@type record_transformer
remove_keys remote_addr, user_agent
</filter>
record_transformer est le même plugin que celui utilisé pour l’enrichissement (voir l’exemple du nom d’hôte dans le guide précédent) ; remove_keys en est simplement l’autre sens, retirer des champs plutôt qu’en ajouter. C’est un endroit raisonnable pour masquer tout ce qui est sensible, une adresse e-mail, un jeton de session, une IP interne, avant que cela ne quitte votre propre infrastructure vers une destination tierce, plutôt que de compter sur la destination pour le gérer correctement après coup.
Guides populaires
-
Pourquoi centraliser les logs : le problème que Fluentd résout Ce qui dysfonctionne quand les logs se répartissent dans des dizaines de fichiers et de formats, et comment le pipeline collecter-transformer-expédier de Fluentd y remédie. -
Bases de la configuration de Fluentd : source, filter, match et tags Les directives dont toute configuration Fluentd est faite, comment les tags les relient, et comment valider une configuration avant de l'exécuter. -
Collecter des logs depuis des fichiers, HTTP et des conteneurs Configurez les trois sources d'entrée les plus courantes : un fichier sur disque, un endpoint HTTP et tous les conteneurs d'un hôte Docker.