
在 .NET 6 Worker
中使用 NLog 日誌記錄
日誌記錄是一個重要的組件,能夠幫助我們追蹤工作器的運行狀態和錯誤訊息。在這篇文章中,我們將介紹如何在 .NET 6 Worker 應用程式中啟用 NLog 日誌記錄並進行相關的設定。
安裝 NLog 套件
在開始之前,我們需要先安裝 NLog 套件。我們這裡使用 NuGet 管理器來安裝 NLog 套件。

設定 NLog.config 檔案
在專案的根目錄下新增一個名為 NLog.config 的檔案(點選專案右鍵>加入>新增項目>應用程式組態檔),這個檔案將包含 NLog 的設定內容。可以使用 XML 格式來定義日誌記錄的輸出位置、格式和層級等設定。
以下為我使用的設定內容:
<?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"
xsi:schemaLocation="http://www.nlog-project.org/schemas/NLog.xsd NLog.xsd"
autoReload="true"
throwExceptions="false"
internalLogLevel="Off" internalLogFile="c:\temp\nlog-internal.log">
<!--[變數] 文字樣板 -->
<variable name="Layout" value="${longdate} | ${level:uppercase=true} | ${logger} | ${message}
${onexception:${newline}${exception:format=tostring}}"/>
<!--[設定] 寫入目標-->
<targets>
<target name="TimeBasedFileArchival" xsi:type="File"
layout="${Layout}"
fileName="c:/Logs/worker1/log.txt"
archiveFileName="c:/Logs/worker1/ogs/archives/{#}.txt"
archiveEvery="Day"
archiveNumbering="Date"
archiveDateFormat="yyyy-MM-dd"
maxArchiveFiles="7"
archiveAboveSize="4388608"
concurrentWrites="true"
keepFileOpen="false"
encoding="UTF-8" />
<target name="eventlog" xsi:type="EventLog"
source="worker1" log="Application"
layout="${date}: ${message} ${stacktrace}" />
</targets>
<!--[設定] 紀錄規則-->
<rules>
<logger name="*" levels="Trace,Debug,Info,Warn,Error,Fatal" writeTo="TimeBasedFileArchival" />
<logger name="*" levels="Error,Fatal" writeTo="eventlog"/>
</rules>
</nlog>
上述的 NLog.config 檔案主要包括了,文字樣版、寫入目標和紀錄規則,以下將逐一說明設定內容:
文字樣版
<!--[變數] 文字樣板 -->
<variable name="Layout" value="${longdate} | ${level:uppercase=true} | ${logger} | ${message}
${onexception:${newline}${exception:format=tostring}}"/>
此段新增了一個變數叫做Layout
來儲存Log輸出時的文字樣版,可以運用Nlog內建的tag來定義想要的文字樣版,以下為常用的tag:
${longdate}
:日期與時間(格式: yyyy-MM-dd HH:mm:ss.ffff)${level}
:Log等級(ex. ERROR、DEBUG、INFO)${logger}
:Logger名稱${message}
:Log Message${exception}
:例外資訊${stacktrace}
:追蹤程式碼${identity}
:身分資訊(名字和驗證資訊)
完整的tag清單請見官方文件
寫入目標
<!--[設定] 寫入目標-->
<targets>
<target name="TimeBasedFileArchival" xsi:type="File"
layout="${Layout}"
fileName="c:/Logs/worker1/log.txt"
archiveFileName="c:/Logs/worker1/ogs/archives/{#}.txt"
archiveEvery="Day"
archiveNumbering="Date"
archiveDateFormat="yyyy-MM-dd"
maxArchiveFiles="7"
archiveAboveSize="4388608"
concurrentWrites="true"
keepFileOpen="false"
encoding="UTF-8" />
<target name="eventlog" xsi:type="EventLog"
source="worker1" log="Application"
layout="${date}: ${message} ${stacktrace}" />
</targets>
寫入目標可以設定多個日誌的目的地,像是File、Console、EventLog、Database等等。
更多的Target類型設定請參考官方文件
範例此段共設定了兩個輸出設定(File 和 EventLog)
- TimeBasedFileArchival
設定以檔案形式儲存日誌,每天封存日誌,最多封存七天。
產生的Log目錄結構如下:
C:\LOGS\WORKER1
│ log.txt
│
└─ogs
└─archives
2023-05-03.txt
2023-05-04.txt
2023-05-08.txt
2023-05-09.txt
2023-05-11.txt
2023-05-15.txt
2023-05-16.txt
xsi:type="File"
:設定輸出類型為檔案(File)layout="${Layout}"
:輸出文字模板為變數”Layout”的內容fileName="c:/Logs/worker1/log.txt"
:設定Log檔案位置及名稱archiveFileName="c:/Logs/worker1/ogs/archives/{#}.txt"
:設定封裝檔案位置及名稱archiveEvery="Day"
:設定封裝週期為日(Day)archiveNumbering="Date"
:封裝檔案以日期命名(也就是archiveFuleName中{#})的部分archiveDateFormat="yyyy-MM-dd"
:封裝檔案編碼日期格式(此選項只在archiveNumbering="Date"
時有效)maxArchiveFiles="7"
:封存保留檔案最大數量為7archiveAboveSize="4388608"
:最大容量(以字節為單位),超過將產生新的日誌concurrentWrites="true"
:允許多執行序寫入encoding="UTF-8"
:UTF-8編碼
- eventlog
xsi:type="EventLog"
:Log輸出類型為Windows Event Logssource="worker1"
:設定EventLog來源為worker1(應用程式名稱)log="Application"
:設定eventlog類型為應用程式layout="${date}: ${message} ${stacktrace}"
:設定文字樣版
紀錄規則
<!--[設定] 紀錄規則-->
<rules>
<logger name="*" levels="Trace,Debug,Info,Warn,Error,Fatal" writeTo="TimeBasedFileArchival" />
<logger name="*" levels="Error,Fatal" writeTo="eventlog"/>
</rules>
紀錄規則是設定甚麼樣的Log要寫到甚麼Target(寫入目標)中,此段範例中設定Log Level為Trace、Debug、Info、Warn、Error、Fatal存入TimeBasedFileArchival目標中,Log Level為Error、Fatal存入eventlog目標中。
NLog用法
public class Worker1 : IInvocable
{
//引入logger
private readonly ILogger _logger;
public Worker1(ILogger<StatisticsWork> logger)
{
_logger = logger;
}
public Task Invoke()
{
_logger.LogInformation("This is an Info Log Level Message!");
_logger.LogCritical("This is a Critical Log Level Message!");
_logger.LogDebug("This is a Debug Log Level Message!");
_logger.LogTrace("This is a Trace Log Level Message!");
_logger.LogWarning("This is a Warning Log Level Message!");
_logger.LogError("This is an Error Log Level Message!");
}
}