如何在 ASP.NET MVC Web 应用程序中使用 log4net 异步登录而不用尽所有可用线程?

How to log asynchronously with log4net in an ASP.NET MVC Web Application without using up all available threads?

在 ASP.NET MVC Web 应用程序中使用 AsyncForwardingAppender of the Log4Net.Async package 安全吗?我担心它会阻塞可用线程。

归结为我想调用 async 方法将日志发送到 HTTP API。我可以使用 async void 方法,例如 the way this guy did it:

protected override async void Append(log4net.Core.LoggingEvent loggingEvent)
{
    var message = new SplunkMessage(loggingEvent.Level, loggingEvent.ExceptionObject);
    var success = await _splunkLogger.Report(message);
    //do something with the success status, not really relevant
}

他后来updated his code:

public void DoAppend(log4net.Core.LoggingEvent loggingEvent)
{
    var clientIp = _clientIpRetriever.GetClientIp();
    var message = new SplunkMessage(loggingEvent.Level, loggingEvent.ExceptionObject, clientIp);
    SendMessageToSplunk(message);
}

private async void SendMessageToSplunk(SplunkMessage message)
{
    try
    {
        var success = await _splunkLogger.Report(message);
        //do something unimportant
    }
    catch(Exception x)
    {
        LogLog.Error(GetType(), "Error in SplunkAppender.", x);
    }            
}

但我太害怕了,因为 dangers involved:"First off, let me point out that "fire and forget" 在 ASP.NET 应用程序中几乎总是一个错误"。

有什么建议吗?

查看 source,您可以看到 AsyncForwardingAppender 仅使用一个线程来使事件出队。使用它不会终止您的 MVC 应用程序,因为只会使用一个线程。

将 "Fire and forget" 视为 Web 应用程序中的不良模式,您必须对声明加一点盐,因为答案谈到了让 功能 操作不受监督,而不是日志记录。日志记录应该能够在您的应用程序不停止工作的情况下失败(这就是为什么 log4net 在配置或日志记录失败时从不说任何事情)