Logging
| Variable | Meaning |
|---|---|
RUST_LOG | Standard log filter, for example RUST_LOG=cerulion=info,iceoryx2=warn. A new workspace’s .cargo/config.toml sets a sane default. |
IOX2_LOG_LEVEL | The transport’s own log filter. New workspaces default it to error so framework chatter does not drown out your logs. |
tracing::info! from your tick() goes to stderr while the host’s own logs go to stdout. The filter is RUST_LOG as captured when the graph started, an empty value means info, and RUST_LOG=off silences node-side logs entirely.
Do not install a global
tracing subscriber inside node code — the framework installs one before your node runs, and a second install panics and fails the node load. Control output with RUST_LOG instead.Networking
| Variable | Meaning |
|---|---|
CERULION_NETWORK=off | Run local-only: no gateway process, nothing crosses the machine boundary. Honored by every entry point, and equivalent to --network off. |
CERULION_NETD_LISTEN | The locators the robot’s shared network plane binds, for example tcp/0.0.0.0:7683. Set it on a robot that must be discoverable where LAN multicast is blocked; without it the plane binds nothing and the machine advertises nothing. Setting it also makes the plane standing: it comes up when the machine’s network daemon starts, so topics registered at runtime — the topics a ROS 2 process publishes, for instance — are advertised on the network without a graph ever running, and the daemon stops only on SIGINT/SIGTERM instead of self-exiting once nothing has demanded a topic for the idle grace. |
CERULION_NETD_NETWORK=off | Force the machine’s shared network plane strictly local-only, whatever CERULION_NETD_LISTEN says. Scoped to the daemon, so it never changes what a graph run on the same machine does. |
CERULION_GATEWAY_PORT | Override the well-known gateway port (7683). Parsed strictly. |
CERULION_ROBOT_IDENTITY | The robot name announced on the network. Defaults to the hostname. |
CERULION_PEERS | Extra peer locators to try when discovering robots. |
Recording and capture
| Variable | Meaning |
|---|---|
CERULION_FLASHBACK=off | Turn the Flashback capture plane off, so no run holds a rolling window. |
CERULION_FLASHBACK_DIR | Where captures land. Defaults to <workspace>/recordings/flashbacks/. |
CERULION_RECORD_DISCOVERY=off | With graph run --record, record only the graph’s declared topics instead of also discovering other live producers. |
CERULION_RECORD_DISCOVERY_SETTLE_MS | How long bag creation waits for late producers to appear. |
Visualization
| Variable | Meaning |
|---|---|
CERULION_VIZD_SOCK | Path of the control socket the visualization daemon listens on. Set it on both the daemon and its clients to run a scene at a non-default location. |
ROS 2 on Cerulion transport
Read bycerulion ros2 run / cerulion ros2 launch and by graph run for a graph’s ros2: entries — every path stages the same child environment.
| Variable | Meaning |
|---|---|
CERULION_LIB_DIR | The directory holding librmw_cerulion.so, instead of the directory of the cerulion binary. It is prepended to the ROS 2 child’s LD_LIBRARY_PATH, and a minimal ament prefix linking the library is staged under ~/.cerulion/ros2/ (or the directory is used as-is when it already is an install’s lib/) and prepended to AMENT_PREFIX_PATH. A missing library is exit 69 with the remediation, never a silent fall-through to the stock RMW. Set but empty is an error. |
CERULION_RMW_EVENT_WAIT | Read inside the ROS 2 process itself, by the Cerulion RMW layer. A waiting executor blocks on the transport’s own wake channels, so a publish wakes it in microseconds; off restores the earlier behavior, where the wait probed for new messages every 100 microseconds instead. on, empty, or unset is the default, and any other value warns once and keeps the event-driven wait. |
CERULION_RMW_SLICE_CEILING | Read inside the ROS 2 process itself: per-type payload ceilings for the shared-memory slots its publishers create, as a comma-separated <pkg/Type>:<bytes> list — for example sensor_msgs/Image:33554432,my_pkg/Big:268435456. Without it, a variable-length ROS 2 type takes the same per-type budget Cerulion gives one of its own outputs of that schema, and a type Cerulion does not know takes 128 MiB. An override wins outright, so it can widen or narrow. Names must be exactly pkg/Type: never pkg::Type (the : separates the name from the bytes) and never the rosidl pkg/msg/Type. Bytes must be an integer from 32 to 4294967295. A malformed entry warns and is skipped while the entries around it still apply; duplicate entries for one type warn and the last one wins. The value is read once per process, at the first publisher creation. The ceiling is the real slot size, so a message larger than it fails to publish loudly instead of reserving a blanket slot. An entry naming a fixed-size type is ignored with a warning — those are always sized exactly at their wire size. |
CERULION_ROS2_PRELOAD | Preload control for the ROS 2 child. Unset — the default — auto-injects libcerulion_heaphook.so into LD_PRELOAD when it exists beside librmw_cerulion.so, logging one line naming what it injected. off or none disables preload injection entirely. Any other value is a path to a .so that is added, not substituted: LD_PRELOAD becomes <your library>:<the hook, when present>:<whatever was already there>. A path that does not exist is exit 69; an empty value is an error. Injection is never silently dropped. |
CERULION_HEAPHOOK_DEBUG | Read by the preloaded libcerulion_heaphook.so itself (Linux with glibc). Set it to any non-empty value other than 0 and the library writes one line to stderr as it loads, confirming that it loaded and that it took effect. Unset, empty, or 0 prints nothing. It is a diagnostic: a stock ROS 2 process installs no Cerulion log subscriber, so this line is how you confirm the preload actually reached the child. If another allocator — jemalloc, tcmalloc, or a sanitizer — is preloaded ahead of it, the library says so on stderr as it loads whether or not this variable is set, and stays out of the way. |
Live-run tuning
These affect how the live loop idles and how work is spread across cores. Reach for them when you are chasing latency, not before.| Variable | Meaning |
|---|---|
CERULION_MONITOR_WAIT | 1 forces the live-loop CPU park on, 0 disables it. The default is on for live runs. --no-monitor-wait beats this in both directions. A ROS 2 process on rmw_cerulion reads the same variable for the park its executor wait uses, where the default is per platform: on for Linux aarch64, off for x86_64, on which blocking in the kernel measured faster. |
CERULION_DOORBELL | 1 forces the data doorbell on (a publish wakes a parked consumer immediately), 0 leaves a timer-only park. Linux only. |
CERULION_CPU_DMA_LOCK | 1 pins the CPU out of deep idle states, 0 disables the cap. By default Cerulion derives a cap from the graph’s own tightest timing. Linux only, and it needs privileges — a failed acquire warns and the run continues. |
CERULION_CPU_DMA_LOCK_US | An explicit idle exit-latency cap in microseconds, used under the automatic mode. |
CERULION_FIRE_THREADS | Size of the pool that fires independent nodes within one level. Read once at graph build; the default is derived from the machine and the graph’s widest level. It never changes what fires or in what order. |
CERULION_BARRIER_SPIN_US | Multi-process only: how long a worker waits actively at each level boundary before it sleeps. 0 skips the active wait. Values above 100 ms are clamped with a warning. |
CERULION_BARRIER_OS_SYNC | macOS only: 0 opts out of the faster wake path at level boundaries, at the cost of latency. |
CERULION_PARK_OS_SYNC | macOS 14.4 and later: 0 opts out of the faster wait the live-loop park uses between rechecks, so each recheck waits with a plain sleep instead. It changes only how tightly the park keeps to its recheck interval, never what fires. 1 or unset is the default, any other value warns and keeps the faster wait, and older macOS versions and every other platform are unaffected. |
Build
| Variable | Meaning |
|---|---|
CARGO_TARGET_DIR | Honored identically by cerulion node build and cerulion graph run, so a shared target directory works. |
Related
CLI reference
The flags that override several of these variables.
Network a graph
What the network variables change in practice.