如何动态修改log4j2的配置文件路径,并兼容commong logging门面框架

最近看了篇介绍内存队列disruptor的文章,据说性能比java的blockingqueue性能好很多,用的CAS原语来代替锁。log4j2的异步模式也使用了此队列,故最近把古老的log4j1.x升级到了log4j2。之前用log4j1.x时,配置了本地、测试、线上三套环境,在代码里用静态代码块动态修改log4j.properties的路径,如下:

//静态初始化块
  static {
    //获取java参数中的property,默认使用开发环境的配置
    String argName = SystemConfigConstants.PROFILE;
    String devConf = "dev";
    String profile = System.getProperty(argName);
    if (profile == null) {
      profile = devConf;
    }

    //写入系统变量,并打印出信息
    System.setProperty(argName, profile);
    System.out.println("----------------------------------------------");
    System.out.println("You are using the configuration in folder " + profile);
    System.out.println("----------------------------------------------");

    String log4jPropertiesPath =
        MultiModeConfigurer.class.getResource("/") + "/" + profile + "/log4j.properties";
    //动态配置log4j.properties的路径
    try {
      PropertyConfigurator.configure(new URL(log4jPropertiesPath));
    } catch (MalformedURLException e) {
      e.printStackTrace();
    }
    System.out.println("----------------------------------------------");
    System.out.println("You are using the log4j properties: " + log4jPropertiesPath);
    System.out.println("----------------------------------------------");

  }


系统启动时会传入系统参数profile,来表明当前在哪个环境。开发环境dev,测试环境test,线上环境online(我的是web项目,通过修改tomcat的catalina.sh脚本,加入CATALINA_OPTS="-Dprofile=online“这个配置就行)。而log4j默认是去classpath下获取log4j配置文件的,故需要动态修改。

现在升到log4j2版本了,找了半天,终于在stackoverflow找到答案,参见http://stackoverflow.com/questions/16716556/how-to-specify-log4j-2-x-config-location。

最终代码如下:

//静态初始化块
  static {
    //获取java参数中的property,默认使用开发环境的配置
    String argName = SystemConfigConstants.PROFILE;
    String devConf = "dev";
    String profile = System.getProperty(argName);
    if (profile == null) {
      profile = devConf;
    }

    //写入系统变量,并打印出信息
    System.setProperty(argName, profile);
    System.out.println("----------------------------------------------");
    System.out.println("You are using the configuration in folder " + profile);
    System.out.println("----------------------------------------------");

    String log4jPropertiesPath = MultiModeConfigurer.class.getResource("/") + profile + File.separator + "log4j2.xml";
    //动态配置log4j.properties的路径
    try {
      URL url = new URL(log4jPropertiesPath);
      /*
       * System.setProperty("log4j.configurationFile", url.toString());
       * LoggerContext context = (LoggerContext) LogManager.getContext(false);
       * context.reconfigure();
       * 这种方法也行,但是代码中修改系统属性,不太好维护
       */
      ConfigurationSource source = new ConfigurationSource(url.openStream(), url);
      LoggerContext context = Configurator.initialize(null, source);
      XmlConfiguration xmlConfig = new XmlConfiguration(context, source);
      context.start(xmlConfig);
    } catch (Exception e) {
      e.printStackTrace();
    }
    System.out.println("----------------------------------------------");
    System.out.println("You are using the log4j properties: " + log4jPropertiesPath);
    System.out.println("----------------------------------------------");

  }



注意,网上大部分给的方式是

ConfigurationSource source = new ConfigurationSource(url.openStream(), url);
Configurator.initialize(null, source);

这样对于使用了apache commong loggging框架的是不起作用的,必须调用context.start(config)方法重新初始化



你可能感兴趣的:(java,web)