Build-logger
Build a ConfiguredLogger from LoggerConfig. This is the main config-to-runtime bridge for synchronous logging and is the builder used before async wrapping in config-driven async flows.
Interface
pub fn build_logger(config : LoggerConfig) -> ConfiguredLogger {}input
config : LoggerConfig- Fully assembled logger config including level, target, timestamp, sink, and optional queue wrapper.
output
ConfiguredLogger- A runtime logger backed byRuntimeSink, with queue and file control helpers preserved.
Explanation
Detailed rules explaining key parameters and behaviors
build_logger(...)first constructs a baseRuntimeSinkfromconfig.sink, then appliesconfig.queuewhen present, and finally buildsLogger::new(...)withconfig.min_level,config.target, andconfig.timestamp.- The returned logger still supports normal logging methods because
ConfiguredLoggerisLogger[RuntimeSink]. - The returned logger also keeps inherited logger target behavior such as
with_target(...),child(...), and per-calltarget=overrides onlog(...). - That means
log(..., target=...)can override the target for one write, while severity helpers such asinfo(...),warn(...), anderror(...)continue to use the stored logger target unless a derived logger was created first withwith_target(...)orchild(...). - Queue metrics and file controls remain available through forwarding helpers on the configured logger.
build_application_logger(...)only re-exports this same configured runtime logger result under theApplicationLoggeralias, whilebuild_library_logger(...)wraps the same result inLibraryLogger[RuntimeSink].- This API is deterministic and data-driven, making it suitable for bootstrapping from parsed config.
How to Use
Here are some specific examples provided.
When Need Structured Config-first Bootstrapping
When config is already assembled as typed values:
let logger = build_logger(
LoggerConfig::new(
min_level=Level::Info,
target="svc",
sink=SinkConfig::new(kind=SinkKind::TextConsole),
),
)In this example, no JSON parsing is required because config objects were built directly.
And the runtime logger is ready immediately, with the same ordinary logger target semantics as any other Logger value.
When Need A Per-call Target Override After Typed Config Build
When typed config should still build a logger that supports a one-write target override:
let logger = build_logger(config)
logger.log(Level::Error, "boom", target="svc.audit")In this example, the emitted record uses svc.audit for that write.
And later 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 Config-built Queue Or File Runtime Helpers
When the sink shape comes from config but runtime controls still matter:
let logger = build_logger(config)
ignore(logger.pending_count())
ignore(logger.file_runtime_state())In this example, config-driven construction does not remove observability or control helpers.
Error Case
e.g.:
If config contains a file sink on a non-native backend, callers must still respect backend capability behavior.
If queue is not configured, queue-related counters simply reflect the non-queued runtime shape.
Notes
Use this API when config is already typed as
LoggerConfig.Use
parse_and_build_logger(...)when the starting point is raw JSON text.Use the application or library facade builders only when the boundary name or exposed surface should differ; they do not change the underlying configured runtime logger pipeline built here.