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()

參考資料