Log4j 2 non si disconnette% throwable

Sep 04 2020

Voglio stampare la traccia dello stack durante la registrazione degli errori utilizzando questo Log4j log4j2.xml di base:

<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="WARN">
    <Appenders>
        <Console name="Console" target="SYSTEM_OUT">
            <PatternLayout pattern="throwable: %throwable"/>
        </Console>
    </Appenders>
    <Loggers>
        <Root level="error">
            <AppenderRef ref="Console"/>
        </Root>
    </Loggers>
</Configuration>

Questo è tutto ciò che ho nelle mie dipendenze:

    <dependencies>
        <dependency>
            <groupId>org.apache.logging.log4j</groupId>
            <artifactId>log4j-api</artifactId>
            <version>2.13.3</version>
        </dependency>
        <dependency>
            <groupId>org.apache.logging.log4j</groupId>
            <artifactId>log4j-core</artifactId>
            <version>2.13.3</version>
        </dependency>
    </dependencies>

Quando lo eseguo (asdf non esiste):

public class Main {
    public static void main(String[] args) {
        Logger logger = LogManager.getLogger();
        try {
            new FileInputStream("asdf");
        } catch(Exception e) {
            logger.error(e);
        }
    }
}

la mia uscita è

throwable: 

e voglio qualcosa del genere:

throwable: java.io.FileNotFoundException: asdf (No such file or directory)
    at java.io.FileInputStream.open0(Native Method)
    at java.io.FileInputStream.open(FileInputStream.java:195)
    at java.io.FileInputStream.<init>(FileInputStream.java:138)
    at java.io.FileInputStream.<init>(FileInputStream.java:93)
    at Main.main(Main.java:10)

documentazione da PatternLayout all'indirizzo: https://logging.apache.org/log4j/2.x/manual/layouts.html#PatternLayout default (% throwable) dovrebbe registrare l'intera traccia dello stack

Qualsiasi aiuto sarebbe grande!

Modifica: sto usando Java 8

Risposte

1 Marcono1234 Sep 04 2020 at 03:35

Stai usando Logger.error(Object). Tutti i metodi di registrazione con un singolo parametro oggetto registrano solo il toString()valore di quell'oggetto, anche se è Throwable. Nel tuo caso il pattern dell'appender non contiene %m/ %msg/ %messagequindi vedi solo "throwable:" nell'output della console.
Se aggiungiamo il messaggio al pattern, l'output è:

throwable: java.io.FileNotFoundException: asdf (The system cannot find the file specified) 

Questa è una trappola piuttosto comune quando si utilizza Log4j2 e purtroppo sembra che non cambierà in futuro .

Per registrare correttamente l'eccezione e la sua analisi dello stack è possibile utilizzare uno dei metodi di registrazione con un Throwableparametro separato , ad esempio Logger.error(String, Throwable), oppure è possibile utilizzare Logger.catching(Level, Throwable). Tuttavia, i metodi di registrazione con il parametro messaggio dovrebbero essere preferiti poiché consentono di descrivere il contesto. Altrimenti potresti avere difficoltà a scoprire dove è stato effettivamente creato il messaggio di log.