Log4j2を使ってみる(設定ファイル一切無しで)、その2

2019年7月27日

Log4j2を使ってみる(設定ファイル一切無しで)の続きである。

dependencies {
  compile group: 'org.apache.logging.log4j', name: 'log4j-core', version: '2.12.0'
}

結局のところコンフィグ作成時にはアペンダーを一切作成せず、実行中にアペンダーを自由に追加・削除できるらしい。

以下のようにしてみた。

Wrapper.java

package foo.bar;

import java.nio.file.*;

import org.apache.logging.log4j.*;
import org.apache.logging.log4j.core.*;
import org.apache.logging.log4j.core.Logger;
import org.apache.logging.log4j.core.appender.*;
import org.apache.logging.log4j.core.config.*;
import org.apache.logging.log4j.core.config.builder.api.*;
import org.apache.logging.log4j.core.config.builder.impl.*;
import org.apache.logging.log4j.core.layout.*;

public class Wrapper {

  Configuration configuration;
  LoggerContext context;
  Logger rootLogger;

  public Wrapper(Level level) {
    ConfigurationBuilder<BuiltConfiguration> configBuilder
      = ConfigurationBuilderFactory.newConfigurationBuilder();    
    configBuilder.add(configBuilder.newRootLogger(level));
    configuration = configBuilder.build();
    Configurator.initialize(configuration);    
    context = (LoggerContext)LogManager.getContext(false);
    rootLogger = context.getRootLogger();
  }

  public void setAllLevels(String parent, Level level) {
    Configurator.setAllLevels(parent,  level);
  }

  public void consoleAppender(String name, String layout) {
    ConsoleAppender appender = ConsoleAppender.newBuilder()
      .setName(name)
      .setLayout(PatternLayout.newBuilder().withPattern(layout).build())
      .build();
    appender.start();
    configuration.addAppender(appender);
    rootLogger.addAppender(
      context.getConfiguration().getAppender(appender.getName())
    );
    context.updateLoggers();    
  }

  public void fileAppender(String name, String layout, Path output) {
    FileAppender appender = FileAppender.newBuilder()
      .setName(name)
      .withAppend(false)
      .withFileName(output.toString())
      .setLayout(PatternLayout.newBuilder().withPattern(layout).build())
      .setConfiguration(context.getConfiguration())
      .build();  
    appender.start();
    configuration.addAppender(appender);
    rootLogger.addAppender(context.getConfiguration().getAppender(appender.getName()));
    context.updateLoggers();
  }

  public void removeAppender(String name) {
    configuration.getRootLogger().removeAppender(name);
    context.updateLoggers();    
  }
}

これを以下のように使う。

package foo.bar;

import java.nio.file.*;

import org.apache.logging.log4j.*;

public class Main {

  static Wrapper wrapper = new Wrapper(Level.INFO);
  private static Logger log = LogManager.getLogger(Main.class);

  public static void main(String[]args) {
    log.info("info 1");
    log.trace("trace 1");

    wrapper.consoleAppender("CONSOLE",  "%d{MM/dd HH:mm} %-5p %c{1} - %m%n");

    log.info("info 2");
    log.trace("trace 2");

    wrapper.setAllLevels("foo.bar", Level.TRACE);

    log.info("info 3");
    log.trace("trace 3");

    wrapper.fileAppender("FILE",  "%d{MM/dd HH:mm} %-5p %c{1} - %m%n", Paths.get("logging.txt"));

    log.info("info 4");
    log.trace("trace 4");

    wrapper.removeAppender("CONSOLE");

    log.info("info 5");
    log.trace("trace 5");

    wrapper.removeAppender("FILE");

    log.info("info 6");
    log.trace("trace 6");
  }
}

意図通りに動作している。

コンソール

07/26 11:39 INFO  Main - info 2
07/26 11:39 INFO  Main - info 3
07/26 11:39 TRACE Main - trace 3
07/26 11:39 INFO  Main - info 4
07/26 11:39 TRACE Main - trace 4

logging.txt

07/26 11:39 INFO  Main - info 4
07/26 11:39 TRACE Main - trace 4
07/26 11:39 INFO  Main - info 5
07/26 11:39 TRACE Main - trace 5

この続きはLog4j2を使ってみる(設定ファイル一切無しで)、その3になる。