如何为 log4net 创建异步包装器?
默认情况下,log4net是一种同步日志记录机制,我想知道是否有办法使用log4net进行异步日志记录?
By default, log4net is a synchronous logging mechanism, and I was wondering if there was a way to have asynchronous logging with log4net?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
如果你去log4net网站,你可以找到一些例子,其中至少有一个是异步Appender。
http://logging.apache.org/log4net/release/example-apps.html
请注意,我没有使用过这些示例中的任何一个,因此我无法以某种方式为它们提供保证。
以下是代码存储库中 log4net 示例区域中实际异步附加程序的链接:
http://svn.apache.org/viewvc/logging/log4net/trunk/examples/net/2.0/Appenders/SampleAppendersApp/cs/src/Appender/AsyncAppender.cs?view=markup
我简单地看了一下它,它显然充当了一个或多个“传统”Appender 的包装器。对于每个日志记录请求(包含一个或多个 LoggingEvent 对象),ThreadPool 线程用于将 LoggingEvents 转发到包装的 Appender 列表。
If you go to the log4net website, you can find some examples, at least one of which is an asynchronous Appender.
http://logging.apache.org/log4net/release/example-apps.html
Note that I have not used any of these examples, so I cannot vouch for them one way or the other.
Here is a link to the actual asynchronous appender from the log4net Examples area in their code repository:
http://svn.apache.org/viewvc/logging/log4net/trunk/examples/net/2.0/Appenders/SampleAppendersApp/cs/src/Appender/AsyncAppender.cs?view=markup
I looked at it briefly, and it apparently acts as a wrapper around one or more "conventional" Appenders. On each logging request (containing one or more LoggingEvent objects), a ThreadPool thread is used to forward the LoggingEvents to the list of wrapped Appenders.
只是想提供我的完整解决方案供参考。有几个重要的项目,FixFlags 可让您捕获实际执行日志记录的线程。阻塞集合位于 ReactiveExtensions 中。这里的要点是,您的转发附加器处理异步内容,然后将 LoggingEvent 转发到标准 Log4Net 附加器,这让 Log4Net 可以完成它擅长的所有事情。无需重新发明轮子。
然后,在 log4net.xml 中设置附加程序
更新:
如果您想在 log4net 中使用上下文,如“
log4net.ThreadContext.Properties["CustomColumn"]
"那么您需要更新上面的代码,例如
Just wanted to provide my complete solution for reference. Couple of important items, the FixFlags let you capture the thread that's actually doing the logging. The Blocking Collection is in the ReactiveExtensions. The jist here is that your forwarding appender handles the Asynchronous stuff and then just forwards on the LoggingEvent to a standard Log4Net appender, which lets Log4Net do all of the things that it's good at. No re-inventing the wheel.
Then, in your log4net.xml you setup the appenders thusly
Update:
If you want to use context in log4net like "
log4net.ThreadContext.Properties["CustomColumn"]
"Then you need to update above code like
我就是这样做的:
这样 log4net 在单独的线程上异步执行日志记录...
顺便说一句,
Task
类位于System.Threading.Tasks
命名空间中。This is how I do it:
That way log4net performs logging on a separate thread, asynchronously...
BTW,
Task
class is inSystem.Threading.Tasks
namespace.这里的一些想法是不正确的,会导致无效/过时的数据、无序的日志记录或非常糟糕的性能。例如,接受的答案建议使用 log4net
AsyncAppender
,它使用ThreadPool
导致无序条目,这对某些人来说可能不是问题,但我当然希望我的日志事件如果一个接一个地执行,它也会产生糟糕的性能,并对线程池造成太大压力,而且它不会批量处理日志条目。乔纳森提出的答案当然是一个更好的解决方案,但仍然缺乏最佳性能。关于如何实现这一点的一个很好的例子可以在这里找到,以及基准测试结果和解释< a href="http://www.nimaara.com/2016/01/01/high-performance-logging-log4net/" rel="noreferrer">此处。
该解决方案的另一个好特性是,它已实现为
Forwarder
而不是Appender
,允许用户包含多个Appender
并记录同时向他们每个人发送。Some of the ideas here are incorrect and result in invalid/stale data, out of order logging or very bad performance. For instance the accepted answer suggests using the log4net
AsyncAppender
which uses theThreadPool
resulting in out of order entries which might not be a problem for some but I certainly want my log events to be one after another it also can have terrible performance and put too much strain on theThreadPool
also it does not batch the log entries. The answer suggested by Jonathan is certainly a much better solution but still lacks optimal performance.A good example of how this should be implemented can be found HERE and the benchmarking results and the explanation HERE.
Another good feature of this solution is that it has been implemented as a
Forwarder
not anAppender
allowing the user to include more than oneAppender
and log to each of them at the same time.我本周遇到了这个问题,但是我不想继续向线程池发出请求,因为它最终可能会导致线程应用程序的其余部分挨饿,因此我想出了一个异步附加程序,它运行一个专用线程来附加通过缓冲器馈送。在这里查看:https://github.com/cjbhaines/Log4Net.Async
I came across this problem this week however I did not want to keep firing requests off to the thread pool because it could end up starving the rest of the application of threads so I came up with an Asyncronous appender that runs a dedicated thread for appending which is fed through a buffer. Check it out here: https://github.com/cjbhaines/Log4Net.Async
https://github.com/cjbhaines/Log4Net.Async
我们现在提供异步 log4net 方法。对于正在寻找更新答案的人。
https://www.nuget.org/packages/Log4Net.Async/
https://github.com/cjbhaines/Log4Net.Async
We have asynchronous log4net methods available now. For the people who are looking for updated answers.
https://www.nuget.org/packages/Log4Net.Async/