日志log4j按日期生成文件夹


按日期生成文件夹,自动清理N天前的日志。并且可以设置每个文件最大内存为多少,以及当天允许生成的最大文件个数

 

 API:log4j

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

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

 

JAVA代码

  1 package com.montnets.ljbank.util;
  2 
  3 
  4 import java.io.File;
  5 import java.io.IOException;
  6 import java.text.ParseException;
  7 import java.text.SimpleDateFormat;
  8 import java.util.Date;
  9 import java.util.HashMap;
 10 import java.util.Map;
 11 import java.util.regex.Matcher;
 12 import java.util.regex.Pattern;
 13 
 14 import org.apache.log4j.RollingFileAppender;
 15 import org.apache.log4j.helpers.CountingQuietWriter;
 16 import org.apache.log4j.helpers.LogLog;
 17 import org.apache.log4j.spi.LoggingEvent;
 18 
 19 import com.montnets.ljbank.constant.ConfigConstant;
 20 
 21 //继承log4j的RollingFileAppender类  
 22 public class MyRollingFileAppender extends RollingFileAppender {
 23 
 24     private long nextRollover = 0;
 25     private static Map<String, BeginFileData> fileMaps = new HashMap<String, BeginFileData>();
 26     private static final SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd");
 27     private static final SimpleDateFormat sdf1 = new SimpleDateFormat("yyyy-MM-dd");
 28 
 29     public void rollOver () {
 30 
 31         File target;
 32         File file;
 33         int maxBackupIndexLeng = String.valueOf(maxBackupIndex).length();
 34         if (qw != null) {
 35             long size = ((CountingQuietWriter) qw).getCount();
 36             LogLog.debug("rolling over count=" + size);
 37             nextRollover = size + maxFileSize;
 38         }
 39         //1
 40         LogLog.debug("maxBackupIndex=" + maxBackupIndex);
 41         String nowDateString = sdf.format(new Date());
 42         String newFileName = (fileName.indexOf(".") != -1 ? fileName.substring(0,
 43                 fileName.lastIndexOf(".")) : fileName);
 44 
 45         boolean renameSucceeded = true;
 46         String nowDateStr = sdf1.format(new Date());
 47         if (maxBackupIndex > 0) {
 48 
 49             
 50 //            file = new File(newFileName + '.' + nowDateString + '.'
 51 //                    + getIndex(maxBackupIndex, maxBackupIndexLeng));
 52             
 53             file = new File(newFileName + '.' + nowDateStr + '.'
 54                     + getIndex(maxBackupIndex, maxBackupIndexLeng));
 55 
 56             if (file.exists()) {
 57                 renameSucceeded = file.delete();
 58             }
 59             /**
 60              * 删除最后一个文件,文件名+1
 61              * */        
 62             for (int i = maxBackupIndex - 1; (i >= 1 && renameSucceeded); i--) {
 63 //                file = new File(newFileName + '.' + nowDateString + '.'
 64 //                        + getIndex(i, maxBackupIndexLeng));
 65                 file = new File(newFileName + '.' + nowDateStr + '.'
 66                         + getIndex(i, maxBackupIndexLeng));
 67                 if (file.exists()) {
 68                     //行动文件名
 69 //                    target = new File(newFileName + '.' + nowDateString + '.'
 70 //                            + getIndex(i + 1, maxBackupIndexLeng));
 71                     target = new File(newFileName + '.' + nowDateStr + '.'
 72                             + getIndex(i + 1, maxBackupIndexLeng));
 73                     LogLog.debug("Renaming file " + file + " to " + target);
 74                     renameSucceeded = file.renameTo(target);
 75                 }
 76             }
 77 
 78             if (renameSucceeded) {
 79                 BeginFileData beginFileData = fileMaps.get(fileName);
 80                 // 在每天一个日志目录的方式下,检测日期是否变更了,如果变更了就要把变更后的日志文件拷贝到变更后的日期目录下。
 81                 String pattern = "yyyy/MM/dd";
 82                 if (newFileName.indexOf(nowDateString) == -1
 83                         && beginFileData.getFileName().indexOf(pattern) != -1) {
 84                     newFileName = beginFileData.getFileName().replace(pattern,
 85                             nowDateString);
 86                     newFileName = (newFileName.indexOf(".") != -1 ? newFileName
 87                             .substring(0, newFileName.lastIndexOf(".")) : newFileName);
 88                 }
 89 //                target = new File(newFileName + '.' + nowDateString + '.'
 90 //                        + getIndex(1, maxBackupIndexLeng));
 91                 target = new File(newFileName + '.' + nowDateStr + '.'
 92                         + getIndex(1, maxBackupIndexLeng));
 93                 this.closeFile();
 94                 file = new File(fileName);
 95                 LogLog.debug("Renaming file " + file + " to " + target);
 96 
 97                 renameSucceeded = file.renameTo(target);
 98                 if (!renameSucceeded) {
 99                     try {
100                         this.setFile(fileName, true, bufferedIO, bufferSize);
101                     } catch (IOException e) {
102                         LogLog.error("setFile(" + fileName + ", true) call failed.", e);
103                     }
104                 }
105             }
106         }
107         if (renameSucceeded) {
108 
109             try {
110 
111                 this.setFile(fileName, false, bufferedIO, bufferSize);
112                 nextRollover = 0;
113             } catch (IOException e) {
114                 LogLog.error("setFile(" + fileName + ", false) call failed.", e);
115             }
116         }
117         //删除指定日期前文件
118         //清理指定日期前的日志
119         String rootDir = (fileName.indexOf("/") != -1 ? fileName.substring(0,
120                 fileName.indexOf("/")) : fileName);
121         long expireTime = ConfigConstant.MAXDAYS*24*60*60*1000L; //ConfigConstant.MAXDAYS是从配置文件中读取的一个常量,表示日志保留天数 122         cleanExpireFiles(rootDir,expireTime);
123     }
124 
125     /**
126      * 文件个数的长度补零,如果文件个数为10那么文件的个数长度就是2位,第一个文件就是01,02,03....
127      * 
128      * @param i
129      * @param maxBackupIndexLeng
130      * @return
131      */
132     private String getIndex (int i, int maxBackupIndexLeng) {
133         String index = String.valueOf(i);
134         int len = index.length();
135         for (int j = len; j < maxBackupIndexLeng; j++) {
136             index = "0" + index;
137         }
138         return index + ".log";
139     }
140 
141     /**
142      * This method differentiates RollingFileAppender from its super class.
143      * 
144      * @since 0.9.0
145      */
146     protected void subAppend (LoggingEvent event) {
147         super.subAppend(event);
148         if (fileName != null && qw != null) {
149 
150             String nowDate = sdf.format(new Date());
151             // 检测日期是否已经变更了,如果变更了就要重创建日期目录
152             if (!fileMaps.get(fileName).getDate().equals(nowDate)) {
153                 rollOver();
154                 return;
155             }
156 
157             long size = ((CountingQuietWriter) qw).getCount();
158             if (size >= maxFileSize && size >= nextRollover) {
159                 rollOver();
160             }
161         }
162     }
163 
164     private void cleanExpireFiles(String savePath,long expireTime) {
165         //日志根目录
166         File fileRootDir= new File(savePath);
167         if(!fileRootDir.exists()){
168             return;
169         }
170         //遍历根目录下的文件夹
171         //如果文件是n天前的就删除
172         //当前时间
173         long currentTime =System.currentTimeMillis();
174         File file = null;
175         try{
176             
177             File[] files = fileRootDir.listFiles();
178             if(files != null && files.length > 0){
179                 for(int i = 0; i< files.length; i++){
180                     file = files[i];
181                     long fileTime = file.lastModified();
182                     if(file.isDirectory()){
183                         cleanExpireFiles(file.getAbsolutePath(),expireTime);
184                         //文件夹内文件为空,则删除成功
185                         file.delete();
186                     }else{
187                         //获取文件中的日期
188                         String fileTimeStr = getRqStr(file.getName());
189                         Date fileDate = null;
190                         try {
191                             if(fileTimeStr !=null){
192                                 fileDate =sdf1.parse(fileTimeStr);
193                                 fileTime = fileDate.getTime();
194                             }
195                         } catch (ParseException e) {
196                             fileTime = currentTime;
197 //                            fileTime = file.lastModified();
198                         }
199                         //如果文件最后更新时间是N天前就删除
200                         if(currentTime - fileTime > expireTime){
201                             file.delete();
202                         }
203                     }
204             }
205           }    
206         }catch (Exception e) {
207             LogLog.error("删除过期日志失败!", e);
208         }
209     }
210 
211     @Override
212     public synchronized void setFile (String fileName, boolean append,
213             boolean bufferedIO, int bufferSize) throws IOException {
214 
215         String pattern = "yyyy/MM/dd";
216         String nowDate = sdf.format(new Date());
217         // 如果文件路径包含了“yyyy-MM-dd”就是每天一个日志目录的方式记录日志(第一次的时候)
218         if (fileName.indexOf(pattern) != -1) {
219             String beginFileName = fileName;
220             fileName = fileName.replace(pattern, nowDate);
221             fileMaps.put(fileName, new BeginFileData(beginFileName, nowDate));
222         }
223         BeginFileData beginFileData = fileMaps.get(fileName);
224         // 检测日期是否已经变更了,如果变更了就要把原始的字符串给fileName变量,把变更后的日期做为开始日期
225         if (!beginFileData.getDate().equals(nowDate)) {
226             // 获取出第一次的文件名
227             beginFileData.setDate(nowDate);
228             fileName = beginFileData.getFileName().replace(pattern, nowDate);
229             fileMaps.put(fileName, beginFileData);
230         }
231 
232         // D:/data/test/yyyy-MM-dd/test.log 替换yyyy-MM-dd为当前日期。
233         File file = new File(fileName);
234         File parentFile = file.getParentFile();
235         if (!parentFile.exists()) {
236             parentFile.mkdirs();
237         }
238 
239         super.setFile(fileName, append, this.bufferedIO, this.bufferSize);
240     }
241     
242     /**
243      * 获取文件中的日期
244      * @param mes
245      * @return
246      */
247     public static String getRqStr(String mes){
248         String format = ".*([0-9]{4})-(0[1-9]|1[012])-(0[1-9]|[12][0-9]|3[01]).*";
249         String yms = null;
250         Pattern pattern = Pattern.compile(format);
251         Matcher matcher = pattern.matcher(mes);
252         if (matcher.matches()) {
253             pattern = Pattern.compile(".*(\\d{4}-\\d{2}-\\d{2}).*");
254             matcher = pattern.matcher(mes);
255             if (matcher.matches()) {
256                 yms = matcher.group(1);
257             }
258             return yms;
259         }
260         return yms;
261     
262     }
263     public static void main(String[] args) {
264         String rootDir = "E:\\dell\\workspaces\\MyEclipse 10\\ljBank\\logger";
265         long expireTime = 1*24*60*60*1000L;
266         new MyRollingFileAppender().cleanExpireFiles(rootDir,expireTime);
267     }
268 
269     private class BeginFileData {
270 
271         public BeginFileData (String fileName, String date) {
272             super();
273             this.fileName = fileName;
274             this.date = date;
275         }
276 
277         private String fileName;
278         private String date;
279 
280         public String getFileName () {
281             return fileName;
282         }
283         public void setFileName (String fileName) {
284             this.fileName = fileName;
285         }
286         public String getDate () {
287             return date;
288         }
289         public void setDate (String date) {
290             this.date = date;
291         }
292     }
293 }

 

log4j.properties

log4j.rootLogger=console,logfile
log4j.additivity.org.apache=true
log4j.logger.org.apache=off
log4j.logger.com.mchange=off

# 配置为继承RollingFileAppender类重写其方法的子类
log4j.appender.logfile=com.montnets.ljbank.util.MyRollingFileAppender
log4j.appender.logfile.File=logger/yyyy/MM/dd/ljBankLog.log
log4j.appender.logfile.Threshold=INFO
# 每个日志文件的最大内存
log4j.appender.logfile.MaxFileSize=20MB
# 一天内允许生成日志文件的最大个数
log4j.appender.logfile.maxBackupIndex=30
log4j.appender.logfile.layout=org.apache.log4j.PatternLayout
log4j.appender.logfile.layout.ConversionPattern=[%p]%d{yy/MM/dd HH\:mm\:ss\:SSS} %m%n

 

 

 

 

参考地址 https://blog.csdn.net/a15123837995/article/list/1?


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM