C# 多线程安全日志记录
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1519211/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Multithread safe logging
提问by Rene Schulte
We have an application that runs in multiple threads and uses Log4Net as logging framework. We encountered a scenario where some log events weren't logged. As mentioned in the docs, the FileAppenderand the other Appenders are "notsafe for multithreaded operations".
I searched the web for solutions or Appenders, but couldn't find any.
Do you know a multithread safe Log4Net Appender that uses a ring buffer or a queue to provide multithread support? Or should we use a different multithread safe logging framework at all?
Thanks in advance!
我们有一个在多个线程中运行并使用 Log4Net 作为日志记录框架的应用程序。我们遇到了一些日志事件没有被记录的场景。如文档提到的,FileAppender和其他附加目的地是“没有对多线程操作安全”。我在网上搜索解决方案或 Appenders,但找不到任何。
您知道使用环形缓冲区或队列来提供多线程支持的多线程安全 Log4Net Appender 吗?或者我们应该使用不同的多线程安全日志框架吗?
提前致谢!
采纳答案by Rene Schulte
I wrote some Unit tests to reproduce the problem: A test creates 50 threads and each thread logs 500 messages. Afterwards the written lines were counted and as a result I got 25,000 (50 x 500) lines in different order. I tested it on a dual core and on a eight core machine.
I tested a static Logger:
我写了一些单元测试来重现这个问题:一个测试创建 50 个线程,每个线程记录 500 条消息。之后对写入的行进行计数,结果我得到了 25,000 (50 x 500) 行不同顺序的行。我在双核和八核机器上对其进行了测试。
我测试了一个静态记录器:
private static ILog StaticLog = log4net.LogManager.GetLogger(RepositoryName, "Static logger");
and with a Logger for each instance of the test class / thread:
并为测试类/线程的每个实例使用一个记录器:
ILog instanceLog = LogManager.GetLogger(RepositoryName, "Instance logger: " + ThreadId.ToString());
And all tests were green.
So Log4Net works fine and handles multithreading scenarios well. The Appender docs should be updated and state that multithreaded operations are supported if the Logger API is used in the right way.
I guess the problem with missing log entries that we encountered on a customer's machine is caused by other issues. Maybe the underlying VM or hardware is broken.
Thanks for your help!
并且所有测试都是绿色的。
所以 Log4Net 工作正常并且很好地处理多线程场景。应该更新 Appender 文档并声明如果以正确的方式使用 Logger API,则支持多线程操作。
我猜我们在客户机器上遇到的丢失日志条目的问题是由其他问题引起的。也许底层虚拟机或硬件坏了。
谢谢你的帮助!
回答by Darin Dimitrov
I've never used FileAppender and cannot say if it is thread safe but I have never had any problems with RollingFileAppender. The docs state that members of the type are not thread safe, but this should be OK unless you try to directly write to the appender. You do not need to add your own locking code around calls like:
我从未使用过 FileAppender 并且不能说它是否是线程安全的,但我从未在使用RollingFileAppender 时遇到任何问题。文档指出该类型的成员不是线程安全的,但这应该没问题,除非您尝试直接写入附加程序。您不需要在如下调用周围添加自己的锁定代码:
log.Info("message");
回答by user778926
That the tests are green does not mean that the lines were actually written to the file, but that there was no exception. Or did you include check that reads the file for that in your test as well? I encountered the same problem after I switched on web gardens in IIS. At that point only one thread was writing lines to the file.
测试是绿色的并不意味着这些行实际上已写入文件,而是没有例外。或者您是否也包括在测试中读取文件的检查?我在 IIS 中打开网络花园后遇到了同样的问题。那时只有一个线程正在向文件写入行。
回答by Jeff Bramlett
The Log4Net is thread-safe, but the appenders used can be a problem. The file appenders do "block" when called. This means that in your application, every log sent to Log4Net has to complete every appenders before returning to your application.
Log4Net 是线程安全的,但使用的附加程序可能是一个问题。文件附加程序在调用时会“阻塞”。这意味着在您的应用程序中,发送到 Log4Net 的每个日志都必须在返回到您的应用程序之前完成每个附加程序。
It is thread-safe, many threads can use Log4Net to log messages, but where Log4Net is called the application waits for the appenders to complete. The execution time of logging is added to your application time.
它是线程安全的,许多线程可以使用 Log4Net 来记录消息,但是在调用 Log4Net 的地方,应用程序等待 appender 完成。日志记录的执行时间被添加到您的应用程序时间。
This is easily proved. See: https://www.codeproject.com/Tips/1219696/Log-Net-Singleton-Wrapper-for-Concurrent-Logging
这很容易证明。请参阅:https: //www.codeproject.com/Tips/1219696/Log-Net-Singleton-Wrapper-for-Concurrent-Logging
What I have done is to "wrap" the Log4Net functions in a static singleton that is thread-safe and then put each log message into queue running in a concurrent thread. This make all the logging concurrent to the application but the application execution does not wait for the appenders to complete.
我所做的是将 Log4Net 函数“包装”在线程安全的静态单例中,然后将每个日志消息放入在并发线程中运行的队列中。这使得所有日志记录并发到应用程序,但应用程序执行不会等待 appender 完成。