Log4j生成压缩形式日志

Log4j生成压缩形式日志

转:http://blog.csdn.net/zhaosen241/article/details/3248331

 

Log4j提供了强大的日志功能,但是只能生成文本形式的日志文件,对于输出日志很频繁的应用会产生一些资源的浪费,例如我们的一个项目平均每20分钟就会生成一个大约10M的日志文件。为了节约硬盘资源,最近几天修改了一下Log4j,做了一个自己的版本将日志文件做成压缩包。

 

记录下这几天的工作吧:

 

1.       下载Log4j 1.2.15源代码,链接是:http://logging.apache.org/log4j/1.2/download.html

下载apache-log4j-1.2.15.tar.gz是带有源代码的包

 

2.       Log4j是用Maven2打包的,在链接http://maven.apache.org/download.html中下载

apache-maven-2.1.0-M1-bin.zip,这里需要注意下,2.0.9中有bug,打包会失败。

下载Maven后需要配置一下环境变量,就不细说了。

 

3.       下载安装MinGW,用来构建NTEventLogAppender.dll。下载链接:

http://mmtele3.skycn.com/down/MinGWStudioFullSetup-2_05.exe

 

4.       Maven打包Log4j工程没问题后就可以开始修改里面的源代码了。在前一篇blog中转载了关于log4j的详细信息,我们主要更改两种方式的log,一种是DailyRollingFileAppender,一种是RollingFileAppender

DailyRollingFileAppender在往日志文件打log的时候会检测日志文件上次修改的时间,如

果系统当前时间与上次修改时间不是一天,则将日志文件重新命名,在生成一个新的日志文件,例如日志文件是log.log,检测上次修改时间早于当天,则将log.log重命名为log.log.2008-11-7,并将log.log清空来打新的日志,其中2008-11-7是有配置文件指定的。

         RollingFileAppender在往日志文件打log的时候会根据配置文件设置的最大文件大小来与当前日志文件做比较,如果比文件大时,则将log文件重命名,规则为:根据最大日志备份个数做备份,例如最大日志备份个数设置为3,则将log.log更名为log.log.1log.log.2log.log.3、每次会判断这三个文件是否存在,如果存在,则将后缀最大的那个删掉,往后顺移一个,将log.log放到log.log.1中。

 

5.       现在需要做的就是将这两种方式的操作做一下修改。

DailyRollingFileAppender在判断需要将log.log重命名为log.log.2008-11-7时,我们将重命名这个操作改成将log.log打到zip包里面即可;同理,RollingFileAppender也是将文件重命名的操作改成打zip包。

 

6.       实现中主要需要修改两个类中的两个方法,相关代码如下:

DailyRollingFileAppender.java

修改方法rollOver

  

  1. void rollOver() throws IOException {
  2.         // Compute filename, but only if datePattern is specified 
  3.         if (datePattern == null) {
  4.           errorHandler.error("Missing DatePattern option in rollOver().");
  5.           return;
  6.         }
  7.         String datedFilename = fileName+sdf.format(now);
  8.         // It is too early to roll over because we are still within the
  9.         // bounds of the current interval. Rollover will occur once the
  10.         // next interval is reached.
  11.         if (scheduledFilename.equals(datedFilename)) {
  12.           return;
  13.         }
  14.         // close current file, and rename it to datedFilename
  15.         this.closeFile();
  16.         File target  = new File(scheduledFilename + ".zip");
  17.         if (target.exists()) {
  18.           target.delete();
  19.         }
  20.         //log old file 
  21.         File file = new File(fileName);
  22.         
  23.         //creat zip output stream to build zip file
  24.         ZipOutputStream out = null;
  25.        FileInputStream fin = null;
  26.        byte[] buf = new byte[1024];
  27.         
  28.        //file -> zip
  29.        try{
  30.            fin = new FileInputStream(file);
  31.            out = new ZipOutputStream(new FileOutputStream(scheduledFilename + ".zip"));
  32.            out.putNextEntry(new ZipEntry(file.getPath()));
  33.        
  34.            LogLog.debug(fileName + " -> " + scheduledFilename + ".zip");
  35.        
  36.            int len;
  37.            while ((len = fin.read(buf)) > 0) {
  38.               out.write(buf, 0, len);
  39.            }
  40.            
  41.            out.closeEntry();
  42.            fin.close();
  43.            
  44.            LogLog.debug(fileName + " -> " + scheduledFilename + ".zip successful!");
  45.        }catch(IOException e) {
  46.           errorHandler.error("add zip file("+scheduledFilename+") failed.");
  47.         }
  48.        finally{
  49.            if (out != null) {
  50.               out.closeEntry();
  51.               out.close();
  52.            }
  53.            if (fin != null)
  54.               fin.close();
  55.        }
  56.        
  57.        //delete old file
  58.        file.delete();
  59.        
  60.         try {
  61.           // This will also close the file. This is OK since multiple
  62.           // close operations are safe.
  63.           this.setFile(fileName, truethis.bufferedIO, this.bufferSize);
  64.         }
  65.         catch(IOException e) {
  66.           errorHandler.error("setFile("+fileName+", true) call failed.");
  67.         }
  68.         scheduledFilename = datedFilename;
  69.   }

 

RollingFileAppender.java

同样是修改rollOver方法:

  1. public// synchronization not necessary since doAppend is alreasy synched
  2.     void rollOver() {
  3.        File target;
  4.        File file;
  5.        if (qw != null) {
  6.            long size = ((CountingQuietWriter) qw).getCount();
  7.            LogLog.debug("rolling over count=" + size);
  8.            // if operation fails, do not roll again until
  9.            // maxFileSize more bytes are written
  10.            nextRollover = size + maxFileSize;
  11.        }
  12.        LogLog.debug("maxBackupIndex=" + maxBackupIndex);
  13.        boolean renameSucceeded = true;
  14.        // If maxBackups <= 0, then there is no file renaming to be done.
  15.        if (maxBackupIndex > 0) {
  16.            // Delete the oldest file, to keep Windows happy.
  17.            file = new File(fileName + maxBackupIndex + ".zip");
  18.            if (file.exists())
  19.               renameSucceeded = file.delete();
  20.            // Map {(maxBackupIndex - 1), ..., 2, 1} to {maxBackupIndex, ..., 3,
  21.            // 2}
  22.            for (int i = maxBackupIndex - 1; i >= 1 && renameSucceeded; i--) {
  23.               file = new File(fileName + i + ".zip");
  24.               if (file.exists()) {
  25.                   target = new File(fileName + (i + 1) + ".zip");
  26.                   LogLog.debug("Renaming file " + file + " to " + target);
  27.                   renameSucceeded = file.renameTo(target);
  28.               }
  29.            }
  30.            if (renameSucceeded) {
  31.               // zip fileName to fileName1.zip
  32.               
  33.               this.closeFile(); // keep windows happy.
  34.               file = new File(fileName);
  35.               // LogLog.debug("compress file " + file + " to " + target);
  36.               ZipOutputStream out = null;
  37.               FileInputStream fin = null;
  38.               byte[] buf = new byte[8192];
  39.               try {
  40.                   //create zip out put stream to build zip file
  41.                   fin = new FileInputStream(file);
  42.                   out = new ZipOutputStream(new FileOutputStream(fileName
  43.                          + 1 + ".zip"));
  44.                   out.putNextEntry(new ZipEntry(file.getPath()));
  45.                   LogLog.debug(fileName + " -> " + fileName + 1
  46.                          + ".zip");
  47.                   int len;
  48.                   while ((len = fin.read(buf)) > 0) {
  49.                      out.write(buf, 0, len);
  50.                   }
  51.                   out.closeEntry();
  52.                   fin.close();
  53.                   LogLog.debug(fileName + " -> " + fileName + 1
  54.                          + ".zip successful!");
  55.                   
  56.                   file.delete();
  57.               } catch (IOException e) {
  58.                   errorHandler.error("add zip file(" + fileName + 1
  59.                          + ".zip) failed.");
  60.               }finally{
  61.                   try {
  62.                      if (out != null) {
  63.                          out.closeEntry();
  64.                          out.close();
  65.                      }
  66.                      if (fin != null)
  67.                          fin.close();
  68.                   } catch (IOException e) {
  69.                      // TODO Auto-generated catch block
  70.                      errorHandler.error("close out and fin failed.");
  71.                   }
  72.               }
  73.               // if file compress failed, reopen file with append = true
  74.               //
  75.               if (!renameSucceeded) {
  76.                   try {
  77.                      this.setFile(fileName, true, bufferedIO, bufferSize);
  78.                   } catch (IOException e) {
  79.                      if (e instanceof InterruptedIOException) {
  80.                          Thread.currentThread().interrupt();
  81.                      }
  82.                      LogLog.error("setFile(" + fileName
  83.                             + ", true) call failed.", e);
  84.                   }
  85.               }
  86.            }
  87.        }
  88.        //
  89.        // if all renames were successful, then
  90.        //
  91.        if (renameSucceeded) {
  92.            try {
  93.               // This will also close the file. This is OK since multiple
  94.               // close operations are safe.
  95.               this.setFile(fileName, false, bufferedIO, bufferSize);
  96.               nextRollover = 0;
  97.            } catch (IOException e) {
  98.               if (e instanceof InterruptedIOException) {
  99.                   Thread.currentThread().interrupt();
  100.               }
  101.               LogLog
  102.                      .error("setFile(" + fileName + ", false) call failed.",
  103.                             e);
  104.            }
  105.        }
  106. }

 

7.       最后,由于打zip包的时候用到了Ant中的zip代码,下载带源代码的Ant包,链接是

http://archive.apache.org/dist/ant/source/apache-ant-1.6.5-src.zip 将里面zip的类放入log4j工程中,并用refactor将包重命名到org.apache.log4j中。

 

 

PS:这样做肯定会影响Log4j对输出日志的性能的影响,需要做进一步的性能方面的测试。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值