上面我们说过log4j2.xml是可以配置property标签的,如果这些变量的值本身就是动态的,不就能解决问题了吗。非常感谢log4j2.xml支持jvm、系统环境变量的使用。改造的基本思路如下图:
@Override
public void onApplicationEvent(ApplicationEvent event) {
LOGGER.info("CustomerLog4j2Initializer onApplicationEvent");
// 容器启动完成之后load
if (event instanceof ContextRefreshedEvent) {
if (((ContextRefreshedEvent) event).getApplicationContext().getParent() == null) {
LOGGER.info("CustomerLog4j2Initializer , reloading log4j2");
try {
reloadLog4j2();
} catch (FileNotFoundException e) {
e.printStackTrace();
}
LOGGER.info("CustomerLog4j2Initializer , reloaded log4j2 successful");
}
}
}
private PropertiesConfiguration prop = PropertiesConfigurationFactoryBean.getPropertiesConfiguration();
/**
* 重新加载log4j2配置文件
* @throws FileNotFoundException
* @return void
*/
private void reloadLog4j2() throws FileNotFoundException{
LOGGER.info("reloadLog4j2 , load log4j2 properties");
String realLogPath = ""; //最终日志存放的真实路径
//获取diamond配置中心中配置的日志路径
realLogPath = prop.getString("logpath",DEFAULT_LOGPATH);
//解析日志存放路径中的变量,替换ip
realLogPath = realLogPath.replace("{ip}", packageIp());
//获取log4j配置文件路径,如无配置则默认加载classpath:log4j2.xml
String location = prop.getString("log4j2Filepath",DEFAULT_LOG4J2_FILEPATH);
LOGGER.info("reloadLog4j2 , location:"+location+",realLogPath:"+realLogPath);
//将日志存放路径设置至jvm变量中,供log4j配置文件中加载
System.setProperty("reallogpath", realLogPath);
//重新加载log4j2配置文件
String resolvedLocation = SystemPropertyUtils.resolvePlaceholders(location);
if (resolvedLocation.toLowerCase().endsWith(XML_FILE_EXTENSION)) {
LOGGER.info("reloadLog4j2 , LoggerContext.reconfigure--start");
File file = ResourceUtils.getFile(resolvedLocation);
LoggerContext context =(LoggerContext)LogManager.getContext(false);
context.setConfigLocation(file.toURI());
LOGGER.info("reloadLog4j2 , LoggerContext.setConfigLocation:"+file.toURI());
//重新初始化Log4j2的配置上下文
context.reconfigure();
LOGGER.info("reloadLog4j2 , LoggerContext.reconfigure--finished");
}
else {
//暂不支持非xml配置
}
}
${sys:reallogpath}
${LOG_HOME}/static
${LOG_HOME}/ERROR
${LOG_HOME}/INFO
${LOG_HOME}/monitoring