📝 Add logger write API docs

This commit is contained in:
Nanaloveyuki
2026-05-12 16:06:00 +08:00
parent 474a1931c2
commit 661c17e093
9 changed files with 647 additions and 0 deletions
+11
View File
@@ -23,10 +23,21 @@ BitLogger API navigation.
- [logger-with-min-level.md](./logger-with-min-level.md) - [logger-with-min-level.md](./logger-with-min-level.md)
- [logger-with-timestamp.md](./logger-with-timestamp.md) - [logger-with-timestamp.md](./logger-with-timestamp.md)
- [logger-with-context-fields.md](./logger-with-context-fields.md) - [logger-with-context-fields.md](./logger-with-context-fields.md)
- [logger-bind.md](./logger-bind.md)
- [logger-with-filter.md](./logger-with-filter.md) - [logger-with-filter.md](./logger-with-filter.md)
- [logger-with-patch.md](./logger-with-patch.md) - [logger-with-patch.md](./logger-with-patch.md)
- [logger-with-queue.md](./logger-with-queue.md) - [logger-with-queue.md](./logger-with-queue.md)
## Logger write APIs
- [logger-is-enabled.md](./logger-is-enabled.md)
- [logger-log.md](./logger-log.md)
- [logger-trace.md](./logger-trace.md)
- [logger-debug.md](./logger-debug.md)
- [logger-info.md](./logger-info.md)
- [logger-warn.md](./logger-warn.md)
- [logger-error.md](./logger-error.md)
## Formatter and fields ## Formatter and fields
- [text-formatter.md](./text-formatter.md) - [text-formatter.md](./text-formatter.md)
+79
View File
@@ -0,0 +1,79 @@
---
name: logger-bind
group: api
category: logging
update-time: 20260512
description: Attach reusable structured fields to a logger through the bind alias.
key-word:
- logger
- bind
- fields
- public
---
## Logger-bind
Attach shared structured fields to a logger through the `bind(...)` alias. This API is behaviorally identical to `with_context_fields(...)` and exists as a shorter name for common structured context binding.
### Interface
```moonbit
pub fn[S] Logger::bind(self : Logger[S], fields : Array[Field]) -> Logger[ContextSink[S]] {}
```
#### input
- `self : Logger[S]` - Base logger that should gain shared fields.
- `fields : Array[Field]` - Structured fields attached to every emitted record.
#### output
- `Logger[ContextSink[S]]` - New logger wrapper that prepends shared fields at write time.
### Explanation
Detailed rules explaining key parameters and behaviors
- `bind(...)` delegates directly to `with_context_fields(...)`.
- The original logger value is not mutated; a wrapped logger is returned.
- Shared fields are applied to every later log call emitted through the returned logger.
- This alias is useful when you prefer shorter chaining syntax in application code.
### How to Use
Here are some specific examples provided.
#### When Bind Shared Request Context
When a logger should carry stable fields through a flow:
```moonbit
let request_logger = Logger::new(console_sink(), target="api")
.bind([field("request_id", "req-42")])
```
In this example, subsequent writes automatically include `request_id`.
#### When Prefer Shorter Chaining Syntax
When a context-bound child logger should stay readable:
```moonbit
let worker = Logger::new(console_sink(), target="app")
.child("worker")
.bind([field("component", "worker")])
```
In this example, `bind(...)` communicates intent without changing underlying behavior.
### Error Case
e.g.:
- If `fields` is empty, the returned logger remains valid and simply adds no extra metadata.
- If duplicate field keys are bound, all copies are preserved for downstream formatting or inspection.
### Notes
1. Use `bind(...)` and `with_context_fields(...)` interchangeably; choose the one that reads better in context.
2. This alias exists for ergonomics, not for different semantics.
+77
View File
@@ -0,0 +1,77 @@
---
name: logger-debug
group: api
category: logging
update-time: 20260512
description: Emit a debug-level record through the logger using the debug severity shortcut.
key-word:
- logger
- debug
- sync
- public
---
## Logger-debug
Emit a debug-level record through the synchronous logger. This is the convenience wrapper for `log(Level::Debug, ...)`.
### Interface
```moonbit
pub fn[S : Sink] Logger::debug(self : Logger[S], message : String, fields~ : Array[Field] = []) -> Unit {}
```
#### input
- `self : Logger[S]` - Logger that should emit the debug record.
- `message : String` - Debug message text.
- `fields : Array[Field]` - Optional structured fields attached to the record.
#### output
- `Unit` - No return value. The record is handled according to the logger threshold and sink pipeline.
### Explanation
Detailed rules explaining key parameters and behaviors
- This helper delegates to `log(Level::Debug, ...)`.
- Debug logging is useful for development diagnostics that are usually too verbose for normal production visibility.
- Per-call target override is not exposed here; use `log(...)` for that level of control.
- All logger wrappers remain active exactly as they would for the base `log(...)` path.
### How to Use
Here are some specific examples provided.
#### When Need Internal State Diagnostics
When implementation details should be observable during debugging:
```moonbit
logger.debug("cache refreshed")
```
In this example, the call site signals a development-focused diagnostic event.
#### When Attach Structured Debug Fields
When a debug event should carry explicit state:
```moonbit
logger.debug("session loaded", fields=[field("user_id", "42")])
```
In this example, the logger emits structured state without using the fully explicit `log(...)` form.
### Error Case
e.g.:
- If the logger minimum level is above `Debug`, the call returns without writing a record.
- If the event needs a custom target override, use `log(...)` instead of this shortcut.
### Notes
1. Prefer this helper when debug intent is more readable than a raw `log(Level::Debug, ...)` call.
2. Use `is_enabled(Level::Debug)` when building the debug payload is expensive.
+77
View File
@@ -0,0 +1,77 @@
---
name: logger-error
group: api
category: logging
update-time: 20260512
description: Emit an error-level record through the logger using the highest built-in severity shortcut.
key-word:
- logger
- error
- sync
- public
---
## Logger-error
Emit an error-level record through the synchronous logger. This is the convenience wrapper for `log(Level::Error, ...)`.
### Interface
```moonbit
pub fn[S : Sink] Logger::error(self : Logger[S], message : String, fields~ : Array[Field] = []) -> Unit {}
```
#### input
- `self : Logger[S]` - Logger that should emit the error record.
- `message : String` - Error message text.
- `fields : Array[Field]` - Optional structured fields attached to the record.
#### output
- `Unit` - No return value. The record is handled according to the logger threshold and sink pipeline.
### Explanation
Detailed rules explaining key parameters and behaviors
- This helper delegates to `log(Level::Error, ...)`.
- `Error` is the highest built-in severity in this sync logger API.
- 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.
### How to Use
Here are some specific examples provided.
#### When Report A Failing Operation
When an operation should emit a high-severity failure event:
```moonbit
logger.error("worker execution failed")
```
In this example, the call site clearly communicates failure severity.
#### When Attach Structured Error Context
When an error event should include diagnostic fields:
```moonbit
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.
### Error Case
e.g.:
- If the logger minimum level is above `Error`, the call still returns without writing, though this configuration is unusual.
- If a target override is required, use `log(...)` instead of this severity shortcut.
### Notes
1. Use this helper for high-severity application failures.
2. Emitting an error record is separate from throwing or handling program exceptions.
+77
View File
@@ -0,0 +1,77 @@
---
name: logger-info
group: api
category: logging
update-time: 20260512
description: Emit an info-level record through the logger using the standard informational severity shortcut.
key-word:
- logger
- info
- sync
- public
---
## Logger-info
Emit an info-level record through the synchronous logger. This is the convenience wrapper for `log(Level::Info, ...)`.
### Interface
```moonbit
pub fn[S : Sink] Logger::info(self : Logger[S], message : String, fields~ : Array[Field] = []) -> Unit {}
```
#### input
- `self : Logger[S]` - Logger that should emit the info record.
- `message : String` - Informational message text.
- `fields : Array[Field]` - Optional structured fields attached to the record.
#### output
- `Unit` - No return value. The record is handled according to the logger threshold and sink pipeline.
### Explanation
Detailed rules explaining key parameters and behaviors
- This helper delegates to `log(Level::Info, ...)`.
- `Info` is the default minimum logger threshold unless changed explicitly.
- Per-call target override is not exposed here; use `log(...)` if needed.
- Context fields, filters, patches, and queue wrappers behave exactly as they do for other write methods.
### How to Use
Here are some specific examples provided.
#### When Emit Normal Application Events
When a service should report standard lifecycle milestones:
```moonbit
logger.info("service started")
```
In this example, the log event uses the normal informational severity.
#### When Attach Structured Informational Context
When an info event should include machine-readable metadata:
```moonbit
logger.info("request completed", fields=[field("status", "200")])
```
In this example, the event remains concise while still carrying useful fields.
### Error Case
e.g.:
- If the logger minimum level is above `Info`, the call returns without writing a record.
- If the event needs an explicit alternate target, use `log(...)` instead of this shortcut.
### Notes
1. This is the most common convenience method for normal application events.
2. Because `Info` is often the default threshold, this helper is a common baseline for examples and docs.
+80
View File
@@ -0,0 +1,80 @@
---
name: logger-is-enabled
group: api
category: logging
update-time: 20260512
description: Check whether a logger would accept a record at a given level.
key-word:
- logger
- level
- enabled
- public
---
## Logger-is-enabled
Check whether a logger would accept a record at the given level based on its current `min_level`. This API is useful for gating expensive work before building message text or fields.
### Interface
```moonbit
pub fn[S] Logger::is_enabled(self : Logger[S], level : Level) -> Bool {}
```
#### input
- `self : Logger[S]` - Logger whose current minimum level should be checked.
- `level : Level` - Candidate severity to test.
#### output
- `Bool` - `true` when the level is enabled by the logger's current threshold.
### Explanation
Detailed rules explaining key parameters and behaviors
- This method delegates to `level.enabled(self.min_level)`.
- It only checks logger-level severity gating; it does not evaluate sink filters or patch logic.
- The result reflects the current logger value, so derived loggers with different `min_level` settings can return different answers.
- Use it when message construction or field gathering is expensive enough to justify a pre-check.
### How to Use
Here are some specific examples provided.
#### When Avoid Expensive Debug Preparation
When debug data should only be built if needed:
```moonbit
if logger.is_enabled(Level::Debug) {
logger.debug(build_debug_snapshot())
}
```
In this example, expensive string construction is skipped unless debug logging is enabled.
#### When Inspect Effective Logger Threshold
When code should branch based on current logger behavior:
```moonbit
if logger.is_enabled(Level::Trace) {
logger.trace("trace path active")
}
```
In this example, the check mirrors the same severity gate used by `log(...)`.
### Error Case
e.g.:
- If `level` is below the current minimum threshold, the method returns `false`.
- A `true` result does not guarantee final sink output if later filter logic rejects the record.
### Notes
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.
+92
View File
@@ -0,0 +1,92 @@
---
name: logger-log
group: api
category: logging
update-time: 20260512
description: Emit a record through the logger with an explicit level, message, optional fields, and optional target override.
key-word:
- logger
- log
- sync
- public
---
## Logger-log
Emit a record through the synchronous logger with an explicit level and message. This is the core write API behind all level-specific convenience methods.
### Interface
```moonbit
pub fn[S : Sink] Logger::log(
self : Logger[S],
level : Level,
message : String,
fields~ : Array[Field] = [],
target? : String = "",
) -> Unit {}
```
#### input
- `self : Logger[S]` - Logger that should emit the record.
- `level : Level` - Severity level for the record.
- `message : String` - Log message text.
- `fields : Array[Field]` - Optional structured fields attached to the record.
- `target : String` - Optional per-call target override.
#### output
- `Unit` - No return value. The record is either skipped by level gating or written to the sink pipeline.
### Explanation
Detailed rules explaining key parameters and behaviors
- The logger checks `is_enabled(level)` before building and writing the record.
- If `target` is empty, the logger's stored default target is used.
- If timestamping is enabled, `@env.now()` is captured and stored in the emitted record.
- Context, filter, patch, and queue wrappers act through the sink pipeline after the record is constructed.
### How to Use
Here are some specific examples provided.
#### When Need Full Per-call Control
When code should choose level, fields, and target explicitly:
```moonbit
logger.log(
Level::Info,
"worker started",
fields=[field("job", "sync")],
target="service.worker",
)
```
In this example, the call site controls every major record property.
#### When Build Higher-level Wrappers
When application code defines its own logging helpers:
```moonbit
fn log_retry(logger : Logger[ConsoleSink], attempt : Int) -> Unit {
logger.log(Level::Warn, "retry scheduled", fields=[field("attempt", attempt.to_string())])
}
```
In this example, `log(...)` acts as the shared primitive under custom wrappers.
### Error Case
e.g.:
- If `level` is below the current minimum threshold, the method returns without writing a record.
- If `target` is empty and the logger default target is also empty, the emitted record simply has no target label.
### Notes
1. Use this API when the call site needs full control instead of a fixed severity helper.
2. This method is synchronous; any buffering behavior only comes from the wrapped sink type.
+77
View File
@@ -0,0 +1,77 @@
---
name: logger-trace
group: api
category: logging
update-time: 20260512
description: Emit a trace-level record through the logger using the lowest built-in severity shortcut.
key-word:
- logger
- trace
- sync
- public
---
## Logger-trace
Emit a trace-level record through the synchronous logger. This is the convenience wrapper for `log(Level::Trace, ...)`.
### Interface
```moonbit
pub fn[S : Sink] Logger::trace(self : Logger[S], message : String, fields~ : Array[Field] = []) -> Unit {}
```
#### input
- `self : Logger[S]` - Logger that should emit the trace record.
- `message : String` - Trace message text.
- `fields : Array[Field]` - Optional structured fields attached to the record.
#### output
- `Unit` - No return value. The record is handled according to the logger threshold and sink pipeline.
### Explanation
Detailed rules explaining key parameters and behaviors
- This helper delegates to `log(Level::Trace, ...)`.
- Trace is the lowest built-in severity and is often disabled in production.
- Per-call target override is not exposed here; use `log(...)` if that is needed.
- Context, filtering, patching, and queue wrappers still apply through the logger sink chain.
### How to Use
Here are some specific examples provided.
#### When Need Low-level Execution Tracing
When fine-grained flow diagnostics are useful:
```moonbit
logger.trace("entered reconciliation step")
```
In this example, trace intent is explicit and concise.
#### When Attach Structured Trace Context
When a trace event should include fields:
```moonbit
logger.trace("cache probe", fields=[field("key", "user:42")])
```
In this example, trace output stays lightweight while still carrying structured detail.
### Error Case
e.g.:
- If the logger minimum level is above `Trace`, the call returns without writing a record.
- If a per-call target override is required, this helper is too narrow and `log(...)` should be used instead.
### Notes
1. Prefer this helper when trace intent is clearer than a raw `log(Level::Trace, ...)` call.
2. Very verbose trace logging can become expensive even in a synchronous pipeline.
+77
View File
@@ -0,0 +1,77 @@
---
name: logger-warn
group: api
category: logging
update-time: 20260512
description: Emit a warn-level record through the logger using the warning severity shortcut.
key-word:
- logger
- warn
- sync
- public
---
## Logger-warn
Emit a warn-level record through the synchronous logger. This is the convenience wrapper for `log(Level::Warn, ...)`.
### Interface
```moonbit
pub fn[S : Sink] Logger::warn(self : Logger[S], message : String, fields~ : Array[Field] = []) -> Unit {}
```
#### input
- `self : Logger[S]` - Logger that should emit the warning record.
- `message : String` - Warning message text.
- `fields : Array[Field]` - Optional structured fields attached to the record.
#### output
- `Unit` - No return value. The record is handled according to the logger threshold and sink pipeline.
### Explanation
Detailed rules explaining key parameters and behaviors
- This helper delegates to `log(Level::Warn, ...)`.
- Warning records are useful for abnormal but non-fatal conditions.
- Per-call target override is not exposed here; use `log(...)` when that is required.
- All logger wrappers still participate normally in the write path.
### How to Use
Here are some specific examples provided.
#### When Signal A Recoverable Problem
When an operation degraded but still continued:
```moonbit
logger.warn("cache miss ratio increased")
```
In this example, the event is elevated above normal information without being treated as a hard failure.
#### When Attach Structured Warning Context
When a warning should include machine-readable detail:
```moonbit
logger.warn("retry scheduled", fields=[field("attempt", "3")])
```
In this example, the warning remains easy to filter and inspect later.
### Error Case
e.g.:
- If the logger minimum level is above `Warn`, the call returns without writing a record.
- If a target override is needed at this call site, use `log(...)` instead of this shortcut.
### Notes
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.