log4j定时轮换文件
// <logger name="ASYNC_LOGGER">Logger logger = Logger.getLogger("ASYNC_LOGGER");
?
2、使用仓库配置多个不同的log4j配置文件
?
LoggerRepository loggerRepository1 = new Hierarchy(new RootCategory(Level.DEBUG));String path = new File("log4j_1.xml").getAbsolutePath();new DOMConfigurator().doConfigure(path,loggerRepository1);Logger log_1 = loggerRepository1.getLogger("TEST_LOGGER_1");LoggerRepository loggerRepository2 = new Hierarchy(new RootCategory(Level.DEBUG));path = new File("log4j_2.xml").getAbsolutePath();new DOMConfigurator().doConfigure(path,loggerRepository2);Logger log_2 = loggerRepository2.getLogger("TEST_LOGGER_2");?
?
?-------------------------------------------
轮换文件
?
? log4j可以按大小轮换文件(FileAppender, fileSize), 按天轮换文件 (DailyRollingFileAppender )
在我的某个应用场景中,使用log4j做数据落地,就是把每条日志数据格式化后,写入本地日志文件。
然后通过一个进程来读取所有轮换后的文件,分析每一条数据,入库(mongodb)。
做了如下的修改
1、除了使用文件大小来做轮换规则外,添加一个rollTime属性,表示需要轮换的时间s。
如果文件一直为0,不轮换,创建文件时记录下时间戳,定时与当前时间比较,超过rollTime,强制轮换。
2、同时修改轮换文件名称规则,默认的是.1,.2...这种形式。修改为.时间戳的形式。
其实还自定义了一个简单的Layout序列化数据。这个不是必须的。
?
使用方法,在log4j.xml中,
?
<appender
??value="1024" />
??<param name="Encoding" value="UTF-8" />
??<param name="File" value="esb.log" />
??<!--
???<param name="BufferSize" value="8192" />
???<param name="BufferedIO" value="true" />
??-->
??<param name="ImmediateFlush" value="true" />
??<param name="RollTime" value="60" />
??<param name="MaxFileSize" value="100MB" />
?? ......
?
import java.io.File;import java.io.IOException;import java.io.InterruptedIOException;import java.io.Writer;import java.util.Timer;import java.util.TimerTask;import org.apache.log4j.FileAppender;import org.apache.log4j.helpers.CountingQuietWriter;import org.apache.log4j.helpers.LogLog;import org.apache.log4j.helpers.OptionConverter;import org.apache.log4j.spi.LoggingEvent;/** * TODO 根据时间和大小轮换文件 * * @author kimmking (mailto:qinjw@primeton.com) */public class TimeRollingFileAppender extends FileAppender {/** * The default maximum file size is 10MB. */protected long maxFileSize = 10 * 1024 * 1024;/** * There is one backup file by default. */protected int maxBackupIndex = 1;private long nextRollover = 0;protected int rollTime = 60; // secondslong fileTimeStamp = 0;Timer timer = null;private TimerTask getTask() {return new TimerTask() {@Overridepublic void run() {// 时间戳long result = System.currentTimeMillis() - fileTimeStamp - getRollTime() * 1000;if (result > 0)if (new File(fileName).length() > 0)rollOver();}};}/** * The default constructor simply calls its * {@link FileAppender#FileAppender parents constructor}. */public TimeRollingFileAppender() {super();timer = new Timer("TimeRollingFileAppender", true);long period = rollTime * 1000;TimerTask task = getTask();timer.schedule(task, period, 1l); // 从一个轮换时间间隔以后,每秒检查一次}/** * Returns the value of the <b>MaxBackupIndex</b> option. */public int getMaxBackupIndex() {return maxBackupIndex;}/** * Get the maximum size that the output file is allowed to reach before * being rolled over to backup files. * * @since 1.1 */public long getMaximumFileSize() {return maxFileSize;}/** * Implements the usual roll over behaviour. * * <p> * If <code>MaxBackupIndex</code> is positive, then files { * <code>File.1</code>, ..., <code>File.MaxBackupIndex -1</code> are * renamed to {<code>File.2</code>, ..., * <code>File.MaxBackupIndex</code> . Moreover, <code>File</code> is * renamed <code>File.1</code> and closed. A new <code>File</code> is * created to receive further log output. * * <p> * If <code>MaxBackupIndex</code> is equal to zero, then the * <code>File</code> is truncated with no backup files created. */public// synchronization not necessary since doAppend is alreasy synchedsynchronized void rollOver() {File target;File file;if (qw != null) {long size = ((CountingQuietWriter) qw).getCount();LogLog.debug("rolling over count=" + size);// if operation fails, do not roll again until// maxFileSize more bytes are writtennextRollover = size + maxFileSize;}// LogLog.debug("maxBackupIndex=" + maxBackupIndex);long timestamp = System.currentTimeMillis();boolean renameSucceeded = true;// If maxBackups <= 0, then there is no file renaming to be done.// if (maxBackupIndex > 0) {// // Delete the oldest file, to keep Windows happy.// file = new File(fileName + '.' + maxBackupIndex);// if (file.exists())// renameSucceeded = file.delete();// // Map {(maxBackupIndex - 1), ..., 2, 1} to {maxBackupIndex, ..., 3,// // 2}// for (int i = maxBackupIndex - 1; i >= 1 && renameSucceeded; i--) {// file = new File(fileName + "." + i);// if (file.exists()) {// target = new File(fileName + '.' + (i + 1));// LogLog.debug("Renaming file " + file + " to " + target);// renameSucceeded = file.renameTo(target);// }// }//// if (renameSucceeded) {// Rename fileName to fileName.1target = new File(fileName + "." + timestamp);this.closeFile(); // keep windows happy.file = new File(fileName);LogLog.debug("Renaming file " + file + " to " + target);renameSucceeded = file.renameTo(target);//// if file rename failed, reopen file with append = true//if (!renameSucceeded) {try {this.setFile(fileName, true, bufferedIO, bufferSize);} catch (IOException e) {if (e instanceof InterruptedIOException) {Thread.currentThread().interrupt();}LogLog.error("setFile(" + fileName + ", true) call failed.", e);}}// }// }//// if all renames were successful, then//if (renameSucceeded) {try {// This will also close the file. This is OK since multiple// close operations are safe.this.setFile(fileName, false, bufferedIO, bufferSize);nextRollover = 0;} catch (IOException e) {if (e instanceof InterruptedIOException) {Thread.currentThread().interrupt();}LogLog.error("setFile(" + fileName + ", false) call failed.", e);}}}public synchronized void setFile(String fileName, boolean append, boolean bufferedIO, int bufferSize) throws IOException {File file = new File(fileName).getParentFile();if (!file.exists())file.mkdirs();super.setFile(fileName, append, this.bufferedIO, this.bufferSize);if (append) {File f = new File(fileName);((CountingQuietWriter) qw).setCount(f.length());}fileTimeStamp = System.currentTimeMillis();}public void setRollTime(int rollTime) {if (this.rollTime == rollTime)return;this.rollTime = rollTime;// if (this.timer != null) {// this.timer.cancel();// }// this.timer = new Timer("TimeRollingFileAppender", true);//// if (rollTime > 0) {// long period = rollTime * 1000;// this.timer.schedule(getTask(), period, period);// }}public final int getRollTime() {return this.rollTime;}/** * Set the maximum number of backup files to keep around. * * <p> * The <b>MaxBackupIndex</b> option determines how many backup files are * kept before the oldest is erased. This option takes a positive integer * value. If set to zero, then there will be no backup files and the log * file will be truncated when it reaches <code>MaxFileSize</code>. */public void setMaxBackupIndex(int maxBackups) {this.maxBackupIndex = maxBackups;}/** * Set the maximum size that the output file is allowed to reach before * being rolled over to backup files. * * <p> * This method is equivalent to {@link #setMaxFileSize} except that it is * required for differentiating the setter taking a <code>long</code> * argument from the setter taking a <code>String</code> argument by the * JavaBeans {@link java.beans.Introspector Introspector}. * * @see #setMaxFileSize(String) */public void setMaximumFileSize(long maxFileSize) {this.maxFileSize = maxFileSize;}/** * Set the maximum size that the output file is allowed to reach before * being rolled over to backup files. * * <p> * In configuration files, the <b>MaxFileSize</b> option takes an long * integer in the range 0 - 2^63. You can specify the value with the * suffixes "KB", "MB" or "GB" so that the integer is interpreted being * expressed respectively in kilobytes, megabytes or gigabytes. For example, * the value "10KB" will be interpreted as 10240. */public void setMaxFileSize(String value) {maxFileSize = OptionConverter.toFileSize(value, maxFileSize + 1);}protected void setQWForFiles(Writer writer) {this.qw = new CountingQuietWriter(writer, errorHandler);}/** * This method differentiates RollingFileAppender from its super class. * * @since 0.9.0 */protected void subAppend(LoggingEvent event) {super.subAppend(event);if (fileName != null && qw != null) {long size = ((CountingQuietWriter) qw).getCount();if (size >= maxFileSize && size >= nextRollover) {rollOver();}}}}?
?
?
<p>?? ......</p>