1

I'm using SLF4j with Log4j2. The SLF4j version is 1.7.22 and the Log4j2 version is 2.8.2. When I log an exception with Log4j2 in a method, it only logs one line. I expected the log to show the full stack trace of the exception in my log. Due to this question, I am unable to identify the cause of the NullPointerException.

Here is my code snippet:

try{
    // Some code
}catch (Throwable e){
    logger.error("Occur exception -> ", e);
}

The log file only has one line.

java.lang.NullPointerException: null

My log4j2.xml

<?xml version="1.0" encoding="UTF-8"?>
<Configuration packages="com.changing" >
    <Appenders>

        <!-- DailyFile & Log file Name format by pattern -->
        <RollingFile name="DailyFile"
            fileName="C:/logs/log.log"
            filePattern="C:/logs/log-%d{yyyyMMdd}.log">
            <PatternLayout charset="UTF-8"
                pattern="%d{yyyy-MM-dd HH:mm:ss.SSS} [%-5level] [%t] %c{2}:%L - %msg%n" />
            <Policies>
                <TimeBasedTriggeringPolicy interval="1"
                    modulate="true" />
            </Policies>
        </RollingFile>
    </Appenders>
    <Loggers>
        <Logger name="com.contoso" level="debug">
            <AppenderRef ref="DailyFile" />
        </Logger>
    </Loggers>
</Configuration>

I have checked that this code correctly writes the full stack trace in my environment and test environment. However, when the same code runs on the production environment, it only shows one line.

If I manually throw the exception, it will log the full stack trace even in the production environment. However, when the NullPointerException occurs, it will only log one line.

I have checked that the log4j2.xml file is the same between the test environment and the production environment, only the file path is different.

I also tested throwing an exception in a different method in the same class, and it showed the full stack trace even in the production environment. Method A only showed one line of the full stack trace, whereas Method B showed the full stack trace.

class A {
    private static Logger logger = LogManager.getLogger(A.class);
    void methodA(){
        try{
           // Some code
        }catch (Throwable e){
            logger.error("Occur exception -> ", e);
        }
    }
    void methodB(){
        try{
           // Some code
        }catch (Throwable e){
            logger.error("Occur exception -> ", e);
        }
    }  
}
Ziv
  • 119
  • 7
  • In your A/B testing, was the exception thrown the same? – Randommm May 08 '23 at 10:29
  • Yes, I threw the exception using "throw new Exception("Some message");" in Method A and Method B. – Ziv May 08 '23 at 10:32
  • 1. this is unbelievable (methodA and B look identical!;) 2. there could be some "hidden (jvm) setting": [old but relevant](https://stackoverflow.com/questions/2295015/log4j-not-printing-the-stacktrace-for-exceptions) – xerx593 May 08 '23 at 10:46
  • @xerx593 I have checked that the Java options in my production environment do not include "-XX:-OmitStackTraceInFastThrow". – Ziv May 08 '23 at 10:53
  • Log4j 2.8.2 is **very** old and has severe security vulnerabilities. Check with the newest version! Are you logging to a file or `System.out/System.err`? The latter contains not only Log4j's logs but also other kinds of output, e.g. the output of the default [`UncaughtExceptionHandler`](https://docs.oracle.com/javase/8/docs/api/java/lang/Thread.UncaughtExceptionHandler.html), which looks pretty much as what you describe. – Piotr P. Karwasz May 08 '23 at 12:59
  • @PiotrP.Karwasz Thanks about security vulnerabilities advice. We have scheduled a time for the upgrade. Update my log4j.xml in question. – Ziv May 08 '23 at 14:40
  • @Ziv: what version of Java are you using during development and production? Do you use a `SecurityManager`? Log4j versions before 2.9.0 does not support Java 11+. You can try adding `%ex` to your pattern, while waiting for the upgrade. – Piotr P. Karwasz May 08 '23 at 17:34
  • @PiotrP.Karwasz All environments are using Java 8, but the minor versions may differ. I will check the SecurityManager and update later. – Ziv May 09 '23 at 00:03

1 Answers1

0

To fix the issue, you can update the logging level for your logger to an appropriate level, such as "DEBUG" or "TRACE", to make sure that the exception is fully logged in your log file. You can also modify your logger statement to include the exception's stack trace explicitly.

Here's an example of how you can modify your logger statement to include the full stack trace of the exception:

try {
    // Some code
} catch (Throwable e) {
    StringWriter sw = new StringWriter();
    PrintWriter pw = new PrintWriter(sw);
    e.printStackTrace(pw);
    logger.error("Occur exception -> " + sw.toString());
}

This will print the full stack trace of the exception in your log file, which can help you identify the cause of the NullPointerException.

zeynep
  • 54
  • 5
  • Thank you for your advice. The NullPointerException does not always occur. I will add this to my code and wait for the exception to happen again. I will update with the result. – Ziv May 08 '23 at 14:45