From 3a68be920ef15ff898b130bf5eb01b636517cd97 Mon Sep 17 00:00:00 2001 From: Nanaloveyuki Date: Sun, 14 Jun 2026 01:14:45 +0800 Subject: [PATCH] :memo: clarify library logger wrapper docs --- docs/api/library-logger-new.md | 21 ++++++++++++++++++--- docs/api/library-logger-to-logger.md | 19 +++++++++++++++++-- docs/api/library-logger.md | 10 +++++++++- docs/api/logger-to-library-logger.md | 19 +++++++++++++++++-- 4 files changed, 61 insertions(+), 8 deletions(-) diff --git a/docs/api/library-logger-new.md b/docs/api/library-logger-new.md index 9b1e198..a6c5cdf 100644 --- a/docs/api/library-logger-new.md +++ b/docs/api/library-logger-new.md @@ -3,7 +3,7 @@ name: library-logger-new group: api category: facade update-time: 20260613 -description: Create a narrower sync library logger facade from any sink implementation. +description: Create a narrower sync library logger facade by building a regular logger and wrapping the same underlying state. key-word: - library - facade @@ -27,7 +27,7 @@ pub fn[S] LibraryLogger::new( #### input -- `sink : S` - Any sink value implementing `Sink`, such as `console_sink()` or a composed sink. +- `sink : S` - Underlying sink value that should receive writes, such as `console_sink()` or a composed sink. - `min_level : Level` - Minimum enabled level. Messages below this threshold are ignored. - `target : String` - Default target attached to emitted records unless later overridden. @@ -39,9 +39,10 @@ pub fn[S] LibraryLogger::new( Detailed rules explaining key parameters and behaviors -- This API builds a regular `Logger::new(...)` internally and then wraps it as `LibraryLogger`. +- This API builds a regular `Logger::new(...)` internally and then wraps that same value as `LibraryLogger`. - The returned facade intentionally exposes a smaller method set than the full `Logger[S]` type. - The original sink type is still preserved in `LibraryLogger[S]`. +- This constructor does not add timestamps, filters, patches, or extra sink wrappers by itself; it only creates the base sync logger and narrows its public surface. - Call `to_logger()` if later code must recover the full sync logger surface. ### How to Use @@ -67,6 +68,16 @@ let logger = LibraryLogger::new(text_console_sink(text_formatter()), target="wor In this example, sink typing remains explicit while the consumer only sees the library facade. +#### When Need Full Logger Composition Later + +When library-facing construction should still allow later access to broader sync composition helpers: +```moonbit +let logger = LibraryLogger::new(console_sink(), target="lib") +let full = logger.to_logger().with_timestamp() +``` + +In this example, construction starts from the narrower facade, but the same underlying logger can still be recovered and extended later. + ### Error Case e.g.: @@ -74,8 +85,12 @@ e.g.: - If later code needs methods outside the facade, it must unwrap with `to_logger()`. +- If callers want additional wrappers such as timestamps, filters, patches, or queued/context sink layers immediately, they must apply those through the full `Logger[S]` surface or the dedicated facade helpers. + ### Notes 1. This is the direct constructor counterpart to `Logger::new(...)` for library-oriented APIs. 2. Prefer this when public package boundaries should stay narrower than `Logger[S]`. + +3. Use `Logger::new(...)` directly when the full sync composition surface should remain public from the start. diff --git a/docs/api/library-logger-to-logger.md b/docs/api/library-logger-to-logger.md index 3a977d9..e726c74 100644 --- a/docs/api/library-logger-to-logger.md +++ b/docs/api/library-logger-to-logger.md @@ -3,7 +3,7 @@ name: library-logger-to-logger group: api category: facade update-time: 20260613 -description: Recover the underlying full sync logger from the library-facing sync facade. +description: Recover the underlying full sync logger from the library-facing sync facade without rebuilding sink or logger composition state. key-word: - logger - library @@ -34,8 +34,9 @@ pub fn[S] LibraryLogger::to_logger(self : LibraryLogger[S]) -> Logger[S] {} Detailed rules explaining key parameters and behaviors - This conversion unwraps the existing logger instead of rebuilding it. -- Sink wiring, target, min level, and attached wrappers remain the same. +- Sink wiring, target, min level, timestamp behavior, and attached wrappers remain the same. - Use this when code needs full-surface APIs such as `with_timestamp(...)`, `with_filter(...)`, or `with_patch(...)`. +- This is also the step required for configured-runtime helpers such as `flush()`, `drain()`, `pending_count()`, or file controls when the wrapped sink is `RuntimeSink`. ### How to Use @@ -51,6 +52,16 @@ let full_logger = library_logger.to_logger().with_timestamp() In this example, the facade is unwrapped so the caller can access full logger composition APIs again. +#### When Need Runtime Helpers After Library-oriented Config Build + +When a library-facing runtime logger should later expose configured runtime controls internally: +```moonbit +let full = logger.to_logger() +ignore(full.pending_count()) +``` + +In this example, unwrapping exposes the broader configured-runtime helper surface on the same underlying logger state. + ### Error Case e.g.: @@ -58,8 +69,12 @@ e.g.: - Unwrapping does not change the current target or sink behavior by itself. +- Recovering the full logger does not rebuild or reset the existing sink wrappers. + ### Notes 1. Use this only when the narrower facade is no longer sufficient. 2. This is the inverse projection of `Logger::to_library_logger()`. + +3. Use `LibraryLogger[S]` directly when the narrower package-facing surface is still sufficient. diff --git a/docs/api/library-logger.md b/docs/api/library-logger.md index b6c4abd..5441d68 100644 --- a/docs/api/library-logger.md +++ b/docs/api/library-logger.md @@ -3,7 +3,7 @@ name: library-logger group: api category: facade update-time: 20260613 -description: Public library-facing sync logger facade type used to expose a narrower surface than Logger while preserving sink typing. +description: Public library-facing sync logger facade type used to expose a narrower surface than Logger while preserving the wrapped logger state. key-word: - library - logger @@ -34,7 +34,9 @@ Detailed rules explaining key parameters and behaviors - This is a public facade struct, not a type alias. - The wrapped sink type `S` is preserved, so sink-specific typing remains available through the facade type parameter. - The facade keeps common library-safe operations such as `new(...)`, `with_target(...)`, `child(...)`, `bind(...)`, `is_enabled(...)`, and the main write methods `log(...)`, `info(...)`, `warn(...)`, and `error(...)`. +- The facade wraps the same underlying `Logger[S]` value rather than copying or rebuilding it. - It does not expose the wider `Logger[S]` composition surface or `ConfiguredLogger` runtime helper methods directly. +- Most facade reshaping helpers keep the same visible sink type, but `with_context_fields(...)` and `bind(...)` intentionally return `LibraryLogger[ContextSink[S]]` because they extend the sink pipeline. - Call `to_logger()` when later code must recover the full underlying `Logger[S]` surface. ### How to Use @@ -60,6 +62,8 @@ full.info("started") In this example, the facade can be unwrapped when broader logger operations are needed internally. +And the unwrapped value still carries the same target and sink pipeline that existed behind the library facade. + ### Error Case e.g.: @@ -69,8 +73,12 @@ e.g.: - If the wrapped sink type is `RuntimeSink`, queue and file runtime helpers still exist on the underlying logger but are not callable through `LibraryLogger[RuntimeSink]` unless it is unwrapped with `to_logger()`. +- If callers need direct composition helpers such as `with_timestamp(...)`, `with_filter(...)`, or `with_patch(...)`, they must unwrap first with `to_logger()`. + ### Notes 1. Use `LibraryLogger::new(...)`, `build_library_logger(...)`, or `parse_and_build_library_logger(...)` when you need a value of this type. 2. Use `Logger[S]` directly when exposing the full sync composition surface is acceptable. + +3. Use `to_logger()` when internal code later needs broader composition or runtime-helper access without changing the public facade type. diff --git a/docs/api/logger-to-library-logger.md b/docs/api/logger-to-library-logger.md index eb8ed9b..db48ec9 100644 --- a/docs/api/logger-to-library-logger.md +++ b/docs/api/logger-to-library-logger.md @@ -3,7 +3,7 @@ name: logger-to-library-logger group: api category: facade update-time: 20260613 -description: Convert a full sync logger into the narrower library-facing sync facade. +description: Convert a full sync logger into the narrower library-facing sync facade without rebuilding the underlying logger state. key-word: - logger - library @@ -34,8 +34,9 @@ pub fn[S] Logger::to_library_logger(self : Logger[S]) -> LibraryLogger[S] {} Detailed rules explaining key parameters and behaviors - This conversion does not rebuild the sink or change the logger configuration. -- Target, min level, timestamp behavior, and sink wiring are preserved. +- Target, min level, timestamp behavior, and sink wiring are preserved because the same underlying logger value is wrapped. - The returned facade keeps library-oriented write APIs such as `info(...)`, `warn(...)`, and `error(...)`. +- Broader sync composition helpers remain on the underlying `Logger[S]` and are intentionally hidden until `to_logger()` is used again. ### How to Use @@ -51,6 +52,16 @@ let public_logger = logger.to_library_logger() In this example, `public_logger` keeps the same logging behavior but exposes the library facade. +#### When Need To Narrow Surface Without Resetting Logger Composition + +When an already-shaped logger should be projected to a library boundary without losing its current wrappers: +```moonbit +let full = Logger::new(console_sink(), target="lib").with_timestamp() +let public_logger = full.to_library_logger() +``` + +In this example, the projection changes the exposed type only; it does not remove the existing timestamp behavior or other logger state. + ### Error Case e.g.: @@ -58,8 +69,12 @@ e.g.: - The conversion does not remove existing target or field bindings from the original logger. +- If callers later need composition helpers such as `with_timestamp(...)`, `with_filter(...)`, or `with_patch(...)`, they must unwrap again with `to_logger()`. + ### Notes 1. Use this when library boundaries should avoid exposing the full sync logger surface. 2. This is a projection API, not a copy or rebuild step. + +3. Use `build_library_logger(...)` or `parse_and_build_library_logger(...)` when construction and narrowing should happen together from config.