OpenRAL observability — OpenTelemetry tracing + structlog→OTLP logging bridge for Skill / inference / safety spans
Project description
openral-observability
OpenRAL observability — OpenTelemetry tracing + structlog→OTLP logging bridge for Skill / inference / safety spans
Part of OpenRAL — the open Robot Abstraction Layer for vision-language-action robotics. This package is one member of the OpenRAL Python workspace; see the architecture overview and the eight-layer model in the project docs.
- Docs: https://openral.github.io/openral/
- Source: https://github.com/OpenRAL/openral
- License: Apache-2.0
All OpenRAL workspace packages move in lockstep at
0.1.xuntil the first public release.
Voice prompt (local speech-to-text)
The live dashboard's operator-prompt box has a mic button. Click it and the
browser listens until you stop speaking — voice-activity detection runs
client-side via @ricky0123/vad-web
(Silero VAD). The captured audio is POSTed to POST /api/transcribe, which
runs a local faster-whisper
model on the host, fills the prompt box with the transcript, and sends it via
the normal /api/prompt path. Your audio never leaves the machine.
faster-whisper ships with the dashboard extra (which openral-cli already
pulls in). The small browser glue files for VAD are vendored under
static/vendor/vad/; the large pinned Silero ONNX and onnxruntime WASM assets
are fetched and checksum-verified into $OPENRAL_CACHE_DIR/dashboard_assets/vad/
on dashboard startup, then copied into the served static directory. If those
assets are unavailable, /api/config reports voice_prompt_enabled=false and
the mic button stays disabled instead of failing at click time. The transcription
endpoint still degrades to HTTP 503 if faster-whisper is ever stripped from the
environment. Whisper model weights are fetched from the Hugging Face Hub on the
first transcription and then cached (pre-pull both caches to stay air-gapped).
Tuning knobs (read at first transcription; defaults run on any CPU):
| Env var | Default | Notes |
|---|---|---|
OPENRAL_STT_MODEL |
base.en |
any faster-whisper model id (tiny.en, small, large-v3, …) |
OPENRAL_STT_DEVICE |
cpu |
cuda to use a local GPU |
OPENRAL_STT_COMPUTE |
int8 |
CTranslate2 compute type (int8, float16, …) |
The vendored browser assets and their versions/licenses are documented in
static/vendor/vad/NOTICE.md,
which also records the npm pack command to refresh them.
Live camera video (MJPEG stream)
The camera cards in the dashboard now show live video instead of a static thumbnail. Each camera is served at:
GET /api/camera/{source}/stream
This endpoint re-serves the per-camera OTLP thumbnail JPEG as a continuous
multipart/x-mixed-replace MJPEG stream — the same thumbnails that already
flow in via the sensors.read_latest span attribute thumbnail_jpeg_b64. No
extra camera pipeline is needed. The frame rate is bounded by how often the
workload exports spans (configured via OPENRAL_OTEL_SPAN_SCHEDULE_DELAY_MS,
default 30 ms ≈ 33 Hz). The endpoint returns 404 only when the source name is
entirely unknown to the store; a known camera that has not yet emitted a frame
opens the stream and waits.
mDNS discovery (mdns extra)
Install the optional mdns extra to let openral dashboard advertise itself
on the LAN and browse for other OpenRAL services:
pip install openral-observability[mdns]
# or, inside the OpenRAL workspace:
uv sync --group mdns
This pulls in zeroconf>=0.131
(LGPL-2.1, TSC-approved 2026-06-21; used unmodified as an optional declared
dependency, not vendored).
When zeroconf is importable, run_dashboard starts a Discovery instance
that:
- Browses for
_openral-otlp._tcp.local.services on the LAN (always). - Advertises the dashboard's own OTLP endpoint on the LAN — but only
when the bind address is a non-loopback, non-wildcard IPv4 address. A
loopback (
127.0.0.1) or wildcard (0.0.0.0) bind is browse-only and never advertised (advertising a loopback address to the LAN is meaningless, and advertising a wildcard address is ambiguous).
Discovered services are surfaced in the "Add Robot" panel via a read-only endpoint:
GET /api/robots
→ {"enabled": true, "robots": [{name, addresses, port, properties, last_seen}, …]}
When the mdns extra is absent or zeroconf fails to start, the endpoint
returns {"enabled": false, "robots": []} — the dashboard runs exactly as
before; discovery is additive, never load-bearing.
Write-controls (OPENRAL_DASHBOARD_WRITE_CONTROLS)
Default: OFF. These endpoints are pending safety-WG review and a hazard-log update. Do not enable in production until the safety WG has signed off.
Two guarded write endpoints are available when the flag is set:
POST /api/skill/execute # dispatch an ExecuteRskill action goal (returns 202 on acceptance)
POST /api/param/set # tune a non-safety ROS 2 parameter via ros2 param set
POST /api/skill/execute returns HTTP 202 as soon as the action server
accepts the goal — it does not block on skill completion. The response body
includes goal_id for telemetry correlation. Execution progress is tracked via
the dashboard SSE stream and OTLP telemetry. The acceptance timeout is
configurable via OPENRAL_DASHBOARD_SKILL_ACCEPT_TIMEOUT_S (default 12 s).
Enable them by starting the dashboard with the environment variable set:
OPENRAL_DASHBOARD_WRITE_CONTROLS=1 openral dashboard
The dashboard prints a loud WARNING: banner to stderr on startup when the
flag is on. The flag is also surfaced in GET /api/config:
{"jaeger_ui_url": "...", "write_controls_enabled": true}
Safety posture:
- Both endpoints return
403when the flag is off (default). POST /api/param/setalso refuses any param name that matches a substring in a hard-coded safety denylist (velocity,accel,force,torque,limit,workspace,estop,e_stop,deadman,dead_man,safety,safe,watchdog) — these must be changed via a reviewed config or manifest, never the dashboard (CLAUDE.md §1.1).- Every attempt (permitted or denied) is audit-logged at WARNING level before any subprocess is spawned, providing a paper trail.
- The safety kernel (
cpp/openral_safety_kernel) remains the sole authority on whether a skill action proceeds — the dashboard shells out toros2 action send_goal /openral/execute_rskill; the kernel disposes.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file openral_observability-0.1.0.tar.gz.
File metadata
- Download URL: openral_observability-0.1.0.tar.gz
- Upload date:
- Size: 653.0 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.13.13
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
ce972e0e76a2ac7c251bdfdc282bed168009b82ec860da0e517121d63ca2d555
|
|
| MD5 |
20d0952b6c0e0a72662a0ae92c8d2e60
|
|
| BLAKE2b-256 |
42b0e11fc870fb07c46c63c5debbe326f99e5f19b54d61e3abe2815b08833185
|
File details
Details for the file openral_observability-0.1.0-py3-none-any.whl.
File metadata
- Download URL: openral_observability-0.1.0-py3-none-any.whl
- Upload date:
- Size: 321.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.13.13
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
0db5b89b8a58e17ccc08b2471940b95b194b891b28ff901955ec2f7bcbe61f96
|
|
| MD5 |
45e0935465dc445ba5d89c9431c2a89b
|
|
| BLAKE2b-256 |
0e4c439ecc98567a605eb8ace4df8a1e85413f6664275a2a49dc8a253d7e04b7
|