現在、Tomcat、Spring、Javaを使用してアプリケーションを構築しています。私は使っている Log4J
私のロギングライブラリとして。現在、すべてをテキストファイルに記録しています。私が抱えている問題の1つは、RuntimeExceptions
がどのファイルにも記録されていないことです。アプリケーションログファイルにスローされる可能性のあるすべてのRuntimeExceptions
をログに記録する方法があるかどうか疑問に思いました。そうでない場合は、別のログファイルにログを記録することは可能ですか?これを行うための標準的な方法はありますか?もしそうなら、Tomcat内でアプリケーションを実行するときにこれを行う標準的な方法はありますか?
よろしくお願いします!
これがあなたが探しているものであるかどうかはわかりませんが、スレッドを終了する例外のハンドラーがあります。これは、スレッドのターゲットによって明示的にキャッチされない例外のハンドラーです。
デフォルトの「キャッチされない例外ハンドラ」は、単にThrowable
でprintStackTrace()
を呼び出して、スタックトレースをSystem.err
に出力します。ただし、 replace これを独自の 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);
}
}
Runnable
オブジェクトを渡すエグゼキュータフレームワークを使用している場合、そのスレッドには、例外がキャッチされない例外ハンドラに到達するのを防ぐ独自のcatch
ブロックがある可能性があります。そこでRuntime
例外をキャッチしたい場合、それを行う1つの方法は、次のように各タスクをロギングラッパーでラップすることです。
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));
キャッチされていないRuntimeExceptions(またはキャッチされていないThrowables)をログに記録する1つの方法は、 Thread.UncaughtExceptionHandler を実装するクラスを作成することです。このクラスのuncaughtException()
メソッドは、単に例外の詳細をログに書き込みます。行を追加することで、キャッチされなかったRuntimeExceptionがスレッドを終了するたびに、JVMにこの例外ハンドラーを呼び出させることができます。
Thread.setDefaultUncaughtExceptionHandler(new MyExceptionHandler());
あなたのコードに。
StdErrをリダイレクトして、ロガーを使用してみてください。これにより、std errに書き込まれた結果が出力されます(未処理の例外が含まれている必要があります)
このブログ投稿では、ロガーの一部であるFileHandlerにリダイレクトする方法について詳しく説明しています。
https://blogs.Oracle.com/nickstephen/entry/Java_redirecting_system_out_and