level_filter_sink.hpp¶
LevelFilterSink — per-subsystem log levels.
This header declares 1 type (8 members).
Extracted from include/shulib/diag/level_filter_sink.hpp — this page is that header's documentation, reformatted, so it cannot disagree with the code. Prose about how to think about the API lives in the user guide; worked recipes live in the cookbook; this page is the complete, mechanical list of what exists.
Contents¶
class LevelFilterSinkLevelFilterSinksetGlobalLevelsetLevelclearLevelslogwantsRecordemitsummarize
class LevelFilterSink¶
A RUNTIME per-subsystem log-level dial, as a decorator wrapped around any other sink: turn [MOT] up to Debug while holding [LOC] at Warn, with no rebuild. A line passes iff its level is at least as severe as its channel's threshold, which is the TAG's override if one is set and otherwise the global level — default Trace, so a freshly constructed filter is transparent. Only the leveled-message channel is filtered; records, summaries and wantsRecord() forward untouched. A blocked line is NOT a drop and is never tallied as one: the operator asked not to see it, which is configuration, not the involuntary degradation RateLimitedSink counts. Fixed capacity, no heap; single-task by contract, like the rest of diag/.
class, declared at include/shulib/diag/level_filter_sink.hpp:53.
LevelFilterSink::LevelFilterSink¶
inner must outlive the filter. Transparent until configured (global default Trace: everything passes).
function, declared at include/shulib/diag/level_filter_sink.hpp:57.
LevelFilterSink::setGlobalLevel¶
Threshold for every tag WITHOUT an override. Trace = pass everything.
function, declared at include/shulib/diag/level_filter_sink.hpp:60.
LevelFilterSink::setLevel¶
Per-subsystem override. Re-setting an existing tag updates it in place. Precondition: tag non-empty, ≤ kMaxTagBytes; table not full (LOUD, never a silently ignored dial — kMaxOverrides is far past any real tag census).
function, declared at include/shulib/diag/level_filter_sink.hpp:65.
LevelFilterSink::clearLevels¶
Drop every override (the global level stays).
function, declared at include/shulib/diag/level_filter_sink.hpp:85.
LevelFilterSink::log¶
Pass the line to the inner sink iff level is at least as severe as subsystem's threshold — an unrecognised tag simply has no override and gets the global level, so there is nothing to register in advance. A blocked line is discarded here and counted nowhere (see the class note). Throws nothing the inner sink does not: the seam forbids it.
function, declared at include/shulib/diag/level_filter_sink.hpp:91.
LevelFilterSink::wantsRecord¶
Whatever the inner sink answers — this decorator never suppresses record POPULATION. Answered as a PAIR with emit(), which is the seam's rule: overriding one without the other is how a sink ends up paying to build records it then throws away.
function, declared at include/shulib/diag/level_filter_sink.hpp:101.
LevelFilterSink::emit¶
Forwarded untouched. Per-tick records are DATA, not chatter, so no level threshold applies to them; the record stream's own dial is RateLimitedSink.
function, declared at include/shulib/diag/level_filter_sink.hpp:104.
LevelFilterSink::summarize¶
Forwarded untouched, and forwarded deliberately: the base's summarize() is a no-op body, so a decorator that failed to override it would silently EAT the end-of-run summary.
function, declared at include/shulib/diag/level_filter_sink.hpp:107.
Design commentary, from the header¶
The header opens with the reasoning behind these shapes. It is reproduced here in full because a reference that only lists signatures teaches nobody why.
The header’s own reasoning — 33 lines
LevelFilterSink — per-subsystem log levels (diagnostics-plan D-1; WS13, chunk C5).
The single most-used debugging move in practice: turn [MOT] up to DEBUG while
holding [LOC] at WARN. Before this decorator, levels were global — chasing one
subsystem meant either drowning in every other subsystem's chatter or a REBUILD
with different compile-time levels. This is a RUNTIME dial on the sink chain:
TermSink term{clock, out};
LevelFilterSink filtered{term};
filtered.setLevel("LOC", LogLevel::Warn); // quiet the localizer…
filtered.setLevel("MOT", LogLevel::Debug); // …while watching the motion layer
Semantics (each pinned by test/level_filter_test.cpp):
* A line passes iff its level is AT OR ABOVE the channel's threshold in
severity (Error > Warn > Info > Debug > Trace). setLevel(tag, Warn) means
"from tag, Warn and Error only".
* The threshold is the TAG's override if one is set, else the global level
(default Trace = everything passes — the decorator is transparent until told
otherwise).
* Filtering affects ONLY the leveled-message channel: records, summaries, and
wantsRecord() forward untouched (they are data, not chatter — and the record
stream has its own dial, RateLimitedSink).
FILTERING IS NOT DROPPING (the D-2 distinction, stated deliberately): a filtered
line is one the operator ASKED not to see — explicit configuration, not silent
degradation — so it is not counted in any dropped tally. Throttling (D-2) is
involuntary and therefore counted. Conflating the two would bury real drops in
requested quiet.
Fixed capacity, no heap: overrides live in a bounded table; exceeding it is a
LOUD precondition, never a silently ignored setLevel. Single-task by contract,
like the rest of diag/.
Last updated 2026-08-15 — published from the main release branch, commit fa545ff. This site tracks releases, so between them it can lag the repository — that lag is deliberate, and it is what keeps the development log off the public site. For the current state of the code, see the repository.