- 浏览: 546600 次
- 性别:
- 来自: 中华大丈夫学院
文章分类
最新评论
-
lxmin0702:
你好,我刚下载了您的附件,但是发现里面并没有正文所提到的Lis ...
SWT中ole/activex实践--操作word的一个例子 -
kkkwoai:
我想请教下 我有个要求是实现ppt解析为图片,用的是jac ...
Office 开发: 现实生活中的 OBA 解决方案模式 -
pengshan:
However, the mutability of the ...
【翻译】Spring Integration参考手册-第二章 -
kms1989:
导出pdf中文乱码怎么搞?
jsPDF介绍与兼容IE的补丁 -
kms1989:
你好,请问不支持中文怎么解决?
jsPDF介绍与兼容IE的补丁
网友 zhangyang6380006在帖子
http://www.iteye.com/topic/1006088
正好做过,就丢出来献丑了。
-------------------------------------------------------------------------------
同步异步
另外log4j是异步输出,服务停止的瞬间不保证能输出所有的log,如果是精确度高的业务也许不合适
http://www.iteye.com/topic/900845
log4j内置的三种 输出方式
flush=true 直接输出到文件,同步不缓存
bufferedIO 按一定字节大小缓存,同步缓存
AsynFileAppender 按一定的条数缓存,异步输出
-------------------------------------------------------------------------------
仓库与自定义配置
说到log4j,大家最常见的用法就是 配置一个log4j.xml或properties,放在classpath的根目录下。
在里面配置上多个Appender,多个package对应的Logger或是Category,然后在代码里,直接用Class获取logger。
其实还有两点可以提一提:
1、使用命名logger,而不是class
// <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
class="xxx.log.TimeRollingFileAppender"
name="ROLLING_FILE">
<param name="MaxBackupIndex" 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; // seconds long fileTimeStamp = 0; Timer timer = null; private TimerTask getTask() { return new TimerTask() { @Override public 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 synched synchronized 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 written nextRollover = 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.1 target = 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(); } } } }
评论
但是我的需求是不行的。
rollover后的文件,我有一个进程处理入库。
这个进程是与生成log的esb进程独立的。
我的需求里,入库的数据要求延迟不能太大。
就是说:esb里来了一条数据,我必须让它在2分钟内在governor的控制台上可以看到。
ps:其实可以esb的log直接入库,但是考虑入库的效率和esb的稳定性,这两步分离了。
是的,你的实现需要比较精确的写日志。我的方法是被动式,还是有问题的,呵呵。
JDK7正式发布就好了,文件大小限制可以通过File Modification Notification事件来回调,Timer只管理定时了,这样代码更加好维护。又做定时和大小还是比较麻烦的,尤其是多线程。
File Modification Notification的话,
可以直接把这部分用 native的方式来做。
ps: dotnet一直都支持 filewatch。
但是我的需求是不行的。
rollover后的文件,我有一个进程处理入库。
这个进程是与生成log的esb进程独立的。
我的需求里,入库的数据要求延迟不能太大。
就是说:esb里来了一条数据,我必须让它在2分钟内在governor的控制台上可以看到。
ps:其实可以esb的log直接入库,但是考虑入库的效率和esb的稳定性,这两步分离了。
是的,你的实现需要比较精确的写日志。我的方法是被动式,还是有问题的,呵呵。
JDK7正式发布就好了,文件大小限制可以通过File Modification Notification事件来回调,Timer只管理定时了,这样代码更加好维护。又做定时和大小还是比较麻烦的,尤其是多线程。
但是我的需求是不行的。
rollover后的文件,我有一个进程处理入库。
这个进程是与生成log的esb进程独立的。
我的需求里,入库的数据要求延迟不能太大。
就是说:esb里来了一条数据,我必须让它在2分钟内在governor的控制台上可以看到。
ps:其实可以esb的log直接入库,但是考虑入库的效率和esb的稳定性,这两步分离了。
<div class="quote_div">
<p class="name">网友 zhangyang6380006在帖子 </p>
<p><a href="/topic/1006088">http://www.iteye.com/topic/1006088</a></p>
<p><a href="/topic/1006088"><span style="color: #006699;">主题:求一个log文件定时生成功能</span></a></p>
<p> </p>
<p>正好做过,就丢出来献丑了。</p>
<p> -------------------------------------------------------------------------------</p>
<p><strong>同步异步</strong></p>
<div class="quote_title">Foxswily 写道</div>
<div class="quote_div">不知道有没有考虑用slf4j+logback,log4j的作者已经转到把精力完全放倒这上边了,据说性能有提升。 <br><br>另外log4j是异步输出,服务停止的瞬间不保证能输出所有的log,如果是精确度高的业务也许不合适</div>
<p><br><a href="/topic/900845">http://www.iteye.com/topic/900845</a> <br>log4j内置的三种 输出方式 <br><br>flush=true 直接输出到文件,同步不缓存 <br>bufferedIO 按一定字节大小缓存,同步缓存 <br>AsynFileAppender 按一定的条数缓存,异步输出</p>
<p> -------------------------------------------------------------------------------</p>
<p><strong>仓库与自定义配置</strong></p>
<p><strong></strong> </p>
<p>说到log4j,大家最常见的用法就是 配置一个log4j.xml或properties,放在classpath的根目录下。</p>
<p>在里面配置上多个Appender,多个package对应的Logger或是Category,然后在代码里,直接用Class获取logger。</p>
<p> </p>
<p>其实还有两点可以提一提:</p>
<p>1、使用命名logger,而不是class</p>
<pre name="code" class="java">// <logger name="ASYNC_LOGGER">
Logger logger = Logger.getLogger("ASYNC_LOGGER");</pre>
<p> </p>
<p>2、使用仓库配置多个不同的log4j配置文件</p>
<p> </p>
<pre name="code" class="java"> LoggerRepository loggerRepository1 = new Hierarchy(new RootCategory(Level.DEBUG));
String path = new File("<span style="background-color: #ff0000;">log4j_1.xml</span>").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("<span style="background-color: #ff0000;">log4j_2.xml</span>").getAbsolutePath();
new DOMConfigurator().doConfigure(path,loggerRepository2);
Logger log_2 = loggerRepository2.getLogger("TEST_LOGGER_2");</pre>
<p> </p>
<p> </p>
<p> -------------------------------------------------------------------------------</p>
<p><strong>轮换文件</strong></p>
<p> </p>
<p> log4j可以按大小轮换文件(FileAppender, fileSize), 按天轮换文件 (<span style="font-size: x-small;">DailyRollingFileAppender </span>)</p>
<p>在我的某个应用场景中,使用log4j做数据落地,就是把每条日志数据格式化后,写入本地日志文件。</p>
<p>然后通过一个进程来读取所有轮换后的文件,分析每一条数据,入库(mongodb)。</p>
<p>做了如下的修改</p>
<p>1、除了使用文件大小来做轮换规则外,添加一个rollTime属性,表示需要轮换的时间s。</p>
<p>如果文件一直为0,不轮换,创建文件时记录下时间戳,定时与当前时间比较,超过rollTime,强制轮换。</p>
<p>2、同时修改轮换文件名称规则,默认的是.1,.2...这种形式。修改为.时间戳的形式。</p>
<p>其实还自定义了一个简单的Layout序列化数据。这个不是必须的。</p>
<p> </p>
<p>使用方法,在log4j.xml中,</p>
<p> </p>
<p><appender<br><span style="background-color: #ff0000;"> class="xxx.log.TimeRollingFileAppender"<br></span> name="ROLLING_FILE"><br> <param name="MaxBackupIndex" value="1024" /><br> <param name="Encoding" value="UTF-8" /><br> <param name="File" value="esb.log" /><br> <!--<br> <param name="BufferSize" value="8192" /><br> <param name="BufferedIO" value="true" /><br> --><br> <param name="ImmediateFlush" value="true" /><br> <span style="background-color: #ff0000;"><param name="RollTime" value="60" /><br></span> <param name="MaxFileSize" value="100MB" /></p>
<p> ......</p>
<p> </p>
<pre name="code" class="java">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; // seconds
long fileTimeStamp = 0;
Timer timer = null;
private TimerTask getTask() {
return new TimerTask() {
@Override
public 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 synched
synchronized 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 written
nextRollover = 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.1
target = 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();
}
}
}
}</pre>
<p> </p>
<p> </p>
<p> </p>
</div>
<p> </p>
<p><span style="">kimmking </span>哥你搞复杂了,呵呵!</p>
<p> </p>
<p>扩张一下DailyRollingFileAppender的<span style="white-space: pre;">subAppend:</span></p>
<p> </p>
<p> </p>
<pre name="code" class="java">protected void subAppend(LoggingEvent event) {
long n = System.currentTimeMillis();
if (n >= nextCheck) {
now.setTime(n);
nextCheck = rc.getNextCheckMillis(now);
try {
rollOver();
}
catch(IOException ioe) {
LogLog.error("rollOver() failed.", ioe);
}
}
super.subAppend(event);
}</pre>
<p> </p>
<p>每次调用log方法时做了定期检查,不过这个DailyRollingFileAppender只能定位到分钟,不能粒度更小(不过应该可以满足99%的需要)。</p>
<p> </p>
<p>加一个限定文件大小的check就OK了。</p>
没发现这个问题。
我这里是几百个线程。
是进程,线程是很安全的,但很多个JVM同时写一个log文件,ROLLOVER的时候会出先混乱...
恩,进程肯定不行。
没有相互协调的简单机制。
写多个文件吧。
好吧,谢谢~
没发现这个问题。
我这里是几百个线程。
是进程,线程是很安全的,但很多个JVM同时写一个log文件,ROLLOVER的时候会出先混乱...
恩,进程肯定不行。
没有相互协调的简单机制。
写多个文件吧。
没发现这个问题。
我这里是几百个线程。
是进程,线程是很安全的,但很多个JVM同时写一个log文件,ROLLOVER的时候会出先混乱...
没发现这个问题。
我这里是几百个线程。
构造函数TimeRollingFileAppender()里面,第一次运行的时候的 rollTime 始终是定义的值 60,以后才会读去配置的值...
setRollTime() 在构造函数后运行造成的?
如果这里修改了,就完美了。
log4j的配置文件加载机制是,
调用构造函数,
然后读取xml中的key-value,set到appender的property中去。
构造函数里的那个只是检查的时间,不是rollover的时间。
另外,注释掉的那一段timer的代码,就是解决你说的这个问题的,
根据set的rollTime,重设检查时间,后来发现没必要。
嗯,谢谢~了解的,本来我想的是可以重载下activateOptions这个方法...
构造函数TimeRollingFileAppender()里面,第一次运行的时候的 rollTime 始终是定义的值 60,以后才会读去配置的值...
setRollTime() 在构造函数后运行造成的?
如果这里修改了,就完美了。
log4j的配置文件加载机制是,
调用构造函数,
然后读取xml中的key-value,set到appender的property中去。
构造函数里的那个只是检查的时间,不是rollover的时间。
另外,注释掉的那一段timer的代码,就是解决你说的这个问题的,
根据set的rollTime,重设检查时间,后来发现没必要。
构造函数TimeRollingFileAppender()里面,第一次运行的时候的 rollTime 始终是定义的值 60,以后才会读去配置的值...
setRollTime() 在构造函数后运行造成的?
如果这里修改了,就完美了。
被我注释掉了。~
顶一个了
另外log4j是异步输出,服务停止的瞬间不保证能输出所有的log,如果是精确度高的业务也许不合适
http://www.iteye.com/topic/900845
log4j内置的三种 输出方式
flush=true 直接输出到文件,同步不缓存
bufferedIO 按一定字节大小缓存,同步缓存
AsynFileAppender 按一定的条数缓存,异步输出
另外log4j是异步输出,服务停止的瞬间不保证能输出所有的log,如果是精确度高的业务也许不合适
按照每一天的操作记录
年---》月---》日---》操作类型+serialNo
发表评论
-
微信公众平台申请消息接口验证工具
2013-08-06 16:37 4104申请了一个微信公众账号,还没想好服务器端用什么技术开发。 ... -
jaxb的类型绑定
2011-07-04 20:06 1815今天一个同事使用jaxb将海航的wsdl里的几个sch ... -
websocket的例子
2011-02-28 11:39 2436flash的websocket实现:https://gi ... -
eclipse e4的web版本开发工具orion
2011-02-18 15:33 4400Orion是一个新提名的eclipse顶级项目,目前处于准备阶 ... -
Axis支持gzip的请求
2010-09-18 10:21 2462webservice相对于其他的rpc来说,报文数据实在太大了 ... -
一个简单的投票机
2010-09-05 03:51 4238刚才无意间看到一个投票,在页面右键,源码,看了下,就几个 ... -
SWT中ole/activex实践--操作word的一个例子
2010-08-26 01:08 7944这几年,做了很多word/excel/ppt方面的开发,特别是 ... -
jetty7的log
2010-07-20 17:05 3886jetty7启动的时候,总是自己打出来3行log信息。 自己 ... -
JNI技术实践小结--原理分析和详细步骤截图说明
2008-12-25 23:40 15574JNI技术实践小结 xx组 ...
相关推荐
在"Log4j.jar包,和log4j.properties属性文件打包下载"中,我们有两个关键组成部分: 1. **Log4j.jar**:这是Log4j的主要库文件,包含了所有必需的类和方法,使得程序员能够方便地在代码中插入日志语句。它提供了...
本话题将深入探讨如何使用Log4j实现多文件输出打印,以及自定义日志的配置。 首先,我们要理解Log4j的基本工作原理。Log4j的核心组件包括Logger、Appender和Layout。Logger负责生成日志事件,Appender则负责接收...
1. **log4j-1.2.17.jar**: 这是Log4j的主要库文件,包含了所有Log4j的类和接口。通过这个库,开发者可以方便地在代码中插入日志语句,记录程序运行时的信息、警告、错误等。 2. **commons-logging-1.2.jar**: 这是...
下面我们将从配置文件类型、核心JAR包、文件渲染和Log调用四个方面来比较Log4j和Log4j2的区别。 配置文件类型 Log4j通过一个.properties文件作为主配置文件,而Log4j2则弃用了这种方式,采用的是.xml、.json或者....
### Log4J 全能配置文件详解 #### 一、概述 Log4J是一款非常流行的Java日志框架,被广泛应用于各种规模的应用程序中。它提供了灵活的日志记录机制,可以将日志输出到不同的目的地,如控制台、文件、数据库等,并且...
### log4j.properties配置文件详解 #### 一、概述 `log4j.properties`是Apache Log4j框架中用于配置日志记录行为的核心文件之一。通过这个文件,开发者可以定义日志消息的输出方式(例如控制台或文件)、日志级别...
《深入理解Log4j及其配置文件》 在Java开发领域,日志管理是不可或缺的一部分,它可以帮助开发者跟踪程序运行状态,排查错误,优化性能。Log4j,作为Apache的一个开源项目,是Java中最广泛使用的日志框架之一。本文...
每天生成一个log4j日志文件,如果只需要将最近一段时间内的日志文件保留,以前或更早的文件不用保留。例如只保留最近一周的日志,日志文件保留3天等等这些。。。通过这个jar包就可以实现。 log4j.properties文件在...
log4j2配置,文件分割,自动清除等相关配置。
在提供的压缩包文件列表中,"log4j2.16.0"可能包含了Log4j2库的更新JAR文件或其他相关资源。用户应当解压这个文件,然后根据项目的具体依赖管理方式,将新的JAR添加到若依框架的类路径中,或者更新Maven或Gradle的...
log4j.properties 文件放置在其它目录下 在 Tomcat 中,log4j.properties 文件通常被放在 src 目录下,这样系统自动会找到该文件的路径是在 WEB-INF/classes 文件下,该目录在 classpath 下,所以直接就能找到。...
本文将详细探讨Log4j的使用,主要关注1.2.17版本的jar包以及配置文件`log4j.properties`。 ### 1. Log4j简介 Log4j是一个开源的日志组件,支持多种输出格式,如控制台、文件、数据库等。它的核心概念包括Logger、...
例如,`log4j.appender.Console=org.apache.log4j.ConsoleAppender`配置了一个控制台Appender,而`log4j.appender.File=org.apache.log4j.DailyRollingFileAppender`则配置了一个每天滚动的日志文件Appender。...
在Java应用中使用Log4j进行日志记录的第一步,是创建并配置log4j的属性文件(log4j.properties)。这个文件定义了日志的级别、输出目的地以及日志的格式。以下是一个典型的log4j配置示例: ```properties # 设置根...
四、在 Maven 项目中引入 Log4j 依赖 在 Maven 项目中,需要引入 Log4j 依赖项,以便使用 Log4j。下面是一个基本的 Maven 依赖项配置: ``` <groupId>log4j <artifactId>log4j <version>1.2.16 ``` 这个配置...
- **日志文件写入速度**:Log4j2通过优化的布局(Layout)和过滤器(Filter),实现了更快的日志文件写入速度。这对于大数据量的日志记录尤为重要。 综上所述,Log4j2在效率方面较Log4j 1.x有了显著提升,这主要得益...
本文将深入探讨log4j的配置以及配置文件的详解。** 首先,我们要理解什么是`log4j.properties`文件。这是log4j框架的配置文件,使用Java Properties格式,用于定义日志输出的行为。主要包括以下几个核心部分: 1. ...
`log4j.properties`文件是Log4j的核心配置文件,它定义了日志输出的行为,包括日志级别、输出目的地、格式以及过滤规则等。 在`log4j.properties`文件中,有以下几个关键知识点: 1. **日志级别(Logging Levels)...
这是做日志分析的最新log4j2所必需的文件和包
使用Log4j时,你需要在项目的类路径下包含`log4j.jar`文件,这是Log4j的基本运行库。然后,创建一个`log4j.properties`或`log4j.xml`配置文件,定义Logger、Appender和Layout的具体设置。例如: ```properties # ...