.net core中的那些常用的日誌框架(NLog篇)

喜歡吃魚的青年發表於2020-10-13

前言

我們們上回講到,.net core中內建的Logging日誌框架的使用,以及淺顯的講解,接下來,給大家介紹一個第三方日誌框架(NLog)。

NLog簡介

NLog是適用於各種.NET平臺(包括.NET標準)的靈活,免費的日誌記錄平臺。NLog使寫入多個目標變得容易 。(資料庫,檔案,控制檯)並即時更改日誌記錄配置。

NLog的優勢

  • NLog支援結構化 和傳統日誌記錄。
  • NLog的重點是:高效能,易於使用,易於擴充套件和靈活配置。

1.NuGet安裝NLog

NLog.Web.AspNetCore
NLog.Config

簡短說明:

  • NLog.Web.AspNetCore:引入第三方的服務,可以在程式中使用
  • NLog.Config:安裝之後,會自動生成一個配置檔案模板(NLog.Config)。

2.引入服務(Program)

  public class Program
    {
        public static void Main(string[] args)
        {
            //新增Nlog的配置項
            NLogBuilder.ConfigureNLog("NLog.config");
            CreateHostBuilder(args).Build().Run();
        }

        public static IHostBuilder CreateHostBuilder(string[] args) =>
            Host.CreateDefaultBuilder(args)
                 .ConfigureLogging(log => {
                //從builder移除內建的日誌框架(如果引用第三方,一定要設定這屬性)
                log.ClearProviders();
                //將日誌新增到控制檯
                log.AddConsole();
                //將日誌新增到Debug視窗
                log.AddDebug();
                })
                .ConfigureWebHostDefaults(webBuilder =>
                {
                    webBuilder.UseStartup<Startup>();
                }).
                UseNLog();//引用第三方日誌框架
    }

需要注意的幾個地方:

  • NLogBuilder.ConfigureNLog("NLog.config");引入配置檔案
  • log.ClearProviders();移除內建的日誌框架(Logging)
  • log.AddConsole();將日誌新增到控制檯
  • log.AddDebug();將日誌新增到debug視窗
  • UseNLog()在末尾引入第三方的日誌框架(一定要寫

3.修改NLog.Config檔案

簡單介紹配置檔案中的配置資訊

+ xmlns,xsi是引入名稱空間
+ autoReload="true"是熱更新,在程式執行過程中也可以修改配置檔案
+ throwExceptions:NLog日誌系統丟擲異常
+ internalLogLevel:日誌級別
+ internalLogFile:內部日誌檔案
+ variable:定義變數
+ targets:日誌輸出地方
+ rules:日誌的路由規則

3.1日誌顯示控制檯版本

<?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="myvar" value="myvalue"/>

  <targets>
      <!--使用可自定義的著色將日誌訊息寫入控制檯-->
      <target name="colorConsole" xsi:type="ColoredConsole" layout="[${date:format=HH\:mm\:ss}]:${message} ${exception:format=message}" />
  </targets>

  <rules>
    <logger name="*" minlevel="Warn" writeTo="colorConsole" />
  </rules>
</nlog>

效果如下:

3.2日誌存入本地txt版本

需要注意的地方

target中的引數

  • name:是指的輸出地方的一個名詞(給rules呼叫的)
  • xsi:type:輸出檔案的型別,File指的是檔案
  • fileName:輸出到目標檔案的地址,使用的相對路徑,可以自行配置輸出的地點。
  • layout:在最簡單的形式中,佈局是帶有嵌入標記的文字,這些嵌入標記由${和分隔}
  • archiveFileName:表示滾動日誌存放路徑
  • archiveAboveSize:單次日誌的儲存大小(單位是KB),超過配置,會archiveFileName中建立新的日誌
  • archiveNumbering:Sequence(排序),Rolling(滾動)
  • concurrentWrites:支援多個併發一起寫檔案,提高檔案寫入效能。
  • keepFileOpen:為了提高檔案寫入效能,避免每次寫入檔案都開關檔案
  • autoFlush:為了提高日誌寫入效能,不必每次寫入日誌都直接寫入到硬碟
  • createDirs:若設定的日誌資料夾不存在,則自動建立資料夾。

rules中的引數

  • logger:代表一個路由的規則
  • name:logger名稱,若為*則表示適用於所有日誌
  • minlevel:表示當前日誌的最低日誌級別,只有等於或大於該值的日誌級別才會被記錄
  • writeTo:和target的name匹配,一個rules對應一個target
<?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">

  <!-- optional, add some variables
  https://github.com/nlog/NLog/wiki/Configuration-file#variables
  -->
  <variable name="myvar" value="myvalue"/>

  <targets>

      <!--專案日誌儲存檔案路徑說明fileName="${basedir}/儲存目錄,以年月日的格式建立/${shortdate}/${記錄器名稱}-${單級記錄}-${shortdate}.txt"-->
      <target name="log_file" xsi:type="File"
              fileName="${basedir}/Logs/${shortdate}/${logger}-${level}-${shortdate}.txt"
              layout="${longdate} | ${message} ${onexception:${exception:format=message} ${newline} ${stacktrace} ${newline}"
              archiveFileName="${basedir}/archives/${logger}-${level}-${shortdate}-{#####}.txt"
              archiveAboveSize="1024"
              archiveNumbering="Sequence"
              concurrentWrites="true"
              keepFileOpen="false"
              autoFlush="false"
              encoding="utf-8"
              createDirs="true"
             />
      <!--使用可自定義的著色將日誌訊息寫入控制檯-->
      <target name="colorConsole" xsi:type="ColoredConsole" layout="[${date:format=HH\:mm\:ss}]:${message} ${exception:format=message}" />
  </targets>
  <rules>
    <logger name="Microsoft.*" minlevel="Info" writeTo="log_file" final="true" />
    <logger name="*" minlevel="Info" writeTo="log_file" />
    <!--logger name="*" minlevel="Warn" writeTo="colorConsole" /-->
  </rules>
</nlog>

效果如下

正如大家看到一樣,是以日誌的型別進行區分建立txt日誌文件,這樣不僅可以區分不同的日誌級別,還可以根據不同的Controller生成對應的日誌,在以後分析日誌的問題的時候,可以精確到某一個點的日誌問題。

3.3日誌存入資料庫版本

您可以將此目標與各種資料庫提供程式一起使用,例如System.Data,Microsoft.Data,Oracle,MySql,SqlLite等,本文以SQL為例。
注意事項

  • 在.net core中使用Nlog,dbProvider需要設定說明(是什麼資料庫,在Nlog的官方文件有明確提示)
  • 根據不同的資料庫,安裝不同的驅動,本文使用的是SQL Server,所以需要在NuGet安裝:Microsoft.Data.SqlClient
3.3.1需要建立資料庫
CREATE TABLE [dbo].[NLog] (
   [ID] [int] IDENTITY(1,1) NOT NULL,
   [MachineName] [nvarchar](200) NULL,
   [Logged] [datetime] NOT NULL,
   [Level] [varchar](5) NOT NULL,
   [Message] [nvarchar](max) NOT NULL,
   [Logger] [nvarchar](300) NULL,
   [Properties] [nvarchar](max) NULL,
   [Callsite] [nvarchar](300) NULL,
   [Exception] [nvarchar](max) NULL,
 CONSTRAINT [PK_dbo.Log] PRIMARY KEY CLUSTERED ([ID] ASC) 
   WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) 

3.3.2配置Nlog
<?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">

  <!-- optional, add some variables
  https://github.com/nlog/NLog/wiki/Configuration-file#variables
  -->
  <variable name="myvar" value="myvalue"/>

  <targets>
    <!--儲存資料庫-->
    <target name="apiUsageLog" 
            xsi:type="Database" 
            dbProvider="Microsoft.Data.SqlClient.SqlConnection,Microsoft.Data.SqlClient" 
            connectionString="Data Source=.;Initial Catalog=test;User ID=sa;Password=123456;">
      <commandText>
        INSERT INTO [dbo].[NLog] (
    [MachineName],
    [Logged],
    [Level],
    [Message],
    [Logger],
    [Properties],
    [Callsite],
    [Exception]
  ) VALUES (
    @machineName,
    @logged,
    @level,
    @message,
    @logger,
    @properties,
    @callsite,
    @exception
  );
      </commandText>
      <parameter name="@machineName"    layout="${machinename}" />
  <parameter name="@logged"         layout="${date}" />
  <parameter name="@level"          layout="${level}" />
  <parameter name="@message"        layout="${message}" />
  <parameter name="@logger"         layout="${logger}" />
  <parameter name="@properties"     layout="${all-event-properties:separator=|}" />
  <parameter name="@callsite"       layout="${callsite}" />
  <parameter name="@exception"      layout="${exception:tostring}" />
    </target>
  </targets>

  <rules>
    <logger name="*" minlevel="Trace" writeTo="apiUsageLog" />
  </rules>
</nlog>
3.3.3如何使用?
        //獲取Nlog物件
        private Logger _logger = LogManager.GetCurrentClassLogger();
        public void Get()
        {
            _logger.Info("asd");
            _logger.Debug("測試訊息Debug");
            _logger.Warn("測試訊息Warn");
            _logger.Trace("測試訊息Trace");
            _logger.Error("測試訊息Error");
        } 
3.3.4實際效果

3.4郵箱傳送日誌版本

這個比較簡單,只需要簡單配置即可

<?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">

  <!-- optional, add some variables
  https://github.com/nlog/NLog/wiki/Configuration-file#variables
  -->
  <variable name="myvar" value="myvalue"/>

  <targets>
    <!--郵箱-->
    <target xsi:type="Mail"
            name="emial"
            header="=============================================="
            footer="=============================================="
            html="true" 
            addNewLines="true"
            encoding="UTF-8"
            subject="測試日誌資訊${machinename}"
            body="${newline}${message}${newline}"
            enableSsl="true"
            to="接受郵件的郵箱地址"
            from="傳送郵件的郵箱地址"
            smtpPassword="傳送郵件的郵箱密碼"
            smtpAuthentication="Basic"
            smtpServer="smtp.163.com"
            smtpPort="25"
            smtpUserName="傳送郵件的郵箱地址">
    </target>
  </targets>

  <rules>
    <logger name="*" minlevel="Trace" writeTo="emial" />
  </rules>
</nlog>

效果如下圖:

4.總結

想比較Logging日誌框架,NLog的好處就不必多說,多樣的儲存方式,簡潔明瞭的配置資訊,在專案中使用,來給我帶來很好的分析問題的好幫手,日誌型別還可以分塊,日誌大小還能切割,極大的滿足了我們的日常需求。需要注意一點,發郵件可以群發,需要配置,存資料庫可以用儲存過程,可以檢視官方文件。

5.參考文件

Nlog官方文件

相關文章