Expand description
drmkit’s library-wide diagnostic surface.
Port of src/log.hpp from drm-cxx @ dc2915b. Two knobs are exposed,
matching the C++ contract:
-
set_log_level— process-wide threshold. Records at or below the active level are emitted; the rest are dropped before formatting cost is paid. A call below the threshold reduces to one relaxed atomic load and a branch. -
set_log_sink— process-wide redirection hook. The default sink writes to stderr (errors, warnings) or stdout (info, debug) prefixed with[drm:LEVEL]. Consumers can forward totracing, journald, syslog, or an in-memory test buffer.reset_log_sinkrestores the default — the Rust spelling of the C++set_log_sink(nullptr)path.
§Deviations from the C++ original
The C++ set_log_sink is documented thread-unsafe (“install once during
application startup, before spinning up worker threads”), and its
set_log_level is a plain unsynchronized write. Here both are genuinely
thread-safe: the level is an AtomicU8 and the sink lives behind an
RwLock whose guard is released before the sink runs, so a sink that logs
cannot deadlock and a sink that panics cannot wedge logging for the rest of
the process. The startup-only discipline remains good practice; it is no
longer load-bearing.
§Untrusted content in log records
Records are delivered to the sink verbatim — no escaping, no newline stripping. That matters here more than in a typical library, because some of what drmkit will log is attacker-influenced: EDID monitor names and serial strings come off the wire from whatever display is plugged in, and a hostile or simply malformed EDID can carry newlines or ANSI escape sequences. Written straight to a terminal by the built-in sink, those can forge log lines or move the cursor.
The C++ original has the same property. Rather than diverge silently, the rule for the port is: sanitize at the point the untrusted string enters a record, not in the sink. Any crate that logs an EDID string must sanitize it before formatting – none currently logs one – because the sink cannot tell a monitor name from a driver name once they are one formatted string. Consumers who route this into a terminal and cannot trust their displays should install a sink that escapes control characters.
§Initial level
The C++ side bakes its default in at compile time via DRM_CXX_LOG_LEVEL.
Here the initial level resolves once, on first use, from the
DRMKIT_LOG_LEVEL environment variable (silent/error/warn/info/
debug, case-insensitive, or the numeric discriminant, plus the aliases
off/none, warning and trace). An unset or unparseable value yields
LogLevel::Info, matching the C++ default. An explicit set_log_level
before first use always wins.
§Example
use drmkit_log::{LogLevel, log_warn, set_log_level};
set_log_level(LogLevel::Warn);
log_warn!("plane {} rejected modifier {:#x}", 31, 0x0100_0000_0000_0001_u64);§A note on the examples
The level and the sink are process-global, and under edition 2024 every doctest in a crate is merged into one binary and run on parallel threads. Examples here therefore demonstrate the API but never assert on what a sink received: a concurrently running example would have replaced the sink or moved the threshold, and the assertion would fail for reasons having nothing to do with the code. The behavioral assertions live in the unit tests, which serialize on a mutex the way the C++ gtest fixture does.
Macros§
- log_
channel - Emit a line belonging to an opt-in diagnostic channel — one already gated
by its own switch, such as the
DRM_ALLOC_DEBUG/DRM_EXT_DMABUF_DEBUGenvironment variables on the C++ side. - log_
debug - Emit at
LogLevel::Debug. - log_
error - Emit at
LogLevel::Error. - log_
info - Emit at
LogLevel::Info. - log_
warn - Emit at
LogLevel::Warn.
Enums§
- LogLevel
- Severity of a diagnostic record.
Functions§
- install_
tracing_ sink - Route every admitted record into
tracingunder thedrmkittarget. - log_
level - The active process-wide threshold.
- log_
sink - The installed sink, or
Nonewhen the built-in stdio sink is active. - reset_
log_ sink - Restore the built-in stdio sink — the Rust spelling of the C++
set_log_sink(nullptr)path. - set_
log_ level - Set the process-wide threshold.
- set_
log_ sink - Install a sink, replacing whatever was there.
Type Aliases§
- LogSink
- A sink receives the record’s level and its fully formatted body — no level prefix, no trailing newline.