web-dev-qa-db-ja.com

log4jを使用してJavaでランタイム例外をログに記録する

現在、Tomcat、Spring、Javaを使用してアプリケーションを構築しています。私は使っている Log4J私のロギングライブラリとして。現在、すべてをテキストファイルに記録しています。私が抱えている問題の1つは、RuntimeExceptionsがどのファイルにも記録されていないことです。アプリケーションログファイルにスローされる可能性のあるすべてのRuntimeExceptionsをログに記録する方法があるかどうか疑問に思いました。そうでない場合は、別のログファイルにログを記録することは可能ですか?これを行うための標準的な方法はありますか?もしそうなら、Tomcat内でアプリケーションを実行するときにこれを行う標準的な方法はありますか?

よろしくお願いします!

21
DkS

これがあなたが探しているものであるかどうかはわかりませんが、スレッドを終了する例外のハンドラーがあります。これは、スレッドのターゲットによって明示的にキャッチされない例外のハンドラーです。

デフォルトの「キャッチされない例外ハンドラ」は、単にThrowableprintStackTrace()を呼び出して、スタックトレースを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));
24
erickson

キャッチされていないRuntimeExceptions(またはキャッチされていないThrowables)をログに記録する1つの方法は、 Thread.UncaughtExceptionHandler を実装するクラスを作成することです。このクラスのuncaughtException()メソッドは、単に例外の詳細をログに書き込みます。行を追加することで、キャッチされなかったRuntimeExceptionがスレッドを終了するたびに、JVMにこの例外ハンドラーを呼び出させることができます。

Thread.setDefaultUncaughtExceptionHandler(new MyExceptionHandler());

あなたのコードに。

15
Luke Woodward

StdErrをリダイレクトして、ロガーを使用してみてください。これにより、std errに書き込まれた結果が出力されます(未処理の例外が含まれている必要があります)

このブログ投稿では、ロガーの一部であるFileHandlerにリダイレクトする方法について詳しく説明しています。

https://blogs.Oracle.com/nickstephen/entry/Java_redirecting_system_out_and

2
Jason D.