2011-07-31 9 views
7

java.util.logging.Loggerで生成されたログステートメントにスレッド名を出力することはできますか? 1つの選択肢は、以下のような何かを行うことです。java.util.loggingを使用してスレッド名を出力する

logger.info(thread.getName() +" some useful info"); 

を、それは繰り返しだとロギングフレームワークがそれを処理する必要があります。

+0

私は、log4jまたはslf4jを使用すると、答えの中で提案されている解決策よりもきれいになると思います。 :) – Diablo

答えて

7

が、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を保持していますが、その名前は保持しません。

1

一部のアプリケーションサーバーは暗黙的にスレッドIDをログに記録します(私はWebSphereのことを知っています)。独自のLogFormatterを作成することができます。フォーマッタに渡されたレコードには、スレッドIDが含まれています。hereを参照してください。私はこのアプローチをTomcatに数回実装しましたが、Java SE環境でも同様に動作します。

ところで、スレッド名はLogRecordでは利用できません。あきれるほど

1

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のような既存のロギングファサードに依存できない理由です。

2

同様の問題がありました。答えとしてここ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); 
    } 

} 
+7

これは、ログエントリを作成したスレッドのスレッド名ではなく、フォーマッタを呼び出すスレッドのスレッド名に入れませんか?私は彼らがいくつかの状況で同じかもしれないと思いますが、保証はありません。 – pauli

1

上記の回答のカップルは、LogRecord.getThreadId()は意味のあるスレッドIDを返すことを示唆していると私たちが見逃しているのは、それをスレッドの名前に関連付ける方法だけです。

残念ながら、LogRecord.getThreadId()は、ログメッセージを引き起こしたスレッドのロングIDに対応しないint値を返します。

したがって、スレッド名を解決するためにManagementFactory.getThreadMXBean()を使用することはできません。ランダムなスレッド名になります。

ロギング機能が常に呼び出し元と同じスレッドでフォーマットされていることが確かであれば、上で提案したようにカスタムフォーマッタを作成し、Thread.currentThread()。getName()を呼び出すことができます。

ロギングファサードやサードパーティライブラリは、完全に安全なオプションのようです。l245c4l答え@補完するために

-1

:代わりに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); 

関連する問題