使用 log4j 在 Java 中记录运行时异常
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2344654/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Log runtime Exceptions in Java using log4j
提问by DkS
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?
我目前正在使用 Tomcat、Spring 和 JAVA 构建应用程序。我Log4J
用作我的日志库。我目前正在将所有内容记录到文本文件中。我遇到的问题之一RuntimeExceptions
是没有记录到任何文件。我想知道是否有办法记录所有RuntimeExceptions
可能抛出到我的应用程序日志文件的内容。如果不是,是否可以将其记录到另一个日志文件中?有没有标准的方法来做到这一点?如果是这样,在 Tomcat 中运行您的应用程序时是否有一种标准方法可以做到这一点?
Thank you in advance for your help!
预先感谢您的帮助!
采纳答案by erickson
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 replacethis with your own UncaughtExceptionHandler
that logs the exception to log4j instead:
默认“未捕获的异常处理程序”只是调用printStackTrace()
上Throwable
打印的堆栈跟踪System.err
。但是,您可以将其替换为UncaughtExceptionHandler
将异常记录到 log4j 的您自己的:
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:
如果您使用传递Runnable
对象的执行器框架,则其线程可能具有自己的catch
块,以防止异常到达未捕获的异常处理程序。如果您想在Runtime
那里捕获异常,一种方法是将每个任务包装在日志包装器中,如下所示:
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));
回答by Jason D.
You can try redirecting the StdErr to use your logger. This should output the result of anything being written to your std err (which should include unhandled exceptions)
您可以尝试重定向 StdErr 以使用您的记录器。这应该输出任何写入 std err 的结果(应该包括未处理的异常)
This blog post gives a good rundown on how to do the redirection into a FileHandler that is apart of your logger.
这篇博客文章很好地概述了如何重定向到属于您的记录器的 FileHandler。
https://blogs.oracle.com/nickstephen/entry/java_redirecting_system_out_and
https://blogs.oracle.com/nickstephen/entry/java_redirecting_system_out_and
回答by Luke Woodward
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
记录未捕获的 RuntimeExceptions(或任何未捕获的 Throwables)的一种方法是创建一个实现Thread.UncaughtExceptionHandler的类。此类的uncaughtException()
方法将简单地将异常详细信息写入日志。您可以通过添加以下行使 JVM 在未捕获的 RuntimeException 终止线程时调用此异常处理程序
Thread.setDefaultUncaughtExceptionHandler(new MyExceptionHandler());
to your code.
到您的代码。