實作NLog_專案Console


Posted by 愛娃仔 on 2020-02-13


NLog

依據使用者所定義的等級,去操作不同的處理方式,像是 Email 通知或是傳訊息等。

這裡等級指的是 TraceDebugInfoWarnErrorFatal


實作步驟

A. 建立新的 Console 檔之後,點選上方工具列「專案」 > 選擇「管理 Nuget 套件」 > 開啟「NuGet Packages Manager」 > 搜尋並安裝 NLog Config,其餘套件便會一併安裝(如下圖)。

B. 修改 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">      

  <!--[變數] 文字樣板 -->
  <variable name="Layout" value="${longdate} | ${level:uppercase=true} | ${logger} | ${message} ${newline}"/>
  <variable name="LayoutFatal" value="${longdate} | ${level:uppercase=true} | ${logger} | ${message} | ${exception:format=tostring} ${newline}"/>

  <!--[變數] 檔案位置 -->
  <variable name="LogTxtDir" value="${basedir}/App_Data/Logs/${shortdate}/"/>
  <variable name="LogTxtLocation" value="${LogTxtDir}/${logger}.log"/>
  <variable name="LogTxtLocationFatal" value="${LogTxtDir}/FatalFile.log"/>

  <!--[設定] 寫入目標-->
  <targets>
    <target name="File" xsi:type="File" fileName="${LogTxtLocation}" layout="${Layout}"
            encoding="utf-8" maxArchiveFiles="30" archiveNumbering="Sequence"
            archiveAboveSize="1048576" archiveFileName="${LogTxtDir}/${logger}.log{#######}" />
    <target name="FileFatal" xsi:type="File" fileName="${LogTxtLocationFatal}" layout="${LayoutFatal}"
            encoding="utf-8" maxArchiveFiles="30" archiveNumbering="Sequence"
            archiveAboveSize="1048576" archiveFileName="${LogTxtDir}/FatalFile.log{#######}" />
    <target name="EventLog" xsi:type="EventLog" source="NLogLogger" log="Application"
            layout="${date}| ${level} | ${message}"/>
  </targets>

  <!--[設定] 紀錄規則-->
  <rules>
    <logger name="*" levels="Trace,Debug,Info,Warn" writeTo="File" />
    <logger name="*" levels="Error,Fatal" writeTo="FileFatal" />
    <logger name="*" levels="Fatal" writeTo="EventLog" />
  </rules>

</nlog>

C. 在 console 專案下的 program.cs 輸入下列程式碼

using NLog;
class Program
{
    private static Logger logger = LogManager.GetCurrentClassLogger();
    static void Main(string[] args)
    {
        logger.Trace("我是追蹤:Trace");
        logger.Debug("我是偵錯:Debug");
        logger.Info("我是資訊:Info");
        logger.Warn("我是警告:Warn");
        logger.Error("我是錯誤:error");
        logger.Fatal("我是致命錯誤:Fatal");
    }
}

D. 在 debug 模式下執行,至檔案位置查看結果如下


查詢 Windows Event log

Windows 鍵 + R 並輸入 eventvwr.msc 打開事件檢視器
Windows 記錄 > 應用程式 > 來源=NLogLogger > 內容

追蹤 NLog 問題

有時候我們可能會在正式上版後遇到 NLog 無法寫出 log file 或是寫到 Windows Event log失敗的問題,但 NLog 內部執行時若遇到錯誤,避免影響主程式執行,NLog 預設會先略過!

可使用檔案追蹤

在 NLog.Config 檔案中的 element 內加入以下原始碼

<nlog ... internalLogLevel="Error" internalLogFile="c:\temp\log\nlog-internal.log">
 ...
</nlog>

範例

接下來去收 internal log 就可以知道 Log 檔案寫入失敗的原因了!

這邊我們會刻意關閉資料夾權限並且設定錯誤的 event source 來測試,執行完 Console 程式後,打開 nlog-internal.log

檔案內容如下:

  • 找不到來源,但無法搜尋部分或全部的事件紀錄檔。無法存取的紀錄檔:Security: 用powershell新增event source。
  • 存取被拒: 確認資料夾是否有權限寫入

    記得以系統管理員身分開啟 Visual Studio

最後如果連 internal lo g也失效,還有另外一招 throwExceptions="true",讓錯誤回拋到主程式處理。

<nlog throwExceptions="true">
   ...
</nlog>

補充 :

內建系統參數名稱

targes

  1. 定義 Log 存放的媒體為何
  2. 定義 Log 的格式內容

rules

  1. 定義各等級的 Log 的處理方式,也就是使用哪一個targets來存放資料。

${basedir}:代表網站根目錄 (或應用程式所在目錄);The current application domain's base directory.
${shortdate}:短日期格式;The short date in a sortable format yyyy-MM-dd.
${longdate}:長日期格式;The date and time in a long, sortable format yyyy-MM-dd HH:mm:ss.mmm.
${logger}:記錄器名稱;The logger name.
${level:uppercase=true}:Log的等級;The log level.
而中間 uppercase=true 就是把等級的文字轉為大寫.
${message}:Log 的訊息內容;The formatted log message.
${newline}:新行符號;A newline literal.
${stacktrace}:Stack trace renderer,如錯誤的堆疊訊息內容。


參考資料

[.NET][C#]Log日誌功能(二)NLog使用及追蹤
NLog 基本介紹與偵錯


#.net #NLog #Console #log