在 ASP.NET Core 中使用 NLog
ASP.NET Core 中雖然也有內建的 log 功能,但個人覺得 NLog 較好用,而且目前也算主流,所以文章會講解使用方式及如何定義設定檔。
首先,在 ASP.NET Core 的專案,加進下列兩個 NuGet 套件:
接下來新增 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="Debug"
internalLogFile="c:\logs\internal-nlog.txt">
<!-- enable asp.net core layout renderers -->
<extensions>
<add assembly="NLog.Web.AspNetCore"/>
</extensions>
<variable name="appname" value="TestNLog" />
<!-- the targets to write to -->
<targets>
<!-- another file log, only own logs. Uses some ASP.NET core renderers -->
<target xsi:type="File" name="ownFile-web" fileName="c:\logs\nlog-own-${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="MyLogTarget" fileName="c:\logs\${shortdate}-${appname}.log"
layout="${longdate}:${level}|${logger}|${aspnet-mvc-action}|${message} " />
</targets>
<!-- rules to map from logger name to target -->
<rules>
<logger name="MyLog" maxlevel="Info" writeTo="ownFile-web" />
<!--Skip non-critical Microsoft logs and so log only own logs-->
<logger name="Microsoft.*" maxlevel="Info" writeTo="ownFile-web" />
<logger name="NLogTestWebApp.*" minlevel="Trace" writeTo="MyLogTarget" final="true" />
</rules>
</nlog>
在此針對設定檔的幾個參數做說明:
target
target 設定的是檔案的寫法位置,以及 log 的格式(分別是 fileName 及 layout),其中 ${level} 這個就是代表置入 level 這個變數,這個變數是內建。
variable
宣告變數用的,在前面的 target 部份,有提到可以置入變數,除了內建的,也可以自行宣告,像是 <variable name="appname" value="TestNLog" />
這行,就是用來設定專案名稱,好讓 log 裡可以清楚顯示是來自於哪個專案。
rule
rule 就是用來設定所謂的 logger,像是 <logger name="MyLog" maxlevel="Info" writeTo="ownFile-web" />
這一行,就是設定要使用前面宣告的哪個 target。而 name 這個部份稍微複雜一點。先看這一行程式碼:
var logger = NLogBuilder.ConfigureNLog("nlog.config").GetLogger("MyLog");
這一行就是直接透過 name 去取得 NLog 物件。
但在 ASP.NET Core 中,都是透過 DI 的方式取得 ILog 物件,再寫入 log。像是會透過這樣的方式取得:
public HomeController(ILogger<HomeController> logger, ITestService testService)
{
_logger = logger;
_testService = testService;
}
在這個 controller 中,我設定的 namespace 是 NLogTestWebApp.Controllers
。也就是說,在整個專案下,基本上 namespace 都會是 NLogTestWebApp
,所以我的 rule name 就可以設定為 NLogTestWebApp.*
,這樣子基本上專案底下的元件都可以吃到這個 rule。
最後,再回頭講解 Program.cs 中需要做什麼設定:
public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.UseStartup<Startup>()
.ConfigureLogging(logging =>
{
logging.ClearProviders();
logging.SetMinimumLevel(Microsoft.Extensions.Logging.LogLevel.Trace);
})
.UseNLog();
基本上只是在結尾加上 UseNLog()
參考資料