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:
1 parent
14e71c72ca
commit
011780e6ab
5 files changed
+88
-10
No files matched your search
@@ -76,6 +76,33 @@ proc configureLogging(localLogSvc: ThreadLocalLogService, verbose: bool) =
|
||||
# Changes automatically propagate to all threads
|
||||
```
|
||||
|
||||
### Avoiding Expensive Log Preparation
|
||||
|
||||
Use `isEnabled` to guard expensive work performed before a logging call:
|
||||
|
||||
```nim
|
||||
if logger.isEnabled(lvlDebug):
|
||||
let details = buildExpensiveDetails()
|
||||
logger.debug(details)
|
||||
```
|
||||
|
||||
`isEnabled` checks the logger's effective threshold without refreshing its
|
||||
configuration. It uses cached namespace thresholds and the shared root fallback
|
||||
level. Namespace changes can remain unseen until the local service refreshes.
|
||||
Normal logging calls and `getLogger` refresh the cache; callers can also use
|
||||
`ensureFreshness(localLogSvc)` explicitly.
|
||||
|
||||
If all logging is guarded by `isEnabled`, a cached disabled level can keep
|
||||
skipping those logging calls indefinitely. To pick up runtime namespace changes
|
||||
in that situation, refresh the local service at suitable application boundaries,
|
||||
such as the start of a request or work batch.
|
||||
|
||||
A true result does not guarantee delivery: the logging call refreshes
|
||||
configuration and appenders apply their own filters. For a single expression,
|
||||
`logger.debug(buildExpensiveDetails())` already delays evaluation until the
|
||||
logger's threshold permits the message. A separate guard is useful when
|
||||
preparation requires multiple statements.
|
||||
|
||||
## Loggers and Appenders
|
||||
|
||||
The logging system is composed of two main components: loggers and appenders.
|
||||
@@ -310,13 +337,13 @@ No explicit flush or delay is needed after joining the threads that log.
|
||||
You can change logging configuration through a service copy or a local service
|
||||
in any thread. Those changes are intended to take effect automatically on
|
||||
subsequent logging calls in every thread using that service, without recreating
|
||||
loggers or configuring each worker separately.
|
||||
loggers or configuring each worker separately. `isEnabled` intentionally does
|
||||
not refresh configuration; see [Avoiding Expensive Log Preparation](#avoiding-expensive-log-preparation).
|
||||
|
||||
> [!NOTE]
|
||||
> Thread-safety work is still in progress. Custom state and captured
|
||||
> formatters must follow the ownership rules above. Standalone `isEnabled()`
|
||||
> checks do not yet notice changed namespace thresholds, and concurrent
|
||||
> local-time timestamp construction still has a known failure.
|
||||
> formatters must follow the ownership rules above. Concurrent local-time
|
||||
> timestamp construction still has a known failure.
|
||||
> Nim 2.2.10 also produces sanitizer reports in its default allocator
|
||||
> during some cross-thread allocation patterns. See
|
||||
> [the regression tests](tests/README.md) for the remaining work.
|
||||
|
||||
Reference in new issue
Block a user