Tutoriels

MQTT vers InfluxDB avec Telegraf : configurer mqtt_consumer

Ingérez des messages MQTT dans InfluxDB v2 avec Telegraf : config mqtt_consumer, parsing json_v2, topics en tags, stack Docker Compose et vérification.

Mis à jour · 9 min de lecture

MQTT vers InfluxDB avec Telegraf : configurer mqtt_consumer

Le chemin le plus court entre un broker MQTT et une base de séries temporelles s'appelle Telegraf : son input mqtt_consumer s'abonne à vos topics, un parser transforme chaque payload en métrique et l'output influxdb_v2 l'écrit dans InfluxDB. Pas de code, un seul fichier de configuration, et il tourne sans souci à côté de la base ou sur une passerelle edge.

Ce guide monte un pipeline fonctionnel avec Docker Compose, parse les payloads JSON avec json_v2, transforme des parties du topic en tags et montre comment valider chaque étape avant d'y brancher de vrais appareils.

Le pipeline en un coup d'œil

ÉtapeComposant TelegrafRôle
S'abonner[[inputs.mqtt_consumer]]Se connecte au broker et s'abonne aux filtres de topic
Parserdata_format = "json_v2"Transforme chaque payload en fields, tags et horodatage
Enrichirtopic_parsingExtrait les ID d'appareil ou les sites des niveaux du topic en tags
Bufferiserréglages [agent]Regroupe les métriques par lots et réessaie en cas d'échec d'écriture
Écrire[[outputs.influxdb_v2]]Envoie du line protocol vers un bucket InfluxDB v2

L'appareil d'exemple publie un JSON de ce type sur testmqtt/telegraf/sensor-01/telemetry :

Payload d'exemple
{"ts": 1760700000000, "site": "lab", "temperature": 21.4, "humidity": 40.2, "status": "ok"}

Démarrer InfluxDB et Telegraf

Ce fichier Compose démarre InfluxDB 2.x avec une organisation, un bucket et un token initiaux, ainsi que Telegraf avec votre configuration montée en lecture seule :

docker-compose.yml
services:
  influxdb:
    image: influxdb:2.7
    ports: ["8086:8086"]
    environment:
      DOCKER_INFLUXDB_INIT_MODE: setup
      DOCKER_INFLUXDB_INIT_USERNAME: admin
      DOCKER_INFLUXDB_INIT_PASSWORD: change-me-please
      DOCKER_INFLUXDB_INIT_ORG: testmqtt
      DOCKER_INFLUXDB_INIT_BUCKET: mqtt
      DOCKER_INFLUXDB_INIT_ADMIN_TOKEN: dev-token-change-me
    volumes:
      - influx-data:/var/lib/influxdb2

  telegraf:
    image: telegraf:1.32
    depends_on: [influxdb]
    environment:
      MQTT_USER: ${MQTT_USER}
      MQTT_PASS: ${MQTT_PASS}
      INFLUX_TOKEN: dev-token-change-me
    volumes:
      - ./telegraf.conf:/etc/telegraf/telegraf.conf:ro

volumes:
  influx-data:

Les variables d'initialisation ne s'appliquent qu'au premier démarrage avec un volume vide. En production, créez pour Telegraf un token dédié en écriture seule au lieu de réutiliser le token admin. Pour une stack locale plus complète avec broker et dashboards, voir la stack MQTT Docker Compose.

Configurer mqtt_consumer

telegraf.conf
[agent]
  interval = "10s"
  flush_interval = "5s"
  metric_batch_size = 1000
  metric_buffer_limit = 50000
  omit_hostname = true

[[inputs.mqtt_consumer]]
  servers = ["ssl://broker.connectmq.com:8883"]
  topics = ["testmqtt/telegraf/+/telemetry"]
  qos = 1
  client_id = "telegraf-ingest-01"
  persistent_session = true
  username = "${MQTT_USER}"
  password = "${MQTT_PASS}"
  max_undelivered_messages = 1000
  topic_tag = ""
  data_format = "json_v2"

  [[inputs.mqtt_consumer.topic_parsing]]
    topic = "testmqtt/telegraf/+/telemetry"
    tags = "_/_/device/_"

  [[inputs.mqtt_consumer.json_v2]]
    measurement_name = "telemetry"
    timestamp_path = "ts"
    timestamp_format = "unix_ms"

    [[inputs.mqtt_consumer.json_v2.tag]]
      path = "site"

    [[inputs.mqtt_consumer.json_v2.field]]
      path = "temperature"
      type = "float"

    [[inputs.mqtt_consumer.json_v2.field]]
      path = "humidity"
      type = "float"

    [[inputs.mqtt_consumer.json_v2.field]]
      path = "status"
      type = "string"

[[outputs.influxdb_v2]]
  urls = ["http://influxdb:8086"]
  token = "${INFLUX_TOKEN}"
  organization = "testmqtt"
  bucket = "mqtt"

Les réglages qui comptent le plus :

  • servers : tcp://host:1883 en clair, ssl://host:8883 pour TLS. Telegraf vérifie le certificat du serveur avec le magasin de CA du système ; ajoutez tls_ca = "/path/ca.pem" pour une CA privée.
  • topics : des filtres MQTT standard, donc + et # fonctionnent. Testez un filtre sur de vrais noms de topics avec le topic matcher. Rappels sur les filtres : topics et wildcards.
  • qos = 1 + persistent_session = true + un client_id fixe : le broker conserve une session pour Telegraf et met en file les messages QoS 1 pendant son redémarrage. Sans client ID stable, la session ne peut pas être reprise. Voir sessions persistantes.
  • max_undelivered_messages : le nombre de messages QoS 1/2 que Telegraf lit avant qu'ils soient écrits dans l'output. C'est le backpressure de Telegraf : si InfluxDB ralentit, Telegraf cesse d'acquitter et le broker garde le reste.
  • topic_tag = "" : désactive le tag topic par défaut. Stocker le topic complet en tag multiplie la cardinalité des séries ; topic_parsing n'extrait que la partie utile.

Comment json_v2 transforme le payload

Avec la configuration ci-dessus, le payload d'exemple devient ce line protocol :

Métrique obtenue
telemetry,device=sensor-01,site=lab temperature=21.4,humidity=40.2,status="ok" 1760700000000000000
Clé du payloadDevientPourquoi
niveau 3 du topic (sensor-01)tag devicetopic_parsing avec _/_/device/_
sitetagValeur à faible cardinalité utilisée pour filtrer
temperature, humidityfields floatValeurs que vous tracez et agrégez
statusfield stringLes textes doivent être déclarés explicitement
tshorodatageHeure de l'appareil en millisecondes

Deux règles gardent InfluxDB en bonne santé : des tags pour ce que vous filtrez et qui a peu de valeurs distinctes, des fields pour les mesures. Et envoyez toujours les nombres comme des nombres JSON : "21.4" entre guillemets est une chaîne, qui sera ignorée ou créera un conflit de type sur le field. Si vos payloads sont parfois malformés, lisez les erreurs de parsing JSON MQTT.

Si les appareils n'envoient pas d'horodatage, supprimez timestamp_path : Telegraf utilisera l'heure d'arrivée. C'est suffisant pour du temps réel, mais les données bufferisées par des appareils hors ligne seront alors horodatées trop tard.

Vérifier chaque étape

Testez le pipeline dans l'ordre où circulent les données : vous saurez toujours quelle étape échoue.

1. Les données sont-elles sur le broker ? Abonnez-vous à testmqtt/telegraf/# avec le client MQTT en ligne et publiez une mesure de test :

Publier un message de test
mosquitto_pub -h broker.connectmq.com -p 8883 --capath /etc/ssl/certs \
  -u "$MQTT_USER" -P "$MQTT_PASS" -q 1 \
  -t testmqtt/telegraf/sensor-01/telemetry \
  -m "{\"ts\":$(date +%s000),\"site\":\"lab\",\"temperature\":21.4,\"humidity\":40.2,\"status\":\"ok\"}"

2. Telegraf le parse-t-il ? Lancez Telegraf en mode test. Il affiche les métriques sur stdout au lieu de les écrire ; --test-wait garde l'input MQTT à l'écoute assez longtemps pour recevoir des messages :

Exécution à blanc
docker compose run --rm telegraf telegraf --config /etc/telegraf/telegraf.conf --test --test-wait 15

Publiez à nouveau pendant l'attente. Vous devez voir la ligne telemetry,device=sensor-01,.... Aucune ligne signifie que l'abonnement ou le parser est faux ; une ligne avec des champs manquants signifie que les chemins ou les types json_v2 ne correspondent pas.

3. Est-ce dans InfluxDB ? Démarrez la stack avec docker compose up -d et interrogez le bucket :

Interroger les dernières valeurs
docker compose exec influxdb influx query --org testmqtt \
  'from(bucket: "mqtt") |> range(start: -10m) |> filter(fn: (r) => r._measurement == "telemetry") |> last()'

Suivre le topic de télémétrie dans le navigateur

Erreurs fréquentes

Message de logCauseCorrection
not AuthorizedLe broker a refusé l'utilisateur ou les ACL interdisent l'abonnementVérifiez les identifiants et le droit de lecture sur le filtre de topic
bad user name or passwordIdentifiants erronés, ou variables d'environnement absentes du conteneurVérifiez le bloc environment et les noms ${...}
identifier rejectedClient ID déjà utilisé ou non autoriséUtilisez un client_id unique par instance Telegraf
401 Unauthorized depuis outputs.influxdb_v2Token absent ou sans droit d'écritureCréez un token avec droit d'écriture sur le bucket
bucket "mqtt" not foundNom de bucket ou d'organisation différentFaites correspondre exactement organization et bucket

Recherchez les reason codes côté broker avec l'outil reason codes. Les erreurs du parser sont journalisées avec le préfixe E! [inputs.mqtt_consumer] et signifient généralement que le payload n'est pas un JSON valide ou qu'un champ déclaré a un autre type. Lancez Telegraf avec --debug pour voir les détails de connexion et de flush.

Montée en charge et rétention

  • Plus de débit : Telegraf traite beaucoup de messages par instance, mais si vous avez besoin de plusieurs instances, abonnez-vous via un abonnement partagé comme $share/telegraf/testmqtt/telegraf/+/telemetry afin que le broker répartisse le flux au lieu de le dupliquer. Chaque instance a besoin de son propre client_id.
  • Rétention : définissez une durée de rétention sur le bucket (dans l'interface ou avec influx bucket update --id <bucket-id> --retention 30d) et sous-échantillonnez les anciennes données avec une task InfluxDB. La question de la durée de conservation de la télémétrie brute est traitée dans rétention et stockage des données MQTT.
  • Visualisation : connectez Grafana à InfluxDB pour l'historique, et ajoutez la source de données MQTT de Grafana si vous voulez aussi un panneau en direct alimenté par le broker.

Avec Telegraf, « MQTT vers InfluxDB » devient une relecture de configuration plutôt qu'un projet logiciel. Choisissez vos tags avec soin, utilisez QoS 1 avec une session persistante sur votre propre broker, validez avec --test avant la mise en production et versionnez la configuration à côté de vos dashboards.

Questions fréquentes

Faut-il écrire du code pour envoyer des données MQTT dans InfluxDB ?

Non. L'input mqtt_consumer de Telegraf s'abonne au broker, un parser comme json_v2 transforme les payloads en métriques et l'output influxdb_v2 les écrit. Tout se fait par configuration dans un seul fichier telegraf.conf.

Pourquoi mes valeurs texte n'apparaissent-elles pas dans InfluxDB ?

L'ancien parser json ignore les valeurs texte, sauf si vous les listez dans json_string_fields. Avec json_v2, déclarez le champ avec type = "string" ou faites-en un tag. La sortie de telegraf --test montre exactement quels champs sont produits.

Telegraf perd-il des messages MQTT quand InfluxDB est indisponible ?

Telegraf garde les métriques en mémoire jusqu'à metric_buffer_limit et réessaie les écritures : les coupures courtes sont couvertes. Les coupures longues ou un redémarrage de Telegraf perdent le buffer. Utilisez QoS 1 avec une session persistante sur votre propre broker pour que les messages attendent sur le broker pendant que Telegraf est hors ligne.