无法使用从属性文件中读取的动态更改配置来配置log4j2(v2.5)

时间:2016-11-25 06:21:38

标签: java logging log4j log4j2

我正在将1.x版本的log4j产品升级到2.5

我们有一个属性文件,其中包含各种配置。示例配置(trace.properties)如下:

cfg_test.status=debug
cfg_test.appenders=rolling
cfg_test.appender.rolling.type=RollingFile
cfg_test.appender.rolling.name=RollingFile_TEST
cfg_test.appender.rolling.fileName=D:/log/test.log
cfg_test.appender.rolling.filePattern=D:/log/test_%d{MMdd}.log
cfg_test.appender.rolling.layout.type=PatternLayout
cfg_test.appender.rolling.layout.pattern=%d %-5p %m%n
cfg_test.appender.rolling.policies.type = Policies
cfg_test.appender.rolling.policies.time.type = TimeBasedTriggeringPolicy
cfg_test.appender.rolling.policies.time.interval = 1
cfg_test.appender.rolling.policies.time.modulate = true
cfg_test.appender.rolling.policies.size.type = SizeBasedTriggeringPolicy
cfg_test.appender.rolling.policies.size.size=100MB
cfg_test.appender.rolling.strategy.type = DefaultRolloverStrategy
cfg_test.appender.rolling.strategy.max = 5

cfg_test.rootLogger.level=debug
cfg_test.rootLogger.appenderRefs=test
cfg_test.rootLogger.appenderRef.test.ref=RollingFile_TEST



cfg_crp.rootLogger.level=info
cfg_crp.rootLogger.appenderRefs=crp, stdout
cfg_crp.rootLogger.appenderRef.crp.ref=RollingFile_CRP
cfg_crp.rootLogger.appenderRef.stdout.ref=STDOUT

此处cfg_test是测试配置,cfg_crp是产品功能的配置,作为单独的模块启动。

我有一个自定义工厂,如下所示:

public class TraceFactory {

  private static boolean isInitialized = false;


  /**
   * intializes the trace with the given trace key.
   * <p/>
   * If if the trace key is null, we will use the console trace
   *
   * @param traceKey trace key
   */
  public static void initialize(String traceKey) {
    initPrefix(traceKey != null ? "cfg_" + traceKey + "." : null,   PropertiesUtils.readFromClassPath("properties/trace"));
  }

  private static void initPrefix(String prefix, Properties properties) {
    if (isInitialized) {
      return;
    }

    if (prefix == null) {
      TraceFactory.initializeAsConsoleTracer();
      return;
    }

    Properties cfg = new Properties();

    for (Map.Entry<Object, Object> objectObjectEntry : properties.entrySet()) {
  Map.Entry entry = (Map.Entry) objectObjectEntry;
  String key = (String) entry.getKey();
  String value = (String) entry.getValue();

  if (key.startsWith(prefix)) {
    cfg.put(key.substring(prefix.length()), value);
  }
}

PropertiesConfigurationFactory factory = new PropertiesConfigurationFactory();   // This line and the try catch below replace the 
try {
  ConfigurationSource configSrc = createConfigurationSource(cfg);                //PropertyConfigurator.configure(cfg); from log4j1.2

  Configuration conf = factory.getConfiguration(configSrc);
  LoggerContext  ctx = Configurator.initialize(conf);

  ctx.reconfigure();
}
catch (IOException io)
{

}

    isInitialized = true;
  }

  /**
   *
   * @param cfg the log4j configuration as a properties bundle read from a  properties file.
   * @return {@link ConfigurationSource} object
   * @throws IOException
   */
   private static ConfigurationSource createConfigurationSource(Properties cfg) throws IOException {

    ByteArrayOutputStream out = new ByteArrayOutputStream();
    cfg.store(out, null);
    InputStream in = new ByteArrayInputStream(out.toByteArray());
    return new ConfigurationSource(in);
  }



  public static TraceInterface getTracer(Class class_) {
   if (useConsoleTracer) {
      return new ConsoleTracer(null);
    }
    return Log4JTracer.getTracer(class_);
  }


  public static TraceInterface getTracer(String name) {
   if (useConsoleTracer) {
      return new ConsoleTracer(null);
    }
    return Log4JTracer.getTracer(name);
  }
}

我的LogWrapper Log4JTracer是: -

public class Log4JTracer implements TraceInterface {


  private static final String FQCN = Log4JTracer.class.getName();

  /**
   * extended logger wrapper
   */
  private final ExtendedLoggerWrapper log;


  private Log4JTracer(final Logger logger) {
    this.log = new ExtendedLoggerWrapper((AbstractLogger)logger,  logger.getName(), logger.getMessageFactory());
  }

/**
 * Constructs new logger.
 *
 * @param name internally used by log4j.
 */

protected Log4JTracer(String name) {
    Logger logger = LogManager.getLogger(name);
    log = new ExtendedLoggerWrapper((ExtendedLogger) logger, logger.getName(), logger.getMessageFactory());
}

/**
 *
 * @param clazz
 */
public Log4JTracer(Class<?> clazz)
{
    Logger logger = LogManager.getLogger(clazz);
    log = new ExtendedLoggerWrapper((ExtendedLogger) logger, logger.getName(), logger.getMessageFactory());
}



  /**
   * {@inheritDoc}
   */
  public void debug(Object message) {
    debug(message, null);
  }

  /**
   * {@inheritDoc}
   */
  public void debug(Object message, Throwable t) {
    log.logIfEnabled(FQCN, Level.DEBUG, null, message, t);
  }


  /**
   * {@inheritDoc}
   */
  public void info(Object message) {
    info(message, null);
  }

  /**
   * {@inheritDoc}
   */
  public void info(Object message, Throwable t) {
    log.logIfEnabled(FQCN, Level.INFO, null, message, t);
  }



  /**
   * {@inheritDoc}
   */
  public boolean isWarnEnabled() {
    return log.isWarnEnabled();
  }


  /**
   * {@inheritDoc}
   */
   public void warn(Object message) {
    warn(message, null);
   }

  /**
   * {@inheritDoc}
   */
   public void warn(Object message, Throwable t) {
    log.logIfEnabled(FQCN, Level.WARN, null, message, t);
   }

   /**
    * {@inheritDoc}
    */
   public boolean isErrorEnabled() {
    return log.isErrorEnabled();
   }

  /**
   * {@inheritDoc}
   */
  public void error(Object message) {
    error(message, null);
  }

  /**
   * {@inheritDoc}
   */
   public void error(Object message, Throwable t) {
    log.logIfEnabled(FQCN, Level.ERROR, null, message, t);
  }

    /**
     * {@inheritDoc}
     */
    public boolean isFatalEnabled() {
     return log.isFatalEnabled();
    }




  /**
   * {@inheritDoc}
   */
   public void fatal(Object message, Throwable t) {
    log.logIfEnabled(FQCN, Level.FATAL, null, message, t);
   }


  /**
   * {@inheritDoc}
   */
  @Override
  public boolean isDebugEnabled() {
    return log.isDebugEnabled();
  }

  /**
   * {@inheritDoc}
   */
  @Override
 public boolean isInfoEnabled() {
   return log.isInfoEnabled();
  }


   public static Log4JTracer getTracer(Class cl) {
     return new Log4JTracer(cl);
   }


   public static Log4JTracer getTracer(String name) {
     return new Log4JTracer(name);
   }

}

现在,当我尝试使用类中的记录器时,它根据配置没有得到记录器:

Public class Test {



 Private TraceInterface trace;



Public void execute() {



 TraceFactory.initialize("test");

 trace = TraceFactory.getTracer();

  trace.debug("testing..");   // this never prints. Although a test.log is created with zero size as soon as the TraceFactory.initialize method finshes.

谢谢和问候,

塔伦

1 个答案:

答案 0 :(得分:0)

我通过以下方式开展工作:

将TraceFactory修改为:

private LoggerContext ctx;

..... 在方法initPrefix

//ctx.reconfigure();
ctx.start(conf);
ContextAnchor.THREAD_CONTEXT.set(ctx);
ctx.updateLoggers();