我们有一个在多个线程中运行的应用程序,并使用Log4Net作为日志框架。我们遇到了一些未记录某些日志事件的情况。正如文档中所提到的,FileAppender和其他Appender对于多线程操作来说是“不安全”。 我在网上搜索解决方案或Appender,但找不到任何 您是否知道使用环形缓冲区或队列来提供多线程支持的多线程安全Log4Net Appender?或者我们应该使用不同的多线程安全日志框架吗? 提前谢谢!
答案 0 :(得分:14)
我写了一些单元测试来重现问题:测试创建50个线程,每个线程记录500条消息。然后计算书面行,结果我得到了25,000(50 x 500)行不同的顺序。我在双核和八核机器上进行了测试。 我测试了静态记录器:
private static ILog StaticLog = log4net.LogManager.GetLogger(RepositoryName, "Static logger");
并为测试类/线程的每个实例使用Logger:
ILog instanceLog = LogManager.GetLogger(RepositoryName, "Instance logger: " + ThreadId.ToString());
所有测试都是绿色的。
因此Log4Net运行良好,可以很好地处理多线程场景。应更新Appender文档,并说明如果以正确的方式使用Logger API,则支持多线程操作。
我想我们在客户机器上遇到的缺少日志条目的问题是由其他问题引起的。也许底层的VM或硬件坏了。
谢谢你的帮助!
答案 1 :(得分:8)
我从未使用过FileAppender而且不能说它是否是线程安全的,但我从来没有遇到RollingFileAppender的任何问题。文档声明该类型的成员不是线程安全的,但除非您尝试直接写入appender,否则这应该没问题。您不需要在以下调用中添加自己的锁定代码:
log.Info("message");
答案 2 :(得分:0)
测试是绿色并不意味着这些行实际写入文件,但没有例外。或者你是否包括检查你的测试中的文件?我在IIS中打开Web园后遇到了同样的问题。那时只有一个线程在文件中写入行。
答案 3 :(得分:0)
Log4Net是线程安全的,但使用的appender可能是个问题。调用时文件追加器会“阻塞”。这意味着在您的应用程序中,发送到Log4Net的每个日志都必须在返回到您的应用程序之前完成每个appender。
它是线程安全的,许多线程可以使用Log4Net来记录消息,但是在调用Log4Net的情况下,应用程序等待appender完成。日志记录的执行时间会添加到您的应用程序时间。
这很容易证明。请参阅:https://www.codeproject.com/Tips/1219696/Log-Net-Singleton-Wrapper-for-Concurrent-Logging
我所做的是将Log4Net函数“包装”在一个线程安全的静态单例中,然后将每个日志消息放入并发线程中运行的队列中。这使得所有日志记录与应用程序并发,但应用程序执行不会等待appender完成。