Raman, would you mind sparing some cycles for the following question,
please?

---------- Forwarded message ---------
From: Hans <[email protected]>
Date: Mon, Jun 15, 2026 at 12:19 PM
Subject: [apache/logging-log4j2] No use of `inline` in `log4j-api-kotlin`?
(Discussion #4146)
To: apache/logging-log4j2 <[email protected]>
Cc: Subscribed <[email protected]>


As a preface, i will say that i am writing this here but I am not entirely
sure that this is the appropriate forum. It looks to me as if
log4j-api-kotlin is an independent project based on the fact that it is
hosted in a different github repo
<https://github.com/apache/logging-log4j-kotlin> and it is not included in
log4j-bom. *If this is not the correct forum, I would appreciate being
pointed in the right direction*. I didn't want to open an actual github
issue in the repo before even discussing this somewhere, but that repo
doesn't have discussions enabled, so I will use this one as fallback.
------------------------------

While i was experimenting with reactive spring, i added log4j's kotlin api,
which is supposed to use kotlin's super cool powers to make log4j more
kotlin idiomatic by moving lambdas to the last argument and promoting
string templates instead of log4j's template arguments.

Another of kotlin's powers is function call inlining. What i noticed,
though, is that none of the lambda based functions in KotlinLogger are
inline.

*Was this discussed at any point?* I cannot find any discussion or issues
related to this topic.

Designing KotlinLogger's lambda based functions to be inline would allow
things like suspending in the middle of the lambda. It might also make
these logs

I noticed this quirk when i wanted to log the current coroutine context.
The function currentCoroutineContext() from kotlinx-coroutines is a
suspending function, but the following code will not compile:

// this would be in a classsuspend fun fetchUser() {
    // logger is defined in the companion object, as recommended in the docs
    logger.info { "Context: ${currentCoroutineContext()" }
                 ^ compiler error}

The problem here is that, since the lambda passed to the info() method is
neither suspend nor inlined, you cannot call a suspending function inside
that lambda. Marking the lambda as suspend would not allow use in regular
non-suspend code.

This is because the implementation delegates to logIfEnabled, turning the
lambda reference into a org.apache.logging.log4j.util.Supplier. On the
other hand, if the info() method was redesigned to allow inlining, the
error would disappear. See this simple example:

inline fun info(supplier: () -> String) {
    if (delegate.isInfoEnabled)
        delegate.info(supplier())
}

With this change, the method call would be translated into the if statement
in the method body, and the call to the lambda would also be inlined.

This function:

fun main() {
    val logger = logger("com.example")
    logger.inlineInfo { "Message: ${expensiveOperation()}" }
}

Compiles into this code (decompiled with fernflower, slightly cleaned up
for readability)

public static final void main() {
    KotlinLogger logger = LoggingFactoryKt.logger("com.example");
    if (logger.getDelegate().isInfoEnabled()) {
         ExtendedLogger delegate = logger.getDelegate();
         delegate.info("Message: " + expensiveOperation());
    }
}

As you can see, the call to expensiveOperation() happens directly in main,
but only if the info level is enabled.

What this means is that now, if the call site is a suspend function, you
can call a suspend function in the lambda and, after compilation, it would
be called directly in the suspend function, which is legal, so the first
code block in this post (the one that failed to compile when calling
currentCoroutineContext()) would compile and work just fine.

—
Reply to this email directly, view it on GitHub
<https://github.com/apache/logging-log4j2/discussions/4146?email_source=notifications&email_token=AAARTSLAR33IDUQKUIOP4BD477EUZA5CNFSNUABBM5UWIORPF5TWS5BNNB2WEL2ENFZWG5LTONUW63RPGEYDENRQGEYDBJTSMVQXG33OVJZXKYTTMNZGSYTFMSSWK5TFNZ2KYZTPN52GK4S7MNWGSY3L>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AAARTSNHPJ6I6GJY6ZDDTH3477EUZAVCNFSNUABHKJSXA33TNF2G64TZHMYTANRTG44DSNR3IRUXGY3VONZWS33OHMYTAMRWGAYTAMFBOYBA>
.
Triage notifications, keep track of coding agent tasks and review pull
requests on the go with GitHub Mobile for iOS
<https://github.com/notifications/mobile/ios/AAARTSKVSZX5BOJAJBR3KKD477EUZA5CNFSNUABBM5UWIORPF5TWS5BNNB2WEL2ENFZWG5LTONUW63RPGEYDENRQGEYDBJTSMVQXG33OVJZXKYTTMNZGSYTFMSSWK5TFNZ2KUZTPN52GK4S7NFXXG>
and Android
<https://github.com/notifications/mobile/android/AAARTSMSNANZ6T33XW66B7D477EUZA5CNFSNUABBM5UWIORPF5TWS5BNNB2WEL2ENFZWG5LTONUW63RPGEYDENRQGEYDBJTSMVQXG33OVJZXKYTTMNZGSYTFMSSWK5TFNZ2K4ZTPN52GK4S7MFXGI4TPNFSA>.
Download it today!
You are receiving this because you are subscribed to this thread.Message
ID: <apache/logging-log4j2/repo-discussions/[email protected]>

Reply via email to