我已经在.net core 2.2 Web API中成功配置了NLog。 但是我想通过日志记录达到规范。 如何实现以下目标:
但是当前带有请求日志的文件也将错误/警告日志保存在同一文件中,也将错误/警告特定日志文件保存在同一文件中。 如何将日志分类到分类文件中,以便将特定日志仅存储在该文件中,而不同时存储在其他文件中?
我的nlog.config文件
<?xml version="1.0" encoding="utf-8" ?>
<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" autoReload="true" internalLogLevel="info" internalLogFile="internalLog.txt">
<extensions>
<add assembly="NLog.Web.AspNetCore" />
</extensions>
<!-- the targets to write to -->
<targets>
<!-- write to file -->
<target xsi:type="File"
name="allFile"
fileName="${var:customDir}\logs\AllLog\${shortdate}.log"
layout="${longdate}|${event-properties:item=EventId_Id}|${uppercase:${level}}|${logger}|${message} ${exception:format=tostring}" />
<!-- another file log. Uses some ASP.NET core renderers -->
<target xsi:type="File"
name="requestFile"
fileName="${var:customDir}\logs\RequestTrace\${shortdate}.log"
layout="${longdate}|${event-properties:item=EventId_Id}|${uppercase:${level}}|${logger}|${message} ${exception:format=tostring}|url: ${aspnet-request-url}|action: ${aspnet-mvc-action}" />
<target xsi:type="File" name="warnFile" fileName="${var:customDir}\logs\Warnings\Warn_${shortdate}.log" />
<target xsi:type="File" name="errorFile" fileName="${var:customDir}\logs\Errors\Error_${shortdate}.log" />
</targets>
<!-- rules to map from logger name to target -->
<rules>
<logger name="*" minLevel="Trace" writeTo="allFile" />
<!--Skip non-critical Microsoft logs and so log only own logs-->
<!--<logger name="Microsoft.*" maxLevel="Info" final="true" />-->
<logger name="*" minLevel="Info" writeTo="requestFile" />
<logger name="*" minLevel="Warn" writeTo="warnFile" />
<logger name="*" minLevel="Error" writeTo="errorFile" />
</rules>
</nlog>
我的启动文件
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc(config =>
{
config.Filters.Add(new ApiLoggingMiddleware());
config.Filters.Add(new ApiExceptionLoggingMiddleware());
}
).SetCompatibilityVersion(CompatibilityVersion.Version_2_1).AddJsonOptions(
options => options.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore)
.ConfigureApiBehaviorOptions(options =>
{
options.SuppressInferBindingSourcesForParameters = true;
});
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
app.UseDeveloperExceptionPage();
app.UseAuthentication();
//app.UseMiddleware<ApiLoggingMiddleware>();
LogManager.Configuration.Variables["customDir"] = Directory.GetCurrentDirectory();
}
}
}
我的apilogginmiddleware.cs文件
public class ApiLoggingMiddleware : TypeFilterAttribute
{
public ApiLoggingMiddleware() : base(typeof(AutoLogActionFilterImpl))
{
}
private class AutoLogActionFilterImpl : IActionFilter
{
private readonly ILogger _logger;
public AutoLogActionFilterImpl(ILoggerFactory loggerFactory)
{
_logger = loggerFactory.CreateLogger<ApiLoggingMiddleware>();
}
public void OnActionExecuting(ActionExecutingContext context)
{
// perform some business logic work
}
public void OnActionExecuted(ActionExecutedContext context)
{
...
_logger.LogInformation("Log request data");
...
}
}
}
}
MY apiexceptionloggingmiddleware.cs文件
public class ApiExceptionLoggingMiddleware : TypeFilterAttribute
{
public ApiExceptionLoggingMiddleware() : base(typeof(AutoLogExceptionImpl))
{
}
private class AutoLogExceptionImpl : IExceptionFilter
{
private readonly ILogger _logger;
public AutoLogExceptionImpl(ILoggerFactory loggerFactory)
{
_logger = loggerFactory.CreateLogger<ApiLoggingMiddleware>();
}
public void OnException(ExceptionContext context)
{
_logger.LogError("Errors : " + context.Exception
+ Environment.NewLine + Environment.NewLine);
}
}
}
}
答案 0 :(得分:0)
规则从上到下匹配。所以minlevel = info也将匹配错误等。
这里的解决方案简单,使用level
代替minlevel
<rules>
<logger name="*" minLevel="Trace" writeTo="allFile" />
<!--Skip non-critical Microsoft logs and so log only own logs-->
<!--<logger name="Microsoft.*" maxLevel="Info" final="true" />-->
<logger name="*" level="Info" writeTo="requestFile" />
<logger name="*" level="Warn" writeTo="warnFile" />
<logger name="*" level="Error" writeTo="errorFile" />
</rules>
另一种选择是使用final
并在出现错误时首先进行匹配,然后发出警告等。
例如
<rules>
<logger name="*" minLevel="Trace" writeTo="allFile" />
<!--Skip non-critical Microsoft logs and so log only own logs-->
<!--<logger name="Microsoft.*" maxLevel="Info" final="true />-->
<logger name="*" minLevel="Error" writeTo="errorFile" final="true” />
<logger name="*" minLevel="Warn" writeTo="warnFile" final="true" />
<logger name="*" minLevel="Info" writeTo="requestFile" final="true" />
</rules>
另请参阅https://github.com/NLog/NLog/wiki/Configuration-file#rules
答案 1 :(得分:0)
我建议您为请求记录程序ApiLoggingMiddleware
设置特殊的记录规则:
<rules>
<logger name="*" minLevel="Trace" writeTo="allFile" />
<!--Skip non-critical Microsoft logs and so log only own logs-->
<!--<logger name="Microsoft.*" maxLevel="Info" final="true" />-->
<logger name="*ApiLoggingMiddleware" minLevel="Info" writeTo="requestFile" />
<logger name="*" minLevel="Error" writeTo="errorFile" final="true" />
<logger name="*" minLevel="Warn" writeTo="warnFile" final="true" />
</rules>
那么requestFile
-目标将不会被其他Info-logging-events污染。
但是请确保ApiExceptionLoggingMiddleware
和ApiLoggingMiddleware
没有共享相同的Logger名称。看起来ApiLoggingMiddleware
执行了请求记录,因此避免重用/滥用其Logger名称(请参阅loggerFactory.CreateLogger<ApiLoggingMiddleware>()
)