Skip to main content
Version: 3.5.x

10. Event Stream Listener

Connects to the events channel (port 10020) and prints system events with optional filtering by level, name pattern, and exclusions. Read-only — no session profile, no commands sent.

What you'll learn:

  • Subscribing to the events WebSocket (port 10020) as a passive observer
  • Parsing event JSONlevel, name, category, data, message
  • Filtering by minimum severity level
  • Wildcard name matching and exclusion
  • Using this tutorial to benchmark the control loop alongside any other tutorial

Workflow

  1. Parse CLI flags (--level, --name, --exclude, --no-hide-rate, --port).
  2. Connect to ws://localhost:10020 (the events channel) — no session profile is sent since this is a read-only observer.
  3. For each incoming message, parse the event JSON and apply filters:
    • Drop if level is below the minimum severity.
    • If --name patterns are given, drop unless one matches (against either name alone or category/name).
    • If any --exclude pattern matches, drop.
  4. Print surviving events with their level, qualified name, optional message, and optional data payload.

Parameters

FlagDefaultPurpose
--port10020Event channel port
-l, --levelinfoMinimum severity — one of info, notice, warning, error, critical, panic
-n, --name(none)Only show events matching pattern (glob, repeatable)
-x, --exclude(none)Hide events matching pattern (glob, repeatable)
--no-hide-ratefalseInclude system-rate-report events (hidden by default — very noisy)
Benchmark the control loop

Run any tutorial (04-hello-floor, 05-position-control, 06-combined...) in one terminal, and the event listener with --no-hide-rate in another. The system-rate-report event includes the effective device tick rate — compare across the Python / C++ nlohmann / C++ Glaze variants of the same tutorial to observe serialization overhead on a ~4 kHz control loop.

# 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

State fields read

Each incoming message is a single event:

  • level — string severity (info ... panic)
  • name — event name (e.g. device-connected, system-rate-report)
  • category — category (e.g. device, session, system)
  • message — optional human-readable string
  • data — optional nested JSON payload (shape depends on the event)

Full event catalogue: Events & Monitoring.

Send / receive

Passive subscription — only recv() is used; nothing is sent back. All three variants implement the same filter pipeline; the interesting Inverse-API-specific part is the event struct shape.

async for msg in websocket is the shortest form of the receive-only loop.

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))

Source: Python · C++ · C++ Glaze

Related: Events & Monitoring · WebSocket Protocol