e.printStackTrace()を実行すると、例外をキャッチし、標準出力(コンソールなど)で以下を取得したとします。
Java.io.FileNotFoundException: so.txt
at Java.io.FileInputStream.<init>(FileInputStream.Java)
at ExTest.readMyFile(ExTest.Java:19)
at ExTest.main(ExTest.Java:7)
次に、これを代わりにlog4jなどのロガーに送信して、以下を取得します。
31947 [AWT-EventQueue-0] ERROR Java.io.FileNotFoundException: so.txt
32204 [AWT-EventQueue-0] ERROR at Java.io.FileInputStream.<init>(FileInputStream.Java)
32235 [AWT-EventQueue-0] ERROR at ExTest.readMyFile(ExTest.Java:19)
32370 [AWT-EventQueue-0] ERROR at ExTest.main(ExTest.Java:7)
これどうやってするの?
try {
...
} catch (Exception e) {
final String s;
... // <-- What goes here?
log.error( s );
}
例外をロガーに直接渡します。
try {
...
} catch (Exception e) {
log.error( "failed!", e );
}
スタックトレースをレンダリングするのはlog4jです。
例外を伴わずにスタックトレースを記録したい場合は、次のようにします:
String message = "";
for(StackTraceElement stackTraceElement : Thread.currentThread().getStackTrace()) {
message = message + System.lineSeparator() + stackTraceElement.toString();
}
log.warn("Something weird happened. I will print the the complete stacktrace even if we have no exception just to help you find the cause" + message);
ExceptionUtils.getStackTrace
を介して文字列としてスタックトレースを取得することもできます。
log.debug
をシンプルにするために、log.error
にのみ使用します。
この回答は、尋ねられた質問に関連するのではなく、質問のタイトルに関連する場合があります。
public class ThrowableTest {
public static void main(String[] args) {
Throwable createdBy = new Throwable("Created at main()");
ByteArrayOutputStream os = new ByteArrayOutputStream();
PrintWriter pw = new PrintWriter(os);
createdBy.printStackTrace(pw);
try {
pw.close();
os.close();
} catch (IOException e) {
e.printStackTrace();
}
logger.debug(os.toString());
}
}
OR
public static String getStackTrace (Throwable t)
{
StringWriter stringWriter = new StringWriter();
PrintWriter printWriter = new PrintWriter(stringWriter);
t.printStackTrace(printWriter);
printWriter.close(); //surprise no IO exception here
try {
stringWriter.close();
}
catch (IOException e) {
}
return stringWriter.toString();
}
OR
StackTraceElement[] stackTraceElements = Thread.currentThread().getStackTrace();
for(StackTraceElement stackTrace: stackTraceElements){
logger.debug(stackTrace.getClassName()+ " "+ stackTrace.getMethodName()+" "+stackTrace.getLineNumber());
}
それは私に起こったし、役に立つことができるからです。これをするなら
try {
...
} catch (Exception e) {
log.error( "failed! {}", e );
}
スタックトレース全体ではなく、例外のヘッダーを取得します。ロガーは文字列を渡していると考えるからです。スカッフマンが言ったように{}
なしでそれをしなさい
スカッフマンからの答えは間違いなく正しい答えです。 error()
、warn()
、info()
、debug()
などのすべてのロガーメソッドは、Throwableを2番目のパラメーターとして受け取ります。
try {
...
} catch (Exception e) {
logger.error("error: ", e);
}
ただし、スタックトレースも文字列として抽出できます。 「{}」プレースホルダーを使用してフォーマット機能を利用したい場合に役立つことがあります-メソッドvoid info(String var1, Object... var2);
を参照してくださいこの場合、文字列としてスタックトレースがあると言うと、実際には次のようなことができます:
try {
...
} catch (Exception e) {
String stacktrace = TextUtils.getStacktrace(e);
logger.error("error occurred for usename {} and group {}, details: {}",username, group, stacktrace);
}
これは、メソッドの場合と同じ方法で、パラメーター化されたメッセージとスタックトレースを最後に出力します:logger.error("error: ", e);
実際に、スタックトレースを文字列として抽出するためのユーティリティと、スタックトレースからノイズをスマートに除去するオプションを備えたオープンソースライブラリを作成しました。つまりパッケージプレフィックスを指定すると、抽出されたスタックトレースに興味のない部分が除外され、情報が非常に制限されたままになります。ライブラリに含まれるユーティリティとその入手先(Mavenアーティファクトとgitソースの両方)とその使用方法について説明している記事へのリンクです。 オープンソースJavaライブラリ、スタックトレースフィルタリング、サイレントストリング解析Unicodeコンバーター、およびバージョン比較 「スタックトレースノイズフィルター」
Try this:
catch (Throwable t) {
logger.error("any message" + t);
StackTraceElement[] s = t.getStackTrace();
for(StackTraceElement e : s){
logger.error("\tat " + e);
}
}
以下のコードを使用できます。
import org.Apache.logging.log4j.Logger;
import org.Apache.logging.log4j.LogManager;
public class LogWriterUtility {
Logger log;
public LogWriterUtility(Class<?> clazz) {
log = LogManager.getLogger(clazz);
}
public void errorWithAnalysis( Exception exception) {
String message="No Message on error";
StackTraceElement[] stackTrace = exception.getStackTrace();
if(stackTrace!=null && stackTrace.length>0) {
message="";
for (StackTraceElement e : stackTrace) {
message += "\n" + e.toString();
}
}
log.error(message);
}
}
ここで呼び出すことができます:LogWriterUtility.errorWithAnalysis( YOUR_EXCEPTION_INSTANCE);
StackTraceがログに出力されます。
これは、log4jエラー/例外のログを記録するのに適しています-splunk /その他のログ/監視ソフトウェアで読み取り可能です。すべてがキーと値のペアの形式です。 log4jは、例外obj e
からスタックトレースを取得します
try {
---
---
} catch (Exception e) {
log.error("api_name={} method={} _message=\"error description.\" msg={}",
new Object[]{"api_name", "method_name", e.getMessage(), e});
}