Logger-with-context-fields
Bind shared structured fields to a logger. This is the standard way to attach stable metadata such as service name, component, region, request scope, or subsystem identity without repeating them for every log call.
Interface
pub fn[S] Logger::with_context_fields(self : Logger[S], fields : Array[Field]) -> Logger[ContextSink[S]] {}input
self : Logger[S]- The base logger that should gain shared fields.fields : Array[Field]- Structured fields that will be prepended to each emitted record.
output
Logger[ContextSink[S]]- A new logger wrapping the original sink with context-field merging behavior.
Explanation
Detailed rules explaining key parameters and behaviors
- Context fields are merged at write time, not by mutating previously created records.
- When a log call also passes per-record fields, the context fields are placed before those per-call fields.
- This API returns a new typed logger wrapper; it does not mutate the original logger variable.
- The returned logger keeps the same stored target, min level, and timestamp behavior while extending the sink pipeline with context-field merging.
bind(...)is an ergonomic alias for this same behavior.
How to Use
Here are some specific examples provided.
When Need Stable Service Metadata
When every record from a logger should carry service-level metadata:
let logger = Logger::new(console_sink(), target="billing")
.with_context_fields([field("service", "billing"), field("region", "cn")])
logger.info("started")In this example, both service and region are automatically included on every record.
And callers only need to provide fields that actually vary per event.
The original base logger value is still unchanged if later code keeps using it directly.
When Build Child Loggers For Subsystems
When a subsystem has both a target and fixed fields:
let worker = Logger::new(console_sink(), target="app")
.child("worker")
.with_context_fields([field("component", "worker")])In this example, target composition and field binding stay separate but work together cleanly.
Error Case
e.g.:
If
fieldsis empty, the logger remains valid and just adds no extra metadata.If duplicate field keys are provided, all fields are still emitted; conflict handling is left to the consumer/formatter side.
Notes
Use this for stable metadata, not highly dynamic event-specific values.
Prefer
fields([("k", "v")])when you want a more ergonomic call site.Use
bind(...)when you want the same behavior with a shorter, library-style call name.