使用log4j 1.2.17和java8u162

时间:2018-05-28 11:50:07

标签: java log4j apache-commons-logging fileappender

我们在生产环境中遇到问题,在某些情况下,日志文件不会被翻转。     我们使用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这样的问题?请分享您的意见。 提前谢谢。

2 个答案:

答案 0 :(得分:0)

我认为最好的方法就是调试代码,log4j可以像任何其他代码一样调试,没有这个我们只能推测。

我从您的配置中看到您正在使用com.ge.medit.util.logging.MaxFileSizeRollingFileAppender 这不是log4j的标准滚动文件追加器(可能是你公司的自定义appender,可能有错误)。

如果您无法调试它,我只能提供一些提示,这可能会有所帮助。

  1. 修改appender并使用org.apache.log4j.helpers.LogLog打印一些关于appender本身工作的信息,就像“登录log4j” - 这取决于一个系统。严重程度

  2. 通常翻转(参见“翻转”功能)是作为一系列文件的“重命名”实现的。我曾经看过(再次,只是推测)这种方法只有在以下情况下才能起作用:

    • 您拥有文件权限
    • 您的应用程序拥有唯一的文件句柄(尤其与Windows操作系统相关)。
  3. 在调试中很容易跟踪,因为从技术上讲,重命名可能是使用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的快速反应。