使用logrotate的垃圾收集器日志(loggc)文件轮换无法正常工作

时间:2011-12-02 08:04:54

标签: java linux logging garbage-collection

在使用Linux logrotate命令使用JVM垃圾收集日志选项时,我遇到了一个奇怪的问题。 执行旋转时,它将NUL(^ @)值填充为作为JVM参数给出的文件的第一行。

假设这是java调用(Test.class位于/ home / test /):

  

java -Xloggc:/home/test/test.log -cp / home / test / Test

此文件的logrotate配置如下:

  

/home/test/test.log {
  旋转56
  missingok
  notifempty
  copytruncate
  nocreate的
  nomail
  }

我还每分钟都有一个crontab条目用于测试目的:

  

* / 1 * * * * / usr / sbin / logrotate -f /etc/logrotate.d/gcLog

我得出的结论是JVM写入追加模式并保留某种偏移用于在相关文件中写下一行,即使文件被logrotate截断(我可能错了)。
<登记/>

我的下一个想法是尝试将stdout重定向到test.log文件。 我使用了这个java调用,并为logrotate和cron保留了相同的配置:

  

java -verbose:gc -cp / home / test / Test&gt; /home/test/test.log

再次,当log.ate截断test.log时,新创建的文件在第一行填充NUL(^ @)值。


无需说我没有找到任何有用的谷歌。 我发现了另一个关于stackoverflow类型的问题,但我无法设置Java Script Wrapper,所以这不起作用。

有人遇到过这个问题吗?知道为什么会这样吗?更好,任何变通方法或解决方案? 我需要尝试将对应用程序的调用传递给读取输出的某个脚本,并且可能会看看Tomcat在catalina.out中记录和旋转stdout的方式(这里也会非常感谢一些帮助)

4 个答案:

答案 0 :(得分:6)

我们在运行Jboss7和Java6的地方遇到了同样的问题,我们在GC文件中得到了NULL,而且它们一直在增长。

解决方案是将GC记录到stdout,然后 stdout追加到文件中:

简单示例:

java -verbose:gc >> console.log

显然使用append(&gt;&gt;)可以删除文件中某个位置的Java“指针”。还有一个额外的好处就是没有重新启动每个服务器的GC日志,所以我们可以随着时间的推移得到一些统计数据。

至少IBM PMAT工具在使用GC输出解析sysout时没有问题。

最简单的解决方案有时是最好的:)

虽然我希望Java能够支持GC日志的转换,但我看到之前有人在讨论过: http://mail.openjdk.java.net/pipermail/hotspot-runtime-dev/2011-April/002061.html

答案 1 :(得分:4)

为了解释null,Java维护一个内部引用来计算缩进的位置,当你移动文件时,它会导致将空字符写入日志。

我见过篡改GC日志文件导致系统崩溃,忽略了写入日志文件时导致的中止(请参阅此处的代码http://pastebin.com/HWkNv3PM),导致JVM继续忽略错误。

当文件重新打开时,我相信位置计数器没有被重置。

关于如何滚动日志文件的其他想法 - 另请参阅:Rolling garbage collector logs in java

答案 2 :(得分:3)

一个简单的解决方法可能是更改我在问题中使用的Java调用:

  

java -Xloggc:/home/test/test.log -cp / home / test / Test

  

java -verbose:gc -cp / home / test / Test | tee -a / home / test / test / log

logrotate和cron的配置可以保持不变(即使应该增加cron周期)。

请参阅我在该问题下的评论,以获取有关Linux中的logrotate和文件处理程序的更多详细信息的链接。 另请参阅有关Java行为的brainzzy's explanations

答案 3 :(得分:0)

而不是java -verbose:gc&gt;&gt;我可以做console.log: java -Xloggc:logs / gc.log&gt;&gt; console.log所以输出将保存在一个文件中,然后也可以旋转到console.log?