最も簡単なcommons-logging + Log4jの使い方

ネットを見ると、commons-logging + Log4jの使用方法についてプロパティファイルを使うだの何だのと面倒なことが書いてあるのだが、そんな必要は無い。プロパティファイルを一切使わず、しかもプログラムの実行途中でもログ設定の切り替えられる方法を示す。

commons-loggingの設定用クラス

以下だけである。プロパティファイルは必要無い。

/**
 * commons-log + Log4jを使うためのコンフィギュレーション
 * <p>
 * システムプロパティにLog4Jの使用を指示すればよい。
 * </p>
 * @author ysugimura
 */
public class CommonsLoggingConfigurator {

  static final String COMMONS_LOGGING_LOG = "org.apache.commons.logging.log";
  static final String LOGGING_IMPL_LOG4JLOGGER = "org.apache.commons.logging.impl.Log4JLogger";

  public static void config() {
    System.setProperty(COMMONS_LOGGING_LOG, LOGGING_IMPL_LOG4JLOGGER);    
  }
}

Log4jの設定用クラス

Log4jのコンフィギュレーションはプログラム実行中に何度でも変更してよい。その都度、configを呼び出すこと。

/**
 * Log4jのコンフィグレーションを行う。
 */
public class Log4jConfigurator {

  /** 文字列からリセット */
  public static void config(String s) {
    Properties props = stringToProperties(s);
    if (props != null) config(props);
  }

  private static boolean configured;

  /** Propertiesからリセット */
  public synchronized static void config(Properties props) {
    if (configured) LogManager.resetConfiguration();
    PropertyConfigurator.configure(props);
    configured = true;
  }

  /** 改行まじりの設定文字列をPropertiesに変換 */
  public static Properties stringToProperties(String s) {
    Properties props = new Properties();
    try {
      props.load(new StringReader(s));
    } catch (Exception ex) {
      ex.printStackTrace();
      return null;
    }
    return props;
  }
}

使用例

少々ややこしいのだが、Log4jのコンフィギュレーションを変更することによって三つのロガーのログの出力が変更することがわかると思う。


import org.apache.commons.logging.*; public class LogTest { static Log fooLogger; static Log barLogger; static Log foobarLogger; public static void main(String[]args) { CommonsLoggingConfigurator.config(); fooLogger = LogFactory.getLog("com.sample.foo"); barLogger = LogFactory.getLog("com.sample.bar"); foobarLogger = LogFactory.getLog("com.foobar"); Log4jConfigurator.config( "log4j.rootLogger=fatal,CONSOLE\n" + "log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender\n" + "log4j.appender.CONSOLE.layout=org.apache.log4j.PatternLayout\n" + "log4j.appender.CONSOLE.layout.ConversionPattern=%d{MM/dd HH:mm} %-5p %c{1} - %m%n\n" + "log4j.logger.com.sample=info\n" + "log4j.logger.com.sample.foo=trace" ); logSomething(); System.out.println("---- changing configuration ----"); Log4jConfigurator.config( "log4j.rootLogger=trace,CONSOLE\n" + "log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender\n" + "log4j.appender.CONSOLE.layout=org.apache.log4j.PatternLayout\n" + "log4j.appender.CONSOLE.layout.ConversionPattern=%d{MM/dd HH:mm} %-5p %c{1} - %m%n\n" + "log4j.logger.com.sample=fatal\n" + "log4j.logger.com.sample.foo=info" ); logSomething(); } static void logSomething() { fooLogger.fatal("fatal"); fooLogger.info("info"); fooLogger.trace("trace"); barLogger.fatal("fatal"); barLogger.info("info"); barLogger.trace("trace"); foobarLogger.fatal("fatal"); foobarLogger.info("info"); foobarLogger.trace("trace"); } }

この結果は以下の通り

05/13 14:40 FATAL foo - fatal
05/13 14:40 INFO  foo - info
05/13 14:40 DEBUG foo - trace
05/13 14:40 FATAL bar - fatal
05/13 14:40 INFO  bar - info
05/13 14:40 FATAL foobar - fatal
---- changing configuration ----
05/13 14:40 FATAL foo - fatal
05/13 14:40 INFO  foo - info
05/13 14:40 FATAL bar - fatal
05/13 14:40 FATAL foobar - fatal
05/13 14:40 INFO  foobar - info
05/13 14:40 DEBUG foobar - trace

Log4jのコンフィギュレーション内容は?

これはそこそこ複雑なので次回にまわすが、しかし、おおよそわかると思う。

  • rootLoggerに設定したログレベルが出力される
  • 特にロガーの名前を指定すると(log4j.logger.com.sample)、上の設定を上書きし、それ以下のロガーの出力レベルになる
  • 更にその下のロガーの名前を指定すると(log4j.logger.com.sample.foo)、上の設定を上書きする

それ以外の部分は、ログをどこに出力するか、どういう形式で出力するかの指定である。