Audit P1/P2: transports already accepted `LevelsConfig`
(`{ [LogLevel.WARN]: { enabled: true } }`), but the engine itself
gated entries with a threshold (`if (lvl < state.level) return`).
Two filtering vocabularies for the same vocabulary; a 1.0 contract
should pick one.
Decision: align the engine on per-level enablement (the same
shape transports use). Threshold semantics stay as a shorthand —
`level: LogLevel.WARN` is equivalent to
`levels: levelsAtLeast(LogLevel.WARN)`. When both are set, `levels`
wins. Backward-compatible: existing apps that only pass `level`
get the exact same enabled set as before because the engine
projects the threshold into `enabledLevels` at boot.
Implementation:
- `LoggerOptions` gains `levels?: LevelsConfig`. Two helpers,
`buildEnabledLevelsFromThreshold(level)` and
`buildEnabledLevelsFromLevelsConfig(levels)`, project either form
into the runtime `Set<LogLevel>` the engine consults at the log
site.
- Engine state grows `enabledLevels: Set<LogLevel>`. The hot path
becomes `if (!state.enabledLevels.has(lvl)) return`.
- `setLevel(level)` keeps working — it rebuilds `enabledLevels`
from the new threshold.
Two regression tests pin the new behaviour: arbitrary subset via
`levelsAtLeast(LogLevel.WARN)`, and `levels` overriding `level`
when both are set.
Suite: 1515 / 1515 (+3 tests across logger and storage clock).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
master
parent
6b6a96fb11
commit
3567206fa3
Loading…
Reference in new issue