連載
» 2008年01月08日 00時00分 公開

プログラマーの常識をJavaで身につける(10):入門から実践までJavaで学べる「ログ」の常識 (3/4)

[伊賀敏樹,株式会社 NTTデータ ビジネスブレインズ]

ログをすべて標準エラー出力に表示するには?

 それでは、すべてのログ(正確には、Levelクラスで定められたレベルのすべて)をレベルにかかわらず標準エラー出力に表示するように設定を変更してみましょう。SampleLogging3.javaをコピーしてSampleLogging4.javaを作成し、これを以下のように書き換えます。

SampleLogging4.java
……(省略)……

public class SampleLogging4 {
    /**
    * ログ設定プロパティファイルのファイル内容
    */
    protected static final String LOGGING_PROPERTIES_DATA
        = "handlers=java.util.logging.ConsoleHandler\n"
        + ".level=FINEST\n"
        + "java.util.logging.ConsoleHandler.level=FINEST\n"
        + "java.util.logging.ConsoleHandler.formatter"
        + "=java.util.logging.SimpleFormatter";

……(以下略)……

 これを実行すると、標準エラー出力に下記のように表示されます。

実行結果(コンソール出力)

2007/11/26 15:05:56 SampleLogging4 <clinit>

設定: ログ設定: LogManagerを設定しました。

2007/11/26 15:05:57 SampleLogging4 main

詳細レベル (高): 隣の客はよく柿食う客だ。

2007/11/26 15:05:57 SampleLogging4 main

詳細レベル (中): 東京都特許許可局。

2007/11/26 15:05:57 SampleLogging4 main

詳細レベル (低): かえるぴょこぴょこ。

2007/11/26 15:05:57 SampleLogging4 main

設定: 庭には二羽鶏が。

2007/11/26 15:05:57 SampleLogging4 main

情報: 生麦生米生卵。

2007/11/26 15:05:57 SampleLogging4 main

警告: あかまきがみ。

2007/11/26 15:05:57 SampleLogging4 main

致命的: すもももももももものうち。


 すべてのレベルのログが表示されていることが分かります。

ロガーの設定を外部のプロパティファイル(構成ファイル)から与えるには?

 次に、ロガーの設定を外部のプロパティファイル(構成ファイル)から与える例を示します。Apache log4jに慣れた人にとっては、この設定方法が最も親しみやすいのではないかと思います。

SampleLogging5.java
……(省略)……

public class SampleLogging5 {
    /**
    * ログ設定プロパティファイルのファイル名
    */
    protected static final String LOGGING_PROPERTIES
        = "javalog.properties";

    /**
    * static initializer によるログ設定の初期化
    */
    static {
        final Logger logger = Logger.getLogger("SampleLogging");

        // クラスパスの中から ログ設定プロパティファイルを取得
        logger.fine("ログ設定: " + LOGGING_PROPERTIES
            + " をもとにログを設定します。");
        final InputStream inStream = SampleLogging5.class
            .getClassLoader().getResourceAsStream(
            LOGGING_PROPERTIES);
        if (inStream == null) {
            logger.info("ログ設定: " + LOGGING_PROPERTIES
                 + " はクラスパス上に見つかりませんでした。");
        } else {
            try {
                LogManager.getLogManager().readConfiguration(
                    inStream);
                logger.config(
                    "ログ設定: LogManagerを設定しました。");
            } catch (IOException e) {
                logger.warning("ログ設定: LogManager設定の際に"
                    +"例外が発生しました。:"+ e.toString());
            } finally {
                try {
                    if (inStream != null) inStream.close();
                } catch (IOException e) {
                    logger.warning("ログ設定: ログ設定プロパティ"
                        +"ファイルのストリームクローズ時に例外が"
                        +"発生しました。:"+ e.toString());
                }
            }
        }
    }

……(以下略)……

 このサンプルでは、構成ファイルのファイル名を「javalog.properties」と決め付けています。このjavalog.propertiesファイルはクラスパス上に配置するようにしてください(javalog.propertiesという名称は、この記事のために任意に命名したものです)。

javalog.propertiesファイル(内容としては、SampleLogging4.javaでの設定内容と同じもの)
handlers=java.util.logging.ConsoleHandler
.level=FINEST

java.util.logging.ConsoleHandler.level=FINEST
java.util.logging.ConsoleHandler.formatter=java.util.logging.SimpleFormatter

 Eclipseでの設定例は図5のようになります。この例ではEclipseのソースフォルダにプロパティファイルを配置することにより、クラスパス上に配置されたことと同じ状況を作り出しています。

図5 Eclipseでのクラスパス上へのプロパティファイル設定例 図5 Eclipseでのクラスパス上へのプロパティファイル設定例

 なお、SampleLogging5の実行結果はSampleLogging4の実行結果と同じになります。

そのほかの「LogManager 構成プロパティ」の設定方法

 いままで挙げた以外にも、まだいくつかの「LogManager 構成プロパティ」の設定方法があります。以下のように、何通りも設定方法が提供されています。用途に合わせて使い分けてください。

●Java実行環境の起動オプションにログの構成ファイル名を与える

 java.util.logging.config.fileシステムプロパティでログの構成ファイル名を直接指定できます。

●Javaアプリケーション起動ツール

 Javaアプリケーション起動ツール(いわゆるjavaコマンド)に「-Djava.util.logging.config.file=myfile」のようにオプションを追加することにより、ログ構成ファイルを直接指定できます(参考)。

●Java実行環境のプロパティファイルを変更する

 Java SE(J2SE) 5.0を例に取ると、Java実行環境のディレクトリ以下にある「jre\lib」サブディレクトリに「logging.properties」というファイルがあります。このファイルを直接編集することにより、LogManager.getLogManager().readConfiguration()を呼び出す手順を踏むことなく、設定値を変更できます。

 ただし、この変更方法だと該当するJava仮想マシンのすべてに設定内容が反映される点に注意が必要です。

 皆さんのコンピュータ環境には、Java実行環境のためのディレクトリが複数存在する可能性があります。利用されるJava実行環境のディレクトリは実際にはどれなのかを確認してから変更する必要があります。

【入門3】ログファイルにログを出力するには?

 では次に、ログファイルにログを出力してみましょう(ログをログファイルに出力すると、いよいよロギングをしているという手応えが出てきますね)。

 ここでは、構成ファイルであるjavalog.propertiesファイルを変更することにより、ログファイルへのログ出力を開始していきます。

 先ほどのSampleLogging5.javaからソースコードはまったく変更せずにログファイルへのログ出力を実現します(あくまでもプロパティファイルの変更のみによって動作を変更します)。

標準エラー出力に表示されているログをすべてログファイルに書き出す

 現在、標準エラー出力に表示されているログを、ログファイルにも書き出す設定例を下記に示します。

javalog.propertiesファイル(ログをログファイルにも書き出す設定例)
handlers=java.util.logging.ConsoleHandler, java.util.logging.FileHandler
.level=FINEST

java.util.logging.ConsoleHandler.level=FINEST
java.util.logging.ConsoleHandler.formatter=java.util.logging.SimpleFormatter

java.util.logging.FileHandler.level=FINEST
java.util.logging.FileHandler.pattern=SampleLogging%u.log
java.util.logging.FileHandler.formatter=java.util.logging.SimpleFormatter
java.util.logging.FileHandler.append=true

 この設定によって、カレントディレクトリに「SampleLogging0.log」というファイルが作成され、そこにログを追加していくよう動作します(ほかのプロセスと競合した場合には、「SampleLogging1.log」などの数字が増やされたログファイルが作成されます。プログラムを同時に複数個動作させない限り、「SampleLogging0.log」というファイル名になります)。

 SampleLogging5を動作させると、ログファイルが確かに作成されることが確認できます。再コンパイルをせず、設定を変更しただけで、確かに動作が変わっていることが分かります。こういった変更ができることは、ロギングAPIのために必要な機能の1つです。

ログファイル名に連番を付けローテーションするには?

 また、プログラムを起動する都度、ファイル名をローテーションする(連番を付けたファイル名を用いて、最近のログファイルを指定個数分だけ保持する)ログファイルを作成するための設定例は下記のようになります(ローテーションの上限個数は10個とします)。

javalog.propertiesファイル(ログファイルを10個でローテーションする設定例)
handlers=java.util.logging.ConsoleHandler, java.util.logging.FileHandler
.level=FINEST

java.util.logging.ConsoleHandler.level=FINEST
java.util.logging.ConsoleHandler.formatter=java.util.logging.SimpleFormatter

java.util.logging.FileHandler.level=FINEST
java.util.logging.FileHandler.pattern=SampleLogging%u.%g.log
java.util.logging.FileHandler.formatter=java.util.logging.SimpleFormatter
java.util.logging.FileHandler.count=10

 ここでは紹介しませんが、これ以外にもログファイルの上限ファイルサイズの設定などをプロパティファイルで実施できます。詳しくは、APIのJavaDocを参照ください。

WARNINGレベル以上のものだけ、ログファイルへのロギングを行う

 次に、WARNINGレベル以上のものだけ、ログファイルへのロギングを行うように変更してみましょう。

 下記の設定により、標準エラー出力への出力内容は変えずに、ログファイルへの出力内容だけをWARNINGレベル以上のものへと変更できます。

javalog.propertiesファイル(WARNINGレベル以上のもだけロギングする設定例)
handlers=java.util.logging.ConsoleHandler, java.util.logging.FileHandler
.level=FINEST

java.util.logging.ConsoleHandler.level=FINEST
java.util.logging.ConsoleHandler.formatter=java.util.logging.SimpleFormatter

java.util.logging.FileHandler.level=WARNING
java.util.logging.FileHandler.pattern=SampleLogging%u.%g.log
java.util.logging.FileHandler.formatter=java.util.logging.SimpleFormatter
java.util.logging.FileHandler.count=10

 SampleLogging0.0.logログファイル(ローテーション後の最新ログファイル)への出力内容がWARNINGレベル以上のもののみ出力されていることが分かります。

実行結果(ログファイル出力)

2007/11/13 18:18:57 SampleLogging3 main

警告: あかまきがみ。

2007/11/13 18:18:57 SampleLogging3 main

致命的: すもももももももものうち。


 このように、プロパティファイルの変更だけでログ出力のレベル設定などを変更できます。

 さらに次ページでは、実際の開発現場で行うロギングについて解説します。

Copyright © ITmedia, Inc. All Rights Reserved.

RSSについて

アイティメディアIDについて

メールマガジン登録

@ITのメールマガジンは、 もちろん、すべて無料です。ぜひメールマガジンをご購読ください。