Microsoft Owin日志-Web Api 2-如何创建日志
本文关键字:日志 创建 何创建 Owin -Web Api Microsoft | 更新日期: 2023-09-27 18:11:23
我正试图使用Web Api 2和Owin将日志记录添加到我的应用程序中,所以我开始使用Microsoft Owin logging,它需要一个ILogger
和ILoggerFactory
,并且已经实现,当我需要在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控制器中,但对于已经存在的东西来说,这似乎太复杂了。
任何想法都将不胜感激。
我建议您编写中间件,以便您可以在控制器之外处理日志记录:
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/