123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240 |
- package org.apache.log4j;
- import java.text.*;
- import java.io.*;
- import org.apache.log4j.helpers.*;
- import java.util.*;
- import java.util.zip.GZIPOutputStream;
- import org.apache.log4j.spi.*;
- /**
- * 替换log4j包里的DailyRollingFileAppender类,
- * 增加文件压缩流程,
- * @author xu.zhou
- * @date 20211108
- */
- public class CompressDailyRollingFileAppender extends FileAppender
- {
- static final int TOP_OF_TROUBLE = -1;
- static final int TOP_OF_MINUTE = 0;
- static final int TOP_OF_HOUR = 1;
- static final int HALF_DAY = 2;
- static final int TOP_OF_DAY = 3;
- static final int TOP_OF_WEEK = 4;
- static final int TOP_OF_MONTH = 5;
- private String datePattern;
- private String scheduledFilename;
- private long nextCheck;
- Date now;
- SimpleDateFormat sdf;
- RollingCalendar rc;
- int checkPeriod;
- static final TimeZone gmtTimeZone;
-
- public CompressDailyRollingFileAppender() {
- this.datePattern = "'.'yyyy-MM-dd";
- this.nextCheck = System.currentTimeMillis() - 1L;
- this.now = new Date();
- this.rc = new RollingCalendar();
- this.checkPeriod = -1;
- }
-
- public CompressDailyRollingFileAppender(final Layout layout, final String filename, final String datePattern) throws IOException {
- super(layout, filename, true);
- this.datePattern = "'.'yyyy-MM-dd";
- this.nextCheck = System.currentTimeMillis() - 1L;
- this.now = new Date();
- this.rc = new RollingCalendar();
- this.checkPeriod = -1;
- this.datePattern = datePattern;
- this.activateOptions();
- }
-
- public void setDatePattern(final String pattern) {
- this.datePattern = pattern;
- }
-
- public String getDatePattern() {
- return this.datePattern;
- }
-
- public void activateOptions() {
- super.activateOptions();
- if (this.datePattern != null && super.fileName != null) {
- this.now.setTime(System.currentTimeMillis());
- this.sdf = new SimpleDateFormat(this.datePattern);
- final int type = this.computeCheckPeriod();
- this.printPeriodicity(type);
- this.rc.setType(type);
- final File file = new File(super.fileName);
- this.scheduledFilename = super.fileName + this.sdf.format(new Date(file.lastModified()));
- }
- else {
- LogLog.error("Either File or DatePattern options are not set for appender [" + super.name + "].");
- }
- }
-
- void printPeriodicity(final int type) {
- switch (type) {
- case 0: {
- LogLog.debug("Appender [" + super.name + "] to be rolled every minute.");
- break;
- }
- case 1: {
- LogLog.debug("Appender [" + super.name + "] to be rolled on top of every hour.");
- break;
- }
- case 2: {
- LogLog.debug("Appender [" + super.name + "] to be rolled at midday and midnight.");
- break;
- }
- case 3: {
- LogLog.debug("Appender [" + super.name + "] to be rolled at midnight.");
- break;
- }
- case 4: {
- LogLog.debug("Appender [" + super.name + "] to be rolled at start of week.");
- break;
- }
- case 5: {
- LogLog.debug("Appender [" + super.name + "] to be rolled at start of every month.");
- break;
- }
- default: {
- LogLog.warn("Unknown periodicity for appender [" + super.name + "].");
- break;
- }
- }
- }
-
- int computeCheckPeriod() {
- final RollingCalendar rollingCalendar = new RollingCalendar(CompressDailyRollingFileAppender.gmtTimeZone, Locale.ENGLISH);
- final Date epoch = new Date(0L);
- if (this.datePattern != null) {
- for (int i = 0; i <= 5; ++i) {
- final SimpleDateFormat simpleDateFormat = new SimpleDateFormat(this.datePattern);
- simpleDateFormat.setTimeZone(CompressDailyRollingFileAppender.gmtTimeZone);
- final String r0 = simpleDateFormat.format(epoch);
- rollingCalendar.setType(i);
- final Date next = new Date(rollingCalendar.getNextCheckMillis(epoch));
- final String r2 = simpleDateFormat.format(next);
- if (r0 != null && r2 != null && !r0.equals(r2)) {
- return i;
- }
- }
- }
- return -1;
- }
-
- /**
- * 日志滚动
- * @throws IOException
- */
- void rollOver() throws IOException {
- if (this.datePattern == null) {
- super.errorHandler.error("Missing DatePattern option in rollOver().");
- return;
- }
- String dateStr = this.sdf.format(this.now);
- final String datedFilename = super.fileName + dateStr;
- //要删除的文件是否与最后的日志文件相同,说明此文件还不要处理,正在写入
- if (this.scheduledFilename.equals(datedFilename)) {
- return;
- }
- this.closeFile();
- //生成要滚动的文件
- final File target = new File(this.scheduledFilename);
- if (target.exists()) {
- //System.out.println("删除文件=>"+target.getName());
- target.delete();
- }
- //System.out.println("datePattern=>"+datePattern);
- //System.out.println("datedFilename=>"+datedFilename);
- //System.out.println("scheduledFilename=>"+this.scheduledFilename);
- //System.out.println("super.fileName=>"+super.fileName);
- final File file = new File(super.fileName);
- //把正在写入的日志文件更名为带日期的日志文件
- final boolean result = file.renameTo(target);
- if (result) {
- LogLog.debug(super.fileName + " -> " + this.scheduledFilename);
- }
- else {
- LogLog.error("Failed to rename [" + super.fileName + "] to [" + this.scheduledFilename + "].");
- }
- try {
- this.setFile(super.fileName, false, super.bufferedIO, super.bufferSize);
- }
- catch (IOException e) {
- super.errorHandler.error("setFile(" + super.fileName + ", false) call failed.");
- }
-
- //压缩日志后删除文件
- zipfile(this.scheduledFilename);
-
- this.scheduledFilename = datedFilename;
-
- }
- /**
- * 压缩日志后删除文件
- * @param fileName
- */
- private void zipfile(String fileName){
- //System.out.println("zipfile.fileName========================"+fileName);
- File file = new File(fileName);
-
- //creat zip output stream to build zip file
- GZIPOutputStream gzout = null;
- FileInputStream fin = null;
- byte[] buf = new byte[1024];
-
- //file -> gz
- try {
- fin = new FileInputStream(file);
- gzout = new GZIPOutputStream(new FileOutputStream(fileName + ".gz"));
-
- int num;
- while ((num = fin.read(buf, 0, buf.length)) != -1) {
- gzout.write(buf, 0, num);
- }
- gzout.flush();
- gzout.finish();
-
- LogLog.debug(fileName + " -> " + fileName + ".gz" + " successful!");
- } catch (IOException e) {
- LogLog.error("add gz file(" + fileName + ".gz" + ") failed.");
- } finally {
- try {
- if (gzout != null) {
- gzout.close();
- }
- if (fin != null)
- fin.close();
- } catch (IOException e) {
- LogLog.error("close Stream failed");
- }
- }
-
- //delete old file
- file.delete();
- }
-
- protected void subAppend(final LoggingEvent event) {
- final long n = System.currentTimeMillis();
- if (n >= this.nextCheck) {
- this.now.setTime(n);
- this.nextCheck = this.rc.getNextCheckMillis(this.now);
- try {
- this.rollOver();
- }
- catch (IOException ioe) {
- LogLog.error("rollOver() failed.", ioe);
- }
- }
- super.subAppend(event);
- }
-
- static {
- gmtTimeZone = TimeZone.getTimeZone("GMT");
- }
- }
|