Microsoft Owin日志-Web Api 2-如何创建日志

本文关键字:日志 创建 何创建 Owin -Web Api Microsoft | 更新日期: 2023-09-27 18:11:23

我正试图使用Web Api 2和Owin将日志记录添加到我的应用程序中,所以我开始使用Microsoft Owin logging,它需要一个ILoggerILoggerFactory,并且已经实现,当我需要在STARTUP方法或任何Owin中间件组件内记录任何内容时,它非常有效。

例如,当我使用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);
    }

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

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

例如:

public class AccountController : ApiController
{
    public int Get(int id)
    {
        // Create logger here
        return id + 1;
    }
}

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

任何想法都将不胜感激。

Microsoft Owin日志-Web Api 2-如何创建日志

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

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
    }
}

然后在启动类中:

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);
    }
}

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

但是,如果您只想将对象从中间件发送到控制器,则可以在中间件中使用context.Set("loggingObject", loggingObject);,然后控制器中的CCD_ 6。

我没有在每个方法中添加日志记录代码,而是创建了一个可以在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
    }
}

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

GlobalConfiguration.Configuration.MessageHandlers.Add(new MessageLoggingHandler());

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

我建议您在应用程序中使用NuGet上提供的Common.Logging库。日志记录为您提供了一个使用首选日志记录解决方案的通用界面。它解决了很多像你这样的问题。下面是一个使用Common.Logging和NLog:的例子

在你的控制器中,你可以这样访问它:

public class MyController : ApiController
  {
    private static readonly ILog Log = LogManager.GetLogger<MyController>();
    public async Task<IHttpActionResult> Get([FromUri] int id)
    {
      Log.Debug("Called Get with id " + id.ToString());
      return Ok();
    }
  }

在NuGet上获取最新的Common.Loggin.NLog包(截至本文撰写之时,它应该是Common.Logning.NLog41(。然后在web.config中,您将配置Common.Logging以使用您的NLog配置:

<common>
  <logging>
    <factoryAdapter type="Common.Logging.NLog.NLogLoggerFactoryAdapter, Common.Logging.NLog41">
      <arg key="configType" value="FILE" />
      <arg key="configFile" value="~/NLog.config" />
    </factoryAdapter>
  </logging>
</common>

以下是一些附加链接:

https://github.com/net-commons/common-logging

https://cmatskas.com/an-introduction-to-common-logging-api-2/