Les topics SYS MQTT constituent la branche $SYS/... de l'arborescence de topics, dans laquelle un broker publie des informations sur lui-même plutôt que des données applicatives. Dans cet article, vous découvrirez l'origine de cette convention, pourquoi un simple abonnement # ne les affiche jamais, ce qu'un broker type y expose et comment utiliser l'unique topic système publié par ConnectMQ pour suivre l'état de connexion des clients.
Que sont les topics SYS MQTT ?
La spécification MQTT réserve les topics commençant par $ à un usage propre au broker. Les clients ne sont pas censés y publier de données applicatives, et la spécification laisse entièrement leur contenu à l'implémentation. Au fil des années, $SYS/ est devenu le préfixe de fait pour la télémétrie du broker : temps de fonctionnement, version, nombre de clients connectés, compteurs de messages et d'octets, et autres données de gestion similaires.
Le mot important est « de fait ». Il n'existe ni liste standard de topics $SYS, ni format de payload standard, ni garantie qu'un broker donné en publie un seul. Mosquitto a popularisé une vaste arborescence, d'autres brokers en publient un sous-ensemble ou une organisation différente, et de nombreux brokers MQTT managés en remplacent l'essentiel par des tableaux de bord et des API. Considérez chaque topic $SYS comme un détail d'implémentation du broker précis auquel vous êtes connecté.
Pourquoi un abonnement # ne les affiche pas
Cela surprend presque tout le monde la première fois. Si vous vous abonnez à #, vous recevez tous les messages applicatifs du broker, mais rien de $SYS. C'est voulu. La spécification MQTT sur mqtt.org indique qu'un filtre de topic commençant par un wildcard (# ou +) ne doit pas correspondre aux noms de topic commençant par $.
Cette règle protège les abonnés « fourre-tout » ordinaires contre un déluge de statistiques du broker, et évite que les outils qui répliquent # ne republient accidentellement des données système. Pour lire les topics système, vous devez nommer explicitement le préfixe $SYS :
# -> application topics only, never $SYS
$SYS/# -> everything under $SYS (if the broker allows it)
$SYS/broker/+/+ -> a specific depth under $SYS/broker
+/broker/uptime -> does NOT match $SYS/broker/uptime
Le même raisonnement s'applique aux règles des wildcards pour les topics MQTT en général : les wildcards fonctionnent niveau par niveau, et le niveau initial $ est tout simplement exclu de la correspondance par wildcard en première position.
Une arborescence $SYS type (exemple Mosquitto)
Mosquitto est la référence la plus courante : c'est donc un bon moyen de voir ce que peuvent contenir les topics système. Avec la configuration par défaut, il publie un instantané de ses compteurs toutes les quelques secondes. L'intervalle se règle dans mosquitto.conf :
# mosquitto.conf
# Publier les mises à jour $SYS toutes les 10 secondes (0 désactive les mises à jour périodiques)
sys_interval 10
Une sélection des topics que vous verrez sur une instance Mosquitto locale :
| Topic | Signification |
|---|---|
$SYS/broker/version |
Chaîne de version du broker |
$SYS/broker/uptime |
Secondes écoulées depuis le démarrage du broker |
$SYS/broker/clients/connected |
Clients actuellement connectés |
$SYS/broker/clients/disconnected |
Sessions persistantes dont le client est hors ligne |
$SYS/broker/messages/received |
Total des messages reçus depuis le démarrage |
$SYS/broker/messages/sent |
Total des messages envoyés depuis le démarrage |
$SYS/broker/subscriptions/count |
Abonnements actifs |
$SYS/broker/retained messages/count |
Retained messages conservés |
$SYS/broker/load/messages/received/1min |
Moyenne glissante des messages reçus |
$SYS/broker/bytes/received |
Total des octets reçus |
Pour les observer sur votre propre broker Mosquitto, mettez le topic entre guillemets afin que votre shell n'interprète pas $SYS :
mosquitto_sub -h localhost -p 1883 -i sys-watcher-01 -t '$SYS/#' -v
La plupart des valeurs sont publiées sous forme de retained messages : un nouvel abonné reçoit donc immédiatement le dernier instantané au lieu d'attendre le prochain intervalle. Les compteurs sont remis à zéro au redémarrage du broker, ce qui compte si vous en faites des graphiques : une chute à zéro signifie un redémarrage, pas une heure calme.
Pièges courants avec les données $SYS
- Supposer la portabilité. Un tableau de bord construit sur les topics
$SYSde Mosquitto casse dès que vous passez à un autre broker. Gardez la logique d'analyse à un seul endroit. - Oublier le shell. En bash,
"$SYS/#"entre guillemets doubles remplace$SYSpar une variable vide, et vous vous abonnez à/#. Utilisez des guillemets simples. - L'exposer publiquement. Sur un broker auto-hébergé, les topics système révèlent le nombre de clients et les numéros de version. Restreignez-les avec les règles d'autorisation de votre broker s'il est accessible depuis Internet.
- Interroger trop souvent. Un
sys_intervaltrès court ajoute du trafic pour peu de valeur. Dix à soixante secondes suffisent largement pour des graphiques d'exploitation.
Les topics SYS MQTT sur un broker managé
Sur un broker MQTT managé, vous n'avez généralement pas besoin d'une vaste arborescence $SYS, car l'opérateur collecte déjà les métriques du broker et vous les présente. C'est l'approche de ConnectMQ. Les informations au niveau du broker, comme les connexions et le trafic, sont présentées dans le tableau de bord du portail, et l'explorateur de topics en direct vous montre quels topics sont actifs : inutile donc d'analyser des compteurs issus de topics système.
Il publie exactement un topic système :
$SYS/broker/connection/{clientId}/state
Ce topic indique l'état de connexion d'un client ID précis. C'est la donnée $SYS dont le code applicatif a réellement besoin : « l'appareil X est-il en ligne en ce moment ? » Tout le reste, comme le nombre de clients et les débits de messages, relève de la supervision plutôt que de votre flux de données MQTT.
Suivre l'état de connexion d'un client
L'exemple ci-dessous utilise paho-mqtt 2.x en Python pour s'abonner au topic d'état d'un appareil sur votre broker privé. Remplacez les valeurs génériques par les identifiants générés dans le portail, et définissez DEVICE_ID avec le client ID de l'appareil à surveiller.
import ssl
import paho.mqtt.client as mqtt
BROKER = "YOUR_BROKER_HOST" # affiché dans le portail
PORT = 8883
DEVICE_ID = "YOUR_DEVICE_CLIENT_ID"
STATE_TOPIC = f"$SYS/broker/connection/{DEVICE_ID}/state"
def on_connect(client, userdata, flags, reason_code, properties):
if reason_code.is_failure:
print(f"Connect failed: {reason_code}")
return
print("Connected, subscribing to", STATE_TOPIC)
client.subscribe(STATE_TOPIC, qos=1)
def on_subscribe(client, userdata, mid, reason_code_list, properties):
for rc in reason_code_list:
print("SUBACK:", rc)
def on_message(client, userdata, msg):
print(f"{msg.topic} -> {msg.payload.decode(errors='replace')}")
client = mqtt.Client(
mqtt.CallbackAPIVersion.VERSION2,
client_id="YOUR_CLIENT_ID",
protocol=mqtt.MQTTv5,
)
client.username_pw_set("YOUR_USERNAME", "YOUR_PASSWORD")
client.tls_set(cert_reqs=ssl.CERT_REQUIRED)
client.on_connect = on_connect
client.on_subscribe = on_subscribe
client.on_message = on_message
client.connect(BROKER, PORT, keepalive=60)
client.loop_forever()
Lancez-le, puis éteignez et rallumez l'appareil ou arrêtez son client. Vous verrez le topic d'état changer à mesure que l'appareil se déconnecte et se reconnecte. Avant d'écrire votre logique d'analyse, examinez le payload réel dans le client MQTT intégré au navigateur du portail, afin que votre code corresponde à ce que le broker envoie et non à ce que vous supposez.
État $SYS ou Last Will
Vous suivez peut-être déjà la présence avec un message Last Will and Testament. Les deux approches se complètent :
| Approche | Qui publie | Point fort | Limite |
|---|---|---|---|
| Last Will plus message « online » retenu | L'appareil, et le broker en son nom | Fonctionne sur n'importe quel broker ; le topic et le payload vous appartiennent | L'appareil doit être correctement configuré ; un client mal configuré ne signale jamais rien |
$SYS/broker/connection/{clientId}/state |
Le broker | Aucun code côté appareil ; reflète ce que le broker voit réellement | Organisation des topics propre au broker |
Un modèle sensé consiste à garder le Last Will pour les consommateurs applicatifs qui connaissent déjà votre arborescence de topics, et à utiliser le topic d'état du broker pour les outils d'exploitation et pour vérifier le bon comportement des appareils sans Will. Le guide sur le statut en ligne des appareils MQTT détaille le modèle basé sur le Will.
Liste de vérification de la supervision sans grande arborescence $SYS
Si vous venez d'un broker auto-hébergé dont les graphiques Grafana étaient alimentés par $SYS, voici comment couvrir les mêmes besoins sur un broker MQTT managé :
- Nombre de connexions et trafic. Utilisez le tableau de bord du broker dans le portail plutôt que
$SYS/broker/clients/connected. - Topics actifs. Utilisez l'explorateur de topics en direct plutôt qu'un abonnement à
#depuis un ordinateur portable. - Présence par appareil. Abonnez-vous à
$SYS/broker/connection/{clientId}/statepour les client ID qui vous intéressent, ou utilisez un Last Will. - Conditions de seuil sur les données. Configurez des règles d'alerte dans le portail pour des valeurs comme la température ou la pression, et consultez le journal des alertes.
- Historique des métriques à long terme. Exécutez votre propre abonné (Telegraf, un petit service Python ou Node-RED) qui écrit les données nécessaires dans votre base de séries temporelles.
- Suivi des quotas. Surveillez le reason code MQTT 5
0x97(quota exceeded) dans les journaux des clients ; il indique qu'une limite de l'offre a été atteinte.
Tester sur le broker public
Si vous voulez seulement expérimenter la structure des topics, le serveur MQTT public gratuit broker.connectmq.com accepte les connexions anonymes avec n'importe quel client ID unique non vide. Gardez à l'esprit que l'espace public est lisible par tous : utilisez un préfixe unique et n'envoyez jamais de données sensibles.
# Terminal 1 : s'abonner à votre propre préfixe de démonstration
mosquitto_sub -h broker.connectmq.com -p 1883 -i sys-demo-sub-7f3a \
-t 'connectmq/demo/7f3a/#' -v
# Terminal 2 : publier un message de test
mosquitto_pub -h broker.connectmq.com -p 1883 -i sys-demo-pub-7f3a \
-t 'connectmq/demo/7f3a/hello' -m 'hi'
Remarquez que l'abonnement # du terminal 1 voit votre message, mais rien sous $SYS, exactement comme l'exige la spécification. Pour une vue d'ensemble de la manière dont les topics, les abonnements et le broker s'articulent, le tutoriel MQTT est une bonne lecture suivante, et les conventions de nommage des topics MQTT expliquent comment garder votre propre arborescence aussi ordonnée que l'arborescence système d'un broker.
Démarrer avec ConnectMQ
Vous voulez les métriques du broker sans analyser des compteurs $SYS ? Créez un broker Serverless gratuit sur app.connectmq.com, sans carte bancaire. En quelques minutes, vous obtenez des identifiants générés, un tableau de bord, un explorateur de topics en direct et le topic $SYS/broker/connection/{clientId}/state pour la présence de chaque appareil.
Questions fréquentes
Pourquoi l'abonnement à # n'affiche-t-il pas les messages $SYS ?
La spécification MQTT indique que les filtres de topic commençant par un wildcard ne doivent pas correspondre aux topics commençant par $. Abonnez-vous explicitement à $SYS/# si votre broker publie des topics système et vous autorise à les lire.
Les topics SYS MQTT sont-ils standardisés ?
Non. Seule la réservation des topics préfixés par $ est standardisée. Les noms de topics, les payloads et les intervalles de mise à jour diffèrent d'un broker à l'autre : le code qui les lit est donc propre à chaque broker.
Quel topic $SYS ConnectMQ publie-t-il ?
ConnectMQ publie $SYS/broker/connection/{clientId}/state, qui indique l'état de connexion d'un client. Les métriques du broker, comme les connexions et le trafic, sont affichées dans le tableau de bord du portail.
Puis-je publier mes propres messages sur les topics $SYS ?
C'est déconseillé. Le préfixe $ est réservé au broker, et la plupart des brokers rejettent ou ignorent les publications des clients à cet endroit. Placez vos propres données de statut dans l'arborescence de topics de votre application.



