Logstash pour les devs - 25 - Debugger un pipeline Logstash

Techniques et outils pour debugger un pipeline qui ne fait pas ce que tu veux. stdout, tags, metadata et log level.

  1. 01 Logstash pour les devs - 00 - Pourquoi Logstash existe encore en 2026
  2. 02 Logstash pour les devs - 01 - L'Elastic Stack de A a Z
  3. 03 Logstash pour les devs - 02 - Installer Logstash avec Docker en 5 minutes
  4. 04 Logstash pour les devs - 03 - Anatomie d'un pipeline Logstash
  5. 05 Logstash pour les devs - 04 - Inputs stdin et file : lire des donnees locales
  6. 06 Logstash pour les devs - 05 - Input Beats : recevoir des logs de Filebeat
  7. 07 Logstash pour les devs - 06 - Inputs HTTP, TCP et UDP : recevoir des donnees réseau
  8. 08 Logstash pour les devs - 07 - Inputs Kafka et JDBC : sources avancees
  9. 09 Logstash pour les devs - 08 - Les codecs : decoder et encoder les donnees
  10. 10 Logstash pour les devs - 09 - Le filtre Grok : parser n'importe quel log
  11. 11 Logstash pour les devs - 10 - Le filtre Dissect : parser sans regex
  12. 12 Logstash pour les devs - 11 - Le filtre Mutate : transformer les champs
  13. 13 Logstash pour les devs - 12 - Filtres Date et GeoIP : temps et geolocalisation
  14. 14 Logstash pour les devs - 13 - Filtres KV, JSON et XML : parser les formats structures
  15. 15 Logstash pour les devs - 14 - Le filtre Ruby : quand les autres ne suffisent pas
  16. 16 Logstash pour les devs - 15 - Filtres Aggregate et Metrics : correler les événements
  17. 17 Logstash pour les devs - 16 - Conditionnels et contrôle de flux
  18. 18 Logstash pour les devs - 17 - Output Elasticsearch : envoyer les donnees
  19. 19 Logstash pour les devs - 18 - Outputs file, stdout et les autres
  20. 20 Logstash pour les devs - 19 - Gerer le multiline : stack traces et logs multi-lignes
  21. 21 Logstash pour les devs - 20 - Pipelines multiples et pipeline-to-pipeline
  22. 22 Logstash pour les devs - 21 - Performance et tuning Logstash
  23. 23 Logstash pour les devs - 22 - Monitoring Logstash : metriques et alertes
  24. 24 Logstash pour les devs - 23 - Dead Letter Queue : ne plus perdre d'événements
  25. 25 Logstash pour les devs - 24 - Sécurité Logstash : SSL, auth et secrets
  26. 26 Logstash pour les devs - 25 - Debugger un pipeline Logstash
  27. 27 Logstash pour les devs - 26 - Tester ses pipelines avant la prod
  28. 28 Logstash pour les devs - 27 - Cas pratique : centraliser des logs applicatifs
  29. 29 Logstash pour les devs - 28 - Cas pratique : ETL avec Logstash et PostgreSQL
  30. 30 Logstash pour les devs - 29 - Cas pratique : enrichir des donnees en temps réel
  31. 31 Logstash pour les devs - 30 - Logstash en production : architecture et bonnes pratiques
  32. 32 Logstash pour les devs - 31 - Glossaire Logstash de A a Z

25 - Debugger un pipeline Logstash

Ce que tu vas apprendre

  • Une methodologie systématique pour debugger un pipeline
  • Utiliser stdout a des points strategiques
  • Tracer l'exécution avec des tags et des champs @metadata
  • Changer le log level a chaud
  • Les erreurs les plus courantes et leurs solutions

Prerequisites

  • Avoir un pipeline fonctionnel (ou un qui ne fonctionne pas, c'est le sujet)

La methodologie : du général au spécifique

Quand un pipeline ne fait pas ce qu'on attend, la tentation est de regarder le code pendant 30 minutes en esperant voir l'erreur. Ca ne marche jamais. Ma méthode :

  1. Les logs Logstash : est-ce que Logstash signale une erreur ?
  2. Les événements arrivent-ils ? : stdout au début du pipeline
  3. Le parsing fonctionne-t-il ? : stdout apres les filtres
  4. L'output recoit-il les donnees ? : vérifier Elasticsearch
  5. Les champs sont-ils corrects ? : inspecter un événement en détail

Étape 1 : les logs Logstash

bashdocker compose logs logstash --tail 50

Les erreurs courantes apparaissent ici : syntaxe .conf invalide, plugin manquant, Elasticsearch injoignable. Si Logstash ne démarré pas, la réponse est dans les logs.

Augmente le log level pour plus de détail :

yaml# logstash.yml
log.level: debug

Ou a chaud via l'API (sans redemarrage) :

bashcurl -X PUT "http://localhost:9600/_node/logging?pretty" \
  -H "Content-Type: application/json" \
  -d '{"logger.logstash.outputs.elasticsearch": "DEBUG"}'

Ca active le debug uniquement pour l'output Elasticsearch. Moins de bruit que log.level: debug global.

Pour revenir au niveau normal :

bashcurl -X PUT "http://localhost:9600/_node/logging?pretty" \
  -H "Content-Type: application/json" \
  -d '{"logger.logstash.outputs.elasticsearch": "INFO"}'

Étape 2 : stdout comme sonde

Place un stdout temporaire a l'endroit ou tu suspectes le problème :

input {
  beats { port => 5044 }
}

filter {
  # Sonde 1 : voir l'evenement brut
  stdout { codec => rubydebug }

  grok {
    match => { "message" => "%{COMBINEDAPACHELOG}" }
  }

  # Sonde 2 : voir l'evenement apres Grok
  stdout { codec => rubydebug }

  mutate {
    convert => { "response" => "integer" }
  }
}

output {
  elasticsearch {
    hosts => ["http://elasticsearch:9200"]
    index => "logs-%{+YYYY.MM.dd}"
  }
}

Oui, tu peux mettre stdout dans le bloc filter. C'est un output, mais Logstash l'accepte a cet endroit pour le debug. Ca affiche l'événement a ce point precis du pipeline.

stdout conditionnel

Pour ne pas noyer la console, filtre les événements affiches :

filter {
  grok {
    match => { "message" => "%{COMBINEDAPACHELOG}" }
  }

  # Afficher uniquement les evenements en erreur
  if "_grokparsefailure" in [tags] {
    stdout { codec => rubydebug }
  }
}

Étape 3 : tracer avec des tags

Ajoute des tags a chaque étape pour voir par ou l'événement est passe :

filter {
  mutate { add_tag => ["step_1_raw"] }

  grok {
    match => { "message" => "%{COMBINEDAPACHELOG}" }
    add_tag => ["step_2_grok_ok"]
    tag_on_failure => ["step_2_grok_fail"]
  }

  if "step_2_grok_ok" in [tags] {
    date {
      match => ["timestamp", "dd/MMM/yyyy:HH:mm:ss Z"]
      add_tag => ["step_3_date_ok"]
      tag_on_failure => ["step_3_date_fail"]
    }
  }

  geoip {
    source => "clientip"
    add_tag => ["step_4_geoip_ok"]
    tag_on_failure => ["step_4_geoip_fail"]
  }
}

output {
  stdout { codec => rubydebug }
}

Dans la sortie, regarde le tableau tags :

"tags" => ["step_1_raw", "step_2_grok_ok", "step_3_date_ok", "step_4_geoip_fail"]

Tu vois immédiatement que GeoIP a echoue. Peut-etre une IP privee, un champ clientip absent, ou la base GeoLite2 non montee.

N'oublie pas de supprimer les tags de debug avant la mise en production.

Étape 4 : @metadata pour le debug invisible

Si tu veux tracer sans polluer les tags (qui apparaissent dans Elasticsearch) :

filter {
  mutate {
    add_field => { "[@metadata][debug_after_grok]" => "true" }
  }

  # Voir les metadata
  stdout { codec => rubydebug { metadata => true } }
}

Les champs @metadata n'apparaissent jamais dans Elasticsearch. Tu peux les laisser dans le pipeline sans consequence.

Les erreurs les plus courantes

_grokparsefailure

Le pattern Grok ne matche pas la ligne.

Diagnostic :

filter {
  grok {
    match => { "message" => "%{COMBINEDAPACHELOG}" }
    tag_on_failure => ["_grokparsefailure"]
  }

  if "_grokparsefailure" in [tags] {
    # Afficher la ligne qui ne matche pas
    ruby {
      code => 'logger.warn("Grok failed on: #{event.get("message")}")'
    }
  }
}

La ligne qui echoue apparaît dans les logs Logstash. Copie-la dans le Grok Debugger et ajuste le pattern.

Causes frequentes : nouveau format de log, espaces supplementaires, caractères speciaux, encodage UTF-8 avec BOM.

_dateparsefailure

Le format de date ne correspond pas.

Diagnostic : affiche la valeur du champ avec stdout et compare au format défini.

Causes frequentes : timezone manquante, format yyyy vs yy, millisecondes absentes, espaces en début/fin de champ.

Mapping conflict dans Elasticsearch

L'événement est rejete par Elasticsearch.

Diagnostic :

bashdocker compose logs logstash | grep "mapper_parsing_exception"

Causes frequentes : un champ status envoye comme string puis comme integer, ou inversement. Definis un index template explicite (voir article 17).

Pipeline ne charge pas

bashdocker compose logs logstash | grep -i "error\|failed\|exception"

Causes frequentes : syntaxe .conf invalide (virgule en trop, accolade manquante), path.config incorrect dans pipelines.yml, fichier .conf non monte dans Docker.

Événements perdus

events.in augmente mais events.out stagne.

Diagnostic : vérifié si un drop {} ou event.cancel supprime des événements. Verifie les tags _grokparsefailure et les conditionnels qui pourraient router les événements vers un output inexistant.

Performance degradee

Diagnostic : API _node/stats et _node/hot_threads (voir articles 21 et 22).

Le fichier .conf minimal pour isoler un problème

Quand rien ne marche, reduis au minimum :

input {
  generator {
    message => 'ta ligne de log problematique ici'
    count => 1
  }
}

filter {
  grok {
    match => { "message" => "ton pattern ici" }
  }
}

output {
  stdout { codec => rubydebug }
}

Pas d'Elasticsearch, pas de Filebeat, pas de conditions. Juste l'input, le filtre suspect, et stdout. Si ca marche, le problème est ailleurs. Si ca ne marche pas, tu as isole le filtre coupable.

C'est ma technique sur paltemps.fr quand un pipeline en prod se comporte bizarrement. Je copie le filtre suspect dans un pipeline minimal, je teste avec 5 lignes de log, et je trouve le bug en 2 minutes au lieu de 30.

Valider la syntaxe sans démarrer

bashdocker exec logstash bin/logstash --config.test_and_exit \
  -f /usr/share/logstash/pipeline/main.conf

Logstash vérifié la syntaxe du fichier et quitte. Pas de JVM a démarrer, pas d'attente. Si la syntaxe est bonne :

Configuration OK

Si elle est mauvaise, le message d'erreur indique la ligne et le type d'erreur.

Résumé

  • Methodologie : logs Logstash -> stdout en sonde -> tags de trace -> inspecter les champs
  • stdout { codec => rubydebug } peut etre place dans le bloc filter pour inspecter a mi-chemin
  • Les tags de debug tracent par ou passe l'événement, @metadata est invisible dans l'output
  • Le log level se change a chaud via l'API (PUT _node/logging)
  • --config.test_and_exit valide la syntaxe sans démarrer
  • Isole le problème dans un pipeline minimal avec generator + stdout

Precedent : 24 - Sécurité | Suivant : 26 - Testing

Sources

Réservez un audit gratuit de 30 minutes. Je vous montre concrètement ce qu'on peut automatiser.