Logger
Logger[S] is the public synchronous root logger type. It stores a concrete sink type S together with minimum level, default target, and timestamp settings, then serves as the base value for typed composition helpers and write APIs.
Interface
pub struct Logger[S] {
min_level : Level
sink : S
target : String
timestamp : Bool
}output
Logger[S]- Public synchronous logger value parameterized by the concrete sink typeS.
Explanation
Detailed rules explaining key parameters and behaviors
- This is a public root struct, not a type alias.
- The current fields are
min_level : Level,sink : S,target : String, andtimestamp : Bool. - The sink type parameter is preserved across composition, which is why helpers such as
with_context_fields(...),with_filter(...),with_patch(...), andwith_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 astrace(...),debug(...),info(...),warn(...), anderror(...)continue using the stored logger target unless code derives another logger first withwith_target(...)orchild(...). - In particular, synchronous
with_context_fields(...)andbind(...)change the visible logger type toLogger[ContextSink[S]]because shared fields are implemented by extending the sink pipeline rather than by storing extra root-level context metadata onLogger[S]itself. Logger::new(...)constructs this type as the main synchronous entry point.- This root type is also what sits underneath both facade families:
ApplicationLoggeris a direct alias over the configuredLogger[RuntimeSink]line, whileLibraryLogger[S]is a narrowing wrapper around aLogger[S]value.
How to Use
Here are some specific examples provided.
When Need A Typed Root Logger Value
When synchronous logging should begin from a concrete sink-preserving root object:
let logger : Logger[ConsoleSink] = Logger::new(console_sink(), target="app")In this example, the root logger keeps the concrete console sink type visible for later typed composition.
When Need A One-call Target Override On The Root Logger
When sync code should keep one logger value but emit a single record under a different target:
logger.log(Level::Error, "boom", target="app.audit")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:
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:
let logger = Logger::new(console_sink(), min_level=Level::Info)
.with_timestamp()
.with_context_fields([field("service", "billing")])In this example, the root type becomes the stable base for later logging behavior changes.
Error Case
e.g.:
Logger[S]itself does not have a runtime failure mode.Actual write behavior still depends on the wrapped sink
S, so sink-specific limitations remain unchanged behind the logger type.
Notes
Use
Logger::new(...)when you need a value of this type in code.Use
ConfiguredLoggerwhen config-built runtime helpers should stay directly available on the returned logger value.Use
ApplicationLoggerwhen application code wants that same configured-runtime surface under an app-facing alias.Use
LibraryLogger[S]when a library boundary should intentionally narrow the public logger surface and expose broader composition only throughto_logger().