2009-10-05 199 views
8

我们有一个在多线程中运行并使用Log4Net作为日志框架的应用程序。我们遇到了一些未记录日志事件的场景。正如文档中提到的,FileAppender和其他Appender是“而不是多线程操作的安全”。 我搜索了网络上的解决方案或Appenders,但找不到任何。
您是否知道使用环形缓冲区或队列提供多线程支持的多线程安全Log4Net Appender?或者我们是否应该使用不同的多线程安全日志框架?
在此先感谢!多线程安全日志

+4

重复http://stackoverflow.com/questions/1294668 - 基本上,log4net将适当地为您使用appender。 – 2009-10-05 10:16:19

+0

感谢您的回答。我编写了一些确认Log4Net多线程安全的单元测试(请参阅下面的答案)。 – 2009-10-05 14:58:19

回答

13

我写了一些单元测试来重现问题:测试创建50个线程和每个线程记录500条消息。之后,对笔迹进行了统计,结果我按不同的顺序得到了25,000(50×500)行。我在双核心和八核心机器上测试过它。
我测试了静态记录仪:

private static ILog StaticLog = log4net.LogManager.GetLogger(RepositoryName, "Static logger"); 

,并与测试类/线程的每个实例记录器:

ILog instanceLog = LogManager.GetLogger(RepositoryName, "Instance logger: " + ThreadId.ToString()); 


和所有测试都是绿色的。

因此,Log4Net正常工作,并很好地处理多线程情况。如果以正确的方式使用Logger API,则应该更新Appender文档并声明支持多线程操作。

我想我们在客户机器上遇到的缺少日志条目的问题是由其他问题引起的。也许底层的虚拟机或硬件坏了。

感谢您的帮助!

8

我从来没有使用FileAppender,不能说它是线程安全的,但我从来没有任何问题RollingFileAppender。文档声明该类型的成员不是线程安全的,但是除非您尝试直接写入appender,否则这应该是确定的。你并不需要添加自己的锁定周围的代码调用,如:

log.Info("message"); 
+1

是的,log4net自动锁定日志通话,因此这里没有线程问题。 – 2009-10-05 10:17:49

+0

所以你说Log4Net是多线程安全的,如果它通过Logger API使用的话?所以我想我们的代码中有使用它的问题?
在每个班级中,我们正在创建一个这样的记录程序:

  private static readonly log4net.ILog Log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);  

但是,只有一个此类的实例在线程中使用。 – 2009-10-05 10:28:47

0

测试是绿色的并不意味着这些行实际上是写入文件,但没有例外。或者你是否包含了在你的测试中读取文件的检查?在IIS中打开Web花园后,我遇到了同样的问题。那时,只有一个线程正在向文件写入行。

更多关于多线程和log4net的位置:herehere

+3

Web-garden场景意味着IIS正在使用多个*进程*,这与多个*线程*不同。写入FileAppender的多个线程很好;由于文件系统的工作原理,写入FileAppender的多个进程会导致错误。 – Bleaourgh 2011-10-31 20:17:26

0

log4net的是线程安全的,但附加目的地使用的可能是一个问题。文件appender在被调用时会“阻止”。这意味着在您的应用程序中,发送到Log4Net的每个日志都必须在返回到您的应用程序之前完成每个appender。

它是线程安全的,许多线程可以使用Log4Net来记录消息,但在调用Log4Net的应用程序等待appender完成。日志记录的执行时间将添加到您的应用程序时间。

这很容易证明。请参阅:https://www.codeproject.com/Tips/1219696/Log-Net-Singleton-Wrapper-for-Concurrent-Logging

我所做的是将Log4Net函数“包装”到线程安全的静态单例中,然后将每个日志消息放入并发线程中运行的队列中。这将使所有日志记录与应用程序并发,但应用程序执行不会等待appender完成。