--- name: library-async-logger-with-target group: api category: facade update-time: 20260614 description: Replace the default target carried by a LibraryAsyncLogger facade while rewrapping the derived async logger state behind the same library-facing surface. key-word: - async - library - facade - public --- ## Library-async-logger-with-target Replace the default target on a `LibraryAsyncLogger[S]`. This is the library-facing counterpart to `AsyncLogger::with_target(...)` when package code wants to retarget an async logger without exposing the full async logger API. ### Interface ```moonbit pub fn[S] LibraryAsyncLogger::with_target( self : LibraryAsyncLogger[S], target : String, ) -> LibraryAsyncLogger[S] { ``` #### input - `self : LibraryAsyncLogger[S]` - Base facade whose default target should be replaced. - `target : String` - New default target namespace. #### output - `LibraryAsyncLogger[S]` - New library-facing async facade carrying the updated target. ### Explanation Detailed rules explaining key parameters and behaviors - This API delegates to the wrapped async logger's `with_target(...)` behavior and then re-wraps the result as another `LibraryAsyncLogger[S]`. - The original facade is not mutated. The returned facade stores the replacement target while the source facade keeps its previous target. - Timestamp behavior, enabled-level gating, sink type, queue state, async config, and failure/lifecycle state stay the same because only the default target field changes. - This replaces the default target instead of composing it. - Async state helpers remain hidden behind the narrower facade after rewrapping; use `to_async_logger()` if later code needs them. ### How to Use Here are some specific examples provided. #### When Need A New Fixed Async Namespace Inside Library Code When one facade should emit under a different async target namespace: ```moonbit let logger = LibraryAsyncLogger::new(@bitlogger.console_sink()) .with_target("sdk.http") ``` In this example, later async writes inherit `sdk.http` unless a call overrides the target directly. #### When Reuse One Async Setup Across Library Subsystems When multiple library-facing async loggers should share one queue policy: ```moonbit let base = LibraryAsyncLogger::new( @bitlogger.console_sink(), config=AsyncLoggerConfig::new(max_pending=64), ) let cache = base.with_target("cache") let io = base.with_target("io") ``` In this example, one base facade becomes several target-specific async facades. And each derived facade still wraps the same kind of queue-backed async logger state, differing only in the default target it carries. The derived facade keeps the same timestamp and level-gating behavior as the source facade. ### Error Case e.g.: - If `target` is empty, the returned logger remains valid and later records simply use an empty default target. - If callers need hierarchical target composition rather than replacement, `child(...)` is the better API. ### Notes 1. Use this API for replacement, not target-path composition. 2. It keeps the narrower `LibraryAsyncLogger` boundary intact. 3. Use `child(...)` when the new target should be combined with the current one instead of replacing it.