top / index / prev / next / target / source

2007-11-23 diary: java.util.logging を Apache Commons Logging の代わりに利用する

いがぴょん画像(小) 日記形式でつづる いがぴょんコラム ウェブページです。

old-v2

java.util.logging を Apache Commons Logging の代わりに利用する

java.util.logging を Apache Commons Logging の代わりに利用することができると考えました。これを実現するための blanco.log.logging.BlancoLogLog4jHandler クラス を作成しました。

java.util.logging を Apache Commons Logging の代わりに利用する

java.util.logging を Apache Commons Logging の代わりに利用することができると考えました。これを実現するための blanco.log.logging.BlancoLogLog4jHandler クラス を作成しました。

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行のソースコードによって実現されています。

利用方法

下記のような手順で利用することが出来ます。

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利用の検討をされることをおすすめします。

blanco.log.logging.BlancoLogLog4jHandler クラスの性能

パターン分けで簡単に計測

java.util.logging を利用する

下記の2パターンがあります。

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 を利用する

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ミリ秒の増加。


この日記について