目的是加載所有jar下的log4j配置,然後以指定哪個jar爲參照版本,引用項目內配置爲最高優先級,
引用的項目只需簡單配置,即可按照級別生成log文件
默認log4j配置:log4j-default.properties
log4j.rootCategory=INFO,stdout
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d %p [%c] - <%m>%n
cqliving-log.jar下log4j詳細配置:log4j.properties
# 指定日誌所屬項目名
log4j.project.name=cqliving-log
# 指定日誌項
log4j.rootCategory=INFO,stdout,infofile,errorfile,warnfile,allfile
# 指定包日誌等級
log4j.logger.org.springframework.aop.framework.Cglib2AopProxy=OFF
log4j.logger.org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping=OFF
log4j.logger.jdbc=OFF
log4j.logger.com.cqliving=DEBUG
log4j.logger.com.alibaba.druid=INFO
log4j.logger.com.cqliving.edu.log.aop.EduLogControllerAdvice=TRACE
### 配置控制檯輸出日誌 = tomcat Catalina.out
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%-d{yyyy-MM-dd HH:mm:ss,SSS}[ %t:%r ]-[%p] %l %m%n
### 輸出到文件file info ###(每天產生一個日誌文件:DailyRollingFileAppender)
log4j.appender.infofile = info
log4j.appender.infofile = org.apache.log4j.DailyRollingFileAppender
log4j.appender.infofile.append = true
log4j.appender.infofile.Threshold = INFO
log4j.appender.infofile.datePattern = '.'yyyy-MM-dd'.log'
log4j.appender.infofile.layout = org.apache.log4j.PatternLayout
log4j.appender.infofile.File = /var/www/logs/${log4j.project.name}/info.log
log4j.appender.infofile.layout.ConversionPattern=%-d{yyyy-MM-dd HH:mm:ss,SSS}[ %t:%r ]-[%p] %l %m%n
### 輸出到文件file warn ###(每天產生一個日誌文件:DailyRollingFileAppender)
log4j.appender.warnfile = warn
log4j.appender.warnfile = org.apache.log4j.DailyRollingFileAppender
log4j.appender.warnfile.append = true
log4j.appender.warnfile.Threshold = WARN
log4j.appender.warnfile.datePattern = '.'yyyy-MM-dd'.log'
log4j.appender.warnfile.layout = org.apache.log4j.PatternLayout
log4j.appender.warnfile.File = /var/www/logs/${log4j.project.name}/warn.log
log4j.appender.warnfile.layout.ConversionPattern =%-d{yyyy-MM-dd HH:mm:ss,SSS}[ %t:%r ]-[%p] %l %m%n
### 輸出到文件file error ###(每天產生一個日誌文件:DailyRollingFileAppender)
log4j.appender.errorfile = error
log4j.appender.errorfile = org.apache.log4j.DailyRollingFileAppender
log4j.appender.errorfile.append = true
log4j.appender.errorfile.Threshold = ERROR
log4j.appender.errorfile.datePattern = '.'yyyy-MM-dd'.log'
log4j.appender.errorfile.layout = org.apache.log4j.PatternLayout
log4j.appender.errorfile.File = /var/www/logs/${log4j.project.name}/error.log
log4j.appender.errorfile.layout.ConversionPattern =%-d{yyyy-MM-dd HH:mm:ss,SSS}[ %t:%r ]-[%p] %l %m%n
### 輸出到文件file all ###(每天產生一個日誌文件:DailyRollingFileAppender)
log4j.appender.allfile = all
log4j.appender.allfile = org.apache.log4j.DailyRollingFileAppender
log4j.appender.allfile.append = true
log4j.appender.allfile.Threshold = ALL
log4j.appender.allfile.datePattern = '.'yyyy-MM-dd'.log'
log4j.appender.allfile.layout = org.apache.log4j.PatternLayout
log4j.appender.allfile.File = /var/www/logs/${log4j.project.name}/all.log
log4j.appender.allfile.layout.ConversionPattern=%-d{yyyy-MM-dd HH:mm:ss,SSS}[ %t:%r ]-[%p] %l %m%n
java核心代碼
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.Properties;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import org.apache.log4j.PropertyConfigurator;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
/**
* Title:註冊監聽器加載所有log4j配置
* <p>Description:</p>
* Copyright (c) CQLIVING 2019
* @author liuzongyang on 2019年9月27日
*/
public class LogApplicationListener implements ServletContextListener {
private static Logger logger = LoggerFactory.getLogger(LogApplicationListener.class);
private static final String JAR_NAME = "cqliving-log";
@Override
public void contextInitialized(ServletContextEvent sce) {
PathMatchingResourcePatternResolver patternResolver = new PathMatchingResourcePatternResolver();
try {
Resource[] resources = patternResolver.getResources("classpath*:log4j.properties");
List<Resource> list = new ArrayList<>(Arrays.asList(resources));
// 反轉log4j加載順序,最後加載當前項目下的log4j
Collections.reverse(list);
// 需要初始化一次配置
Resource[] defaultR = patternResolver.getResources("classpath*:log4j-default.properties");
Properties defaults = read(defaultR[0].getInputStream());
PropertyConfigurator.configure(defaults);
// 倒數第二個加載cqliving-log
Iterator<Resource> it = list.iterator();
Resource param = null;
while (it.hasNext()) {
Resource resource = it.next();
String path = resource.getURL().toString();
if(path.contains(JAR_NAME)) {
it.remove();
param = resource;
break;
}
}
if(null != param) {
list.add(list.size()-1, param);
}
// 讀取所有項目下的配置,整合後重新配置log4j
Properties properties = new Properties();
logger.info("log4j配置文件以cqliving-log包下的log4j.properties爲準,其餘工程下的配置請參照自定義配置,將會覆蓋cqliving-log配置");
for (Resource resource : list) {
String path = resource.getURL().toString();
properties.putAll(read(resource.getInputStream()));
logger.debug("加載Log4j配置文件{}.", path);
}
Object projectName = properties.get("log4j.project.name");
if(JAR_NAME.equals(projectName)) {
System.err.println("日誌所屬項目沒配置或爲默認配置,請在log4j.properties中配置所屬項目的log4j.project.name屬性");
}
PropertyConfigurator.configure(properties);
} catch (IOException e) {
logger.error("加載配置文件失敗:{}", e);
}
}
/**
* 根據{@link InputStream}解析
* @param is
* @throws IOException
*/
private Properties read(InputStream is) throws IOException {
Properties properties = new Properties();
properties.load(new InputStreamReader(is, StandardCharsets.UTF_8));
return properties;
}
@Override
public void contextDestroyed(ServletContextEvent sce) { }
}
引用項目配置:log4j.properties
# 指定日誌所屬項目名
log4j.project.name=cqliving-activity-cms
log4j.logger.com.cqliving=DEBUG
引用項目配置:web.xml,或者springboot設置@WebListener
<listener>
<listener-class>com.cqliving.log.listener.LogApplicationListener</listener-class>
</listener>
效果: