Library-logger-with-context-fields
Bind shared structured fields to a LibraryLogger[S]. This is the library-facing API for attaching stable metadata such as component name, plugin id, or request scope without repeating those fields on every log call.
Interface
pub fn[S] LibraryLogger::with_context_fields(
self : LibraryLogger[S],
fields : Array[Field],
) -> LibraryLogger[ContextSink[S]] {input
self : LibraryLogger[S]- Base facade that should gain shared fields.fields : Array[Field]- Structured fields stored in the addedContextSinkand prepended to each emitted record.
output
LibraryLogger[ContextSink[S]]- New library-facing facade wrapping the original sink with context-field merging behavior.
Explanation
Detailed rules explaining key parameters and behaviors
- This API delegates to the wrapped logger's
with_context_fields(...)behavior and then narrows the result back toLibraryLogger. - Context fields are merged at write time rather than by mutating previously created records.
- The returned facade carries
ContextSink[S]because the sink pipeline is extended around the previous sink instead of keeping the original visible sink typeS. - Minimum level, target, and timestamp behavior are preserved while the sink pipeline changes from
StoContextSink[S]. - Broader composition helpers remain hidden behind the narrower facade after rewrapping; use
to_logger()if later code needs them. bind(...)is an ergonomic alias for this same behavior.
How to Use
Here are some specific examples provided.
When Need Stable Library Metadata On Every Record
When a package should attach fixed metadata to all emitted records:
let logger = default_library_logger()
.with_target("plugin")
.with_context_fields([field("plugin", "alpha"), field("region", "cn")])In this example, both fields are automatically included on every later write.
When Combine Target Scoping And Shared Fields
When a subsystem facade should carry both a target and stable context:
let worker = LibraryLogger::new(console_sink(), target="sdk")
.child("worker")
.with_context_fields([field("component", "worker")])In this example, target composition and field binding stay separate but compose cleanly.
And the returned facade keeps the same logger configuration while exposing the widened sink type ContextSink[S].
Error Case
e.g.:
If
fieldsis empty, the returned facade remains valid and simply stores an empty shared field set insideContextSink[S].If duplicate field keys are provided, all fields are still emitted for downstream formatting or inspection.
If callers want event-specific fields without changing the shared bound set, they should pass those through
log(..., fields=...)on the returned facade.
Notes
Use this for stable shared metadata, not highly dynamic event-specific values.
The narrower
LibraryLoggersurface is preserved after context binding, even though the visible sink type changes toContextSink[S].Use
bind(...)when the shorter alias reads better in chained library code.