java.util.logging.Loggerで生成されたログステートメントにスレッド名を出力することはできますか? 1つの選択肢は、以下のような何かを行うことです。java.util.loggingを使用してスレッド名を出力する
logger.info(thread.getName() +" some useful info");
を、それは繰り返しだとロギングフレームワークがそれを処理する必要があります。
java.util.logging.Loggerで生成されたログステートメントにスレッド名を出力することはできますか? 1つの選択肢は、以下のような何かを行うことです。java.util.loggingを使用してスレッド名を出力する
logger.info(thread.getName() +" some useful info");
を、それは繰り返しだとロギングフレームワークがそれを処理する必要があります。
が、java.util.logging
はこれを行うことはできませんように見える...
デフォルトjava.util.logging.SimpleFormatter
は全くスレッド名をログに記録する機能を持っていません。 java.util.logging.FileHandler
は、テンプレートのプレースホルダをほとんどサポートしていません。スレッド名はどれもありません。
java.util.logging.XMLFormatter
は、最も近いものですが、唯一のスレッドIDを記録します:あなたは私たちが近づいていると思う場合は
<record>
<date>2011-07-31T13:15:32</date>
<millis>1312110932680</millis>
<sequence>0</sequence>
<logger></logger>
<level>INFO</level>
<class>java.util.logging.LogManager$RootLogger</class>
<method>log</method>
<thread>10</thread>
<message>Test</message>
</record>
を - 私たちではありません。 LogRecord
クラスはスレッドIDを保持していますが、その名前は保持しません。
一部のアプリケーションサーバーは暗黙的にスレッドIDをログに記録します(私はWebSphereのことを知っています)。独自のLogFormatterを作成することができます。フォーマッタに渡されたレコードには、スレッドIDが含まれています。hereを参照してください。私はこのアプローチをTomcatに数回実装しましたが、Java SE環境でも同様に動作します。
ところで、スレッド名はLogRecordでは利用できません。あきれるほど
java.util.loggingには多くの興味深い特質があります。あなたは
public class Log
Logger logger;
static public Log of(Class clazz)
return new Log(Logger.getLogger(clazz.getName()));
public void error(Throwable thrown, String msg, Object... params)
{
log(ERROR, thrown, msg, params);
}
void log(Level level, Throwable thrown, String msg, Object... params)
{
if(!logger.isLoggable(level)) return;
// bolt on thread name somewhere
LogRecord record = new LogRecord(...);
record.setXxx(...);
...
logger.log(record);
}
----
static final Log log = Log.of(Foo.class);
....
log.error(...);
彼らは、サードパーティの依存関係を持っている必要はありませんので、人々は主にJavaのログを使用
その振る舞いを微調整するためにファサードのAPIを追加することができます。それはまた、apacheやslf4jのような既存のロギングファサードに依存できない理由です。
同様の問題がありました。答えとしてここHow to align log messages using java.util.loggingあなたはjava.util.logging.Formatter
を拡張することができますが、代わりになっLogRecord#getThreadID()
あなたは、このようなThread.currentThread().getName()
を呼び出すことにより、スレッド名を取得できます。
public class MyLogFormatter extends Formatter
{
private static final MessageFormat messageFormat = new MessageFormat("[{3,date,hh:mm:ss} {2} {0} {5}]{4} \n");
public MyLogFormatter()
{
super();
}
@Override
public String format(LogRecord record)
{
Object[] arguments = new Object[6];
arguments[0] = record.getLoggerName();
arguments[1] = record.getLevel();
arguments[2] = Thread.currentThread().getName();
arguments[3] = new Date(record.getMillis());
arguments[4] = record.getMessage();
arguments[5] = record.getSourceMethodName();
return messageFormat.format(arguments);
}
}
これは、ログエントリを作成したスレッドのスレッド名ではなく、フォーマッタを呼び出すスレッドのスレッド名に入れませんか?私は彼らがいくつかの状況で同じかもしれないと思いますが、保証はありません。 – pauli
上記の回答のカップルは、LogRecord.getThreadId()は意味のあるスレッドIDを返すことを示唆していると私たちが見逃しているのは、それをスレッドの名前に関連付ける方法だけです。
残念ながら、LogRecord.getThreadId()は、ログメッセージを引き起こしたスレッドのロングIDに対応しないint値を返します。
したがって、スレッド名を解決するためにManagementFactory.getThreadMXBean()を使用することはできません。ランダムなスレッド名になります。
ロギング機能が常に呼び出し元と同じスレッドでフォーマットされていることが確かであれば、上で提案したようにカスタムフォーマッタを作成し、Thread.currentThread()。getName()を呼び出すことができます。
ロギングファサードやサードパーティライブラリは、完全に安全なオプションのようです。l245c4l答え@補完するために
:代わりにSimpleFormatterを(使用したのは)使用:
T:{4}
はスレッドID(引数4)である
//fileHandler.setFormatter(new SimpleFormatter());
class MyFormatter extends Formatter {
private final MessageFormat messageFormat = new MessageFormat("{0,date}, {0,time} {1} {2}: {3} [T:{4}] {5}\n");
public String format(LogRecord record)
{
Object[] arguments = new Object[6];
arguments[0] = new Date(record.getMillis());
arguments[1] = record.getSourceClassName();
arguments[2] = record.getSourceMethodName();
arguments[3] = record.getLevel();
arguments[4] = Long.toString(Thread.currentThread().getId());
arguments[5] = record.getMessage();
return messageFormat.format(arguments);
}
}
fileHandler.setFormatter(new MyFormatter());
Logger myLogger = Logger.getLogger("<LOGGER_NAME>");
myLogger.addHandler(fileHandler);
。
私は、log4jまたはslf4jを使用すると、答えの中で提案されている解決策よりもきれいになると思います。 :) – Diablo