Expand description
Structured logging, shared by all three binaries.
Before this module the workspace had no tracing, no metrics crate and no
structured log anywhere: a failure in production left println! output and
nothing correlatable. Everything in the operability goals — uptime
monitoring, failure detection, API analytics — depends on this existing
first, which is why it landed ahead of the rest of its phase.
§Three rules, and they are not style preferences
- Logs go to stderr, always. The CLI’s stdout is a machine-readable
contract (
{"ok":true,…}); a log line written there corrupts the JSON envelope an agent is parsing.with_writer(std::io::stderr)is what makesunv … --json | jqkeep working withUNV_LOG=debugset. - Never log a secret value. Log the fingerprint (
out::fingerprint), the entry id, or the provider name — neverapi_key, never a password, never a session token. A log file is not encrypted and is routinely shipped somewhere else. - Logging is off unless asked for. The default level is chosen by each binary, and every one of them is quiet enough that normal operation produces nothing on stderr. A secrets manager that chatters is a secrets manager whose output nobody reads.
§Configuring it
| Variable | Effect |
|---|---|
UNV_LOG | tracing filter directive (info, unv_server=debug, …). Checked first. |
RUST_LOG | Same, checked only when UNV_LOG is unset, so an unrelated RUST_LOG in the environment still works. |
UNV_LOG_FORMAT | json for one JSON object per line; anything else is the human format. |
An unparseable filter falls back to the caller’s default rather than panicking: a typo in an environment variable must not stop a server booting.
Functions§
- init
- Installs the process-wide subscriber. Safe to call more than once; only the first call has any effect.
- is_
initialised - True once
inithas run in this process. Tests use it; nothing else should need to ask.