简体   繁体   中英

Java standalone application logging exceptions (log4j)

I have a standalone java application. Application is using couple of libraries and it's managed by maven and 'shade' plugin to create one-big-jar with all the dependencies. I have a problem with logging uncaught exceptions into a file (application is ran on linux). I configured log4j.properties and added rolling file appender. It's working but whenever exception is thrown it's printed on console rather in the configured log file. Basically I'm ending with log file with all the INFO+ entries but no exceptions (uncaught).

Here is the log4j.properties:

# Root logger option
log4j.rootLogger=INFO, file

# Direct log messages to a log file
log4j.appender.file=org.apache.log4j.RollingFileAppender
log4j.appender.file.File=logs/my-app.log
log4j.appender.file.MaxFileSize=100MB
log4j.appender.file.MaxBackupIndex=10
log4j.appender.file.layout=org.apache.log4j.PatternLayout
log4j.appender.file.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %-5p %c{1}:%L - %m%n

I running application using:

java -jar -Dlog4j.configuration=file:log4j.properties myApp.jar

Currently I bypassed the problem using console appender and running application using:

java -jar -Dlog4j.configuration=file:log4j.properties myApp.jar >> logs/my-app.log 2>&1

...but I'd really would like to use rolling file appender.

Found a solution for such a problem. It's quite easy. You need to add DefaultUncaughtExceptionHandler in you 'main' class. Here is the snippet:

    Thread.setDefaultUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {

        @Override
        public void uncaughtException(Thread t, Throwable e) {
            logger.error("Uncaught exception", e);
        }
    });

对于异常,您不应使用e.printStackTrace()而应使用logger.fatal(e.getStrackTrace())。

If the exceptions are uncaught then they won't get logged by log4j at all. So I think a redirection is very useful, regardless.

Note that if (say) you trigger a thread stack trace via a kill -3, that comes out on stderr and consequently I would always catch stderr / out and write it to a log file distinct from the log4j file.

Since you can't guarantee two processes writing to the same log file will interleave correctly, I wouldn't log both the redirection and log4j to the same log file (as you're doing above).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM