Skip to content

Async-logger-with-patch

Attach a record patch to an async logger so each record is transformed before filtering and enqueue. This is the main API for async record rewriting without changing the sink implementation.

Interface

moonbit
pub fn[S] AsyncLogger::with_patch(
  self : AsyncLogger[S],
  patch : @bitlogger.RecordPatch,
) -> AsyncLogger[S] {}

input

  • self : AsyncLogger[S] - Base async logger to wrap.
  • patch : RecordPatch - Transformation applied to each record before enqueue.

output

  • AsyncLogger[S] - A new async logger value that rewrites each record before filtering and queue insertion.

Explanation

Detailed rules explaining key parameters and behaviors

  • Patch logic runs after record creation and field merging but before filtering and enqueue.
  • Existing patch logic is preserved and composed so the new patch wraps the current one.
  • The returned logger is derived from self; the original async logger value is not mutated.
  • Only the stored patch pipeline changes. Target, minimum level, queue configuration, and lifecycle/failure state stay on the same AsyncLogger[S] surface.
  • Patching can normalize, redact, or enrich records before they consume queue capacity.
  • In the current direct async coverage, patched target/message/field changes are visible to later filter logic, and the original async logger still emits unpatched records when used separately.

How to Use

Here are some specific examples provided.

When Need Async Record Enrichment

When records should gain stable extra data before enqueue:

moonbit
let logger = async_logger(console_sink())
  .with_patch(@bitlogger.append_fields([
    @bitlogger.field("channel", "async"),
  ]))

In this example, the added fields are part of the record before filtering and queue insertion.

And the returned async logger still keeps the same queue-facing API surface as the source logger.

When Need Redaction Before Queueing

When sensitive fields should be removed early:

moonbit
let logger = async_logger(console_sink())
  .with_patch(@bitlogger.redact_fields(["token", "password"]))

In this example, sensitive values are rewritten before they enter the async pipeline.

Error Case

e.g.:

  • If the patch removes or rewrites important data incorrectly, later filters and sinks will only see the patched version.

  • If callers need selection logic rather than transformation, with_filter(...) should be used instead.

Notes

  1. Use patches for transformation, not filtering decisions.

  2. Redaction before enqueue helps keep sensitive data out of the queued pipeline.

  3. State helpers such as pending_count(), dropped_count(), is_closed(), and has_failed() remain available on the returned logger because the visible async logger surface is preserved.

  4. Derive a patched logger when one path needs rewritten records and another should keep the original async record shape.

Published from the repository docs folder with VitePress.