szymon
szymon

Reputation: 161

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.

Upvotes: 1

Views: 2744

Answers (3)

szymon
szymon

Reputation: 161

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);
        }
    });

Upvotes: 4

Brian Agnew
Brian Agnew

Reputation: 272267

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).

Upvotes: 0

Julien
Julien

Reputation: 1312

For exception, you should not use e.printStackTrace() but logger.fatal(e.getStrackTrace()).

Upvotes: 0

Related Questions