📝 clarify root context shape contrast

This commit is contained in:
Nanaloveyuki
2026-06-14 08:43:18 +08:00
parent c78669393c
commit 296901d2ba
2 changed files with 24 additions and 0 deletions
+12
View File
@@ -38,6 +38,7 @@ Detailed rules explaining key parameters and behaviors
- The current fields are `min_level : Level`, `sink : S`, `target : String`, and `timestamp : Bool`.
- The sink type parameter is preserved across composition, which is why helpers such as `with_context_fields(...)`, `with_filter(...)`, `with_patch(...)`, and `with_queue(...)` can return more specific logger shapes.
- The root logger also preserves the core target contract used across the sync API surface: `log(..., target=...)` can override the target for one call, while fixed-level helpers such as `trace(...)`, `debug(...)`, `info(...)`, `warn(...)`, and `error(...)` continue using the stored logger target unless code derives another logger first with `with_target(...)` or `child(...)`.
- In particular, synchronous `with_context_fields(...)` and `bind(...)` change the visible logger type to `Logger[ContextSink[S]]` because shared fields are implemented by extending the sink pipeline rather than by storing extra root-level context metadata on `Logger[S]` itself.
- `Logger::new(...)` constructs this type as the main synchronous entry point.
- This root type is also what sits underneath both facade families: `ApplicationLogger` is a direct alias over the configured `Logger[RuntimeSink]` line, while `LibraryLogger[S]` is a narrowing wrapper around a `Logger[S]` value.
@@ -65,6 +66,17 @@ In this example, the emitted record uses `app.audit` only for that one call.
And later `trace(...)`, `debug(...)`, `info(...)`, `warn(...)`, or `error(...)` calls still use the logger's stored target unless code derives another logger first with `with_target(...)` or `child(...)`.
#### When Need Shared Context On A Sync Root Logger
When sync code should attach stable metadata to later records:
```moonbit
let contextual = logger.with_context_fields([field("service", "billing")])
```
In this example, the returned value has the visible type `Logger[ContextSink[S]]`.
And that type change is expected because sync context binding extends the sink pipeline instead of only updating root-level metadata.
#### When Need To Build A Composed Logging Pipeline
When code should start from one root logger and then derive more specific wrapped forms: