Monitoring
DevOps
Kubernetes

Fluent Bit : construire un pipeline de logs performant

22 février 2026

8 min de lecture

Intro : le défi de la collecte de logs à l'échelle

Vos serveurs, conteneurs et applications produisent des téraoctets de logs quotidiens. Les centraliser, les parser et les router vers vos outils d'analyse (Elasticsearch, Loki, CloudWatch) devient rapidement un goulot d'étranglement critique.

Fluentd, historiquement, assumait ce rôle—mais sa consommation mémoire (200+ Mo par instance) et son overhead CPU font qu'il n'est pas idéal pour des déploiements lightweight, notamment en edge ou sur Kubernetes. Fluent Bit, réécrit en C par la même communauté, apporte une alternative : 2-3 Mo de RAM, zero-copy buffers, et une latence minimum. Chez SHPV, sur notre backbone AS41652 de 150 Gbps opérant depuis 2012, le monitoring d'infrastructure à l'échelle impose de tels choix.

Cet article vous guide dans le déploiement productif de Fluent Bit : architecture, configuration, intégration Kubernetes, et tuning performance.


Plan de l'article

  • Fluent Bit vs Fluentd : quand et pourquoi choisir
  • Architecture du pipeline (Input → Parser → Filter → Buffer → Output)
  • Installation et structure de configuration
  • Sources d'entrée : tail, systemd, Kubernetes, TCP
  • Parsing et filtrage : regex, JSON, Lua
  • Destinations : Elasticsearch, Loki, S3, Splunk
  • Déploiement DaemonSet et enrichissement métadonnées
  • Tuning performance et gestion de backpressure
  • Monitoring et health checks
  • Intégrations complémentaires

Fluent Bit vs Fluentd : lequel choisir ?

CritèreFluentdFluent Bit
Mémoire200+ Mo2-3 Mo
LangageRubyC
LatenceModéréeUltra-faible
Plugins500+100+ (essentiels)
Overhead CPUMoyenMinimal
Use caseAgrégation centralisée, grosse infraEdge, sidecar, volume élevé

Verdict : Fluent Bit pour les agents de log (DaemonSet, sidecars) ; Fluentd pour l'agrégation centralisée. Les deux cohabitent souvent : Fluent Bit → Fluentd → Storage.


Architecture Fluent Bit : le pipeline

Input → Parser → Filter → Buffer → Output
  1. Input : lit des logs (fichiers, sockets, systemd)
  2. Parser : parse les événements en records structurés
  3. Filter : enrichit, modifie, supprime des champs (record_modifier, grep, Lua)
  4. Buffer : stockage temporaire en mémoire ou disque (avec backpressure)
  5. Output : envoie vers destination (Elasticsearch, Loki, HTTP, etc.)

Chaque stage est non-bloquant : si un output est slow, le buffer absorbe sans ralentir les inputs.


Installation et premiers pas

Package manager
# Ubuntu/Debian
curl https://packages.fluentbit.io/fluentbit.key | apt-key add -
echo "deb https://packages.fluentbit.io/ubuntu/jammy jammy main" | tee /etc/apt/sources.list.d/fluentbit.list
apt update && apt install -y fluent-bit

# Alpine (Docker)
apk add fluent-bit
Structure de configuration
/etc/fluent-bit/
├── fluent-bit.conf        # Principal
├── parsers.conf           # Définitions parsers
├── plugins.conf           # Plugins custom
└── inputs/                # Fichiers inputs
    ├── syslog.conf
    ├── docker.conf
    └── app.conf
Configuration minimale
[SERVICE]
    Daemon Off
    Flush 5
    Log_Level info
    Parsers_File parsers.conf
    HTTP_Server On
    HTTP_Listen 0.0.0.0
    HTTP_Port 2020
    Health_Check On

[INPUT]
    Name tail
    Path /var/log/app.log
    Parser json
    Tag app.*

[OUTPUT]
    Name loki
    Match app.*
    Host loki.monitoring.svc
    Port 3100

Inputs : collecter les logs

Tail (fichiers)
[INPUT]
    Name tail
    Path /var/log/*.log
    Parser docker
    Tag container.*
    Skip_Long_Lines On
    Mem_Buf_Limit 50MB
    DB /var/log/.flb_kube.db     # SQLite state
Systemd
[INPUT]
    Name systemd
    Tag systemd.*
    Read_From_Tail On
    Path /var/log/journal
TCP/UDP (application logging)
[INPUT]
    Name forward
    Listen 0.0.0.0
    Port 24224
    Tag app.forward
Kubernetes (logs de pod)
[INPUT]
    Name tail
    Path /var/log/containers/*.log
    Tag kube.*
    Parser docker
    DB /var/log/.flb_kube.db
    Mem_Buf_Limit 50MB

Parsers et filtres

Parser JSON simple
[PARSER]
    Name json
    Format json
    Time_Key timestamp
    Time_Format %Y-%m-%dT%H:%M:%S.%LZ
    Time_Keep On
Parser regex (Apache/Nginx)
[PARSER]
    Name nginx
    Format regex
    Regex ^(?<remote>[^ ]*) (?<host>[^ ]*) (?<user>[^ ]*) \[(?<time>[^\]]*)\] "(?<method>\S+)(?: +(?<path>[^\"]*?)(?: +\S*)?)?" (?<code>[^ ]*) (?<size>[^ ]*)(?: "(?<referer>[^\"]*)" "(?<agent>[^\"]*)")?$
    Time_Key time
    Time_Format %d/%b/%Y:%H:%M:%S %z
Multiline (stack traces)
[PARSER]
    Name multiline
    Format multiline
    Multiline_Parser line1, line2, line3

[MULTILINE_PARSER]
    Name line1
    Flush_timeout 1000
    Rule "start_state" "/^\d{4}-\d{2}-\d{2}/" "cont"
    Rule "cont" "/^[^\d]/" "cont"
    Rule "cont" "/^\d{4}-\d{2}-\d{2}/" "start_state"
Filtres : record_modifier
[FILTER]
    Name record_modifier
    Match *
    Add hostname ${HOSTNAME}
    Add service app-backend
    Add environment production
Filtres : Lua (logique custom)
[FILTER]
    Name lua
    Match app.*
    Script /etc/fluent-bit/scripts/enrich.lua
    Call enrich

# enrich.lua
function enrich(tag, timestamp, record)
    record["traced_by"] = "fluent-bit"
    record["cluster"] = os.getenv("CLUSTER_NAME")
    return 2, timestamp, record
end
Filtres : grep (inclusion/exclusion)
[FILTER]
    Name grep
    Match app.*
    Exclude level DEBUG
    Regex message .*ERROR.*

Outputs : router les logs

Elasticsearch
[OUTPUT]
    Name es
    Match app.*
    Host elasticsearch.default.svc
    Port 9200
    HTTP_User elastic
    HTTP_Passwd ${ELASTIC_PASSWORD}
    Index my-app-%Y.%m.%d
    Type _doc
    Retry_Limit 5
Loki (Grafana)
[OUTPUT]
    Name loki
    Match kube.*
    Host loki.monitoring.svc
    Port 3100
    Labels job=kubernetes, cluster=${CLUSTER}
    Remove_Keys kubernetes_namespace_name
S3 (archivage)
[OUTPUT]
    Name s3
    Match archive.*
    Bucket my-logs
    Region eu-west-1
    S3_Key_Format logs/%Y/%m/%d/%H/
HTTP custom
[OUTPUT]
    Name http
    Match *
    Host webhook.example.com
    Port 443
    URI /logs
    Format json
    json_date_key timestamp
    json_date_format iso8601

Déploiement Kubernetes

DaemonSet + ConfigMap
apiVersion: v1
kind: ConfigMap
metadata:
  name: fluent-bit-config
  namespace: monitoring
data:
  fluent-bit.conf: |
    [SERVICE]
        Daemon Off
        Flush 5
        Log_Level info
        HTTP_Server On
        HTTP_Listen 0.0.0.0
        HTTP_Port 2020

    [INPUT]
        Name tail
        Path /var/log/containers/*.log
        Parser docker
        Tag kube.*
        DB /var/log/.flb_kube.db
        Mem_Buf_Limit 50MB
        Refresh_Interval 10

    [FILTER]
        Name kubernetes
        Match kube.*
        Kube_URL https://kubernetes.default.svc:443
        Merge_Log On
        Keep_Log Off
        K8S_Logging_Parser On

    [OUTPUT]
        Name loki
        Match kube.*
        Host loki.monitoring.svc
        Port 3100

  parsers.conf: |
    [PARSER]
        Name docker
        Format json
        Time_Key time
        Time_Format %Y-%m-%dT%H:%M:%S.%LZ
        Time_Keep On

---
apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: fluent-bit
  namespace: monitoring
spec:
  selector:
    matchLabels:
      app: fluent-bit
  template:
    metadata:
      labels:
        app: fluent-bit
    spec:
      serviceAccountName: fluent-bit
      containers:
        - name: fluent-bit
          image: fluent/fluent-bit:2.1.8
          resources:
            limits:
              memory: 100Mi
              cpu: 100m
            requests:
              memory: 50Mi
              cpu: 50m
          volumeMounts:
            - name: varlog
              mountPath: /var/log
            - name: varlibdockercontainers
              mountPath: /var/lib/docker/containers
              readOnly: true
            - name: config
              mountPath: /fluent-bit/etc/
          livenessProbe:
            httpGet:
              path: /api/v1/health
              port: 2020
            initialDelaySeconds: 30
            periodSeconds: 10
      volumes:
        - name: varlog
          hostPath:
            path: /var/log
        - name: varlibdockercontainers
          hostPath:
            path: /var/lib/docker/containers
        - name: config
          configMap:
            name: fluent-bit-config
      tolerations:
        - effect: NoSchedule
          operator: Exists
RBAC pour Kubernetes filter
apiVersion: v1
kind: ServiceAccount
metadata:
  name: fluent-bit
  namespace: monitoring

---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: fluent-bit
rules:
  - apiGroups: ['']
    resources:
      - namespaces
      - pods
      - pods/logs
    verbs: ['get', 'list', 'watch']

---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: fluent-bit
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: fluent-bit
subjects:
  - kind: ServiceAccount
    name: fluent-bit
    namespace: monitoring

Performance et tuning

Gestion du buffer
[SERVICE]
    Storage.path /var/log/flb-storage
    Storage.sync normal
    Storage.checksum off
    Storage.max_chunks_up 128
    Storage.backlog.mem_limit 5M

[OUTPUT]
    Name loki
    Match *
    Retry_Limit 5
    net.dns.mode TCP
    net.keepalive on
    net.keepalive_idle_timeout 30
Backpressure et throttling
[INPUT]
    Name tail
    Path /var/log/app.log
    Mem_Buf_Limit 50MB        # Pause la lecture si buffer > 50MB
    Skip_Empty_Lines On

[FILTER]
    Name throttle
    Match *
    Rate 1000              # Max 1000 records/sec
    Window 5               # Window de 5 secondes
    Print_Status true
Réduction de mémoire
  • Skip_Long_Lines On : ignore les logs > 32 KB
  • Mem_Buf_Limit 50MB : cap mémoire par input
  • Storage.path : offload sur disque si buffer full

Monitoring Fluent Bit

Endpoint Prometheus natif
curl http://localhost:2020/api/v1/metrics | jq .
Scrape Prometheus
scrape_configs:
  - job_name: 'fluent-bit'
    static_configs:
      - targets: ['localhost:2020']
    metrics_path: '/api/v1/metrics'
    scrape_interval: 15s
Health check / Readiness
curl -I http://localhost:2020/api/v1/health
# HTTP/1.1 200 OK
Alertes clés
- alert: FluentBitHighMemory
  expr: container_memory_usage_bytes{pod="fluent-bit"} > 100000000
  for: 5m

- alert: FluentBitOutputErrors
  expr: increase(fluentbit_output_errors_total[5m]) > 10
  for: 5m

Perspectives complémentaires

Pour approfondir votre stack logging :


Sources


Conclusion

Fluent Bit s'impose comme l'agent de log léger par excellence pour la collecte distribuée. Sa footprint minimal, son pipeline flexible et sa maturité en Kubernetes en font un choix solide pour toute infrastructure moderne.

Chez SHPV, nous l'utilisons pour monitorer notre backbone 150 Gbps et nos services infogérance à travers notre SLA 99.9%+. Déployé en DaemonSet avec Loki en backend, il garantit une visibilité complète sur des millions d'événements quotidiens, sans impacter les performances des applications.

Prochaines étapes :

  1. Testez en staging avec un volume proche du production
  2. Tuning du buffer et Mem_Buf_Limit selon votre throughput
  3. Intégrez healthchecks et monitoring Prometheus
  4. Escaladez vers Fluentd ou Vector si besoins d'agrégation avancée

Bon logging !

Besoin d'aide sur ce sujet ?

Notre équipe d'experts est là pour vous accompagner dans vos projets d'infrastructure et d'infogérance.

Contactez-nous

Articles similaires