package com.mttang.js.auth.util; 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 MttangLog4jRollingFileAppender 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"); // synchronization not necessary since doAppend is alreasy synched 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); // if operation fails, do not roll again until // maxFileSize more bytes are written 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 maxBackups <= 0, then there is no file renaming to be done. if(maxBackupIndex > 0) { // Delete the oldest file, to keep Windows happy. file = new File(newFileName +'.'+nowDateString+'.' +getIndex(maxBackupIndex,maxBackupIndexLeng)); if (file.exists()){ renameSucceeded = file.delete(); } // Map {(maxBackupIndex - 1), ..., 2, 1} to {maxBackupIndex, ..., 3, 2} 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+"\t beginFileData="+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 file rename failed, reopen file with append = true // 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 will also close the file. This is OK since multiple // close operations are safe. 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为当前日期。 super.setFile(fileName, append, this.bufferedIO, this.bufferSize); } 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配置文件:
<appender class=" com.mttang.log4j.MyRollingFileAppender">
<param value=" D:/data/test/yyyy-MM-dd/test.log"/>
<param value="true"/>
<param value="50KB"/><!-每个文件50KB->
<param value="10"/><!-每天的日期目录下10个日志文件->
<layout class="org.apache.log4j.PatternLayout">
<param value="%c %d{ISO8601}-- %p -- %m%n"/>
</layout>
<filter class="org.apache.log4j.varia.LevelRangeFilter">
<param value="INFO" />
<param value="INFO" />
<param value=" http://wwww.baoshengdianzi.com " />
</filter>
</appender>
金属膜电阻供应商 http://wwww.baoshengdianzi.com