Logstash pour les devs - 06 - Inputs HTTP, TCP et UDP : recevoir des donnees réseau

Transformer Logstash en endpoint HTTP ou socket TCP/UDP pour recevoir des donnees depuis n'importe quelle source.

  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

06 - Inputs HTTP, TCP et UDP : recevoir des donnees réseau

Ce que tu vas apprendre

  • Transformer Logstash en endpoint HTTP pour recevoir des webhooks ou des logs applicatifs
  • Recevoir des donnees via TCP (connexion persistante) et UDP (syslog)
  • Envoyer des événements depuis une application Node.js vers Logstash HTTP
  • Recevoir des webhooks GitHub/GitLab dans Logstash
  • Choisir entre HTTP, TCP et UDP selon le cas d'usage

Prerequisites

  • Le lab Docker qui tourne (voir article 02)
  • Savoir utiliser curl (ou un client HTTP)

Envoyer des logs par HTTP, ca parait bizarre

La première fois qu'un collegue m'a dit "on envoie les logs en HTTP", j'ai grimace. HTTP pour des logs ? C'est pas fait pour des pages web, ca ?

En fait, c'est un des patterns les plus pratiques. Ton application envoie ses logs en JSON par POST a Logstash. Pas de fichier a lire, pas de Filebeat a installer, pas de volume Docker a partager. L'app fait un POST, Logstash recoit. C'est direct.

C'est aussi comme ca que fonctionnent les webhooks. GitHub envoie un POST quand quelqu'un push du code. Stripe envoie un POST quand un paiement est traite. Logstash peut recevoir ces webhooks, les parser, et les indexer dans Elasticsearch.

Input HTTP

Configuration de base

# logstash/pipeline/main.conf

input {
  http {
    port => 8080
    codec => json
  }
}

output {
  stdout {
    codec => rubydebug
  }
}

Ajoute le port 8080 dans ton compose.yaml :

yamllogstash:
  # ...
  ports:
    - "5044:5044"
    - "8080:8080"
    - "9600:9600"

Redarre Logstash, puis teste avec curl :

bashcurl -X POST http://localhost:8080 \
  -H "Content-Type: application/json" \
  -d '{"level":"ERROR","service":"api-users","message":"Connection timeout","duration_ms":5023}'

Dans les logs Logstash, tu verras :

json{
    "@timestamp" => 2026-03-31T14:30:00.123Z,
      "@version" => "1",
         "level" => "ERROR",
       "service" => "api-users",
       "message" => "Connection timeout",
   "duration_ms" => 5023,
          "host" => {
        "ip" => "172.18.0.1"
    },
          "http" => {
        "method" => "POST",
        "request" => {
            "body" => {
                "bytes" => "89"
            },
            "mime_type" => "application/json"
        },
        "version" => "HTTP/1.1"
    },
           "url" => {
        "path" => "/"
    },
    "user_agent" => {
        "original" => "curl/8.4.0"
    }
}

Logstash a parse le JSON et ajoute des metadonnees HTTP (méthode, IP source, user-agent).

Authentification basique

En production, tu ne veux pas que n'importe qui puisse envoyer des donnees a Logstash. Ajoute un login/mot de passe :

input {
  http {
    port => 8080
    codec => json
    user => "logstash"
    password => "s3cret"
  }
}
bashcurl -X POST http://localhost:8080 \
  -u logstash:s3cret \
  -H "Content-Type: application/json" \
  -d '{"message":"authenticated event"}'

Sans les credentials, Logstash renvoie un 401.

Codes de réponse custom

Par défaut, Logstash répond 200 a chaque requête. Tu peux changer le code :

input {
  http {
    port => 8080
    codec => json
    response_code => 202
  }
}

202 (Accepted) est plus semantiquement correct : "j'ai reçu ta requête, je la traiterai".

Recevoir du texte brut

Si l'expediteur n'envoie pas du JSON mais du texte brut :

input {
  http {
    port => 8080
    codec => plain
  }
}

Le texte entier arrive dans le champ message. A toi de le parser avec un filtre Grok ou Dissect.

Cas pratique : recevoir des webhooks GitHub

Quand tu configures un webhook GitHub sur un repo, GitHub envoie un POST a l'URL que tu specifies a chaque événement (push, PR, issue, etc.).

# logstash/pipeline/webhooks.conf

input {
  http {
    port => 8080
    codec => json
    additional_codecs => {}
    type => "github"
  }
}

filter {
  if [type] == "github" {
    # Extraire les infos utiles du payload GitHub
    mutate {
      rename => {
        "[repository][full_name]" => "repo"
        "[sender][login]" => "author"
        "[head_commit][message]" => "commit_message"
      }
    }

    # Garder le header X-GitHub-Event comme champ
    mutate {
      rename => {
        "[headers][x-github-event]" => "github_event"
      }
    }

    # Nettoyer : supprimer le payload brut
    mutate {
      remove_field => ["headers", "repository", "sender", "head_commit", "commits", "pusher", "organization", "compare", "ref"]
    }
  }
}

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

  stdout { codec => rubydebug }
}

Pour tester sans GitHub, simule un webhook push :

bashcurl -X POST http://localhost:8080 \
  -H "Content-Type: application/json" \
  -H "X-GitHub-Event: push" \
  -d '{
    "ref": "refs/heads/main",
    "repository": {"full_name": "paltemps/api"},
    "sender": {"login": "nicolasnguyen"},
    "head_commit": {"message": "fix: resolve timeout on /users endpoint"},
    "commits": [{"id": "abc123"}]
  }'

Cas pratique : envoyer des logs depuis Node.js

Ton application Node.js peut envoyer ses logs directement a Logstash par HTTP. Pas de fichier, pas de Filebeat.

typescript// logger.ts — envoi direct a Logstash
const LOGSTASH_URL = process.env.LOGSTASH_URL || "http://localhost:8080";

type LogLevel = "DEBUG" | "INFO" | "WARN" | "ERROR";

async function log(level: LogLevel, message: string, meta?: Record<string, unknown>) {
  const event = {
    "@timestamp": new Date().toISOString(),
    level,
    message,
    service: process.env.SERVICE_NAME || "unknown",
    hostname: process.env.HOSTNAME || "localhost",
    ...meta,
  };

  try {
    await fetch(LOGSTASH_URL, {
      method: "POST",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify(event),
    });
  } catch {
    // fallback sur stderr si Logstash est injoignable
    console.error(JSON.stringify(event));
  }
}

// Utilisation
await log("INFO", "User logged in", { userId: 42, ip: "192.168.1.10" });
await log("ERROR", "Database timeout", { query: "SELECT * FROM users", duration_ms: 5023 });

C'est simple, mais ca a un coût : chaque log fait une requête HTTP. Pour des applications a fort volume, préféré Filebeat ou un buffer local. Pour des applications legeres (API interne, scripts, workers), le HTTP direct marche bien.

Sur paltemps.fr, les workers de taches de fond utilisent ce pattern. Ils tournent dans des conteneurs éphémères et n'ont pas de volume partage. Envoyer les logs en HTTP est la solution la plus simple.

Input TCP

TCP est utile pour les connexions persistantes. Le client ouvre une connexion, envoie des événements ligne par ligne, et la connexion reste ouverte.

Configuration de base

input {
  tcp {
    port => 5000
    codec => json_lines
  }
}

output {
  stdout { codec => rubydebug }
}

Le codec json_lines attend un objet JSON par ligne (NDJSON). Chaque \n marque la fin d'un événement.

Teste avec nc (netcat) :

bashecho '{"level":"INFO","message":"test TCP"}' | nc localhost 5000

Ou envoie plusieurs événements a la suite :

bashprintf '{"level":"INFO","msg":"event 1"}\n{"level":"ERROR","msg":"event 2"}\n' | nc localhost 5000

TCP pour les logs syslog

Beaucoup d'equipements réseau (firewalls, routeurs, switches) envoient leurs logs en syslog via TCP ou UDP. Logstash peut les recevoir :

input {
  tcp {
    port => 5514
    codec => plain
    type => "syslog-tcp"
  }
}

filter {
  if [type] == "syslog-tcp" {
    grok {
      match => { "message" => "%{SYSLOGLINE}" }
    }
  }
}

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

TCP avec SSL

Pour chiffrer la connexion TCP :

input {
  tcp {
    port => 5000
    codec => json_lines
    ssl_enabled => true
    ssl_certificate => "/certs/logstash.crt"
    ssl_key => "/certs/logstash.key"
  }
}

On verra les certificats en détail dans l'article 24 sur la sécurité.

Input UDP

UDP est non connecte et non fiable. Pas de garantie de livraison, pas d'accusee de reception. Mais c'est rapide et leger.

Configuration de base

input {
  udp {
    port => 5514
    codec => plain
    type => "syslog-udp"
  }
}

Le syslog traditionnel (RFC 3164) utilise UDP sur le port 514. Dans Docker, on utilise un port non privilegie (5514).

Quand utiliser UDP

UDP est le choix par défaut pour :

  • Les equipements réseau qui ne supportent que syslog UDP
  • Les metriques a haut debit ou la perte occasionnelle est acceptable
  • Les environnements ou la latence de TCP est un problème

Pour des logs applicatifs, préféré toujours TCP ou HTTP. La garantie de livraison est plus importante que la vitesse.

Comparaison : HTTP vs TCP vs UDP

HTTP TCP UDP
Protocole Requete/réponse Connexion persistante Datagramme
Fiabilite Oui (réponse 200) Oui (TCP ACK) Non
Format JSON, texte, form Ligne par ligne Datagramme
Auth Oui (user/password) SSL Non
Use case principal Webhooks, apps web Syslog, flux continus Syslog legacy, metriques
Overhead Eleve (headers HTTP) Moyen (TCP handshake) Faible
Backpressure Oui (client attend 200) Oui (TCP flow control) Non

Mon choix par défaut :

  • Webhooks et applications web : HTTP
  • Logs applicatifs en flux continu : TCP avec json_lines (ou Filebeat)
  • Equipements réseau legacy : UDP

Exposer plusieurs inputs sur des ports différents

Un pipeline Logstash peut avoir plusieurs inputs. Chaque input écoûte sur son propre port :

input {
  # Beats sur 5044
  beats {
    port => 5044
  }

  # HTTP sur 8080
  http {
    port => 8080
    codec => json
    type => "http"
  }

  # TCP sur 5000
  tcp {
    port => 5000
    codec => json_lines
    type => "tcp"
  }

  # UDP sur 5514
  udp {
    port => 5514
    codec => plain
    type => "syslog"
  }
}

filter {
  if [type] == "syslog" {
    grok { match => { "message" => "%{SYSLOGLINE}" } }
  }
  # ... filtres specifiques par type
}

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

N'oublie pas d'exposer tous les ports dans le compose.yaml :

yamllogstash:
  ports:
    - "5044:5044"
    - "8080:8080"
    - "5000:5000"
    - "5514:5514/udp"
    - "9600:9600"

Note le /udp pour le port UDP. Par défaut, Docker n'expose que le TCP.

Résumé

  • L'input HTTP transforme Logstash en serveur web qui recoit des POST
  • C'est le bon choix pour les webhooks (GitHub, Stripe) et les logs d'apps legeres
  • L'input TCP recoit des flux continus (une ligne par événement, codec json_lines)
  • L'input UDP recoit du syslog ou des metriques sans garantie de livraison
  • Chaque input ajoute un champ type pour router les événements dans les filtres
  • Un pipeline peut avoir plusieurs inputs sur des ports différents

Precedent : 05 - Input Beats | Suivant : 07 - Inputs Kafka et JDBC

Sources

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