我尝试以这样的方式配置log4j.xml:文件将按文件大小滚动,并且滚动文件的名称将是:“C:/ temp / test / test_log4j-%d {yyyy-MM-dd -HH_mm_ss}的.log” 我跟着这个讨论:http://web.archiveorange.com/archive/v/NUYyjJipzkDOS3reRiMz
最后,只有当我添加时,它才对我有用:
try {
Thread.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
方法:
public boolean isTriggeringEvent(Appender appender, LoggingEvent event,
String filename, long fileLength)
使它有效。
问题是,是否有更好的方法使其发挥作用? 因为这种方法会多次调用并减慢我的程序。
以下是代码:
package com.mypack.rolling;
import org.apache.log4j.rolling.RollingPolicy;
import org.apache.log4j.rolling.RolloverDescription;
import org.apache.log4j.rolling.TimeBasedRollingPolicy;
/**
* Same as org.apache.log4j.rolling.TimeBasedRollingPolicy but acts only as
* RollingPolicy and NOT as TriggeringPolicy.
*
* This allows us to combine this class with a size-based triggering policy
* (decision to roll based on size, name of rolled files based on time)
*
*/
public class CustomTimeBasedRollingPolicy implements RollingPolicy {
TimeBasedRollingPolicy timeBasedRollingPolicy = new TimeBasedRollingPolicy();
/**
* Set file name pattern.
* @param fnp file name pattern.
*/
public void setFileNamePattern(String fnp) {
timeBasedRollingPolicy.setFileNamePattern(fnp);
}
/*
public void setActiveFileName(String fnp) {
timeBasedRollingPolicy.setActiveFileName(fnp);
}*/
/**
* Get file name pattern.
* @return file name pattern.
*/
public String getFileNamePattern() {
return timeBasedRollingPolicy.getFileNamePattern();
}
public RolloverDescription initialize(String file, boolean append) throws SecurityException {
return timeBasedRollingPolicy.initialize(file, append);
}
public RolloverDescription rollover(String activeFile) throws SecurityException {
return timeBasedRollingPolicy.rollover(activeFile);
}
public void activateOptions() {
timeBasedRollingPolicy.activateOptions();
}
}
package com.mypack.rolling;
import org.apache.log4j.helpers.OptionConverter;
import org.apache.log4j.Appender;
import org.apache.log4j.rolling.TriggeringPolicy;
import org.apache.log4j.spi.LoggingEvent;
import org.apache.log4j.spi.OptionHandler;
/**
* Copy of org.apache.log4j.rolling.SizeBasedTriggeringPolicy but able to accept
* a human-friendly value for maximumFileSize, eg. "10MB"
*
* Note that sub-classing SizeBasedTriggeringPolicy is not possible because that
* class is final
*/
public class CustomSizeBasedTriggeringPolicy implements TriggeringPolicy, OptionHandler {
/**
* Rollover threshold size in bytes.
*/
private long maximumFileSize = 10 * 1024 * 1024; // let 10 MB the default max size
/**
* 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.
*
* @param value
* the maximum size that the output file is allowed to reach
*/
public void setMaxFileSize(String value) {
maximumFileSize = OptionConverter.toFileSize(value, maximumFileSize + 1);
}
public long getMaximumFileSize() {
return maximumFileSize;
}
public void setMaximumFileSize(long maximumFileSize) {
this.maximumFileSize = maximumFileSize;
}
public void activateOptions() {
}
public boolean isTriggeringEvent(Appender appender, LoggingEvent event,
String filename, long fileLength) {
try {
Thread.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
boolean result = (fileLength >= maximumFileSize);
return result;
}
}
和log4j.xml:
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/" debug="true">
<appender name="console" class="org.apache.log4j.ConsoleAppender">
<param name="Target" value="System.out" />
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%d [%t] %-5p %c -> %m%n" />
</layout>
</appender>
<appender name="FILE" class="org.apache.log4j.rolling.RollingFileAppender">
<param name="file" value="C:/temp/test/test_log4j.log" />
<rollingPolicy class="com.mypack.rolling.CustomTimeBasedRollingPolicy">
<param name="fileNamePattern" value="C:/temp/test/test_log4j-%d{yyyy-MM-dd-HH_mm_ss}.log" />
</rollingPolicy>
<triggeringPolicy class="com.mypack.rolling.CustomSizeBasedTriggeringPolicy">
<param name="MaxFileSize" value="200KB" />
</triggeringPolicy>
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%d [%t] %-5p %c -> %m%n" />
</layout>
</appender>
<logger name="com.mypack.myrun" additivity="false">
<level value="debug" />
<appender-ref ref="FILE" />
</logger>
<root>
<priority value="debug" />
<appender-ref ref="console" />
</root>
</log4j:configuration>
答案 0 :(得分:0)
如果向该方法添加调试输出,您将看到该方法经常被调用,即使触发器已经触发,但文件大小仍然大于最大文件大小。
我假设滚动行为有某种缓冲区,它在实际(同步?)翻转发生之前被清空。
我认为它与com.mypack.rolling.CustomTimeBasedRollingPolicy
中的fileNamePattern有关。只要文件名中的“第二个”没有改变,就会连续调用CustomSizeBasedTriggeringPolicy.isTriggeringEvent
方法,其数量大于最大文件大小。
答案 1 :(得分:0)
感谢您的回答。
我做了2次更改:
1)I为文件名模式添加毫秒:
<param name="fileNamePattern" value="C:/temp/test/test_log4j-%d{yyyy-MM-dd-HH_mm_ss_SSS}.log" />
2)我改变了
com.mypack.rolling.CustomSizeBasedTriggeringPolicy.isTriggeringEvent
到
public boolean isTriggeringEvent(Appender appender, LoggingEvent event,
String filename, long fileLength) {
boolean result = (fileLength >= maximumFileSize);
if (result) {
try {
Thread.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
return result;
}
现在,只有在创建(滚动)新文件时才会调用Thread.sleep(1)。