是否有必要使用 log4net 为 ASP.NET MVC 实现异步日志记录?

Is it necessary to implement async logging for ASP.NET MVC with log4net?

我看到了一个消息队列,就像使用 log4net 实现日志记录 class。

它用于ASP.NET MVC web 应用程序,所以我觉得线程已经被隔离了。此实施有​​什么好处?

public class Logger
{
    private ILog _logger;
    private static Logger _instance;
    private Queue<Action> _logQueue = new Queue<Action>();
    private ManualResetEvent _newItemsExist = new ManualResetEvent(false);
    private ManualResetEvent _terminate = new ManualResetEvent(false);
    private ManualResetEvent _waiter = new ManualResetEvent(false);
    private static object _syncLock = new object();

    private Thread _logThread;

    public enum LoggingType { Debug, Info, Warn, Error, Fatal };
    public Logger()
    {
        _logger = LogManager.GetLogger(
            System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);

        _logThread = new Thread(new ThreadStart(ProcessQueue));
        _logThread.IsBackground = true;
        _logThread.Start();
    }

    public static Logger Instance
    {
        get
        {
            if (_instance == null)
                lock (_syncLock)
                    if (_instance == null)
                        _instance = new Logger();

            return _instance;
        }
    }

    private void ProcessQueue()
    {
        while (true)
        {
            _waiter.Set();

            int i = ManualResetEvent.WaitAny(new WaitHandle[] { _newItemsExist, _terminate });
            if (i == 1) return;

            _newItemsExist.Reset();
            _waiter.Reset();

            Queue<Action> queueCopy;
            lock (_logQueue)
            {
                queueCopy = new Queue<Action>(_logQueue);
                _logQueue.Clear();
            }

            foreach (Action logAction in queueCopy)
                logAction();
        }
    }
    public void _LogMessage(string msg_, Exception inEx_, LoggingType type_)
    {
        lock (_logQueue)
            _logQueue.Enqueue(() => AsyncLogMessage(msg_, inEx_, type_));

        _newItemsExist.Set();
    }
    private void AsyncLogMessage(string msg_, Exception inEx_, LoggingType type_)
    {
        switch (type_)
        {
            case LoggingType.Debug:
                _logger.Debug(msg_, inEx_);
                break;

            case LoggingType.Info:
                _logger.Info(msg_, inEx_);
                break;

            case LoggingType.Warn:
                _logger.Warn(msg_, inEx_);
                break;

            case LoggingType.Error:
                _logger.Error(msg_, inEx_);
                break;

            case LoggingType.Fatal:
                _logger.Fatal(msg_, inEx_);
                break;
        }
    }
}

您不需要为 log4net 实现任何异步记录器,有一个非常好的实现伴随着包含基准测试和解释必要细节的博客条目。

总而言之,async 只是问题的一半,您还需要提供批处理日志记录以提高吞吐量,否则一个接一个地刷新每条日志消息会导致线程主线程或其他方面出现瓶颈。

您可以在 GitHub, NuGet and the blog entry HERE 上找到图书馆。