diff --git a/docs/api/build-async-logger.md b/docs/api/build-async-logger.md index e038498..81e8735 100644 --- a/docs/api/build-async-logger.md +++ b/docs/api/build-async-logger.md @@ -39,6 +39,7 @@ Detailed rules explaining key parameters and behaviors - File, formatter, and any configured synchronous queue choices all come from config rather than direct code-side sink wiring. - The returned sink type is `RuntimeSink`, which keeps configured control helpers available where relevant. - This builder returns the underlying `AsyncLogger[@bitlogger.RuntimeSink]` value directly. `build_application_async_logger(...)` only re-exports the same result under the `ApplicationAsyncLogger` alias, while `build_library_async_logger(...)` wraps the same result in `LibraryAsyncLogger[@bitlogger.RuntimeSink]`. +- The returned async logger also keeps ordinary target rules unchanged: `log(..., target=...)` can override the target for one call, while severity helpers such as `debug(...)`, `info(...)`, and `error(...)` continue to use the stored logger target unless a derived logger was created first with `with_target(...)` or `child(...)`. - Because this path starts from `build_logger(config.logger)`, it preserves the broader runtime-sink build path, including sync-side queue decoration when `LoggerConfig.queue` is present. - In the current direct builder coverage, the returned logger exposes the expected serialized async state snapshot, runtime-sink variant choice, queue counters, lifecycle flags, and later failure fields after `run()` or `shutdown()`. - File-backed runtime helpers also stay directly available on the returned `RuntimeSink` with the same behavior later observed through the application and library facade equivalence tests. @@ -66,6 +67,18 @@ In this example, parsing and async runtime wiring are separated cleanly. And the returned logger can immediately be started with `run()`. +#### When Need A Per-call Target Override After Typed Async Build + +When typed async config should still build a logger that supports a one-call target override: +```moonbit +let logger = build_async_logger(config) +logger.log(@bitlogger.Level::Error, "boom", target="svc.audit") +``` + +In this example, the emitted record uses `svc.audit` for that call. + +And later `debug(...)`, `info(...)`, or `error(...)` calls still use the logger's stored target unless code derives another logger first with `with_target(...)` or `child(...)`. + #### When Need Runtime Sink Features After Async Build When the sink shape is configured but runtime features still matter: diff --git a/docs/api/build-library-async-logger.md b/docs/api/build-library-async-logger.md index 3252a05..665cf61 100644 --- a/docs/api/build-library-async-logger.md +++ b/docs/api/build-library-async-logger.md @@ -40,6 +40,7 @@ Detailed rules explaining key parameters and behaviors - The returned facade wraps the same underlying `AsyncLogger[@bitlogger.RuntimeSink]` value that `build_async_logger(...)` would produce directly. - The result keeps async lifecycle operations such as `run()` and `shutdown()` while narrowing the public shape. - The narrower facade does not change the underlying runtime-sink queue counters, failure state, sink shape, or runtime-dependent post-close behavior; it only hides the broader helper surface until `to_async_logger()` is used. +- The facade still preserves the underlying async target rules on its exposed write methods: `log(..., target=...)` can override the target for one call, while `info(...)`, `warn(...)`, and `error(...)` continue using the stored logger target unless the facade first derived another logger with `with_target(...)` or `child(...)`. - In the current direct builder coverage, unwrapping this facade produces the same async state snapshot, runtime-sink variant, queue counters, lifecycle flags, and failure fields as calling `build_async_logger(config)` directly. - That same unwrap also preserves file-backed runtime helpers on `RuntimeSink` values rather than replacing them with facade-specific behavior. - Async state helpers such as `pending_count()`, `dropped_count()`, `state()`, `wait_idle()`, and failure-status inspection remain on the underlying `AsyncLogger`, not on the returned facade itself. @@ -75,6 +76,18 @@ ignore(full.pending_count()) In this example, the library async facade is unwrapped before using async state helpers. +#### When Need A Per-call Target Override Through The Library Async Builder Facade + +When typed library async config should still build a facade that allows a one-call target override without unwrapping first: +```moonbit +let logger = build_library_async_logger(config) +logger.log(@bitlogger.Level::Error, "boom", target="lib.audit") +``` + +In this example, the emitted record uses `lib.audit` for that call. + +And later `info(...)`, `warn(...)`, or `error(...)` calls still use the facade's stored target unless code derives another facade first with `with_target(...)` or `child(...)`. + ### Error Case e.g.: