10. イベントフローリスナー
接続先事件窓口(ポート 10020),システムイベントを出力し、レベル、名称パターン、および除外ルールに基づいて任意にフィルタリングすることができます。読み取り専用――セッションプロファイルは使用せず、コマンドも一切送信しません。
学習内容:
- 受動的な観察者として購読する事件 WebSocket(ポート
10020) - 解析事件 JSON —
level、name、category、data、message - 「深刻度の最低レベル」でフィルタリングする
- ワイルドカード名の照合と除外
- このチュートリアルと他の任意のチュートリアルを組み合わせて、制御ループのベンチマークテストを行う
ワークフロー
- 解析コマンドラインオプション(
--level、--name、--exclude、--no-hide-rate、--port)。 - 接続先
ws://localhost:10020(即事件窓口)——これは読み取り専用のオブザーバーであるため、セッションプロファイルは送信されません。 - 受信した各メッセージに対して、イベントの JSON を解析し、フィルタリングルールを適用します:
- 若
level最低の深刻度レベルを下回る場合は、破棄される。 - もし指定された場合は
--nameパターンについては、そのうちのいずれかのパターンに一致した場合にのみ(一致nameそれ自体、あるいはcategory/name)の場合は保持し、それ以外の場合は破棄する。 - いずれか
--excludeパターンに一致する場合は、破棄する。
- 若
- 保存されたイベントを、そのレベル、完全な名称、オプションのメッセージ、およびオプションの
data負荷。
パラメータ
| パラメータ | デフォルト値 | 用途 |
|---|---|---|
--port | 10020 | イベントチャネルポート |
-l, --level | info | 最低の深刻度レベル。選択可能な値は以下の通りです。 info、notice、warning、error、critical、panic の一つ |
-n, --name | (なし) | このパターンに一致するイベントのみを表示します(glob ワイルドカード、複数指定可能) |
-x, --exclude | (なし) | このパターンに一致するイベントを非表示にする(glob ワイルドカード、複数指定可能) |
--no-hide-rate | false | 含む system-rate-report 事件(出力量が多いため、デフォルトでは非表示) |
あるターミナルで任意のチュートリアル(04-hello-floor、05-position-control、06-combined……)を実行し、別のターミナルで --no-hide-rate イベントリスナーを実行します。system-rate-report この事例には、デバイスの有効なティックレートが含まれています。同じチュートリアルの Python / C++ nlohmann 版と C++ Glaze 版を比較すると、約 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
読み込まれたステータスフィールド
受信した各メッセージは、1つのイベントです:
level— 文字列形式の深刻度(info...panic)name— 事件名(例:device-connected、system-rate-report)category— カテゴリ(例:device、session、system)message— オプションの可読文字列data— オプションのネストされた JSON ペイロード(構造はイベントによって異なります)
イベントの完全な一覧については、「イベントと監視」をご覧ください。
送信 / 受信
受動的な購読――使用のみ recv(),いかなる内容も転送しません。3つのバージョンにおけるフィルタリングの処理フローは同じです。注目すべきInverse API固有の部分は、イベント構造体の形式です。
- Python
- C++ (nlohmann)
- C++ (Glaze)
async for msg in websocket これは、ループを受け取るだけの最も簡潔な記述法です。
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))
libhv コールバックモデル――onmessage I/O スレッド上で実行され、メインスレッドは ENTER キーが押されるのをブロックして待機します。イベントは型のない JSON として扱われ、各フィールドはデフォルト値を持つ .value(...) 読み込む。
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
既知のイベントフィールドは、型付きのものにマッピングされます。 event_data 構造体。data フィールドは次のままにしておく glz::raw_json_view,そのため、完全なスキーマを定義することなく、任意のネストされたロード(その構造は具体的なイベントによって異なります)をそのまま転送することができます。
// 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
チュートリアル 10 も SDK とともにローカルにインストールされます。サービスのインストールディレクトリ内の tutorials/10-haply-inverse-events/ 中で探す。
関連コンテンツ: インシデントと監視·WebSocket プロトコル