最近要实现定期删除N天前的日志。 以前都是利用运维的一个cron脚本来定期删除的, 总觉得可移植性不是很好, 比如要指定具体的日志文件路径, 有时候想想为什么log4j自己不实现这个功能呢? 后来发现在logback中已经实现了这个功能. 其配置如下:
- <appender name="vstore"
- class="ch.qos.logback.core.rolling.RollingFileAppender">
- <file>default.log</file>
- <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
- <fileNamePattern>./logs/%d/default.log.%d
- </fileNamePattern>
- <maxHistory>7</maxHistory>
- </rollingPolicy>
- <encoder>
- <pattern>%d{HH:mm:ss.SSS} %level [%thread] %c{0}[%line] %msg%n
- </pattern>
- </encoder>
- </appender>
但是我的应用因为依赖的log相关的jar包的问题, 没法使用logback的jar包, 因为必须使用新的方式来处理. 于是google了一下, 发现老外也遇到了类似的问题. 比如这里是一个解决办法:
http://stackoverflow.com/questions/1050256/how-can-i-get-log4j-to-delete-old-rotating-log-files
这个方式是采用的RollingFileAppender, 然后通过设置maxBackupIndex属性来指定要保留的日志的最大值(这里采用一天一个日志).但是我们一直采用的是DailyRollingFileAppender. 可是该appender没有maxBackupIndex这个属性, 于是又google了一把, 发现老外也想到的解决办法, 而且这里有两个解决方法, 即在RollingFileAppender的基础上, 加入了maxBackupIndex属性.
一种实现方案:
http://www.zybonics.com/zybocodes/code/CodeViewForm.php?codeID=428
- /**************************
- * Zybocodes *******************************
- * Code For :
- * log4j custom DailyRollingFileAppender - manage your
- * logs:maxBackupIndex zip roll archive logging log management
- * logs
- * Contributor : Ed Sarrazin
- * Ref link : http://jconvert.sourceforge.net
- * For this and other codes/logic under any technology visit:
- * http://www.zybonics.com/zybocodes/
- ********************************************************************/
- /*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.apache.org/licenses/LICENSE-2.0
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
- package logger;
- import java.io.File;
- import java.io.FileFilter;
- import java.io.FileInputStream;
- import java.io.FileOutputStream;
- import java.io.IOException;
- import java.io.InputStream;
- import java.io.InterruptedIOException;
- import java.text.ParseException;
- import java.text.SimpleDateFormat;
- import java.util.Calendar;
- import java.util.Date;
- import java.util.GregorianCalendar;
- import java.util.Locale;
- import java.util.TimeZone;
- import java.util.zip.ZipEntry;
- import java.util.zip.ZipInputStream;
- import java.util.zip.ZipOutputStream;
- import org.apache.log4j.FileAppender;
- import org.apache.log4j.Layout;
- import org.apache.log4j.helpers.LogLog;
- import org.apache.log4j.spi.LoggingEvent;
- /**
- * @author Ed Sarrazin
- * <pre>
- * AdvancedDailyRollingFileAppender is a copy of apaches DailyRollingFileAppender. This copy was made because it could not be extended due to package level access. This new version will allow two new properties to be set:
- * MaxNumberOfDays: Max number of log files to keep, denoted in days. If using compression, this days should be longer than
- * - CompressBackupsAfterDays and will become irrelevant as files will be moved to archive before this time.
- * CompressBackups: Indicating if older log files should be backed up to a compressed format.
- * RollCompressedBackups: TURE/FALSE indicating that compressed backups should be rolled out (deleted after certain age)
- * CompressBackupsAfterDays: Number of days to wait until adding files to compressed backup. (Files that are compressed are deleted)
- * CompressBackupsDatePattern: example - "'.'yyyy-MM" - this will create compressed backups grouped by pattern. In this example, every month
- * CompressMaxNumberDays: Number of days to keep compressed backups. RollCompressedBackups must be true.
- *
- * Here is a listing of the log4j.properties file you would use:
- *
- * log4j.appender.RootAppender=com.edsdev.log4j.AdvancedDailyRollingFileAppender
- * log4j.appender.RootAppender.DatePattern='.'yyyyMMdd
- * log4j.appender.RootAppender.MaxNumberOfDays=60
- * log4j.appender.RootAppender.CompressBackups=true
- * log4j.appender.RootAppender.CompressBackupsAfterDays=31
- * log4j.appender.RootAppender.CompressBackupsDatePattern='.'yyyyMM
- * log4j.appender.RootAppender.RollCompressedBackups=true
- * log4j.appender.RootAppender.CompressMaxNumberDays=365
- *
- * </pre>
- * AdvancedDailyRollingFileAppender extends {@link FileAppender} so that the underlying file is rolled over at a user
- * chosen frequency. AdvancedDailyRollingFileAppender has been observed to exhibit synchronization issues and data loss.
- * The log4j extras companion includes alternatives which should be considered for new deployments and which are
- * discussed in the documentation for org.apache.log4j.rolling.RollingFileAppender.
- * <p>
- * The rolling schedule is specified by the <b>DatePattern</b> option. This pattern should follow the
- * {@link SimpleDateFormat} conventions. In particular, you <em>must</em> escape literal text within a pair of single
- * quotes. A formatted version of the date pattern is used as the suffix for the rolled file name.
- * <p>
- * For example, if the <b>File</b> option is set to <code>/foo/bar.log</code> and the <b>DatePattern</b> set to
- * <code>'.'yyyy-MM-dd</code>, on 2001-02-16 at midnight, the logging file <code>/foo/bar.log</code> will be copied
- * to <code>/foo/bar.log.2001-02-16</code> and logging for 2001-02-17 will continue in <code>/foo/bar.log</code>
- * until it rolls over the next day.
- * <p>
- * Is is possible to specify monthly, weekly, half-daily, daily, hourly, or minutely rollover schedules.
- * <p>
- * <table border="1" cellpadding="2">
- * <tr>
- * <th>DatePattern</th>
- * <th>Rollover schedule</th>
- * <th>Example</th>
- * <tr>
- * <td><code>'.'yyyy-MM</code>
- * <td>Rollover at the beginning of each month</td>
- * <td>At midnight of May 31st, 2002 <code>/foo/bar.log</code> will be copied to <code>/foo/bar.log.2002-05</code>.
- * Logging for the month of June will be output to <code>/foo/bar.log</code> until it is also rolled over the next
- * month.
- * <tr>
- * <td><code>'.'yyyy-ww</code>
- * <td>Rollover at the first day of each week. The first day of the week depends on the locale.</td>
- * <td>Assuming the first day of the week is Sunday, on Saturday midnight, June 9th 2002, the file <i>/foo/bar.log</i>
- * will be copied to <i>/foo/bar.log.2002-23</i>. Logging for the 24th week of 2002 will be output to
- * <code>/foo/bar.log</code> until it is rolled over the next week.
- * <tr>
- * <td><code>'.'yyyy-MM-dd</code>
- * <td>Rollover at midnight each day.</td>
- * <td>At midnight, on March 8th, 2002, <code>/foo/bar.log</code> will be copied to
- * <code>/foo/bar.log.2002-03-08</code>. Logging for the 9th day of March will be output to <code>/foo/bar.log</code>
- * until it is rolled over the next day.
- * <tr>
- * <td><code>'.'yyyy-MM-dd-a</code>
- * <td>Rollover at midnight and midday of each day.</td>
- * <td>At noon, on March 9th, 2002, <code>/foo/bar.log</code> will be copied to
- * <code>/foo/bar.log.2002-03-09-AM</code>. Logging for the afternoon of the 9th will be output to
- * <code>/foo/bar.log</code> until it is rolled over at midnight.
- * <tr>
- * <td><code>'.'yyyy-MM-dd-HH</code>
- * <td>Rollover at the top of every hour.</td>
- * <td>At approximately 11:00.000 o'clock on March 9th, 2002, <code>/foo/bar.log</code> will be copied to
- * <code>/foo/bar.log.2002-03-09-10</code>. Logging for the 11th hour of the 9th of March will be output to
- * <code>/foo/bar.log</code> until it is rolled over at the beginning of the next hour.
- * <tr>
- * <td><code>'.'yyyy-MM-dd-HH-mm</code>
- * <td>Rollover at the beginning of every minute.</td>
- * <td>At approximately 11:23,000, on March 9th, 2001, <code>/foo/bar.log</code> will be copied to
- * <code>/foo/bar.log.2001-03-09-10-22</code>. Logging for the minute of 11:23 (9th of March) will be output to
- * <code>/foo/bar.log</code> until it is rolled over the next minute. </table>
- * <p>
- * Do not use the colon ":" character in anywhere in the <b>DatePattern</b> option. The text before the colon is
- * interpeted as the protocol specificaion of a URL which is probably not what you want.
- * @author Eirik Lygre
- * @author Ceki Gülcü
- */
- public class AdvancedDailyRollingFileAppender extends FileAppender {
- // The code assumes that the following constants are in a increasing
- // sequence.
- 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;
- /** Indicates if log files should be moved to archive file */
- private String compressBackups = "false";
- /** Indicates if archive file that may be created will be rolled off as it ages */
- private String rollCompressedBackups = "false";
- /** Maximum number of days to keep log files */
- private int maxNumberOfDays = 31;
- /** Number of days to wait before moving a log file to an archive */
- private int compressBackupsAfterDays = 31;
- /** Pattern used to name archive file (also controls what log files are grouped together */
- private String compressBackupsDatePattern = "'.'yyyy-MM";
- /** Maximum number of days to keep archive file before deleting */
- private int compressMaxNumberDays = 365;
- /**
- * The date pattern. By default, the pattern is set to "'.'yyyy-MM-dd" meaning daily rollover.
- */
- private String datePattern = "'.'yyyy-MM-dd";
- /**
- * The log file will be renamed to the value of the scheduledFilename variable when the next interval is entered.
- * For example, if the rollover period is one hour, the log file will be renamed to the value of "scheduledFilename"
- * at the beginning of the next hour. The precise time when a rollover occurs depends on logging activity.
- */
- private String scheduledFilename;
- /**
- * The next time we estimate a rollover should occur.
- */
- private long nextCheck = System.currentTimeMillis() - 1;
- Date now = new Date();
- SimpleDateFormat sdf;
- RollingCalendar rc = new RollingCalendar();
- int checkPeriod = TOP_OF_TROUBLE;
- // The gmtTimeZone is used only in computeCheckPeriod() method.
- static final TimeZone gmtTimeZone = TimeZone.getTimeZone("GMT");
- /**
- * The default constructor does nothing.
- */
- public AdvancedDailyRollingFileAppender() {
- }
- /**
- * Instantiate a <code>AdvancedDailyRollingFileAppender</code> and open the file designated by
- * <code>filename</code>. The opened filename will become the ouput destination for this appender.
- */
- public AdvancedDailyRollingFileAppender(Layout layout, String filename, String datePattern) throws IOException {
- super(layout, filename, true);
- this.datePattern = datePattern;
- activateOptions();
- }
- /**
- * The <b>DatePattern</b> takes a string in the same format as expected by {@link SimpleDateFormat}. This options
- * determines the rollover schedule.
- */
- public void setDatePattern(String pattern) {
- datePattern = pattern;
- }
- /** Returns the value of the <b>DatePattern</b> option. */