写入具有multithreading性能问题的log4net FileAppender

TickZoom是一款性能非常高的应用程序,它使用自己的并行化库和多个O / S线程来顺利利用多核计算机。

该应用程序遇到瓶颈,用户需要从单独的O / S线程向LogAppender写入信息。

FileAppender使用MinimalLockfunction,以便每个线程可以锁定并写入该文件,然后释放它以供下一个要写入的线程使用。

如果MinimalLock被禁用,log4net会报告有关该文件已被另一个进程(线程)锁定的错误。

log4net执行此操作的更好方法是使用单个线程来处理写入FileAppender,而任何其他线程只需将其消息添加到队列中。

这样,可以禁用MinimalLock以大大提高日志记录的性能。

此外,该应用程序执行大量CPU密集型工作,因此它还可以提高性能,使用单独的线程写入文件,以便CPU永远不会等待I / O完成。

所以问题是,log4net是否已经提供此function? 如果是这样,你如何启用线程写入文件? 是否还有另一个更高级的appender?

如果没有,那么由于log4net已经包含在平台中,因此可以在TickZoom代码中为此目的实现单独的线程和队列。

真诚的,韦恩

编辑:

谢谢,似乎答案指向开发我们自己的解决方案,可能是某种方式的log4net的扩展。 他们清楚地表明log4net不会做这类事情。

此外,我们刚刚意识到我们可能“滥用”日志系统,该系统主要用于通知重要事件或调试信息的人类可读消息。 软件输出的这一特定部分仅用于validation系统准确性的自动化工具。

当然,我们也以“正常”方式使用log4net进行调试,警告等。

但这些更像是“事务日志”而不是调试或用户通知日志。 更具体地说,这些日志不必直接是人类可读的。 如果需要,某种“查看器”可以以ASCII格式显示内容。

因此我们计划将这些事务类型的日志写入高速二进制存储。

谢谢,以下两个答案似乎都非常适合开发我们自己的解决方案。

Log4net不支持您描述的确切方案。 但它确实提供了其他不锁定的appender,如数据库appender或UDP appender。 以下是一些想法:

  1. 将消息记录到消息队列中,然后让读取器(或多个读取器)从队列中读取消息并将其写入日志。 这提供了发送/写入消息的可靠机制。 说实话,我不知道是否已经有一个MSMQ appender,但自己写它不会太难。

  2. 使用UDP appender发送消息,然后编写自己的服务来侦听这些消息并将它们写入文件。

我认为你可以在这里检测一个主题…基本上使用一个非阻塞appender(或编写你自己的)并实现你自己的服务,从appender接收消息并将它们写入文件。

查看Object Guy的记录器,获得高性能,multithreading安全记录器,具有异步记录function以及许多其他function – 我认为非常好 – http://www.theobjectguy.com/DotNetLog/ 。 请参阅此页面上的multithreadingvideo。

非常希望避免向目标线程添加任何I / O,因此向日志记录收集器线程发送消息是个好主意。 我有时也会使用目标线程中的System :: Diagnostics :: Debug :: WriteLine来转储它的输出,但无论如何都必然会有一点锁定。

当然,添加任何额外的日志记录将导致“Heisenberg”效果,因此您必须知道这些影响何时可以忽略不计,何时不能,以便对高性能线程进行有用的记录。

如果你想获得一点点发烧友,你可以让每个线程保存自己的消息列表,然后在经过这么多次迭代后将其转储到某个地方。 因此,数据仅在任何线程执行其日志记录I / O之前的一段时间内有用,但也许您可以捕获足够的信息以进行调试。 此外,您还可以将各个线程日志整理到一个日志中进行分析。