如何在Java或其他平台上创建logrotate友好文件编写器?

在Java中实现与logrotate兼容的文件编写器/记录器的最佳实践是什么? 目标是允许logrotate用于所有日志管理,而不是使用内置的日志API(Log4J等)的轮换/管理。

除了Java之外,我还有兴趣听取其他开发平台的评论/答案。

您只需要定期关闭并重新打开应用程序中的日志文件。 您需要一个保持最后关闭时间的处理程序。 处理程序应该关闭并重新打开文件,如果(例如)自上次关闭后经过20秒并且即将写入日志条目。 它应该在写入日志条目之前进行此类检查

如果不这样做,日志将被写入旧文件,即使它被logrotate(!)重命名(文件描述符保持不变),然后日志被压缩和删除后日志条目将消失(在这种情况下,java将默默地删除此类日志)。

关闭并重新打开日志(使用文件名)将确保如果文件已重命名,则将创建新文件。 每次写入日志时关闭并重新打开文件都是一种过度杀伤,因为打开文件是一项代价高昂的操作。

我看了一些其他的应用程序,显然有copytruncate选项和copytruncate选项 。 copytruncate选项更容易,但我认为它不太可靠,因为缓冲区可能无法刷新(即遵循@Jarek Potuik答案),即使它们是你可能会得到重复的条目或删除的条目。

因此,假设您需要postrotate选项:

postrotate选项允许您运行命令以告知应用程序重新打开文件(关闭然后打开)。 在Java中打开和关闭文件时,您可以使用同步块或某种锁来执行此操作,当然还要刷新任何缓冲区。

让我们假设您的应用程序名为myapp

你会在/etc/logrotate.d/myapp有一个文件,例如:

 /var/log/myapp/*.log { weekly missingok rotate 20 compress delaycompress notifempty sharedscripts postrotate /etc/init.d/myapp rotate-logs > /dev/null endscript } 

命令/etc/init.d/myapp rotate-logs需要向应用程序发出信号以关闭并重新打开日志文件。

信令部分相当棘手,取决于你有什么样的应用程序,因为Java不能很好地支持IPC(即unix信号)所以你可能必须打开一个端口或使用现有的端口,如8080(即HTTP REST命令)在servlet容器的情况下)告诉你的应用程序关闭并重新打开日志文件。