📝 refine library logger write docs

This commit is contained in:
Nanaloveyuki
2026-06-14 01:18:33 +08:00
parent 15a9175cf4
commit 888be5b6fc
5 changed files with 60 additions and 11 deletions
+9 -2
View File
@@ -3,7 +3,7 @@ name: library-logger-error
group: api group: api
category: facade category: facade
update-time: 20260613 update-time: 20260613
description: Emit an error-level record through a LibraryLogger facade using the highest built-in severity shortcut. description: Emit an error-level record through a LibraryLogger facade by delegating to the wrapped logger's error shortcut.
key-word: key-word:
- library - library
- facade - facade
@@ -39,10 +39,11 @@ pub fn[S : Sink] LibraryLogger::error(
Detailed rules explaining key parameters and behaviors Detailed rules explaining key parameters and behaviors
- This helper delegates to `log(Level::Error, ...)` on the wrapped logger. - This helper delegates to `error(...)` on the wrapped logger, which in turn uses `log(Level::Error, ...)`.
- `Error` is the highest built-in severity in this sync facade API. - `Error` is the highest built-in severity in this sync facade API.
- Per-call target override is not exposed here; use `log(...)` when explicit target control is required. - Per-call target override is not exposed here; use `log(...)` when explicit target control is required.
- Sink composition, filtering, patching, and queue wrappers still apply normally. - Sink composition, filtering, patching, and queue wrappers still apply normally.
- Broader composition helpers remain on the underlying `Logger[S]` and require `to_logger()` first.
### How to Use ### How to Use
@@ -66,6 +67,8 @@ logger.error("dispatch failed", fields=[field("job_id", "42")])
In this example, the record carries machine-readable context without dropping to the generic `log(...)` form. In this example, the record carries machine-readable context without dropping to the generic `log(...)` form.
And any shared context already carried by the facade still participates through the wrapped logger pipeline.
### Error Case ### Error Case
e.g.: e.g.:
@@ -73,8 +76,12 @@ e.g.:
- If a target override is required, use `log(...)` instead of this severity shortcut. - If a target override is required, use `log(...)` instead of this severity shortcut.
- If callers need broader composition helpers after logging, they must unwrap first with `to_logger()`.
### Notes ### Notes
1. Use this helper for high-severity library failures. 1. Use this helper for high-severity library failures.
2. Emitting an error record is separate from throwing or handling program exceptions. 2. Emitting an error record is separate from throwing or handling program exceptions.
3. Use `log(...)` instead when the call site needs a per-call target override or a dynamic level.
+10 -2
View File
@@ -3,7 +3,7 @@ name: library-logger-info
group: api group: api
category: facade category: facade
update-time: 20260613 update-time: 20260613
description: Emit an info-level record through a LibraryLogger facade using the informational severity shortcut. description: Emit an info-level record through a LibraryLogger facade by delegating to the wrapped logger's info shortcut.
key-word: key-word:
- library - library
- facade - facade
@@ -39,10 +39,12 @@ pub fn[S : Sink] LibraryLogger::info(
Detailed rules explaining key parameters and behaviors Detailed rules explaining key parameters and behaviors
- This helper delegates to `log(Level::Info, ...)` on the wrapped logger. - This helper delegates to `info(...)` on the wrapped logger, which in turn uses `log(Level::Info, ...)`.
- `Info` is the default minimum logger threshold unless changed explicitly. - `Info` is the default minimum logger threshold unless changed explicitly.
- Per-call target override is not exposed here; use `log(...)` if needed. - Per-call target override is not exposed here; use `log(...)` if needed.
- Any existing sink wrappers inside the logger pipeline still participate normally in the write path.
- The library facade keeps the same write semantics while exposing a smaller public surface. - The library facade keeps the same write semantics while exposing a smaller public surface.
- Broader composition helpers remain on the underlying `Logger[S]` and require `to_logger()` first.
### How to Use ### How to Use
@@ -66,6 +68,8 @@ logger.info("request completed", fields=[field("status", "200")])
In this example, the event remains concise while still carrying useful fields. In this example, the event remains concise while still carrying useful fields.
And any shared context already carried by the facade still participates through the wrapped logger pipeline.
### Error Case ### Error Case
e.g.: e.g.:
@@ -73,8 +77,12 @@ e.g.:
- If the event needs an explicit alternate target, use `log(...)` instead of this shortcut. - If the event needs an explicit alternate target, use `log(...)` instead of this shortcut.
- If callers need broader composition helpers after logging, they must unwrap first with `to_logger()`.
### Notes ### Notes
1. This is the common convenience method for normal library-facing events. 1. This is the common convenience method for normal library-facing events.
2. Because `Info` is often the default threshold, this helper is a natural baseline for facade examples. 2. Because `Info` is often the default threshold, this helper is a natural baseline for facade examples.
3. Use `log(...)` instead when the call site needs a per-call target override or a dynamic level.
+10 -3
View File
@@ -3,7 +3,7 @@ name: library-logger-is-enabled
group: api group: api
category: facade category: facade
update-time: 20260613 update-time: 20260613
description: Check whether a LibraryLogger facade would accept a record at a given level. description: Check whether a LibraryLogger facade passes the wrapped logger's min-level gate for a given severity.
key-word: key-word:
- library - library
- facade - facade
@@ -35,8 +35,9 @@ pub fn[S] LibraryLogger::is_enabled(self : LibraryLogger[S], level : Level) -> B
Detailed rules explaining key parameters and behaviors Detailed rules explaining key parameters and behaviors
- This method delegates directly to the wrapped logger's `is_enabled(...)` behavior. - This method delegates directly to the wrapped logger's `is_enabled(...)` behavior.
- It only checks logger-level severity gating; it does not evaluate sink filters or patch logic. - It only checks logger-level severity gating through `min_level`; it does not evaluate later sink filters, patch logic, or any sink-side buffering/wrapping behavior.
- The result reflects the current facade value, so derived facades with different thresholds can return different answers. - The result reflects the current wrapped logger state, so derived facades with different thresholds can return different answers.
- This check does not require unwrapping because it is part of the narrower library-facing surface.
- Use it when message construction or field gathering is expensive enough to justify a pre-check. - Use it when message construction or field gathering is expensive enough to justify a pre-check.
### How to Use ### How to Use
@@ -65,6 +66,8 @@ if logger.is_enabled(Level::Info) {
In this example, the check mirrors the same severity gate used by later write calls. In this example, the check mirrors the same severity gate used by later write calls.
And a `true` result still means only that the level gate passed, not that the record is guaranteed to survive later sink-side filtering or routing.
### Error Case ### Error Case
e.g.: e.g.:
@@ -72,8 +75,12 @@ e.g.:
- A `true` result does not guarantee final sink output if later filter logic rejects the record. - A `true` result does not guarantee final sink output if later filter logic rejects the record.
- If callers need broader composition helpers rather than just the level gate, they must unwrap first with `to_logger()`.
### Notes ### Notes
1. This is a cheap severity check, not a full end-to-end delivery guarantee. 1. This is a cheap severity check, not a full end-to-end delivery guarantee.
2. Prefer using it only when precomputing the log payload is meaningfully expensive. 2. Prefer using it only when precomputing the log payload is meaningfully expensive.
3. Use `log(...)` or the severity shortcuts directly when no expensive precomputation needs to be avoided.
+21 -1
View File
@@ -3,7 +3,7 @@ name: library-logger-log
group: api group: api
category: facade category: facade
update-time: 20260613 update-time: 20260613
description: Emit a record through a LibraryLogger facade with explicit level, message, fields, and optional target override. description: Emit a record through a LibraryLogger facade with explicit level, message, fields, and optional target override by delegating to the wrapped logger.
key-word: key-word:
- library - library
- facade - facade
@@ -46,7 +46,9 @@ Detailed rules explaining key parameters and behaviors
- This method delegates directly to the wrapped logger's `log(...)` behavior. - This method delegates directly to the wrapped logger's `log(...)` behavior.
- The logger checks `is_enabled(level)` before building and writing the record. - The logger checks `is_enabled(level)` before building and writing the record.
- If `target` is empty, the facade's stored default target is used. - If `target` is empty, the facade's stored default target is used.
- Any existing sink wrappers already inside the wrapped logger, such as `ContextSink`, `FilterSink`, `PatchSink`, or queued/runtime sink variants, still participate normally in the write path.
- The narrower library facade does not change record construction semantics; it only limits the visible API surface. - The narrower library facade does not change record construction semantics; it only limits the visible API surface.
- Broader composition helpers remain on the underlying `Logger[S]` and require `to_logger()` first.
### How to Use ### How to Use
@@ -77,6 +79,20 @@ fn log_retry(logger : LibraryLogger[ConsoleSink], attempt : Int) -> Unit {
In this example, `log(...)` acts as the shared primitive under custom library-facing wrappers. In this example, `log(...)` acts as the shared primitive under custom library-facing wrappers.
#### When Need Shared Context Plus Event-specific Fields
When a facade already carries shared context but one write needs extra detail:
```moonbit
let logger = base.with_context_fields([field("service", "cache")])
logger.log(
Level::Info,
"entry refreshed",
fields=[field("key", "user:42")],
)
```
In this example, both the stored shared context and the per-call fields still flow through the wrapped logger pipeline.
### Error Case ### Error Case
e.g.: e.g.:
@@ -84,8 +100,12 @@ e.g.:
- If `target` is empty and the logger default target is also empty, the emitted record simply has no target label. - If `target` is empty and the logger default target is also empty, the emitted record simply has no target label.
- If callers need broader composition helpers after writing, they must unwrap first with `to_logger()`.
### Notes ### Notes
1. Use this API when the call site needs full control instead of a fixed-severity helper. 1. Use this API when the call site needs full control instead of a fixed-severity helper.
2. The facade remains synchronous; any buffering behavior only comes from the wrapped sink type. 2. The facade remains synchronous; any buffering behavior only comes from the wrapped sink type.
3. Use the optional `target` argument when one write should temporarily override the facade's default target without rebuilding or rewrapping it.
+10 -3
View File
@@ -3,7 +3,7 @@ name: library-logger-warn
group: api group: api
category: facade category: facade
update-time: 20260613 update-time: 20260613
description: Emit a warn-level record through a LibraryLogger facade using the warning severity shortcut. description: Emit a warn-level record through a LibraryLogger facade by delegating to the wrapped logger's warn shortcut.
key-word: key-word:
- library - library
- facade - facade
@@ -39,10 +39,11 @@ pub fn[S : Sink] LibraryLogger::warn(
Detailed rules explaining key parameters and behaviors Detailed rules explaining key parameters and behaviors
- This helper delegates to `log(Level::Warn, ...)` on the wrapped logger. - This helper delegates to `warn(...)` on the wrapped logger, which in turn uses `log(Level::Warn, ...)`.
- Warning records are useful for abnormal but non-fatal conditions. - Warning records are useful for abnormal but non-fatal conditions.
- Per-call target override is not exposed here; use `log(...)` when that is required. - Per-call target override is not exposed here; use `log(...)` when that is required.
- All logger wrappers still participate normally in the write path. - All sink-side wrappers still participate normally in the write path.
- Broader composition helpers remain on the underlying `Logger[S]` and require `to_logger()` first.
### How to Use ### How to Use
@@ -66,6 +67,8 @@ logger.warn("retry scheduled", fields=[field("attempt", "3")])
In this example, the warning remains easy to filter and inspect later. In this example, the warning remains easy to filter and inspect later.
And any shared context already carried by the facade still participates through the wrapped logger pipeline.
### Error Case ### Error Case
e.g.: e.g.:
@@ -73,8 +76,12 @@ e.g.:
- If a target override is needed at this call site, use `log(...)` instead of this shortcut. - If a target override is needed at this call site, use `log(...)` instead of this shortcut.
- If callers need broader composition helpers after logging, they must unwrap first with `to_logger()`.
### Notes ### Notes
1. Use this helper for degraded or suspicious states that do not stop execution. 1. Use this helper for degraded or suspicious states that do not stop execution.
2. Warning logs are often a practical signal threshold for alerting or separate routing. 2. Warning logs are often a practical signal threshold for alerting or separate routing.
3. Use `log(...)` instead when the call site needs a per-call target override or a dynamic level.