initLog static method
Initializes the zenoh logger from the RUST_LOG environment variable,
falling back to fallback if RUST_LOG is not set.
Must be called before Session.open for logging to take effect. This is a one-time initialization -- subsequent calls are ignored by the underlying runtime.
⛔ And it forecloses initLogWithSink for the life of the process.
Canon's logging slot is process-global and first-wins; calling this
claims it permanently, so a host that wants records delivered into
its own application must install the sink first. The foreclosure
surfaces as a StateError at the sink install, not here — this call
stays silent, because a caller who asked for the env logger got the env
logger and there is nothing to report.
Calling it a second time is likewise silent and idempotent, unchanged.
⭐ The asymmetry is deliberate and structural: a throw belongs where
a returned value would otherwise be false. initLogWithSink hands back
a Stream, and a stream that can never emit is a lie handed back as a
live channel; this returns void, and void cannot be false. What a
late call to this loses is a filter level, not a channel.
⚠️ The guard sees only inits made through this binding. Canon
returns void from its own init and reports nothing, so there is no
way to observe an init made by other code in the same process — another
binding, or a Rust crate linked into the same image. This is a guard
against an ordering mistake in your program, not a view of canon's
state.
What the log channel carries, measured
This is the route to canon's own explanation of a failure, and the measurement that made it the recommended one is worth carrying with its condition, because the condition is what a reader needs:
initLog('error')prints the precise cause of aSession.openfailure with zero leakage of the config that produced it. That is true, and it is why open-failure diagnosis is routed here rather than onto the exception message.- ⚠️ It is a property of the failure class, not of the channel.
Config-rejection records echo the offending value verbatim — with
the surrounding source line and a caret under the offending token — on
both build variants. On the default
stablebuild, where the exception channel carries no upstream detail at all, this is the only channel that leaks.
⛔ No severity ceiling removes it, because the records are emitted at
error. The control is a host-side filter on the delivered records,
which is what initLogWithSink exists to make possible; this call sends
them to stdout, where the host has no control at all.
Filter syntax follows the Rust env_logger format:
"error"-- errors only (recommended for production)"warn"-- warnings and errors"info"-- informational messages"debug"-- debug-level detail"trace"-- maximum verbosity
Implementation
static void initLog(String fallback) {
final cStr = fallback.toNativeUtf8();
try {
bindings.zd_init_log(cStr.cast<Char>());
} finally {
calloc.free(cStr);
}
}