Log4kLogger
A logger implementation that adapts the Log4k logging facade to a legacy abstract logger.
Every classic org.slf4j.Logger method is inherited from LegacyAbstractLogger/AbstractLogger and funnels into handleNormalizedLoggingCall. Deliberately not overriding the per-level methods is what gives us SLF4J's argument normalization for free — most importantly, extracting a trailing Throwable argument (log.error("failed for {}", id, e)) so it is attached to the event instead of being consumed as a formatting argument. The base class also short-circuits on isXxxEnabled() before normalizing, so disabled levels cost nothing.
Fluent-API calls (logger.atInfo().addKeyValue("tenant", "acme").log("…")) arrive through LoggingEventAware.log instead: SLF4J routes the fully built event here because this logger is LoggingEventAware, so the key-value pairs survive as the log4k event's tags — rather than being flattened into the message text by SLF4J's non-aware fallback.
A SourceLocation cannot be captured here at compile time — the SLF4J API transports no source location, and the log4k-compiler-plugin instruments log4k entry points only (walking the stack at runtime on every call is deliberately avoided). Instead, the bridge recovers one when the caller (or an upstream instrumentation) has recorded it under a known convention:
the OpenTelemetry code attributes —
code.file.path/code.line.number/code.function.name(the legacy spellingscode.filepath/code.lineno/code.function+code.namespaceare accepted as well);or logstash-logback-encoder's caller-data fields —
caller_file_name/caller_line_number/caller_method_name(+caller_class_name), the shape Logback-based JSON logs use.
The fluent event's key-value pairs are consulted first; pairs that formed the call site are consumed into it instead of being duplicated as tags. Otherwise the MDC is read — on the caller's thread, before the event enters log4k's asynchronous pipeline, so the propagated context is the caller's. The file key is required (without it no SourceLocation is built); the line and function are best-effort (0 / "" when absent).
Properties
Functions
The fluent-API path: forwards the built event's message, arguments, and throwable, and turns its key-value pairs into the log4k event's tags. A null key-value value is rendered as "null", since log4k tag values are non-null. Key-value pairs recorded under the OpenTelemetry code conventions become the event's SourceLocation (falling back to the MDC) and are consumed rather than kept as tags.