7

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

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

FileAppender 使用 MinimalLock 特性,以便每个线程可以锁定并写入文件,然后释放它以供下一个线程写入。

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

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

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

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

所以问题是,log4net 是否已经提供了这个功能?如果是这样,您如何启用对文件的线程写入?也许还有另一个更高级的附加程序?

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

真诚的,韦恩

编辑:

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

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

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

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

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

谢谢,下面的两个答案似乎都对开发我们自己的解决方案起到了很大的推动作用。

4

3 回答 3

7

Log4net 不支持您描述的确切场景。但是,它确实提供了其他不锁定的附加程序,例如数据库附加程序或 UDP 附加程序。这里有几个想法:

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

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

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

于 2010-05-07T00:55:27.307 回答
3

查看 Object Guy 的记录器,了解高性能、多线程安全的记录器,它具有异步记录功能以及许多其他功能 - 我认为非常好 - http://www.theobjectguy.com/DotNetLog/。请参阅此页面上的多线程视频。

于 2010-06-28T08:11:05.353 回答
1

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

当然,添加任何额外的日志记录都会导致“海森堡”效应,因此您必须以某种方式知道这些效应何时可以忽略不计,何时不可忽略,以便对高性能线程进行有用的日志记录。

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

于 2010-05-07T01:32:12.720 回答