日誌 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即可

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章