Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Log runtime Exceptions in Java using log4j

Tags:

I am currently building an application using Tomcat, Spring and JAVA. I am using Log4J as my logging library. I currently am logging everything to a text file. One of the issues I'm having is that RuntimeExceptions are not being logged to any files. I was wondering if there is a way to log all RuntimeExceptions that maybe thrown to my application log file. If not is it possible to have it log to another log file? Is there a standard way to do this? If so is there a standard way to do this when running your application within Tomcat?

Thank you in advance for your help!

like image 997
DkS Avatar asked Feb 26 '10 20:02

DkS


People also ask

What is a log exception?

The exception log is a rolling collection of 4 files; when a file is full, data is added to the next file. When the last file has been filled, data starts to be added to the first file, overwriting the previous data there. This cycle of writing continues, ensuring that the newest data is retained.

What is exception handling and logging?

Logging and exception handling are like two peas in a pod. When a problem happens in your Java code, that typically means you have an exception that needs to be handled, and of course, any time an error or unanticipated event occurs, that occurrence should be logged appropriately.


2 Answers

I'm not sure if this is what you are looking for, but there is a handler for exceptions that terminate threads. It is a handler for any exception that is not caught explicitly by the target of the thread.

The default "uncaught exception handler" simply calls printStackTrace() on the Throwable to print the stack trace to System.err. However, you could replace this with your own UncaughtExceptionHandler that logs the exception to log4j instead:

class Log4jBackstop implements Thread.UncaughtExceptionHandler {    private static Logger log = Logger.getLogger(Log4jBackstop.class);    public void uncaughtException(Thread t, Throwable ex) {     log.error("Uncaught exception in thread: " + t.getName(), ex);   }  } 

If you are using an executor framework to which you pass a Runnable object, its threads probably have their own catch block that prevent exceptions from reaching the uncaught exception handler. If you want to catch Runtime exceptions there, one way to do it is to wrap each task in a logging wrapper, like this:

class Log4jWrapper {    private final Logger log;    private final Runnable target;    Log4jWrapper(Logger log, Runnable target) {      this.log = Objects.requireNonNull(log);     this.target = Objects.requireNonNull(target);    }    public void run() {     try {       target.run();     } catch(RuntimeException ex) {       log.error("Uncaught exception.", ex);       throw ex;     }   }  }  ...  Runnable realTask = ...; executor.submit(new Log4jWrapper(Logger.getLogger(Whatever.class), realTask)); 
like image 173
erickson Avatar answered Sep 28 '22 06:09

erickson


One way to log uncaught RuntimeExceptions (or any uncaught Throwables for that matter) is to create a class that implements Thread.UncaughtExceptionHandler. This class's uncaughtException() method would simply write the exception details to the log. You can make the JVM call this exception handler whenever an uncaught RuntimeException terminates a thread by adding the line

Thread.setDefaultUncaughtExceptionHandler(new MyExceptionHandler()); 

to your code.

like image 28
Luke Woodward Avatar answered Sep 28 '22 07:09

Luke Woodward