最近看了篇介绍内存队列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("----------------------------------------------");
}
现在升到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)方法重新初始化