10. Écouteur de flux d'événements
Se connecte au rubrique Événements (port 10020) et affiche les événements système avec un filtrage facultatif par niveau, modèle de nom et exclusions. En lecture seule — pas de profil de session, aucune commande envoyée.
Ce que vous apprendrez :
- S'abonner à la événements WebSocket (port
10020) en tant qu'observateur passif - Analyse syntaxique JSON d'événement —
level,name,category,data,message - Filtrer par niveau de gravité minimum
- Correspondance et exclusion de noms à l'aide de caractères génériques
- Utiliser ce tutoriel pour comparer la boucle de régulation avec celle d'un autre tutoriel
Flux de travail
- Analyser les options de la ligne de commande (
--level,--name,--exclude,--no-hide-rate,--port). - Se connecter à
ws://localhost:10020(le rubrique Événements) — aucun profil de session n'est envoyé, car il s'agit d'un observateur en lecture seule. - Pour chaque message entrant, analysez le JSON de l'événement et appliquez des filtres :
- Si
levelest inférieure au seuil minimal de gravité. - Si
--namesi plusieurs modèles sont fournis, ne retenir que celui qui correspond (par rapport à l'un ou l'autrenameseul oucategory/name). - Si jamais
--excludeSi le motif correspond, supprimer.
- Si
- Afficher les événements conservés avec leur niveau, leur nom qualifié, un message facultatif et un
datacharge utile.
Paramètres
| Drapeau | Par défaut | Objectif |
|---|---|---|
--port | 10020 | Port du canal d'événements |
-l, --level | info | Gravité minimale — l'une des info, notice, warning, error, critical, panic |
-n, --name | (aucun) | Afficher uniquement les événements correspondant au modèle (regex, répétable) |
-x, --exclude | (aucun) | Masquer les événements correspondant au modèle (glob, répétable) |
--no-hide-rate | false | Inclure system-rate-report événements (masqués par défaut — très bruyants) |
Lancez n'importe quel tutoriel (04-hello-floor, 05-position-control, 06-combined...) dans un terminal, puis l'écouteur d'événements avec --no-hide-rate dans un autre. Le system-rate-report Cet événement inclut la fréquence de mise à jour effective du dispositif — comparez les variantes Python, C++ (nlohmann) et C++ (Glaze) du même tutoriel pour observer la surcharge liée à la sérialisation sur une boucle de contrôle à environ 4 kHz.
# Terminal 1 — pick a variant
./04-haply-inverse-hello-floor # C++ nlohmann
./04-haply-inverse-hello-floor-glz # C++ Glaze
python 04-haply-inverse-hello-floor.py # Python
# Terminal 2 — watch the rate
./10-haply-inverse-events --no-hide-rate
Champs d'état lus
Chaque message reçu correspond à un événement unique :
level— niveau de gravité de la chaîne (info...panic)name— nom de l'événement (par exempledevice-connected,system-rate-report)category— catégorie (par exempledevice,session,system)message— chaîne lisible par l'utilisateur (facultative)data— charge utile JSON imbriquée (facultative) (la structure dépend de l'événement)
Catalogue complet des événements : Événements et suivi.
Envoyer / recevoir
Abonnement passif — uniquement recv() est utilisée ; rien n'est renvoyé. Les trois variantes implémentent le même pipeline de filtrage ; l'élément intéressant propre à l'API Inverse réside dans la structure de la structure d'événement.
- Python
- C++ (nlohmann)
- C++ (Glaze)
async for msg in websocket est la forme la plus concise de la boucle en lecture seule.
async with websockets.connect(uri) as websocket:
async for msg in websocket:
try:
event = json.loads(msg)
except json.JSONDecodeError:
continue
if accept_event(event, min_level_index, name_patterns, exclude_patterns):
print(format_event(event))
Modèle de rappel libhv — onmessage s'exécute sur le thread d'E/S ; le thread principal se bloque sur ENTER. Les événements sont traités comme du JSON non typé — chaque champ est lu via .value(...) par défaut.
ws.onmessage = [&](const std::string &msg) {
json event;
try { event = json::parse(msg); } catch (...) { return; }
if (accept_event(event, opts.min_level, opts.name_patterns, opts.exclude_patterns))
print_event(event);
};
ws.open("ws://localhost:10020");
while (std::cin.get() != '\n') {} // block main thread
Les champs d'événements connus sont mappés à un type event_data struct. Le data le champ reste tel quel glz::raw_json_view ainsi, les charges utiles imbriquées arbitraires (qui dépendent de l'événement) peuvent être transmises telles quelles sans qu'il soit nécessaire de définir un schéma complet.
// Struct model — known fields typed, nested `data` kept as raw JSON
struct event_data {
std::string level;
std::string name;
std::string category;
std::string message;
glz::raw_json_view data{};
};
// Send / receive
ws.onmessage = [&](const std::string &msg) {
event_data event{};
if (glz::read<glz_settings>(event, msg)) return; // drop malformed
if (accept_event(event, opts.min_level, opts.name_patterns, opts.exclude_patterns))
print_event(event);
};
ws.open("ws://localhost:10020");
while (std::cin.get() != '\n') {} // block main thread
Source : Python · C++ · C++ Glaze
Connexes : Événements et surveillance · Protocole WebSocket