ASP.NET WebAPI 2 - MessageHandler在记录之前返回响应

时间:2017-05-05 04:23:27

标签: c# asp.net asp.net-web-api

我已经通过MessageHandler在WebAPI 2中实现了一些日志记录。

在我看来,只有在记录发生后才会返回响应。对于用户来说,接收他们的响应会很好,但是对于日志记录来说是一个想法。这可能吗?

public abstract class MessageHandler : DelegatingHandler
{
    protected HttpRequestMessage requestMessage;
    protected HttpResponseMessage responseMessage;

    protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage requestMessage, CancellationToken token)
    {
        var requestTime = DateTime.Now;
        this.requestMessage = requestMessage;
        responseMessage = await base.SendAsync(requestMessage, token);
        var responseTime = DateTime.Now;

        await LogEntryAsync(requestTime, responseTime);
        return responseMessage;
    }

    protected abstract Task LogEntryAsync(DateTime requestTime, DateTime responseTime);
}

1 个答案:

答案 0 :(得分:0)

是的,当然,这是可能的。 处理此问题的常用方法是将消息放在由处理来自所有源的日志记录的线程使用的并发队列中。 线程和队列将封装在一个Logger类中,其接口类似于:

public class ILog
{
    void Debug(....);
    void Info(....);
    void Warning(....);
}

,您的代码如下:

ILog Log {get; set;}

protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage requestMessage, CancellationToken token)
{
    var requestTime = DateTime.Now;
    this.requestMessage = requestMessage;
    responseMessage = await base.SendAsync(requestMessage, token);
    var responseTime = DateTime.Now;

    log.Info(requestTime, responseTime); // No async needed
    return responseMessage;
}

然后在使用者线程上而不是处理用户HTTP会话的主线程上发生阻塞(例如数据库或文件日志)。

真正的问题是,为什么你想要在几个广泛使用的库已经为你做到这一点并且比你希望在不花费大量时间在一个全面的日志解决方案上更好的时候自己实现它(参见NLog,Log4Net) ,CommonLogging)。