当前位置: 首页 > 知识库问答 >
问题:

异步Log4J2和logrotate工作不正常(truncate已断开)

叶英哲
2023-03-14

我使用Log4J2异步记录器来记录我的Java应用程序,并且每天使用logrotate来存储旧日志。

以前,我同步使用Log4J2,一切都很好;由于我切换到异步日志logrotate停止正常工作。

我想我遇到了这里解释的相同问题:由于我使用了copyruncate选项,旧日志文件在被复制后会被截断,但记录器不知道,因此它会继续从“old”索引开始写入,从而用NUL值填充文件中之前的所有空间,这正是我所看到的。

这是我启动应用程序时使用的命令:

java -Dlog4j2.contextSelector=org.apache.logging.log4j.core.async.AsyncLoggerContextSelector -Dlog4j2.asyncQueueFullPolicy=Discard -Dlog4j2.asyncLoggerRingBufferSize=6553600 -Djava.library.path=my_libs -cp MyApplication.jar:my_libs/* com.gscaparrotti.Main >> logs/other.log

这是我的log4j2的摘录。xml文件:

<Configuration status="debug">
    <Appenders>
        <RandomAccessFile name="LogToFile" fileName="logs/standalone.log" append="true" ImmediateFlush="false">
            <PatternLayout>
                <Pattern>[MyApp - %t - %d{DATE}] %5p %c{1} - %m%n</Pattern>
            </PatternLayout>
        </RandomAccessFile>
        <RandomAccessFile name="LogAnalyzer" fileName="logs/analyzer.txt" append="true" ImmediateFlush="false">
            <PatternLayout>
                <Pattern>[%d{DATE}] %5p %c{1} - %m%n</Pattern>
            </PatternLayout>
        </RandomAccessFile>
    </Appenders>
    <Loggers>
        <Root level="warn">
            <AppenderRef ref="LogToFile"/>
        </Root>
        <Logger name="analyzer" level="debug" additivity="false">
            <AppenderRef ref="LogAnalyzer"/>
        </Logger>
    </Loggers>
</Configuration>

这是我使用的logrotate配置(所有日志文件都是相同的):

/root/logs/analyzer.txt {
  copytruncate
  daily
  rotate 4
  compress
  missingok
  create 640 root root
}

一种解决方案是在logrotatelogrotate之前停止我的应用程序,但这并不是一个好的解决方案,因为我想让它运行。

我还能做什么来解决这个问题?

共有1个答案

凌翔宇
2023-03-14

您应该用一个简单的FileAppender替换RandomAccessFileAppender

您的问题不是由使用异步记录器引起的,而是由您使用的appender引起的:

  • Java的RandomAccessFile,由RandomAccessFileAppender以读/写模式打开文件,而不使用O_APPEND选项(参见open(2)),

此选项的存在与否会影响写入的执行方式:

O_APPEND文件以APPEND模式打开。在每次写入(2)之前,文件偏移量位于文件的末尾,就像使用lseek(2)一样。文件偏移量的修改和写入操作作为单个原子步骤执行。

(摘自《男子网球公开赛》(2))。

截断日志文件时,FileAppenders偏移量将重置为0,而RandomAccessFileAppender将继续在上一个位置写入。

备注:Log4j还提供了一个RollingFileAppender,这将完全消除使用logrotate的需要。

 类似资料:
  • Log4j正在查找我的配置,因为一旦我删除它,我就会收到一条错误消息,说它找不到配置,但是它的属性在登录时不会反映出来。 log4j2。属性: Test.java: 输出: 如您所见,当记录器设置为INFO时,它将返回级别为ERROR,并且时间格式包括毫秒,即使它已被删除。 配置文件取自log4j网站,只做了一些小改动(上面提到的两个,以及) 我使用的是2.8.1版。

  • 使用log4j2,我很难让同步记录器和异步记录器一起工作。 从这里以Apache文档(标题为混合同步和异步记录器)为例,运行下面的应用程序将简单地创建日志文件,但不向其写入任何内容。我也不确定添加两个记录器指向同一个appender,但它的Apache留档,所以我假设这是好的。 LOG4J2配置 pom.xml 应用 但是,如果我更改log4j2配置并修改loggers元素以读取以下内容,我将在日

  • 我使用最新的构建log4j2 beta9,它似乎RollingR随机访问文件和RollingR随机访问文件不能正常工作 是的,它在达到特定文件大小限制后创建存档,但在此之后,日志文件的大小不断增加(即不滚动),这只是一个实现创建,即使我将最大值设置为3。 这里是log4j2的appender设置。xml。有什么帮助吗?

  • 我使用了绝对定位(setBounds和null布局),现在开始练习布局管理器,这段代码是用gridbag布局的,但是很少组件没有显示,或者是单元格有一些问题,或者是其他的东西,请帮助!

  • 我试图创建一个基于警报的应用程序。我正在使用。问题是这一点都不可靠。在某些设备中,它起作用…在其他设备中,它的工作方式…而在其他设备中,它根本不起作用。 这是我的闹钟课: 这是我的OneTimeAlarm,只发射一次就不再发射的警报。 这是我的日常警报器,警报器一天只响一次。

  • 我正在使用ora2pg将我的数据从oracle迁移到postgres数据库。作为第一步,我要导出模式。我发现生成的sql文件有许多错误,如重复的sql语句,函数中的重复参数,这些错误在执行sql时失败。我正在尝试手动更正生成的sql文件中的这些错误。是否有更好的方法或避免sql文件中的此错误。实际上,我只需要将数据从oracle传输到postgres数据库。但不知道这是否可能。我使用的是ORA2P