Using throwable along with parameters in log4j 2 [duplicate]
Asked Answered
C

2

7

I want to log an error(with log4j 2) with some dynamic parameters that will provide better understanding what went wrong and I faced the problem that there is no method like:

void error(String message, Throwable t);

with parameters support.

In my code I want both exception and the parameters to fill {} in the message:

    try {
        //...
    } catch (Exception e) {
        LOGGER.error("Error removing data for account {}", accountId, e);
    }

Is there a better way to implement it rather than using it like this?

LOGGER.error("Error removing token for account " + accountId, e);
Cureall answered 6/8, 2018 at 10:32 Comment(6)
According to the documentation (logging.apache.org/log4j/2.0/log4j-api/apidocs/org/apache/…) they do not provide vararg methods alongside with 'throwable'. Probably you can use varargs method providing e.message and e.stacktrace as additional parameters, but it is not the best idea.Cheeky
So, what's the silver bullet here?Cureall
I know it's perhaps a bit off-topic, but it might interest you that there is a logger library that supports such use case - it's called Flogger (look for withCause). It's developed by Google, but it's still in alpha stage, unfortunately.Telecast
From my perspective, the Silver Bullet is to use Kotlin instead of Java. For solving this problem Kotlin has string interpolation (it looks even better than log4j placeholders). Since Kotlin has excellent interoperability with Java you can start by rewriting this single class from Java to Kotlin. (sorry for real off-topic)Cheeky
Thanks guys for workarounds, really interesting to know about them. But, it's enterprise and we have java and code standards(libraries that we use, language etc). So, it's not an option here :)Cureall
Does this answer your question? Substituting parameters in log message and add a Throwable in Log4j 2Lavonlavona
D
2

Actually, almost all log4j logging methods that accept a message and arguments also accept a Throwable. Since the first release you have always been able to do:

logger.error("Error removing token for account {}", account, ex);

Notice that the format string only has one parameter so the throwable at the end is logged as an exception attached to the message. That is how the ParameterizedMessage class works.

In addition, support for LogBuilder was added in Log4j 2.13.0 which allows you to do

logger.atError().withException(ex).log("Error removing token for account {}", account);

which is a bit clearer. Note that all the following methods are called but if the error level is not being logged then all the methods following atError() are no-ops.

Deloisedelong answered 31/3, 2021 at 5:23 Comment(0)
D
0

You can format the message separately for this, though I had to write a helper method for it:

public void logException(Exception ex, String fmt, Object... args) {
    Message msg = log.getMessageFactory().newMessage(fmt, args);
    log.error(msg, ex);
}
Doublequick answered 27/3, 2021 at 17:38 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.