Fluentd est un collecteur de données open source unifié, projet CNCF Graduated, qui centralise et route les logs vers de multiples destinations. Là où Fluent Bit collecte en périphérie, Fluentd joue le rôle d'agrégateur central, avec un écosystème de plus de 500 plugins.
Ce guide s'adresse aux profils intermédiaires et avancés. Vous allez installer Fluentd (version 1.19), comprendre son pipeline (source, filter, match), écrire une configuration, gérer le buffering et router les logs par tags.
Ce que vous allez apprendre
Section intitulée « Ce que vous allez apprendre »- Comprendre le pipeline Fluentd : source, filter, match (buffer).
- Installer Fluentd proprement (Docker épinglé, gem, fluent-package).
- Configurer collecte, filtres et sorties multiples.
- Router les événements avec le système de tags.
- Fiabiliser avec un buffer fichier persistant.
Pourquoi Fluentd ?
Section intitulée « Pourquoi Fluentd ? »Fluentd est le standard de facto pour l'agrégation de logs dans les environnements cloud-native, avec plus de 500 plugins disponibles.
| Caractéristique | Description |
|---|---|
| Licence | Apache 2.0 |
| Maturité | CNCF Graduated |
| Langage | Ruby + C |
| Plugins | 500+ |
| Communauté | Très active |
Architecture
Section intitulée « Architecture »Fluentd utilise une architecture en pipeline avec des plugins d'entrée, de filtrage et de sortie.
┌─────────────────────────────────────────────────────────────────┐│ Fluentd ││ ┌──────────────┐ ┌───────────────┐ ┌───────────────────────┐ ││ │ Input │──│ Filter │──│ Output │ ││ │ plugins │ │ plugins │ │ plugins │ ││ └──────────────┘ └───────────────┘ └───────────────────────┘ ││ ││ - tail - parser - elasticsearch ││ - forward - record_modifier - loki ││ - http - grep - kafka ││ - syslog - geoip - s3 ││ - tcp - throttle - forward │└─────────────────────────────────────────────────────────────────┘ │ ▼ ┌───────────────┐ │ Buffer │ │ (file/memory) │ └───────────────┘Installation
Section intitulée « Installation »Fluentd est écrit en Ruby, ce qui explique ses trois modes d'installation : le paquet système fluent-package (qui embarque son propre Ruby), la gem pour un environnement Ruby existant, et l'image conteneur pour Docker ou Kubernetes. Le choix a une conséquence directe sur l'emplacement de la configuration et sur la commande d'installation des plugins. Quelle que soit la méthode, épinglez une version précise : latest casse silencieusement les plugins compilés contre une autre version de l'API.
Le paquet historique td-agent est en fin de vie. Son successeur est fluent-package (Fluentd v5), à installer depuis le dépôt signé officiel pour un service système. Pour une installation simple et multiplateforme, Fluentd s'installe aussi comme gem Ruby :
# Fluentd via RubyGems (nécessite Ruby)gem install fluentd
fluentd --versiondocker run -d \ --name fluentd \ -p 24224:24224 \ -p 24224:24224/udp \ -v $(pwd)/fluent.conf:/fluentd/etc/fluent.conf \ fluent/fluentd:v1.19-debian-1helm repo add fluent https://fluent.github.io/helm-chartshelm repo update
helm install fluentd fluent/fluentd \ --namespace logging \ --create-namespaceConfiguration
Section intitulée « Configuration »La configuration Fluentd utilise des directives <source>, <filter> et
<match>.
Configuration minimale
Section intitulée « Configuration minimale »Cette configuration lit un répertoire de logs et les réaffiche sur la sortie standard, de quoi valider la chaîne avant de brancher un vrai backend. Le pos_file est le fichier de position : il mémorise jusqu'où Fluentd a lu dans chaque fichier surveillé. Sans lui, l'agent ne sait pas reprendre où il s'était arrêté après un redémarrage, et les lignes écrites pendant la coupure sont perdues. Le tag (app.logs ici) est la clé qui reliera cette source aux blocs filter et match.
<source> @type tail path /var/log/app/*.log pos_file /var/log/fluentd/app.log.pos tag app.logs <parse> @type json </parse></source>
<match app.logs> @type stdout</match>Exemple complet : logs vers Elasticsearch
Section intitulée « Exemple complet : logs vers Elasticsearch »Cette configuration enchaîne les quatre étages du pipeline : deux sources (fichiers applicatifs et syslog), deux filtres (ajout de métadonnées puis parsing), et une sortie vers Elasticsearch avec un buffer persistant. L'ordre des blocs compte : les filter s'appliquent dans l'ordre du fichier, et un événement sort par le premier match dont le motif correspond à son tag. Un <match **> placé trop haut capturerait donc tout le trafic.
# Collecter les logs applicatifs<source> @type tail path /var/log/app/*.log pos_file /var/log/fluentd/app.pos tag app.logs <parse> @type json time_key timestamp time_format %Y-%m-%dT%H:%M:%S.%L%z </parse></source>
# Collecter syslog<source> @type syslog port 5140 bind 0.0.0.0 tag syslog</source>
# Ajouter des métadonnées<filter app.**> @type record_transformer <record> hostname "#{Socket.gethostname}" environment production </record></filter>
# Parser les logs multi-format<filter app.**> @type parser key_name message reserve_data true <parse> @type multi_format <pattern> format json </pattern> <pattern> format regexp expression /^(?<time>[^ ]+) (?<level>[^ ]+) (?<message>.*)$/ </pattern> </parse></filter>
# Sortie vers Elasticsearch avec buffer<match **> @type elasticsearch host elasticsearch port 9200 index_name fluentd-${tag}-%Y.%m.%d
<buffer tag, time> @type file path /var/log/fluentd/buffer flush_mode interval flush_interval 5s chunk_limit_size 5MB queue_limit_length 512 retry_max_interval 30 retry_forever true </buffer></match>Plugins essentiels
Section intitulée « Plugins essentiels »Sur les 500 plugins du registre, une douzaine couvre la quasi-totalité des besoins. Ils se répartissent selon leur position dans le pipeline : input pour collecter, filter pour transformer, output pour expédier. Seuls quelques-uns sont livrés avec Fluentd ; les autres s'installent séparément, une distinction qui explique la plupart des erreurs de démarrage du type Unknown output plugin.
Input plugins
Section intitulée « Input plugins »Ces plugins déterminent d'où viennent les données. tail lit des fichiers, les autres écoutent sur un port réseau et attendent qu'on leur envoie les événements.
| Plugin | Usage | Configuration |
|---|---|---|
tail | Lire des fichiers | path, pos_file |
forward | Recevoir d'autres Fluentd | port 24224 |
http | API HTTP | port 9880 |
syslog | Recevoir syslog | port 5140 |
tcp | Socket TCP | port 5170 |
Filter plugins
Section intitulée « Filter plugins »Un filtre s'applique aux événements dont le tag correspond à son motif, et peut aussi bien enrichir l'enregistrement que le supprimer. C'est l'endroit où réduire le volume avant l'envoi, donc avant de payer le stockage.
| Plugin | Usage | Exemple |
|---|---|---|
record_transformer | Ajouter/modifier des champs | Ajouter hostname |
parser | Parser le message | JSON, regex |
grep | Filtrer par pattern | Include/exclude |
geoip | Enrichir avec GeoIP | IP → localisation |
Output plugins
Section intitulée « Output plugins »La destination finale des événements. Rien n'oblige à n'en avoir qu'une : plusieurs blocs match avec des motifs différents permettent d'archiver dans S3 tout en indexant dans Elasticsearch, et le plugin forward sert à chaîner un agent vers un agrégateur.
| Plugin | Destination |
|---|---|
elasticsearch | Elasticsearch / OpenSearch |
loki | Grafana Loki |
kafka | Apache Kafka |
s3 | Amazon S3 |
forward | Autre Fluentd |
prometheus | Métriques Prometheus |
Installer des plugins
Section intitulée « Installer des plugins »Les plugins sont des gems Ruby. La commande fluent-gem les installe dans l'environnement Ruby embarqué par Fluentd, ce qui n'est pas la même chose qu'un gem install système. En conteneur, l'installation doit se faire au build de l'image : un plugin ajouté à chaud disparaît au redémarrage du conteneur.
fluent-gem install fluent-plugin-elasticsearchFROM fluent/fluentd:v1.19-debian-1@sha256:f29b1d1103afd4bbcab8a17ecfefb411674ec57694f0cbd6641b4ae4dd65e13bUSER rootRUN gem install fluent-plugin-elasticsearchUSER fluentBuffering et fiabilité
Section intitulée « Buffering et fiabilité »Le buffer est crucial pour la fiabilité. Fluentd supporte deux types.
Memory buffer (défaut)
Section intitulée « Memory buffer (défaut) »Rapide mais perte de données en cas de crash.
<buffer> @type memory flush_interval 5s</buffer>File buffer (recommandé)
Section intitulée « File buffer (recommandé) »Persistant sur disque, survit aux redémarrages.
<buffer> @type file path /var/log/fluentd/buffer chunk_limit_size 8MB total_limit_size 2GB flush_mode interval flush_interval 5s flush_thread_count 2 retry_forever true retry_max_interval 30</buffer>Tags et routing
Section intitulée « Tags et routing »Les tags déterminent le routage des événements. Chaque source attribue un tag à ce qu'elle collecte, et chaque bloc match déclare le motif de tags qu'il traite. La notation pointée (nginx.access) crée une hiérarchie exploitable par les jokers : * remplace un seul segment, ** en remplace un nombre quelconque. Un événement quitte le pipeline par le premier match qui l'accepte, donc l'ordre de déclaration prime sur la précision du motif.
# Source avec tag<source> @type tail path /var/log/nginx/access.log tag nginx.access</source>
# Match exact<match nginx.access> @type elasticsearch</match>
# Match avec wildcard<match nginx.**> @type loki</match>
# Match multiple tags<match {nginx.access,app.logs}> @type s3</match>
# Match tout<match **> @type stdout</match>Déploiement Kubernetes
Section intitulée « Déploiement Kubernetes »Dans un cluster, les logs des conteneurs sont écrits sur chaque nœud, sous /var/log/containers/. Il faut donc un agent sur chaque nœud, déployé en DaemonSet, et c'est le rôle de Fluent Bit. Fluentd se place derrière, en Deployment, pour concentrer le trafic et gérer le buffer avant l'envoi au backend.
Architecture recommandée
Section intitulée « Architecture recommandée »Cette séparation en deux étages évite que chaque nœud ouvre sa propre connexion vers Elasticsearch, et concentre la reprise sur incident au même endroit : si le backend tombe, c'est l'agrégateur qui accumule, pas les dizaines d'agents.
┌─────────────────────────────────────────────────────────────────┐│ Kubernetes Cluster ││ ││ ┌──────────┐ ┌──────────┐ ┌──────────┐ ││ │ Fluent │ │ Fluent │ │ Fluent │ ← DaemonSet ││ │ Bit │ │ Bit │ │ Bit │ (chaque node) ││ └────┬─────┘ └────┬─────┘ └────┬─────┘ ││ │ │ │ ││ └─────────────┼─────────────┘ ││ ▼ ││ ┌─────────────────┐ ││ │ Fluentd │ ← Deployment ││ │ (agrégateur) │ (replicas: 2) ││ └────────┬────────┘ ││ │ │└────────────────────┼──────────────────────────────────────────────┘ ▼ ┌──────────────────────┐ │ Elasticsearch / │ │ Loki / S3 │ └──────────────────────┘Configuration DaemonSet (Fluent Bit → Fluentd)
Section intitulée « Configuration DaemonSet (Fluent Bit → Fluentd) »Côté collecte, Fluent Bit lit les fichiers de logs du nœud et pousse tout vers l'agrégateur avec la sortie forward, le protocole natif de la famille Fluent. Le Host doit correspondre au nom du Service Kubernetes de l'agrégateur, pas à un Pod, sinon la reprise après un redémarrage échoue.
config: inputs: | [INPUT] Name tail Path /var/log/containers/*.log Tag kube.*
outputs: | [OUTPUT] Name forward Match * Host fluentd-aggregator Port 24224Configuration Aggregator (Fluentd)
Section intitulée « Configuration Aggregator (Fluentd) »Côté agrégateur, la source forward écoute sur le port 24224 les événements envoyés par les agents. Le filtre kubernetes_metadata interroge l'API du cluster pour ajouter le namespace, le nom du Pod et les labels à chaque enregistrement : sans lui, vous ne savez pas de quelle application vient une ligne de log. Ce plugin ne fait pas partie du cœur de Fluentd, il s'installe séparément et exige des droits de lecture sur les Pods.
<source> @type forward port 24224 bind 0.0.0.0</source>
<filter kube.**> @type kubernetes_metadata</filter>
<match kube.**> @type elasticsearch host elasticsearch port 9200 index_name kubernetes-%Y.%m.%d
<buffer> @type file path /var/log/fluentd/buffer </buffer></match>Monitoring
Section intitulée « Monitoring »Un collecteur de logs qui tombe est particulièrement pénible : personne ne le voit tant qu'on ne cherche pas un log absent. Fluentd expose donc son propre état par deux voies, une API HTTP interne pour un diagnostic ponctuel, et un endpoint Prometheus pour la surveillance continue. La métrique à suivre en priorité est la taille de la file de buffer : elle monte dès que la destination ralentit.
Métriques internes
Section intitulée « Métriques internes »Le plugin monitor_agent ouvre une petite API HTTP qui expose l'état de chaque plugin chargé, dont la longueur de la file d'attente.
<source> @type monitor_agent bind 0.0.0.0 port 24220</source>Accédez à http://localhost:24220/api/plugins.json.
Exposition Prometheus
Section intitulée « Exposition Prometheus »Deux blocs sont nécessaires : le premier ouvre l'endpoint /metrics sur le port 24231, le second (prometheus_output_monitor) alimente cet endpoint avec les compteurs des plugins de sortie, dont le nombre d'échecs de retry. Le premier seul exposerait une page presque vide.
<source> @type prometheus bind 0.0.0.0 port 24231 metrics_path /metrics</source>
<source> @type prometheus_output_monitor</source>Bonnes pratiques
Section intitulée « Bonnes pratiques »Ces cinq règles répondent toutes au même risque : la perte de logs lors d'un incident, c'est-à-dire précisément au moment où ils sont indispensables. Les deux premières se configurent dans le bloc <buffer>, les trois autres relèvent de l'architecture et de la surveillance.
- Utilisez des buffers fichier en production
- Limitez la taille des chunks pour éviter l'OOM
- Activez retry_forever pour ne pas perdre de logs
- Séparez collecte et agrégation (Fluent Bit + Fluentd)
- Monitorez les buffers pour détecter les backlogs
Dépannage
Section intitulée « Dépannage »La majorité des incidents Fluentd viennent du buffer ou du parsing, rarement du réseau. Avant de modifier la configuration, validez sa syntaxe avec --dry-run : le démarrage échoue de toute façon si un plugin référencé n'est pas installé, mais l'erreur est bien plus lisible en mode -vvv.
| Symptôme | Cause probable | Solution |
|---|---|---|
| Buffer plein | Destination lente/down | Augmenter queue_limit |
| Logs perdus | Memory buffer + crash | Passer en file buffer |
| Haute mémoire | Chunks trop gros | Réduire chunk_limit_size |
| Parsing échoue | Format non reconnu | Vérifier le pattern |
# Vérifier la configfluentd --dry-run -c /etc/fluent/fluent.conf
# Mode debugfluentd -c /etc/fluent/fluent.conf -vvvFAQ : questions fréquentes
Section intitulée « FAQ : questions fréquentes »Les questions ci-dessous reviennent le plus souvent lors de la mise en place : arbitrage entre Fluentd et Fluent Bit, fonctionnement du routage par tags et nécessité d'un buffer fichier.
source → filter → match, avec un écosystème de plus de 500 plugins. On l'emploie surtout comme agrégateur central.source. Les directives match dirigent les événements vers une sortie selon leur tag : match exact (nginx.access), wildcard (nginx.**), plusieurs tags ({a,b}) ou ** pour tout capter. C'est le tag qui décide de la destination, dans l'ordre des blocs match.@type file) persiste sur disque et survit aux redémarrages, avec retry_forever pour ne pas perdre de logs si la destination est temporairement indisponible.À retenir
Section intitulée « À retenir »- CNCF Graduated : standard de l'industrie
- 500+ plugins : intégration avec tout
- Buffer fichier : obligatoire en production
- Tags : système de routage flexible
- Fluent Bit en collecte : Fluentd en agrégation