Microsoft Owin Logging - Web Api 2 - 如何创建记录器?

Dan*_*iel 10 c# owin asp.net-web-api2

我正在尝试使用Web Api 2和Owin向我的应用程序添加日志记录,所以我开始使用Microsoft Owin Logging,这需要一个ILoggerILoggerFactory已经实现的,当我需要在STARTUP方法或任何Owin Middleware组件.

例如,当我在Startup方法中时,我可以使用以下方法创建记录器:

    public void Configuration(IAppBuilder app)
    {
        // Creates configuration
        var configuration = new HttpConfiguration();

        // Configure WebApi Settings
        WebApiConfig.Register(configuration);

        app.SetLoggerFactory(new OwinLog4NetLoggerFactory("Default"));

        var logger = app.CreateLogger<Startup>();
        logger.WriteInformation("test log");

        // Enabled WebApi in OWIN
        app.UseWebApi(configuration);
    }
Run Code Online (Sandbox Code Playgroud)

其中"OwinLog4NetLoggerFactory"是我的自定义ILoggerFactory实现.

到目前为止,这么好......但是......当我在实际的web api动作方法中时,如何创建记录器?...我尝试访问Request.GetOwinEnvironment()并且记录器工厂不在字典中.

例如:

public class AccountController : ApiController
{
    public int Get(int id)
    {
        // Create logger here

        return id + 1;
    }
}
Run Code Online (Sandbox Code Playgroud)

我知道我可以创建一个静态类,引用Logger Factory甚至是注入来将记录器添加到api控制器,但这对于应该存在的东西来说似乎太复杂了.

任何想法,将不胜感激.

小智 6

我建议编写您的中间件,以便您可以处理控制器外部的日志记录:

public class LoggingMiddleware : OwinMiddleware
{
    public LoggingMiddleware(OwinMiddleware next)
        : base(next)
    {
    }

    public override async Task Invoke(IOwinContext context)
    {
            //handle request logging

            await Next.Invoke(context); 

            //handle response logging
    }

}
Run Code Online (Sandbox Code Playgroud)

然后在启动类中:

public class Startup
{
    // ReSharper disable once UnusedMember.Global
    public void Configuration(IAppBuilder appBuilder)
    {
        HttpConfiguration config = new HttpConfiguration();

        config.MapHttpAttributeRoutes();
        appBuilder.Use<LoggingMiddleware>();
        appBuilder.UseWebApi(config);
    }
}
Run Code Online (Sandbox Code Playgroud)

然后请求会进来,点击 LoggingMiddleware 中的请求日志代码,点击控制器代码,然后在返回的路上将响应记录在 LoggingMiddleware 上。

但是,如果您只想将对象从中间件发送到控制器,您可以context.Set("loggingObject", loggingObject);在中间件中使用,然后 var loggingObject = Request.GetOwinContext().Get<LoggerClass>("loggingObject");在控制器中使用。


M. *_*har 0

我没有在每个方法中添加日志记录代码,而是创建一个可以在 Global.asax.cs 中注册一次的 MessageLoggingHandler,然后记录每个请求和响应。

这是我使用的代码,您可以根据您的要求进行修改:

首先创建一个继承自DelegationHandler的MessageHandler类:

    public abstract class MessageHandler : DelegatingHandler
{
    protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
    {
        var corrId = Guid.NewGuid();
        var requestMethod = request.Method.Method.ToString();
        var requestUri = request.RequestUri.ToString();
        var ipAddress = request.GetOwinContext().Request.RemoteIpAddress;

        var requestMessage = await request.Content.ReadAsByteArrayAsync();
        await LogMessageAsync(corrId, requestUri, ipAddress, "Request", requestMethod, request.Headers.ToString(), requestMessage, string.Empty);

        var response = await base.SendAsync(request, cancellationToken);

        var responseMessage = await response.Content.ReadAsByteArrayAsync();
        await LogMessageAsync(corrId, requestUri, ipAddress, "Response", requestMethod, response.Headers.ToString(), responseMessage, ((int)response.StatusCode).ToString() + "-" + response.ReasonPhrase);

        return response;
    }

    protected abstract Task LogMessageAsync(Guid CorrelationId, string APIUrl, string ClientIPAddress, string RequestResponse, string HttpMethod, string HttpHeaders, byte[] HttpMessage, string HttpStatusCode);

}

public class MessageLoggingHandler : MessageHandler
{
    protected override async Task LogMessageAsync(Guid CorrelationId, string APIUrl, string ClientIPAddress, string RequestResponse, string HttpMethod, string HttpHeaders, byte[] HttpMessage, string HttpStatusCode)
    {
        // Create logger here

        //Do your logging here
    }
}
Run Code Online (Sandbox Code Playgroud)

然后在您的 Global.asax.cs 中,您需要注册上面创建的 MessageLoggingHandler:

GlobalConfiguration.Configuration.MessageHandlers.Add(new MessageLoggingHandler());
Run Code Online (Sandbox Code Playgroud)

请注意,这将记录每个请求和响应,以及完整的消息正文。这可能会很快占用大量空间(取决于 API 的使用情况)。因此,您可能需要对此进行调整(例如 - 将记录保存一个月左右,或忽略 200-OK 响应等)

  • 非常感谢,不幸的是我不需要记录每个请求/响应(仅供参考,在 Owin 世界中,您通常通过中间件来执行此操作)。我需要创建记录器,因为我需要在某些操作中记录“一些调试或警告消息”。再次感谢您的回复。 (2认同)