如何刷新缓冲的 log4j FileAppender?
在 log4j 中,当使用具有 BufferedIO=true 和 BufferSize=xxx 属性(即启用缓冲)的 FileAppender 时,我希望能够在正常关闭过程中刷新日志。关于如何做到这一点有什么想法吗?
In log4j, when using a FileAppender with BufferedIO=true and BufferSize=xxx properties (i.e. buffering is enabled), I want to be able to flush the log during normal shutdown procedure. Any ideas on how to do this?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(8)
关闭 LogManager 时:
所有缓冲的日志都会被刷新。
When shutting down the LogManager:
all buffered logs get flushed.
也许您可以重写 WriterAppender#shouldFlush( LoggingEvent ) ,这样它就会为特殊的日志类别返回 true ,例如 log4j.flush.now ,然后你打电话:
http://logging.apache.org/log4j/1.2/apidocs/org/apache/log4j/WriterAppender.html#shouldFlush%28org.apache.log4j.spi.LoggingEvent%29
Maybe you could override
WriterAppender#shouldFlush( LoggingEvent )
, so it would returntrue
for a special logging category, likelog4j.flush.now
, and then you call:http://logging.apache.org/log4j/1.2/apidocs/org/apache/log4j/WriterAppender.html#shouldFlush%28org.apache.log4j.spi.LoggingEvent%29
分享我使用“Andrey Kurilov”的代码示例的经验,或者至少是类似的。
我实际上想要实现的是通过手动刷新实现异步日志条目(immediateFlush = false),以确保在达到 bufferSize 之前刷新空闲缓冲区内容。
初始性能结果实际上与使用 AsyncAppender 实现的结果相当 - 所以我认为它是一个很好的替代方案。
AsyncAppender
使用单独的线程(以及对disruptor
jar 的额外依赖),这使其性能更高,但需要更多的 CPU 和更多的磁盘刷新(没有高负荷冲洗的物质是分批进行的)。因此,如果您想节省磁盘 IO 操作和 CPU 负载,但仍想确保缓冲区在某个时刻被异步刷新,那么这就是正确的方法。
Sharing my experience with using "Andrey Kurilov"'s code example, or at least simmilar.
What I actually wanted to achieve was to implement an asynchronous log entries with manual flush
(immediateFlush = false)
to ensure an idle buffers content will be flushed before the bufferSize is reached.The initial performance results were actually comparable with the ones achieved with the
AsyncAppender
- so I think it is a good alternative of it.The
AsyncAppender
is using a separate thread (and additional dependency todisruptor
jar), which makes it more performant, but with the cost of more CPU and even more disk flushing(no matter with high load flushes are made on batches).So if you want to save disk IO operations and CPU load, but still want to ensure your buffers will be flushed asynchronously at some point, that is the way to go.
对我有用的唯一解决方案是等待一段时间:
The only solution that worked for me is waiting for a while:
尝试:
Try:
我编写了一个修复此问题的附加程序,请参阅 GitHub 或使用 name.wramner.log4j:FlushAppender梅文。它可以配置为刷新具有高严重性的事件,并且可以在接收到特定消息(例如“关闭”)时使附加程序不缓冲。检查单元测试以获取配置示例。当然,它是免费的。
I have written an appender that fixes this, see GitHub or use name.wramner.log4j:FlushAppender in Maven. It can be configured to flush on events with high severity and it can make the appenders unbuffered when it receives a specific message, for example "Shutting down". Check the unit tests for configuration examples. It is free, of course.