The logs in the project need to adopt a consistent naming convention and File specification: Project module Identification _index_ Date Time _ Log level. log, and each level log file in a separate folder, and the number of logs under each folder must not exceed 10, when the number exceeds the limit, delete the relatively old log, keep the newer log. However, discovering that log4j does not meet this requirement, it then defines its own fileappender according to the LOG4J API.
The code is as follows:
Package com.dear.simpler.dbrpc.util.log;
Import Java.io.File;
Import java.io.IOException;
Import java.io.InterruptedIOException;
Import Java.text.SimpleDateFormat;
Import Java.util.Arrays;
Import Java.util.Comparator;
Import Java.util.Date;
Import Java.util.concurrent.atomic.AtomicInteger;
Import Java.util.regex.Matcher;
Import Java.util.regex.Pattern;
Import Org.apache.log4j.RollingFileAppender;
Import Org.apache.log4j.helpers.CountingQuietWriter;
Import Org.apache.log4j.helpers.LogLog;
Import org.apache.log4j.spi.LoggingEvent;
/**; * * @author Lixiang * Custom log file naming rules */public class Mylogfileappender extends Rollingfileappender {private
Long nextrollover = 0; private static Atomicinteger Logindex = new Atomicinteger (0);
Index public void Rollover () {file file = null;
if (QW!= null) {Long size = (countingquietwriter) qw). GetCount ();
Loglog.debug ("Rolling over count=" + size); If operation fails, don't roll again until//MaxFileSize more bytes are written
over = size + maxfilesize;
} loglog.debug ("maxbackupindex=" + maxbackupindex);
if (Maxbackupindex > 0) {file = new file (Getrollingfilename (FileName, Logindex.incrementandget ()));
if (fileexisted (file)) {file = new file (Getrollingfilename (FileName, Logindex.incrementandget ()));
} deleteoldfile (File.getparentfile (), maxbackupindex);
This.closefile ();
try {this.setfile (Getrollingfilename (FileName, Logindex.get ()), False, Bufferedio, buffersize);
Nextrollover = 0; The catch (IOException e) {if (e instanceof interruptedioexception) {Thread.CurrentThread (). In
Terrupt ();
Loglog.error ("Setfile (" + FileName + ", false) call failed.", e);
}private string Getrollingfilename (string fileName, int index) {//using regular expressions instead of index pattern P = Patter
N.compile ("_\\d+\\_");
Matcher M=p.matcher (fileName);
String str = m.replacefirst (String.Format ("_%d_", index)); SimpleDateFormat format = new SimpleDateFormat ("Yyyymmddhhmmss");
Date String datestring = Format.format (new date (System.currenttimemillis ());
str = Str.replaceall ("\\d{14}", datestring);
return str; Public synchronized void Setfile (String filename, boolean append,///modify filename boolean bufferedio, int buff Ersize) throws IOException {SimpleDateFormat format = new SimpleDateFormat ("Yyyymmddhhmmss");
Date String datestring = Format.format (new date (System.currenttimemillis ()); String temp = String.Format (FileName, datestring);
FileName Super.setfile (temp, append, Bufferedio, buffersize); if (append) {File f = new File (temp);
((Countingquietwriter) this.qw). SetCount (F.length ());
} Private Boolean fileexisted (file file) {Boolean res = false;
string[] FTs = File.getname (). Split ("_");
File parentfile = File.getparentfile ();
For (File f:parentfile.listfiles ()) {string[] Fns = F.getname (). Split ("_");
if (Fns[0].equals (fts[0]) && fns[1].equals (fts[1)) {res = true;
Break
} return res; } private void Deleteoldfile (File dir, int maxint) {if (Getfilenum (dir) >= Maxbackupindex) {file[
] files = orderbydate (dir);
for (int i = 0; I <= files.length-maxbackupindex; i++) {File f = files[i];
F.delete ();
}} private int getfilenum (file file) {return file.list (). length;
()//Sort files by date public file[] orderbydate (file dir) {file[] fs = Dir.listfiles (); Arrays.sort (fs,new comparator< File>() {@Override public int compare (file f1, file F2) {long diff = f1.lastmodified ()-F2.lastmo
Dified ();
if (diff > 0) return 1;
else if (diff = = 0) return 0;
else return-1;
@Override public boolean equals (Object obj) {return true;
}
});
return FS;
} @Override protected void Subappend (Loggingevent event) {super.subappend (event);
if (fileName!= null && QW!= null) {Long size = ((Countingquietwriter) QW). GetCount ();
if (size >= maxfilesize && size >= nextrollover) {rollover ();
}
}
}
}
The corresponding log4j.properties configuration file is as follows:
### set log levels ### Log4j.rootlogger = Out,e,i #log4j. Logger.com.dear.simpler.dbrpc.util.log.testutil=out,d log4j. Appender. D = Com.dear.simpler.dbrpc.util.log.MyLogFileAppender Log4j.appender.d.file =.. /..
/logs/db_logs/debug/db_0_%s_debug.log Log4j.appender.d.append = True LOG4J.APPENDER.D.MAXFILESIZE=1024MB log4j.appender.d.maxbackupindex=10 Log4j.appender.d.threshold = DEBUG Log4j.appender.d.layout = Com.dear.simpler.dbrpc.util.log.ExPatternLayout Log4j.appender.d.layout.conversionpattern = [%d{yyyy/mm/dd hh:mm:
ss,sss}][%t:%t][%p][%f:%l:%m][%m]%n LOG4J.APPENDER.E = Com.dear.simpler.dbrpc.util.log.MyLogFileAppender Log4j.appender.e.file =.. /..
/logs/db_logs/error/db_0_%s_error.log Log4j.appender.e.append = True LOG4J.APPENDER.E.MAXFILESIZE=10MB log4j.appender.e.maxbackupindex=10 Log4j.appender.e.threshold = ERROR Log4j.appender.e.layout = Com.dear.simpler.dbrpc.util.log.ExPatternLayout Log4j.appender.e.layout.conversionpattern = [%d{yyyy/mm/dd hh:mm: SS,SSS}][%t:%t][%p][%f:%l:%m][%m]%n log4j.appender.i = Com.dear.simpler.dbrpc.util.log.MyLogFileAppender Log4j.appender.i.file =.. /..
/logs/db_logs/info/db_0_%s_info.log Log4j.appender.i.append = True LOG4J.APPENDER.I.MAXFILESIZE=10MB log4j.appender.i.maxbackupindex=10 Log4j.appender.i.threshold = INFO Log4j.appender.i.layout = Com.dear.simpler.dbrpc.util.log.ExPatternLayout Log4j.appender.i.layout.conversionpattern = [%d{yyyy/mm/dd hh:mm:
ss,sss}][%t:%t][%p][%f:%l:%m][%m]%n
The output log files are named as follows: