2019-10-31 1543 星期四 enAn
说明
1. 重写的 Log4jFile extends RollingFileAppender
2. Log4jFile.java 中的格式化类型与log4j.properties中的输出的文件目录一致 log4j.appender.logFile.File=${log.home.dir}/yyyy/MM/dd/web.log
3. 指向自己重写的类 log4j.appender.logFile=com.ecommerce.platform.common.log.Log4jFile
4. 另外log4j.properties中
log4j.rootLogger的变量logFile,必需与log4j.appender.logFile=com.ecommerce.platform.common.log.Log4jFile保持一致,不然不会输出日志
5.监听器,把变量设置到环境中 [设置到系统属性集 ]java.util.Properties
System.out.println(className + "[设置到系统属性集 ]");
props.setProperty(InitConstant.DUBBO_REGISTRY_APPLICATION, dubbo_registry_application);//dubbo注册的应用名字
props.setProperty(InitConstant.DUBBO_REGISTRY_ADDRESS,dubbo_registry_address);//dubbo:注册地址
props.setProperty(InitConstant.DUBBO_CATALINA_HOME, dubbo_catalina_home);//dubbo缓存文件位置
props.setProperty(InitConstant.LOG_HOME_DIR, log_dir);//log日志文件位置
**
log4j.properties和spring-mvc.xml,取监听器中设置的值
**
log4j.properties 设置值
log4j.appender.logFile.File=${log.home.dir}/yyyy/MM/dd/web.log
spring-mvc.xml 设置值
<!-- 消费方应用名,用于计算依赖关系,不是匹配条件,不要与提供方一样 -->
<dubbo:application name="#{systemProperties['dubbo.registry.application']}" />
<!-- 使用zookeeper注册中心暴露服务地址 -->
<dubbo:registry protocol="zookeeper" address="#{systemProperties['dubbo.registry.address']}" file="#{systemProperties['dubbo.catalina.home']}"/>
log4j.properties配置文件内容
log4j.rootLogger=INFO,DEBUG,console,logFile,ERROR
## 控制台,begin ##
log4j.appender.console=org.apache.log4j.ConsoleAppender
log4j.appender.console.layout=org.apache.log4j.PatternLayout
log4j.appender.console.layout.ConversionPattern=%d{yyyy-MM-dd HH\:mm\:ss} %-5p [%t] %c.%M(%L) - %m%n
## 控制台,end ##
### 输出到控制台,begin ###
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
### 输出到控制台,end ###
### 日志文件设置,begin ###
log4j.appender.logFile=com.ecommerce.platform.common.log.Log4jFile
#输出DEBUG级别日志到文件中
log4j.appender.logFile.Threshold=debug
log4j.appender.logFile.File=${log.home.dir}/yyyy/MM/dd/web.log
log4j.appender.logFile.layout=org.apache.log4j.PatternLayout
log4j.appender.logFile.DatePattern='_'yyyy-MM-dd'.log'
log4j.appender.logFile.layout.ConversionPattern=%d{yyyy-MM-dd HH\:mm\:ss} %-5p [%t] %c.%M(%L) - %m%n
log4j.appender.logFile.MaxFileSize=50MB
### 日志文件设置,end ###
## 指定dao输出sql ##
# 打印sql语句:debug; 执行结果:trace ##
## 指定mapper配置文件中的namespace ##
## (log4j.logger.包名)原因是mybatis设置日志打印级别为TRACE即可输出sql文及sql参数和结果集。 ##
### sql ,begin ###
log4j.logger.com.ibatis=debug
log4j.logger.com.ibatis.common.jdbc.SimpleDataSource=debug
log4j.logger.com.ibatis.common.jdbc.ScriptRunner=debug
log4j.logger.com.ibatis.sqlmap.engine.impl.SqlMapClientDelegate=debug
## ********************************* ##
log4j.logger.java.sql.Connection=debug
log4j.logger.java.sql.Statement=debug
log4j.logger.java.sql.PreparedStatement=debug,stdout
## ********************************* ##
log4j.logger.jdbc.sqlonly=OFF
log4j.logger.jdbc.sqltiming=OFF
log4j.logger.jdbc.audit=OFF
log4j.logger.jdbc.resultset=OFF
log4j.logger.jdbc.connection=OFF
### sql ,end ###
把监听器加放web.xml中
<!-- 自定义监听器,加载指定属性文件中的内容 -->
<listener>
<listener-class>com.ecommerce.platform.listener.InitSystemConfigListener</listener-class>
</listener>
监听器
package com.ecommerce.platform.listener;
import java.util.Map;
import java.util.Properties;
import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import com.ecommerce.platform.common.constant.InitConstant;
import com.ecommerce.platform.common.exception.CommonConfigException;
import com.ecommerce.platform.common.util.LoadProperties;
import com.ecommerce.platform.common.util.PropertiesUtil;
/**
* .::::.
* .::::::::.
* ::::::::::: I && YOU
* ..:::::::::::'
* '::::::::::::'
* .::::::::::
* '::::::::::::::..
* ..::::::::::::.
* ``::::::::::::::::
* ::::``:::::::::' .:::.
* ::::' ':::::' .::::::::.
* .::::' :::: .:::::::'::::.
* .:::' ::::: .:::::::::' ':::::.
* .::' :::::.:::::::::' ':::::.
* .::' ::::::::::::::' ``::::.
* ...::: ::::::::::::' ``::.
* ````':. ':::::::::' ::::..
* '.:::::' ':'````..
* 自定义监听器,加载属性文件中定义的变量值,在web.xml中使用,特别是配置log4j的值
* @author enAn,2019-07-22
* 参考:https://blog.csdn.net/liufunan/article/details/50715167
*/
public class InitSystemConfigListener implements ServletContextListener {
public static final String className = "初始化-自定义监听器[InitSystemConfigListener]...";
public void contextDestroyed(ServletContextEvent sce) {
System.out.println(className + "web exit ... ");
}
public void contextInitialized(ServletContextEvent sce) {
try {
Map<String, String> initPropertiesData = PropertiesUtil.getInitProperties();
String log_dir = "";
String dubbo_catalina_home = "";
System.out.println(className + "init");
Properties props= System.getProperties(); //获得系统属性集
String os = props.getProperty(InitConstant.OS_NAME);
String osVersion = props.getProperty(InitConstant.OS_VERSION); //操作系统版本
String javaVersion = props.getProperty(InitConstant.JAVA_VERSION); //Java 运行时环境版本
System.out.println(className + "当前操作系统是 :" + os);
System.out.println(className + "操作系统的版本 :" + osVersion );
System.out.println(className + "java版本 :" + javaVersion );//当前操作系统是:Windows 7
//**************************************************************************************************************
//加载web.xml中的配置信息
//将Map通过ServletContext存储到全局作用域中
ServletContext sct = sce.getServletContext();
System.out.println(className + "项目名称:" + sct.getInitParameter("MakroProject"));
String classpath = this.getClass().getResource("/").getPath();
System.out.println(className + "classpath:" + classpath);
String type = "";
if ( os != null && os.toLowerCase().startsWith(InitConstant.WIN)) {
//window操作系统[D:/DevelopInstall/Tomcat/apache-tomcat-7.0.41/webapps/ecommerce-web/WEB-INF/classes/]
classpath = classpath.replaceFirst("/", "");
type = InitConstant.WIN;
System.out.println(className + "[type:" + type + "]" + "1.操作系统:" +InitConstant.WIN + ",classpath:" + classpath);
}else if(os != null && os.toLowerCase().startsWith(InitConstant.LINUX)) {
//linux操作系统
type = InitConstant.LINUX;
System.out.println(className + "[type:" + type + "]" + "1.操作系统:" +InitConstant.LINUX);
}else {
throw new CommonConfigException("当前操作系统既不是:" + InitConstant.WIN +"系统,又不是:" + InitConstant.LINUX + "系统");
}
String webAppRoot = classpath.replaceAll("WEB-INF/classes/", "");
System.out.println(className + "webAppRoot:" + webAppRoot);
String configPath = webAppRoot + "WEB-INF/properties/init.properties";
System.out.println(className + "配置文件全路径:" + configPath);
if (type .equals(InitConstant.WIN)) { //window操作系统
dubbo_catalina_home = LoadProperties.getProperty(configPath, InitConstant.DUBBO_CATALINA_HOME_WIN, "");
log_dir = LoadProperties.getProperty(configPath, InitConstant.LOG_DIR_WIN,"");
}else if(type .equals(InitConstant.LINUX)) { //linux操作系统
dubbo_catalina_home = LoadProperties.getProperty(configPath, InitConstant.DUBBO_CATALINA_HOME_LINUX, "");
log_dir = LoadProperties.getProperty(configPath, InitConstant.LOG_DIR_LINUX,"");
}
String altMsg = "配置属性文件有误,请检查:";
String dubbo_registry_application = LoadProperties.getProperty(configPath, InitConstant.DUBBO_REGISTRY_APPLICATION, "");
if(null == dubbo_registry_application || dubbo_registry_application.equals("")) {
throw new CommonConfigException(altMsg + "dubbo注册的应用名字");
}
String dubbo_registry_address = initPropertiesData.get(InitConstant.DUBBO_REGISTRY_ADDRESS);
if(null == dubbo_registry_address || dubbo_registry_address.equals("")) {
throw new CommonConfigException(altMsg + "dubbo注册的地址" + ":为空");
}
if(null == dubbo_catalina_home || dubbo_catalina_home.equals("")) {
throw new CommonConfigException(altMsg + "dubbo缓存文件位置" + ":为空");
}
if(null == log_dir || log_dir.equals("")) {
throw new CommonConfigException(altMsg + "log日志文件位置" + ":为空");
}
//*****************1.[设置到系统属性集 ]*************************************************************
System.out.println(className + "[设置到系统属性集 ]");
props.setProperty(InitConstant.DUBBO_REGISTRY_APPLICATION, dubbo_registry_application);//dubbo注册的应用名字
props.setProperty(InitConstant.DUBBO_REGISTRY_ADDRESS,dubbo_registry_address);//dubbo:注册地址
props.setProperty(InitConstant.DUBBO_CATALINA_HOME, dubbo_catalina_home);//dubbo缓存文件位置
props.setProperty(InitConstant.LOG_HOME_DIR, log_dir);//log日志文件位置
//***************2.[设置到ServletContext存储到全局作用域中里面]***************************************************************
System.out.println(className + "[设置到ServletContext存储到全局作用域中里面]");
sct.setAttribute(InitConstant.DUBBO_REGISTRY_APPLICATION, dubbo_registry_application);
sct.setAttribute(InitConstant.DUBBO_REGISTRY_ADDRESS, dubbo_registry_address);
sct.setAttribute(InitConstant.DUBBO_CATALINA_HOME, dubbo_catalina_home);
sct.setAttribute(InitConstant.LOG_HOME_DIR, log_dir);
//***********3.[设置到系统里面]**********************
System.out.println(className + "[设置到系统里面]");
System.setProperty(InitConstant.DUBBO_REGISTRY_APPLICATION, dubbo_registry_application);
System.setProperty(InitConstant.DUBBO_REGISTRY_ADDRESS, dubbo_registry_address);
System.setProperty(InitConstant.DUBBO_CATALINA_HOME, dubbo_catalina_home);
System.setProperty(InitConstant.LOG_HOME_DIR, log_dir);
//******************************************************************************
System.out.println(className + "dubbo注册的应用名字:" + dubbo_registry_application);
System.out.println(className + "dubbo注册的地址:" + dubbo_registry_address);
System.out.println(className + "dubbo缓存文件位置:" + dubbo_catalina_home);
System.out.println(className + "log日志文件位置:" + log_dir);
} catch (Exception e) {
e.printStackTrace();
throw new RuntimeException(className + e.getMessage());
}
}
}
重写log类
package com.ecommerce.platform.common.log;
import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import org.apache.log4j.RollingFileAppender;
import org.apache.log4j.helpers.CountingQuietWriter;
import org.apache.log4j.helpers.LogLog;
import org.apache.log4j.spi.LoggingEvent;
/**
* 继承log4j的RollingFileAppender类
* 参考:https://blog.csdn.net/a15123837995/article/details/88388797
* @author Administrator 2019-10-29 星期二
*
*/
public class Log4jFile extends RollingFileAppender {
/**
* 格式与log4j.properties中属性:log4j.appender.logFile.File匹配对应
* log4j.appender.logFile.File=${log.home.dir}/yyyy/MM/interface.log
*/
private static String dateFormate = "yyyy/MM/dd";
private long nextRollover = 0;
private static Map<String, BeginFileData> fileMaps = new HashMap<String, BeginFileData>();
private static final SimpleDateFormat sdf = new SimpleDateFormat(dateFormate);
public void rollOver () {
File target;
File file;
int maxBackupIndexLeng = String.valueOf(maxBackupIndex).length();
if (qw != null) {
long size = ((CountingQuietWriter) qw).getCount();
LogLog.debug("rolling over count = " + size);
nextRollover = size + maxFileSize;
}
LogLog.debug("maxBackupIndex=" + maxBackupIndex);
String nowDateString = sdf.format(new Date());
String newFileName = ((fileName.indexOf(".") != -1) ? fileName.substring(0,fileName.lastIndexOf(".")) : fileName);
boolean renameSucceeded = true;
if (maxBackupIndex > 0) {
file = new File(newFileName + '.' + nowDateString + '.' + getIndex(maxBackupIndex, maxBackupIndexLeng));
if (file.exists()) {
renameSucceeded = file.delete();
}
for (int i = maxBackupIndex - 1; (i >= 1 && renameSucceeded); i--) {
file = new File(newFileName + '.' + nowDateString + '.'+ getIndex(i, maxBackupIndexLeng));
if (file.exists()) {
target = new File(newFileName + '.' + nowDateString + '.' + getIndex(i + 1, maxBackupIndexLeng));
LogLog.debug("Renaming file " + file + " to " + target);
renameSucceeded = file.renameTo(target);
}
}
if (renameSucceeded) {
BeginFileData beginFileData = fileMaps.get(fileName);
System.out.println("fileName= " + fileName + "\tbeginFileData="+ beginFileData);
// 在每天一个日志目录的方式下,检测日期是否变更了,如果变更了就要把变更后的日志文件拷贝到变更后的日期目录下。
if (newFileName.indexOf(nowDateString) == -1 && beginFileData.getFileName().indexOf(dateFormate) != -1) {
newFileName = beginFileData.getFileName().replace(dateFormate,nowDateString);
newFileName = (newFileName.indexOf(".") != -1 ? newFileName.substring(0, newFileName.lastIndexOf(".")) : newFileName);
}
target = new File(newFileName + '.' + nowDateString + '.'+ getIndex(1, maxBackupIndexLeng));
this.closeFile();
file = new File(fileName);
LogLog.debug("Renaming file " + file + " to " + target);
renameSucceeded = file.renameTo(target);
if (!renameSucceeded) {
try {
this.setFile(fileName, true, bufferedIO, bufferSize);
} catch (IOException e) {
LogLog.error("setFile(" + fileName + ", true) call failed.", e);
}
}
}
}
//
// if all renames were successful, then
//
if (renameSucceeded) {
try {
this.setFile(fileName, false, bufferedIO, bufferSize);
nextRollover = 0;
} catch (IOException e) {
LogLog.error("setFile(" + fileName + ", false) call failed.", e);
}
}
}
/**
* 文件个数的长度补零,如果文件个数为10那么文件的个数长度就是2位,第一个文件就是01,02,03....
*
* @param i
* @param maxBackupIndexLeng
* @return
*/
private String getIndex (int i, int maxBackupIndexLeng) {
String index = String.valueOf(i);
int len = index.length();
for (int j = len; j < maxBackupIndexLeng; j++) {
index = "0" + index;
}
return index + ".log";
}
/**
* This method differentiates RollingFileAppender from its super class.
*
* @since 0.9.0
*/
protected void subAppend (LoggingEvent event) {
super.subAppend(event);
if (fileName != null && qw != null) {
String nowDate = sdf.format(new Date());
// 检测日期是否已经变更了,如果变更了就要重创建日期目录
if (!fileMaps.get(fileName).getDate().equals(nowDate)) {
rollOver();
return;
}
long size = ((CountingQuietWriter) qw).getCount();
if (size >= maxFileSize && size >= nextRollover) {
rollOver();
}
}
}
@Override
public synchronized void setFile (String fileName, boolean append,boolean bufferedIO, int bufferSize) throws IOException {
String nowDate = sdf.format(new Date());
// 如果文件路径包含了“yyyy-MM-dd”就是每天一个日志目录的方式记录日志(第一次的时候)
if (fileName.indexOf(dateFormate) != -1) {
String beginFileName = fileName;
fileName = fileName.replace(dateFormate, nowDate);
fileMaps.put(fileName, new BeginFileData(beginFileName, nowDate));
}
BeginFileData beginFileData = fileMaps.get(fileName);
// 检测日期是否已经变更了,如果变更了就要把原始的字符串给fileName变量,把变更后的日期做为开始日期
if (!beginFileData.getDate().equals(nowDate)) {
// 获取出第一次的文件名
beginFileData.setDate(nowDate);
fileName = beginFileData.getFileName().replace(dateFormate, nowDate);
fileMaps.put(fileName, beginFileData);
}
// D:/data/test/yyyy-MM-dd/test.log 替换yyyy-MM-dd为当前日期。
File file = new File(fileName);
File parentFile = file.getParentFile();
if (!parentFile.exists()) {
parentFile.mkdirs();
}
super.setFile(fileName, append, this.bufferedIO, this.bufferSize);
}
@SuppressWarnings("unused")
private class BeginFileData {
private String fileName;
private String date;
public BeginFileData (String fileName, String date) {
super();
this.fileName = fileName;
this.date = date;
}
public String getFileName () {
return fileName;
}
public void setFileName (String fileName) {
this.fileName = fileName;
}
public String getDate () {
return date;
}
public void setDate (String date) {
this.date = date;
}
}
}
项目结构
版权声明:本文为yuxueyuanwj原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。