Define cached threshold behavior for isEnabled

Document and test explicit refresh boundaries for isEnabled guards, and
only read the shared root threshold when no namespace threshold applies.
Include the portable Nimble configuration loader.
This commit is contained in:
jdb committed 2026-09-29 08:43:31 -05:00
1 parent 14e71c72ca
commit 011780e6ab
5 files changed
+88 -10

No files matched your search

+18 -2
View File
@@ -541,7 +541,6 @@ func getEffectiveThreshold(logger: Logger): Level {.gcsafe.} =
## Get the effective logging level threshold for a logger. This is the most
## specific level that is set for the logger or any of its parents. The root
## logger is used as the default if no other level is set.
result = logger.threadSvc.shared.rootLevel.load
# Check for exact match first
if logger.threadSvc.thresholds.hasKey(logger.scope):
@@ -555,10 +554,27 @@ func getEffectiveThreshold(logger: Logger): Level {.gcsafe.} =
# If we have matches, return the threshold configured for the most specific.
if namespaces.len > 0:
result = logger.threadSvc.thresholds[namespaces[0]]
return logger.threadSvc.thresholds[namespaces[0]]
return logger.threadSvc.shared.rootLevel.load
proc isEnabled*(l: Logger, lvl: Level): bool {.inline,gcsafe.} =
## Check the logger's effective threshold without refreshing configuration.
## Use this to guard expensive log preparation performed outside a logging
## call. Namespace thresholds come from the thread-local cache; the root
## fallback level is read from the shared service.
##
## Repeated checks do not refresh that cache. Namespace changes can remain
## unseen until a logging call, getLogger, or an explicit ensureFreshness on
## the local service refreshes it. Applications that only log behind these
## guards should refresh their local service at suitable execution boundaries
## if they need to observe configuration changes.
##
## A true result does not guarantee delivery: the subsequent logging call
## refreshes configuration and appenders apply their own filters. Expressions
## passed directly to the level/message logging templates are already
## evaluated only when the logger's threshold permits the message.
lvl >= l.getEffectiveThreshold