在本系例文章的第八篇中,我們聊過官方的日志實作,即《.NET6之MiniAPI(八):日志》。但官方的日志功能更多是提供了一個實作基礎,對于要求一個靈活,強大,友善的日志體系,官方的還是有差距的,那麼本篇就介紹一下NLog,這款強大,靈活,友善的日志庫,在MiniAPI中的使用。
直入主題,首先引入NeGut包
NLog.Web.AspNetCore
添加代碼實作很簡單
using NLog;
using NLog.Web;
//啟動日志
var logger = NLog.LogManager.Setup().LoadConfigurationFromAppSettings().GetCurrentClassLogger();
logger.Debug("init main");
try
{
var builder = WebApplication.CreateBuilder(args);
//配置日志
builder.Logging.ClearProviders();
builder.Logging.SetMinimumLevel(Microsoft.Extensions.Logging.LogLevel.Trace);
builder.Host.UseNLog();
var app = builder.Build();
//使用日志
app.MapGet("/logtest", () =>
{
app.Logger.LogTrace("LogTrace");
app.Logger.LogDebug("LogDebug");
app.Logger.LogWarning("LogWarning");
app.Logger.LogInformation("LogInformation");
app.Logger.LogError("LogError");
app.Logger.LogCritical(new Exception("eLogCritical"), "LogCritical");
return "logtest";
});
app.MapGet("/myvalue", MyService.GetMyValue);
app.Run();
}
catch (Exception exception)
{
//異常時處理日志
logger.Fatal(exception, "Stopped program because of exception");
}
finally
{
NLog.LogManager.Shutdown();
}
class MyService
{
public static string GetMyValue(ILogger<MyService> logger)
{
logger.LogInformation("TestService.GetMyValue");
return "MyValue";
}
}
NLog的真正友善,在配置的豐富,通過配置靈活地實作不日志方式,不同資訊項目的采集。NLog的配置以nlog.config檔案名儲存在項目根目錄下,當然也可以通過修改啟動日志的LoadConfigurationFramAppSettings來配置nlog.config路徑。
配置主要通過targets節點和rules節點協助實作配置,targets主要是配置儲存或顯示日志的方式,是txt檔案,還json檔案,以及layout中日志的内容,具體target的屬性,有很多,參見https://github.com/NLog/NLog/wiki/File-target。另外一個就是layout中,也就是将來的日志資訊有那些元素,可參見https://nlog-project.org/config/?tab=layout-renderers。
rules主要是配置不同的功能子產品,日志級别等資訊,參見https://github.com/nlog/nlog/wiki/Configuration-file#rules。
下面的案例配置,實作了官方模闆自帶的allfile和ownFile-web兩個txt格式的模闆,和一個jsonfile的模闆,同時還有一個彩色控制台模闆(各個模闆的屬性,官方文檔比較詳細,這裡就不展開了)
<?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">
<!-- enable asp.net core layout renderers -->
<extensions>
<add assembly="NLog.Web.AspNetCore"/>
</extensions>
<!-- the targets to write to -->
<targets>
<!-- File Target for all log messages with basic details -->
<target xsi:type="File" name="allfile" fileName="${basedir}\logs\nlog-AspNetCore-all-${shortdate}.log"
layout="${longdate}|${event-properties:item=EventId_Id:whenEmpty=0}|${level:uppercase=true}|${logger}|${message} ${exception:format=tostring}" />
<!-- File Target for own log messages with extra web details using some ASP.NET core renderers -->
<target xsi:type="File" name="ownFile-web" fileName="${basedir}\logs\nlog-AspNetCore-own-${shortdate}.log"
layout="${longdate}|${event-properties:item=EventId_Id:whenEmpty=0}|${level:uppercase=true}|${logger}|${message} ${exception:format=tostring}|url: ${aspnet-request-url}|action: ${aspnet-mvc-action}|${callsite}" />
<!--json格式-->
<target name="jsonfile" xsi:type="File" fileName="${basedir}\logs\${shortdate}.json">
<layout xsi:type="JsonLayout" includeAllProperties="true">
<attribute name="time" layout="${date:format=O}" />
<attribute name="message" layout="${message}" />
<attribute name="logger" layout="${logger}"/>
<attribute name="level" layout="${level}"/>
<attribute name='exception' layout='${exception}' />
<attribute name='request' encode='false' >
<layout type='JsonLayout'>
<attribute name="aspnet-request-ip" layout="${aspnet-request-ip}"/>
<attribute name="aspnet-Request-Url" layout="${aspnet-Request-Url}"/>
<attribute name="aspnet-Request-Host" layout="${aspnet-Request-Host}"/>
<attribute name="aspnet-Request-Method" layout="${aspnet-Request-Method}"/>
</layout>
</attribute>
</layout>
</target>
<!--Console Target for hosting lifetime messages to improve Docker / Visual Studio startup detection -->
<target xsi:type="ColoredConsole" name="lifetimeConsole" layout="${MicrosoftConsoleLayout}" >
<highlight-row condition="level == LogLevel.Error" backgroundColor="NoChange" foregroundColor="NoChange"/>
<highlight-row condition="level == LogLevel.Fatal" backgroundColor="NoChange" foregroundColor="NoChange"/>
<highlight-row condition="level == LogLevel.Warn" backgroundColor="NoChange" foregroundColor="NoChange"/>
<highlight-word text="info" condition="level == LogLevel.Info" backgroundColor="NoChange" foregroundColor="Green" ignoreCase="true" regex="info" wholeWords="true" compileRegex="true"/>
<highlight-word text="warn" condition="level == LogLevel.Warn" backgroundColor="NoChange" foregroundColor="Yellow" ignoreCase="true" regex="warn" wholeWords="true" compileRegex="true"/>
<highlight-word text="fail" condition="level == LogLevel.Error" backgroundColor="NoChange" foregroundColor="Red" ignoreCase="true" regex="fail" wholeWords="true" compileRegex="true"/>
<highlight-word text="crit" condition="level == LogLevel.Fatal" backgroundColor="NoChange" foregroundColor="DarkRed" ignoreCase="true" regex="crit" wholeWords="true" compileRegex="true"/>
</target>
</targets>
<!-- rules to map from logger name to target -->
<rules>
<!--All logs, including from Microsoft-->
<logger name="*" minlevel="Trace" writeTo="allfile" />
<!--Output hosting lifetime messages to console target for faster startup detection -->
<logger name="*" minlevel="Trace" writeTo="lifetimeConsole" />
<!--Skip non-critical Microsoft logs and so log only own logs (BlackHole) -->
<logger name="Microsoft.*" maxlevel="Info" final="true" />
<logger name="System.Net.Http.*" maxlevel="Info" final="true" />
<!--json格式-->
<logger name="*" minlevel="Trace" writeTo="jsonfile" />
<logger name="*" minlevel="Trace" writeTo="ownFile-web" />
</rules>
</nlog>
這裡的appsettings.jsons配置如下
{
"Logging": {
"LogLevel": {
"Default": "Trace",
"Microsoft.AspNetCore": "Trace"
}
},
"AllowedHosts": "*"
}
根據配置,看看具體的實作效果:
控制台結果
![](https://img.laitimes.com/img/__Qf2AjLwojIjJCLyojI0JCLiMGc902byZ2PyI2Y5YzY1EjZwUWNxYmMhhzY4QTN1AjZiFzM0YGMxAzLcBza5QTcsJja2FXLp1ibj1ycvR3Lc5Wanlmcv9CXt92YucWbp9WYpRXdvRnLzA3Lc9CX6MHc0RHaiojIsJye.jpg)
2022-02-20.json結果
nlog-AspNetCore-own-2022-02-20.log結果
nlog-AspNetCore-all-2022-02-20.log結果