1 packagecom.hm.sage.bigdata.spark.log;2
3 importjava.io.File;4 importjava.io.FileInputStream;5 importjava.io.FileOutputStream;6 importjava.io.IOException;7 importjava.text.SimpleDateFormat;8 importjava.util.Date;9 importjava.util.zip.GZIPOutputStream;10
11 importorg.apache.log4j.RollingFileAppender;12 importorg.apache.log4j.helpers.CountingQuietWriter;13 importorg.apache.log4j.helpers.LogLog;14
15
16 public class RoolingAndDateFileAppender extendsRollingFileAppender {17
18 private String datePattern;//日期格式
19 private String dateStr = "";//文件后面的日期
20 private String expirDays = "1";//保留最近几天
21 private String isCleanLog = "true";//是否清日志
22 private String maxIndex = "100";//一天最多几个文件
23 private File rootDir;//父目录的抽象路径名
24 private String gzFormat = "gz";//压缩格式
25
26
27 /**
28 * 设置日期格式29 *30 *@paramdatePattern31 */
32 public voidsetDatePattern(String datePattern) {33 if (null != datePattern && !"".equals(datePattern)) {34 this.datePattern =datePattern;35 }36 }37
38 /**
39 * 获取日期格式40 *41 *@return
42 */
43 publicString getDatePattern() {44 return this.datePattern;45 }46
47 public voidrollOver() {48 //文件后面的日期
49 dateStr = new SimpleDateFormat(this.datePattern).format(newDate(System.currentTimeMillis()));50 File target = null;51 File file = null;52 if (qw != null) {53 //得到写入的字节数
54 long size = ((CountingQuietWriter) this.qw).getCount();55 LogLog.debug("rolling over count=" +size);56 }57 //默认情况下有一个备份文件
58 LogLog.debug("maxBackupIndex=" + this.maxBackupIndex);59 //如果maxIndex<=0则不需命名
60 if (maxIndex != null && Integer.parseInt(maxIndex) > 0) {61 //logRecoed.log.2018-08-24.562 //删除旧文件
63 file = new File(this.fileName + '.' + dateStr + '.' + Integer.parseInt(this.maxIndex) + '.' +gzFormat);64 if (file.exists()) {//测试用这个抽象路径名表示的文件或目录是否存在。65 //如果当天日志达到最大设置数量,则删除当天第一个日志,其他日志为尾号减一
66 Boolean boo =reLogNum();67 if (!boo) {68 LogLog.debug("日志滚动重命名失败!");69 }70 }71 }72 //获取当天日期文件个数
73 int count =cleanLog();74 //生成新文件75 //target=new File(fileName+"."+dateStr+"."+(count+1));
76 this.closeFile();//关闭先前打开的文件。
77 file = newFile(fileName);78
79 //creat zip output stream to build zip file
80 GZIPOutputStream gzout = null;81 FileInputStream fin = null;82 byte[] buf = new byte[1024];83
84 //file -> gz
85 try{86 fin = newFileInputStream(file);87 gzout = new GZIPOutputStream(new FileOutputStream(fileName + "." + dateStr + "." + (count + 1) + '.' +gzFormat));88
89 intnum;90 while ((num = fin.read(buf, 0, buf.length)) != -1) {91 gzout.write(buf, 0, num);92 }93 gzout.flush();94 gzout.finish();95
96 LogLog.debug(fileName + " -> " + fileName + "." + dateStr + "." + (count + 1) + '.' + gzFormat + " successful!");97 } catch(IOException e) {98 LogLog.error("add gz file(" + fileName + "." + dateStr + "." + (count + 1) + '.' + gzFormat + ") failed.");99 } finally{100 try{101 if (gzout != null) {102 gzout.close();103 }104 if (fin != null)105 fin.close();106 } catch(IOException e) {107 LogLog.error("close Stream failed");108 }109 }110
111 //delete old file
112 file.delete();113
114
115 //LogLog.debug("Renaming file"+file+"to"+target);116 //file.renameTo(target);//重命名file文件
117 try{118 setFile(this.fileName, false, this.bufferedIO, this.bufferSize);119 } catch(IOException e) {120 LogLog.error("setFile(" + this.fileName + ",false)call failed.", e);121 }122 }123
124 /**
125 * 获取当天日期文件个数126 *127 *@return
128 */
129 public intcleanLog() {130 int count = 0;//记录当天文件个数
131 if(Boolean.parseBoolean(isCleanLog)) {132 File f = newFile(fileName);133 //返回这个抽象路径名的父目录的抽象路径名
134 rootDir =f.getParentFile();135 //目录中所有文件。
136 File[] listFiles =rootDir.listFiles();137 for(File file : listFiles) {138 if(file.getName().contains(dateStr)) {139 count = count + 1;//是当天日志,则+1
140 } else{141 //不是当天日志需要判断是否到期删除
142 if(Boolean.parseBoolean(isCleanLog)) {143 //清除过期日志
144 String[] split = file.getName().split("\\\\")[0].split("\\.");145 //校验日志名字,并取出日期,判断过期时间
146 if (split.length == 4 && isExpTime(split[2])) {147 file.delete();148 }149 }150 }151 }152 }153 returncount;154 }155
156 /**
157 * 判断过期时间158 *159 *@paramtime160 *@return
161 */
162 publicBoolean isExpTime(String time) {163 SimpleDateFormat format = new SimpleDateFormat(this.datePattern);164 try{165 Date logTime =format.parse(time);166 Date nowTime = format.parse(format.format(newDate()));167 //算出日志与当前日期相差几天
168 int days = (int) (nowTime.getTime() - logTime.getTime()) / (1000 * 3600 * 24);169 if (Math.abs(days) >=Integer.parseInt(expirDays)) {170 return true;171 } else{172 return false;173 }174 } catch(Exception e) {175 LogLog.error(e.toString());176 return false;177 }178 }179
180 /**
181 * 如果当天日志达到最大设置数量,则每次删除尾号为1的日志,182 * 其他日志编号依次减去1,重命名183 *184 *@return
185 */
186 publicBoolean reLogNum() {187 boolean renameTo = false;188 File startFile = new File(this.fileName + '.' + dateStr + '.' + "1" + '.' +gzFormat);189 if (startFile.exists() && startFile.delete()) {//是否存并删除
190 for (int i = 2; i <= Integer.parseInt(maxIndex); i++) {191 File target = new File(this.fileName + '.' + dateStr + '.' + (i - 1) + '.' +gzFormat);192 this.closeFile();193 File file = new File(this.fileName + '.' + dateStr + '.' + i + '.' +gzFormat);194 renameTo = file.renameTo(target);//重命名file文件
195 }196 }197 returnrenameTo;198 }199
200 publicString getDateStr() {201 returndateStr;202 }203
204 public voidsetDateStr(String dateStr) {205 this.dateStr =dateStr;206 }207
208 publicString getExpirDays() {209 returnexpirDays;210 }211
212 public voidsetExpirDays(String expirDays) {213 this.expirDays =expirDays;214 }215
216 publicString getIsCleanLog() {217 returnisCleanLog;218 }219
220 public voidsetIsCleanLog(String isCleanLog) {221 this.isCleanLog =isCleanLog;222 }223
224 publicString getMaxIndex() {225 returnmaxIndex;226 }227
228 public voidsetMaxIndex(String maxIndex) {229 this.maxIndex =maxIndex;230 }231
232 }