日志 log4j按日期生成文件夹

        期望结果:按日期生成文件夹,在最底层文件夹中记录日志,如:2019/03/11,在11这个文件夹下记录11号的日志,03和2019均为11的父文件夹。

        API:log4j

        主要步骤:继承log4j的org.apache.log4j.RollingFileAppender类,重写setFile、subAppend方法

        配置文件:修改log4j的配置文件,将使用的类指向自己写的继承的类,改写日志文件目录格式

java代码:

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类  
public class Log4jFileUpdate extends RollingFileAppender {

	private long nextRollover = 0;
	private static Map<String, BeginFileData> fileMaps = new HashMap<String, BeginFileData>();
	private static final SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd");

	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("yyyy/MM/dd") != -1) {
					newFileName = beginFileData.getFileName().replace("yyyy/MM/dd",
							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("yyyy/MM/dd") != -1) {
			String beginFileName = fileName;
			fileName = fileName.replace("yyyy/MM/dd", 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("yyyy/MM/dd", 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);
	}

	private class BeginFileData {

		public BeginFileData (String fileName, String date) {
			super();
			this.fileName = fileName;
			this.date = date;
		}

		private String fileName;
		private String 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;
		}
	}
}

log4j配置文件:

log4j.rootLogger=console,logErrFile,logfile
log4j.additivity.org.apache=true
log4j.logger.org.apache=off
log4j.logger.com.mchange=off
## (console)
log4j.appender.console=org.apache.log4j.ConsoleAppender
log4j.appender.console.Threshold=DUBUG
log4j.appender.console.ImmediateFlush=true
log4j.appender.console.Target=System.out
log4j.appender.console.layout=org.apache.log4j.PatternLayout
log4j.appender.console.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss}:%p %t %c - %m%n

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}:%p %t %l - %m%n

## (file: ERROR)
log4j.appender.logErrFile=util.Log4jFileUpdate
log4j.appender.logErrFile.Threshold=ERROR
log4j.appender.logErrFile.ImmediateFlush=true
log4j.appender.logErrFile.Append=true
log4j.appender.logErrFile.File=logger/yyyy/MM/dd/error_logs.log
log4j.appender.logErrFile.layout=org.apache.log4j.PatternLayout
log4j.appender.logErrFile.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss}:%p %t %c - %m%n
##log4j.appender.logErrFile.DatePattern =yyyyMMdd

log4j.appender.logfile=util.Log4jFileUpdate
log4j.appender.logfile.File=logger/yyyy/MM/dd/all.log
log4j.appender.logfile.MaxFileSize=10MB
log4j.appender.logfile.layout=org.apache.log4j.PatternLayout
log4j.appender.logfile.layout.ConversionPattern=%d{yyyy-MM-dd HH\:mm\:ss\:SSS}\: %p %t %l - %m%n

效果:

附:

      效果二:将java代码和配置文件中的yyyy/MM/dd改成yyyy-MM-dd即可

猜你喜欢

转载自blog.csdn.net/a15123837995/article/details/88388797