J2SE1.4の新機能にさわる2

作成 2002/10/23

ロギングAPI

とりあえず実行

ロギングです。

パッケージはjava.util.loggingです。

とりあえず、簡単なの作ってみました。

package log;

import java.util.logging.Logger;

public class SimpleLog {

  public static void main(String[] args) throws Exception{

    Logger log = Logger.getLogger(SimpleLog.class.getName());    
    log.info("情報だぜ");
    log.warning("警告だぜ");
    log.severe("シビアだぜ");
  }
}
実行すると、こうなります。
2002/10/23 22:22:29 log.SimpleLog main
情報: 情報だぜ
2002/10/23 22:22:29 log.SimpleLog main
警告: 警告だぜ
2002/10/23 22:22:29 log.SimpleLog main
致命的: シビアだぜ

設定ファイルとレイアウト

出力レイアウト(表示項目と見た目を)変えたいじゃん、と思って探してみたんですが、 デフォルトでは、SimpleFormatter、XMLFormatterしかなく、 書式指定する機能が見つかりませんでした。

代案として、Formatterクラスを継承したクラスを自作しました。

MyFormatter.java

package log;

import java.util.logging.Formatter;
import java.util.logging.LogRecord;

public class MyFormatter extends Formatter{

  public String format(LogRecord record) {

    return record.getSourceClassName()
      + " - "
      + record.getMessage()
      + "\n"
      ;      
  }
}

ロギング設定を変更するには、 LogManager#readConfigure(InputStream)するか VM引数で設定ファイルを指定するようです。

ここでは、簡単に設定ファイルを指定してみました。 ちなみにデフォルトの設定ファイルは JREのlib/logging.properties にあります。

logging.properties(自作)

handlers= java.util.logging.ConsoleHandler
java.util.logging.ConsoleHandler.level = INFO
java.util.logging.ConsoleHandler.formatter = log.MyFormatter

実行するときに
-Djava.util.logging.config.file
オプションで設定ファイルのパスを渡します。

java -Djava.util.logging.config.file=logging.properties log.SimpleLog

実行すると、自作フォーマットで出力されました。

log.SimpleLog - 情報だぜ
log.SimpleLog - 警告だぜ
log.SimpleLog - シビアだぜ

行番号は?

呼び出し元のソースファイルの行番号を出したいんですが。。。 LogRecordにそれらしいのが見当たらない。。。う〜む。 無理やりStackTraceElementを使って行番号を取得してみました。

package log;

import java.util.logging.Formatter;
import java.util.logging.LogRecord;

public class MyFormatter extends Formatter{

  public String format(LogRecord record) {

    return record.getSourceClassName()
      + getCalledElement()
      + " - "
      + record.getMessage()
      + "\n"
      ;      
  }

  private StackTraceElement getCalledElement(){

    Throwable t = new Throwable();
    StackTraceElement[] st = t.getStackTrace();
    return st[8];//数えたら8個前だったから。いいのか?
  }
}

実行するとこんな感じ。

log.SimpleLoglog.SimpleLog.main(SimpleLog.java:12) - 情報だぜ
log.SimpleLoglog.SimpleLog.main(SimpleLog.java:14) - 警告だぜ
log.SimpleLoglog.SimpleLog.main(SimpleLog.java:16) - シビアだぜ

う〜ん。なんだか、正しいやり方でないかもような気がする。

どなたか、もっと簡単な出力レイアウトの設定簡単な行番号の取得の 方法を知ってたらあったら教えてください。

ちょっと使ってみた感じでは、Log4jの方が便利かも?

アサーション

シンプルな言語設計というポリシーのために?、 実装されていなかったアサーション機能がここに来て、 言語レベルで実装されました。

とりあえず実行

簡単なの作ってみました。

public class SimpleAssert {

  public static void main(String[] args) {
    do1(-1);
  }

  /**
   * 何かする1
   * @param 引数 事前条件 >= 0
   */  
  public static void do1(int param){
    assert param >= 0;
  }
}

アサーション有効でコンパイルするには、-sourceオプションをつけます。

javac -source 1.4 SimpleAssert.java

アサーション有効で実行するには -ea オプションをつけます。

java -ea SimpleAssert

実行するとAssertionErrorってのがスローされました。

java.lang.AssertionError
	at SimpleAssert.do1(SimpleAssert.java:11)
	at SimpleAssert.main(SimpleAssert.java:7)
Exception in thread "main" 

dW アサーションの使用Javaのアサーション にちゃんとした解説かいてますね。

javac、java時にわざわざオプション指定するのが手間ですねぇ。 後方互換性のためかしら。

単にAssertException投げるだけなら、 自作AssertクラスやIllegalArgumentException(IllegalStateException)で 事足りる感じもしますが、

という理由(利点)で使ってみるのもいいかも。


TOP