-
Notifications
You must be signed in to change notification settings - Fork 1.6k
New issue
Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? # to your account
DefaultLogBuilder ignores a throwable inferred by created Message #3473
Comments
@rgoers, both the report and the suggested workaround looks legitimate to me. WDYT? |
The current behavior is actually intentional. There is a ton of ambiguity involved when the last parameter is a throwable. Log4j 2 included this behavior since it was present in SLF4J, which we were trying hard to be compatible with for the most part. But it was a really bad idea. The problem here is that just because a throwable occurs as the last parameter does not necessarily mean it will be logged as a throwable. That depends on what the chosen layout chooses to do. In the case of the PatternLayout my recollection is that if there are enough parameters in the format string to include the throwable then it will end up only showing the exception message, otherwise the full stack trace gets printed. Log4j can't know anything about the behavior of a layout at compile time as it has no idea what the configuration will be. As a consequence, when LogBuilder came along we decided to be explicit about when a throwable will be treated as a throwable - i.e - only when withThrowable is specified. I would be very reluctant to change this. |
I agree on that one! 😉 |
Does it mean that
I'm not sure that my suggestion causes this unwanted compatibility to persist - I understand wanting to keep the API cleaner with less "magic" happening or not in different implementation. Can you suggest any workaround that doesn't involve converting all existing logger calls to use explicit Message instances or convert to LogBuilder? |
Shouldn't we make this more sane for 3.0 and get rid of this special hidden behavior? It would better IMO. |
It does not depend on the layout, since this is usually handled in logging-log4j2/log4j-api/src/main/java/org/apache/logging/log4j/spi/AbstractLogger.java Lines 2630 to 2640 in 23290e4
The reported issue comes from the fact that the logging-log4j2/log4j-api/src/main/java/org/apache/logging/log4j/spi/AbstractLogger.java Lines 2847 to 2863 in 23290e4
The behavior is rather inconsistent: sometimes methods that accept |
Description
When using
DefaultLogBuilder
log* methods,throwable
information that might have been inferred by the createdMessage
object is lost - andDefaultLogBuilder
only passes the explicitthrowable
that was set viaLogBuilder.withThrowable(Throwable)
.This is in contradiction to the regular use of
Logger
methods that accept message+args - which creates aMessage
using the configured factory, and then usesMessage.getThrowable()
to extract the throwable.This was initially assumed as a bug in
log4j-transform-maven-plugin
(which converts regularLogger
calls toLogBuilder
):apache/logging-log4j-transform#169
but I realized that it might be a stretch for the plugin to infer this data at build-time to be able to pass it to
.withThrowable
.Suggested Fix
Change
DefaultLogBuilder
'slogMessage(Message)
codefrom
logger.logMessage(level, marker, fqcn, location, message, throwable);
to
logger.logMessage(level, marker, fqcn, location, message, throwable != null ? throwable : message.getThrowable());
Configuration
Version: 2.24.3
Operating system: macOS Sonoma 14.7.2
JDK: eclipse-temurin 17.0.13
Logs
Consider the following code:
results in the following output:
Reproduction
I've tried recreating it in a unit test, but they seem to be using
org.apache.logging.log4j.test.TestLogger
, which does this inference in itslog
method:The text was updated successfully, but these errors were encountered: