|
@@ -10,13 +10,18 @@
|
|
|
package org.apache.hadoop.chukwa.inputtools.log4j;
|
|
|
|
|
|
import java.io.File;
|
|
|
+import java.io.FilenameFilter;
|
|
|
import java.io.IOException;
|
|
|
import java.text.SimpleDateFormat;
|
|
|
+import java.util.ArrayList;
|
|
|
import java.util.Calendar;
|
|
|
+import java.util.Collections;
|
|
|
import java.util.Date;
|
|
|
import java.util.GregorianCalendar;
|
|
|
+import java.util.List;
|
|
|
import java.util.Locale;
|
|
|
import java.util.TimeZone;
|
|
|
+import java.util.regex.Pattern;
|
|
|
|
|
|
import org.apache.hadoop.chukwa.datacollection.controller.ChukwaAgentController;
|
|
|
import org.apache.hadoop.chukwa.util.RecordConstants;
|
|
@@ -130,8 +135,7 @@ import org.apache.log4j.spi.LoggingEvent;
|
|
|
<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. */
|
|
|
-
|
|
|
-
|
|
|
+
|
|
|
public class ChukwaDailyRollingFileAppender extends FileAppender {
|
|
|
|
|
|
static Logger log = Logger.getLogger(ChukwaDailyRollingFileAppender.class);
|
|
@@ -172,6 +176,16 @@ public class ChukwaDailyRollingFileAppender extends FileAppender {
|
|
|
The next time we estimate a rollover should occur. */
|
|
|
private long nextCheck = System.currentTimeMillis () - 1;
|
|
|
|
|
|
+ /**
|
|
|
+ * Regex to select log files to be deleted
|
|
|
+ */
|
|
|
+ private String cleanUpRegex = null;
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Set the maximum number of backup files to keep around.
|
|
|
+ */
|
|
|
+ private int maxBackupIndex = 10;
|
|
|
+
|
|
|
Date now = new Date();
|
|
|
|
|
|
SimpleDateFormat sdf;
|
|
@@ -351,6 +365,7 @@ public class ChukwaDailyRollingFileAppender extends FileAppender {
|
|
|
}
|
|
|
|
|
|
File file = new File(fileName);
|
|
|
+
|
|
|
boolean result = file.renameTo(target);
|
|
|
if(result) {
|
|
|
LogLog.debug(fileName +" -> "+ scheduledFilename);
|
|
@@ -367,8 +382,82 @@ public class ChukwaDailyRollingFileAppender extends FileAppender {
|
|
|
errorHandler.error("setFile("+fileName+", false) call failed.");
|
|
|
}
|
|
|
scheduledFilename = datedFilename;
|
|
|
+ cleanUp();
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ public String getCleanUpRegex() {
|
|
|
+ return cleanUpRegex;
|
|
|
+ }
|
|
|
+
|
|
|
+ public void setCleanUpRegex(String cleanUpRegex) {
|
|
|
+ this.cleanUpRegex = cleanUpRegex;
|
|
|
+ }
|
|
|
+
|
|
|
+ public int getMaxBackupIndex() {
|
|
|
+ return maxBackupIndex;
|
|
|
+ }
|
|
|
+
|
|
|
+ public void setMaxBackupIndex(int maxBackupIndex) {
|
|
|
+ this.maxBackupIndex = maxBackupIndex;
|
|
|
}
|
|
|
|
|
|
+ protected synchronized void cleanUp() {
|
|
|
+ String regex = "";
|
|
|
+ try {
|
|
|
+ File actualFile = new File(fileName);
|
|
|
+
|
|
|
+ String directoryName = actualFile.getParent();
|
|
|
+ String actualFileName = actualFile.getName();
|
|
|
+ File dirList = new File(directoryName);
|
|
|
+
|
|
|
+
|
|
|
+ if (cleanUpRegex == null || !cleanUpRegex.contains("$fileName")) {
|
|
|
+ LogLog.error("cleanUpRegex == null || !cleanUpRegex.contains(\"$fileName\")");
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ regex =cleanUpRegex.replace("$fileName", actualFileName);
|
|
|
+ String[] dirFiles = dirList.list(new LogFilter(actualFileName,regex));
|
|
|
+
|
|
|
+ List<String> files = new ArrayList<String>();
|
|
|
+ for(String file: dirFiles) {
|
|
|
+ files.add(file);
|
|
|
+ }
|
|
|
+ Collections.sort(files);
|
|
|
+
|
|
|
+ while(files.size() > maxBackupIndex) {
|
|
|
+ String file = files.remove(0);
|
|
|
+ File f = new File(directoryName + "/" +file);
|
|
|
+ f.delete();
|
|
|
+ LogLog.debug("Removing: " +file);
|
|
|
+ }
|
|
|
+ } catch(Exception e) {
|
|
|
+ errorHandler.error("cleanUp("+fileName+"," + regex +") call failed.");
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private class LogFilter implements FilenameFilter {
|
|
|
+ private Pattern p = null;
|
|
|
+ private String logFile = null;
|
|
|
+
|
|
|
+ public LogFilter(String logFile,String regex) {
|
|
|
+ this.logFile = logFile;
|
|
|
+ p = Pattern.compile(regex);
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public boolean accept(File dir, String name) {
|
|
|
+ // ignore current log file
|
|
|
+ if (name.intern() == this.logFile.intern() ) {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ //ignore file without the same prefix
|
|
|
+ if (!name.startsWith(logFile)) {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ return p.matcher(name).find();
|
|
|
+ }
|
|
|
+ }
|
|
|
|
|
|
private class ClientFinalizer extends Thread
|
|
|
{
|
|
@@ -614,3 +703,4 @@ int type = ChukwaDailyRollingFileAppender.TOP_OF_TROUBLE;
|
|
|
return getTime();
|
|
|
}
|
|
|
}
|
|
|
+
|