top / index / prev / next / target / source
日記形式でつづる いがぴょんコラム ウェブページです。
java.util.logging を Apache Commons Logging の代わりに利用することができると考えました。これを実現するための blanco.log.logging.BlancoLogLog4jHandler クラス を作成しました。
java.util.logging を Apache Commons Logging の代わりに利用することができると考えました。これを実現するための blanco.log.logging.BlancoLogLog4jHandler クラス を作成しました。
blancoLogの blanco.log.logging.BlancoLogLog4jHandler クラスを利用すると、java.util.logging の出力を Apache log4j にリダイレクトすることができます。これにより、標準 Java API のみを利用して Apache log4j へのログ出力を実現することが出来るようになります。
現在、多くの方々はロギングのインタフェースとして Apache Commons Logging を利用しているのものと思います。でも、Apache Commons Logging を利用すると、Java ソースコードに org.apache.commons.logging.*の import文が必要になってしまいます。「ロギングはしておきたいのだけれども、Javaの import文に 標準 Java API以外のものが入るのは好ましくない」というジレンマを多くの方は感じていることでしょう。これを、blanco.log.logging.BlancoLogLog4jHandlerは矛盾無く解決することが出来ます。
blanco.log.logging.BlancoLogLog4jHandler クラスの仕組みはとてもシンプルなものです。java.util.loggingのログハンドラクラスである java.util.logging.Handler を継承して、その出力を Apache log4j クラスへと引き渡しているだけです。 2007.11.23時点では およそ 105行のソースコードによって実現されています。
利用方法
下記のような手順で利用することが出来ます。
クラスパス上に以下のファイルを配置します。 ※Java実行環境の jre\lib\ext ディレクトリに配置するという方法もあります。
blancolog-?.?.?.jar: blancoLogのjarファイル
java.util.logging の設定を変更します。 ※最も単純な変更方法は、Java実行環境の jre\lib ディレクトリの logging.properties を変更する方法です。なお、変更する前にオリジナルのファイルをバックアップすることを推奨します。
Java実行環境の jre\lib ディレクトリ の logging.properties ファイルを、以下の2行だけに変更します。 <logging.properties> handlers=blanco.log.logging.BlancoLogLog4jHandler .level= ALL
Apache log4j のための設定ファイル <log4j.properties> を設定します。
クラスパス上の どこか利用者の都合の良いディレクトリに log4j.properties という名前のファイルを作成します。なお、状況によっては このファイルは既に存在している場合もあります。
<log4j.properties> の単純な記述内容例 log4j.rootLogger=DEBUG, A1 log4j.appender.A1=org.apache.log4j.ConsoleAppender log4j.appender.A1.layout=org.apache.log4j.PatternLayout log4j.appender.A1.layout.ConversionPattern=%d [%t] %-5p %c - %m%n
java.util.logging を利用してログを出力する
java.util.logging の単純な利用例
``` import java.util.logging.Logger;
public class Sample { public static void main(String[] args) { final Logger logger = Logger.getLogger("Sample"); logger.fine("FINEレベルのログ。"); logger.config("CONFIGレベルのログ。"); logger.info("INFOレベルのログ。"); logger.warning("WARNINGレベルのログ。"); logger.severe("SEVEREレベルのログ。"); } } ```
2007-11-23 10:19:52,462 [main] DEBUG Sample - FINEレベルのログ。
2007-11-23 10:19:52,462 [main] DEBUG Sample - config: CONFIGレベルのログ。
2007-11-23 10:19:52,462 [main] INFO Sample - INFOレベルのログ。
2007-11-23 10:19:52,462 [main] WARN Sample - WARNINGレベルのログ。
2007-11-23 10:19:52,462 [main] ERROR Sample - SEVEREレベルのログ。
java.util.logging から Apache log4j へのログレベルマッピング
java.util.logging と Apache log4j とではログレベルが異なります。これを解決するために、下記のようなログレベルのマッピングを行っています。 java.util.logging のログレベル Apache log4j のログレベル 備考 java.util.logging.Level.FINEST org.apache.log4j.Level.TRACE 「詳細レベル(高)」。 java.util.logging.Level.FINER org.apache.log4j.Level.TRACE 「詳細レベル(中)」。 java.util.logging.Level.FINE org.apache.log4j.Level.DEBUG 「詳細レベル(低)」。 java.util.logging.Level.CONFIG org.apache.log4j.Level.DEBUG 「設定」。ログメッセージに 「config: 」プレフィクスを付与します。 java.util.logging.Level.INFO org.apache.log4j.Level.INFO 「情報」。 java.util.logging.Level.WARNING org.apache.log4j.Level.WARN 「警告」。 java.util.logging.Level.SEVERE org.apache.log4j.Level.ERROR org.apache.log4j.Level.FATAL (*1) 「致命的」。 (*1)メッセージがfatalから始まるもののみ FATAL にマップします。
java.util.logging の可能性
既に java.util.logging の利用を検討したことはあるのだけれども、java.util.logging のログハンドラの非力さが原因で利用を断念した人は多いのではいでしょうか。ログハンドラ部分は Apache log4j のほうが一日の長があり、また多機能であるのは確かなことです。そこで、java.util.logging を Apache Commons Logging の代わりに利用して、ロギングは Apache log4j を使ってしまうという、blanco.log.logging.BlancoLogLog4jHandlerクラス の利用を提案します。是非 この機会に blancoLog の blanco.log.logging.BlancoLogLog4jHandlerクラス を利用して java.util.logging利用の検討をされることをおすすめします。
パターン分けで簡単に計測
java.util.logging を利用する
下記の2パターンがあります。
最後まで java.util.logging を利用する
Apache log4j にリダイレクトする Sample.java
``` import java.util.logging.Logger;
public class Sample { public static void main(String[] args) { final long start = System.currentTimeMillis();
final Logger logger = Logger.getLogger("Sample");
for (int index = 0; index < 50000; index++) {
logger.info("INFOレベルのログ。");
logger.warning("WARNINGレベルのログ。");
logger.severe("SEVEREレベルのログ(1)。");
}
final long end = System.currentTimeMillis();
System.out.println("所用した時間は " + (end - start) + "ミリ秒");
}
} ```
ネイティブな Apache log4j を利用する Sample2.java
import org.apache.log4j.Logger;
public class Sample2 {
public static void main(String[] args) {
final long start = System.currentTimeMillis();
final Logger logger = Logger.getLogger("Sample");
for (int index = 0; index < 50000; index++) {
logger.info("INFOレベルのログ。");
logger.warn("WARNINGレベルのログ。");
logger.error("SEVEREレベルのログ(1)。");
}
final long end = System.currentTimeMillis();
System.out.println("所用した時間は " + (end - start) + "ミリ秒");
}
}
Apache Commons Logging を利用する
Apache log4j にリダイレクトする Sample3.java
``` import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory;
public class Sample3 { public static void main(String[] args) { final long start = System.currentTimeMillis();
final Log logger = LogFactory.getLog("Sample");
for (int index = 0; index < 50000; index++) {
logger.info("INFOレベルのログ。");
logger.warn("WARNINGレベルのログ。");
logger.error("SEVEREレベルのログ(1)。");
}
final long end = System.currentTimeMillis();
System.out.println("所用した時間は " + (end - start) + "ミリ秒");
}
} ```
簡単な計測結果
Core2 Duo (6300) 1.86GHz + 1GBメモリー
java.util.logging -> ネイティブ java.util.logging -> log4j Apache log4j ネイティブ Apache Commons -> log4j 1 5453ミリ秒 5594ミリ秒 4657ミリ秒 5141ミリ秒 2 5485ミリ秒
3
Sample.java Sample.java Sample2.java Sample3.java
感想
java.util.logging を経由すると、1件あたり 5ミリ秒の増加。Apache Commons 比較だと、1件あたり 3ミリ秒の増加。