我们在生产环境中遇到问题,在某些情况下,日志文件不会被翻转。 我们使用Log4j 1.2.17版和apache.commons-logging。 创建自定义appender以翻转文件。 appender正在扩展Log4j的FileAppender。 这是subAppend(LoggingEvent事件)方法的算法:
long n = System.currentTimeMillis();
// Has the time come to roll the log file?
if (n >= nextCheck)
{
now.setTime(n);
nextCheck = rc.getNextCheckMillis(now);
rollOver();
reachedMaxSize = false;
else
{
File f = new File(getFile());
// Has the log file has exceeded its maximum size?
if (!reachedMaxSize && f.length() > maxFileSize)
{
// Log file has reached it maximum size.
reachedMaxSize = true;
// Log one last message to the file stating the max has been reached.
LoggingEvent exeededEvent = new LoggingEvent(
getClass().getName(),
Logger.getLogger(getClass().getName()),
Priority.ERROR,
"Maximum log file size has been reached ("+maxFileSize/1024+"KB)",
null);
super.subAppend(exeededEvent);
}
// If the log has not reached its max size, write it. Otherwise,
// send log event to stdout.
if (!reachedMaxSize)
{
super.subAppend(event);
}
else
{
System.out.println(event.getRenderedMessage());
}
这是Log4j.properties文件
log4j.rootLogger=INFO,RCFLog
log4j.appender.RCFLog=com.ge.medit.util.logging.MaxFileSizeRollingFileAppender
log4j.appender.RCFLog.File=runtime/logs/rcf.log
log4j.appender.RCFLog.DatePattern=yyyyMMdd'_'{0}
log4j.appender.RCFLog.Encoding=UTF-8
log4j.appender.RCFLog.Append=true
log4j.appender.ConsoleLog=org.apache.log4j.ConsoleAppender
log4j.appender.ConsoleLog.layout=org.apache.log4j.PatternLayout
log4j.appender.ConsoleLog.layout.ConversionPattern=%p [%t] %c{1}: %m%n
log4j.appender.RCFLog.layout=org.apache.log4j.PatternLayout
log4j.appender.RCFLog.layout.ConversionPattern=@%d{yyyyMMdd HH:mm:ss.SSS}@ %p {%t} %c{1}: %m%n
log4j.logger.GUIEVT=INFO
根据观察,系统上有日期更改。日期设定为当前日期之前的3个月。
Current Date- 10th May 2018
nextCheck - 11th May 2018 00:00
Changed Date- 10th March 2018
No backup is created as a condition at line 3 failed.
5月11日再过12小时后,日期变为当前日期。到那时,文件的时间戳已更改为3月10日。由于没有RollOver,下一次检查仍然是2018年5月11日00:00。但是在5月12日00:00,文件应该按照第3行的条件滚动,并且应该创建一个没有发生的新文件。此外,该文件已达到最大大小。从那时起,系统重新启动之前就没有日志了。
Java版本为 java8u162 。虽然我找不到任何帖子,说明它是否与java有关。
我尝试在测试环境中重现的相同场景,但一切都按预期工作。
有没有人遇到过Log4j这样的问题?请分享您的意见。 提前谢谢。
答案 0 :(得分:0)
我认为最好的方法就是调试代码,log4j可以像任何其他代码一样调试,没有这个我们只能推测。
我从您的配置中看到您正在使用com.ge.medit.util.logging.MaxFileSizeRollingFileAppender
这不是log4j的标准滚动文件追加器(可能是你公司的自定义appender,可能有错误)。
如果您无法调试它,我只能提供一些提示,这可能会有所帮助。
修改appender并使用org.apache.log4j.helpers.LogLog
打印一些关于appender本身工作的信息,就像“登录log4j” - 这取决于一个系统。严重程度
通常翻转(参见“翻转”功能)是作为一系列文件的“重命名”实现的。我曾经看过(再次,只是推测)这种方法只有在以下情况下才能起作用:
在调试中很容易跟踪,因为从技术上讲,重命名可能是使用java.io.File#renameTo
完成的,返回 true / false ,具体取决于重命名操作是成功还是失败。
为了模拟这种情况,您可以使用消息部署“洪泛”日志的“隐藏”代码(您可以使用A JMX,内部Web servlet /消息处理程序 - 无论您想要什么,但在其中可以包含循环中过多的日志消息(假的),如下所示:
class MyHiddenMBean {
Logger logger = ...
public void doLogManyTimes(int times) {
for(int i = 0; i < times; i++) {
logger.info("Artificial Logging Message : " + i);
}
}
}
你会立即到达最大文件(当然你可以故意将其设置得非常小,以便更快地模拟),然后你就能看到为什么renameTo
不起作用
答案 1 :(得分:0)
我找到了没有备份文件的原因。有多个日期更改。 据观察,该日期首次更改为10/05/2036,然后更改为2021并更改回10/03/2018,之后我们最终将日期更改为当前日期11/05/2018。
因此,当日期更改为将来日期10/05/2036。 nextCheck日期已更新至11/05/2036。 再次将日期更改回当前日期时,如果条件失败(现在(11/05/2018&gt; = 11/05/2036))。 因此,仅当日期更改为11/05/2036或更高时才会进行备份。
需要将条件if(n> = nextCheck)更改为if(n> = nextCheck || nextCheck - n&gt; TimeConstants.MILLISECONDS_PER_DAY。此更改尚未测试。
感谢Mark Bramnik的快速反应。