NLog日志框架使用探究
前言
日志是每個程序的基本模塊。本文是為了探究如何通過NLog方便及記錄日志并通過Log4View工具收集日志統一查看。
為什么是NLog?
下載量NLog和Log4Net差不多,這兩個日志模塊是.Net平臺使用最多的兩大日志模塊。
Log4Net上次更新已經是17年3月
NLog更新的比較頻繁,開發者比較活躍,有問題的話修復更及時。
NLog是適用于各種.net平臺(包括.net standard)的靈活而免費的日志記錄平臺。通過NLog, 可以輕松地寫入多個目標。(數據庫、文件、控制臺), 并動態更改日志記錄配置。
NLog支持結構化和傳統日志記錄。NLog的特點: 高性能、易于使用、易于擴展和靈活配置。
目的
本文為了探究NLog的使用方式,以及如何通過NLog將日志統一收集查看并管理。
配置
NLog可以通過配置方式輕松的記錄不同等級,不同結構的日志。
通過Nuget獲取NLog庫包
Install-Package NLog -Version 4.5.11
下載完后會自動在程序下加入默認的NLog配置
Nlog支持多種配置方式,具體其他配置方式看下《一個簡單好用的日志框架NLog》,講解的很詳細。
基本配置
<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="Info"???????internalLogFile="./logs/nlog-internal.log">NLog 根節點以下幾種配置需要注意
autoReload:配置修改是否自動加載。
throwExceptions:日志出現異常時是否需要拋出異常,若配置為true日志記錄異常時由于沒有捕獲異常,會導致程序掛掉。
internalLogLevel:表示nlog日志的執行日志記錄等級。
internalLogFile:表示nlog日志的執行日志記錄的位置。通過./XXXX的方式可以配置到程序的相對目錄。
日志等級
Nlog支持以下幾種日志等級
| Trace | T | 0 |
| Debug | D | 1 |
| Info | I | 2 |
| Warn | W | 3 |
| Error | E | 4 |
| Fatal | F | 5 |
| Off | O | 6 |
在日志輸入時可以通過${level}輸入日志等級,或者通過${level:format=FirstCharacter}輸出日志等級的簡寫。
若想查看所有參數輸出可以到這里查看。
輸出例子
Logger?logger?=?NLog.LogManager.GetLogger("test");logger.Trace("測試test");logger.Info("測試test");logger.Warn("測試test");logger.Error("測試test");logger.Fatal("測試test");通過NLog.LogManager.GetLogger我們可以獲取一個日志對象示例。傳入的參數為日志實例名,我們可以在日志名中通過${logger}參數輸出日志實例名。可以將不同的日志保存到不同的文件。
在代碼中我們不支持Off等級的輸出。通過NLog不需要我們認為對日志模塊進行啟動或關閉,在我們程序關閉后,它會自動關閉日志。相關的Nlog的日志可以在internalLogFile配置的路徑中中查看到,同時在生產環境建議將internalLogLevelNLog自己的日志等級設置為Info,這樣只會記錄關鍵的日志信息。
我們輸入到文件中,輸入配置如下:
<target?xsi:type="File"?name="f"?fileName="${basedir}/logs/${shortdate}.log"????????????layout="${longdate}?${uppercase:${level}}?${message}"?/><logger?name="*"?minlevel="Debug"?writeTo="f"?/>目標
NLog通過target配置日志輸入的目標。可以通過配置多個target將日志輸入到多個目錄,多個目標(文件,網絡,數據庫等)。
<targets?async="true">??<target?xsi:type="File"?name="f"?fileName="${basedir}/logs/${shortdate}.log"????????????layout="${longdate}?${uppercase:${level}}?${message}"?/></targets>通過將async設置為true可以異步保存日志,從而防止日志影響業務性能。
xsi:type:輸入類型,支持以下類型。
ColoredConsole : 使用可自定義的顏色將日志消息寫入控制臺。
Console - 將日志消息寫入控制臺。
Debug - 模擬目標-用于測試。
File - 將日志消息寫入一個或多個文件。
Mail - 使用 smtp 協議或拾取文件夾通過電子郵件發送日志郵件。
Null - 丟棄日志消息。主要用于調試和基準測試。
name:目標的名字,可以通過創建Rule規則限制目標的輸出。
fileName:文件名,日志保存文件時可以保存到該文件中。文件名支持參數化,通過各種參數更方便的輸出日志。
layout:表示輸出的格式,若為最簡單的內容輸入,則直接通過參數設置輸入格式即可。除了最簡單的文本格式還支持以下四種類型的數據,通過xsi:type參數設置layout的格式,如xsi:type="JsonLayout"。
CSV - A specialized layout that renders CSV-formatted events.
Compound - A layout containing one or more nested layouts.
JSON - A specialized layout that renders to JSON.
Log4JXml - A specialized layout that renders Log4j-compatible XML events.
下面列舉兩項常用的輸入方式,文件輸出和網絡輸出。
文件輸出
通過文件輸入將日志保存到一個或多個文件。可以通過配置動態進行日志的保存。
下面通過json 的格式保存日志信息。
<?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="Info"?internalLogFile="./logs/nlog-internal.log">????<targets>????????<target?xsi:type="File"?name="InfoFile"?????????fileName="${logDir}/InfoLogs/log.txt"?????????archiveFileName="${logDir}/InfoLogs/log.{#}.txt"?????????createDirs="true"?keepFileOpen="true"?autoFlush="false"?????????openFileFlushTimeout="10"?openFileCacheTimeout="30"?archiveAboveSize="10240"?????????archiveNumbering="Sequence"?concurrentWrites="true"?encoding="UTF-8">????????????<layout?xsi:type="JsonLayout">????????????????<attribute?name="counter"?layout="${counter}"?/>????????????????<attribute?name="time"?layout="${longdate}"?/>????????????????<attribute?name="level"?layout="${level:upperCase=true}"/>????????????????<attribute?name="message"?layout="${message:format=message}"?encode="false"?/>????????????</layout>????????</target>????</targets>????<rules>????????<logger?name="*"?minlevel="Info"?writeTo="InfoFile"?/>????</rules></nlog>xsi:type:將文件類型設置為File,將日志保存到文件中。
fileName:將日志文件保存到"${logDir}/InfoLogs/log.txt"。
可以通過參數在文件名中加入參數設置。
archiveFileName:為了防止日志文件保存的太大,我們將日志文件拆分保存。通過archiveFileName參數設置保存格式,具體格式可以到這里查看。
createDirs:若設置的日志文件夾不存在,則自動創建文件夾。
keepFileOpen:為了提高文件寫入性能,避免每次寫入文件都開關文件,將keepFileOpen設置為true,我們通過openFileCacheTimeout參數定時關閉文件。
autoFlush:為了提高日志寫入性能,不必每次寫入日志都直接寫入到硬盤上,將autoFlush設置為false,我們通過openFileFlushTimeout參數定時寫入文件。
openFileCacheTimeout:將keepFileOpen參數設置為false,則設置定時關閉日志。防止日志一直開著占用著。
openFileFlushTimeout:將autoFlush參數設置為false,則設置定時將日志從緩存寫入到硬盤時間。
archiveAboveSize:為了防止一個文件日志太大,我們需要根據指定大小將日志拆文件保存。archiveAboveSize參數的單位是字節。通過設置為10240=10KB,每個日志大小達到10KB就會自動拆分文件,拆分后的文件名規則通過archiveFileName設置,拆分文件名的規則通過archiveNumbering設置,具體規則可以查看這里。
concurrentWrites:支持多個并發一起寫文件,提高文件寫入性能。
encoding: Nlog默認保存的編碼格式為Encoding.Default,中文保存到日志中會出現亂碼,將其設置為utf-8,就可以正常保存了。
我們可以在targets節點下增加多個target,用于輸出多中目標。
當我們開啟異步記錄日志時,同時設置了保持文件打開,且設置了緩存時間,若在時間內超過了日志大小,并不會立即分文件,而是在文件關閉后才會進行分文件。
Json格式保存
<layout?xsi:type="JsonLayout">????<attribute?name="counter"?layout="${counter}"?/>????<attribute?name="time"?layout="${longdate}"?/>????<attribute?name="level"?layout="${level:upperCase=true}"/>????<attribute?name="message"?layout="${message:format=message}"?encode="false"?/>在target中將layout的?xsi:type設置為JsonLayout保存為Json格式。
Json格式保存我們需要在layout節點下增加attribute來增加字段。上面增加了四個字段。
counter:行數,行數表示日志當前記錄的行數。
time:時間,可以通過參數保存自己想要的時間格式。
level:日志等級,當前記錄的日志等級。
message:信息,記錄的信息,若需要記錄中文,則需要設置`encode="false",否則json格式會自動將json的中文內容保存為unicode編碼。
具體的其他Json參數可以看這里
多目標
<targets>????<target?xsi:type="File"?name="InfoFile"?fileName="${logDir}/InfoLogs/log.txt"?archiveFileName="${logDir}/InfoLogs/log.{#}.txt"?createDirs="true"?keepFileOpen="true"?autoFlush="false"?????openFileFlushTimeout="10"?openFileCacheTimeout="30"?????archiveAboveSize="10240"?archiveNumbering="Sequence"?concurrentWrites="true"?encoding="UTF-8">????????<layout?xsi:type="JsonLayout">????????????<attribute?name="counter"?layout="${counter}"?/>????????????<attribute?name="time"?layout="${longdate}"?/>????????????<attribute?name="level"?layout="${level:upperCase=true}"/>????????????<attribute?name="message"?layout="${message:format=message}"?encode="false"?/>????????</layout>????</target>????<target?xsi:type="File"?name="ErrorFile"?fileName="${logDir}/ErrorLogs/log.txt"?????archiveFileName="${logDir}/ErrorLogs/log.{#}.txt"?createDirs="true"?keepFileOpen="true"?autoFlush="false"?????openFileFlushTimeout="10"?openFileCacheTimeout="30"?????archiveAboveSize="10240"?archiveNumbering="Sequence"?????concurrentWrites="true"?encoding="UTF-8">????????<layout?xsi:type="JsonLayout">????????????<attribute?name="time"?layout="${longdate}"?/>????????????<attribute?name="level"?layout="${level:upperCase=true}"/>????????????<attribute?name="message"?layout="${message}"?encode="false"?/>????????????<attribute?name="exception">????????????????<layout?xsi:type="JsonLayout">????????????????????<attribute?name="callsite"?layout="${callsite}"?/>????????????????????<attribute?name="callsite-linenumber"?layout="${callsite-linenumber}?"?/>????????????????</layout>????????????</attribute>????????</layout>????</target></targets><rules>????<logger?name="*"?minlevel="Info"?writeTo="InfoFile"?/>????<logger?name="*"?minlevel="Error"?writeTo="ErrorFile"?/></rules>我們可以在<targets>節點下增加多個target增加多個輸出目標,我們通過設置2個目標,將info和error日志分開保存。其中很多參數是共用的,我們可以設置一個默認參數default-target-parameters,減少配置文件節點。
<default-target-parameters?xsi:type="File"?????????????????createDirs="true"?????????????????keepFileOpen="true"?autoFlush="false"?openFileFlushTimeout="10"?openFileCacheTimeout="30"????????????????archiveAboveSize="10240"?archiveNumbering="Sequence"?concurrentWrites="true"?encoding="UTF-8"/>通過以上設置,這些設計的節點就被設置為默認值,簡化后的配置文件如下。
<target>????<default-target-parameters?xsi:type="File"?createDirs="true"?keepFileOpen="true"?autoFlush="false"?openFileFlushTimeout="10"?openFileCacheTimeout="30"?archiveAboveSize="10240"?archiveNumbering="Sequence"?concurrentWrites="true"?encoding="UTF-8"/>????<target?xsi:type="File"?name="InfoFile"?fileName="${logDir}/InfoLogs/log.txt"?archiveFileName="${logDir}/InfoLogs/log.{#}.txt">????????<layout?xsi:type="JsonLayout">????????????<attribute?name="counter"?layout="${counter}"?/>????????????<attribute?name="time"?layout="${longdate}"?/>????????????<attribute?name="level"?layout="${level:upperCase=true}"/>????????????<attribute?name="message"?layout="${message:format=message}"?encode="false"?/>????????</layout>????</target>????<target?xsi:type="File"?name="ErrorFile"?fileName="${logDir}/ErrorLogs/log.txt"?archiveFileName="${logDir}/ErrorLogs/log.{#}.txt">????????<layout?xsi:type="JsonLayout">????????????<attribute?name="time"?layout="${longdate}"?/>????????????<attribute?name="level"?layout="${level:upperCase=true}"/>????????????<attribute?name="message"?layout="${message}"?encode="false"?/>????????????<attribute?name="exception">????????????????<layout?xsi:type="JsonLayout">????????????????????<attribute?name="callsite"?layout="${callsite}"?/>????????????????????<attribute?name="callsite-linenumber"?layout="${callsite-linenumber}?"?/>????????????????</layout>????????????</attribute>????????</layout>????</target></targets><rules>????<logger?name="*"?minlevel="Info"?writeTo="InfoFile"?/>????<logger?name="*"?minlevel="Error"?writeTo="ErrorFile"?/></rules>參數
在Nlog節點下加入variable節點可以創建自定義參數。
??<variable?name="logDir"?value="${basedir}/logs/${logger:shortName=true}?/${shortdate}"/>name:表示參數名。
value:表示參數值。
參數設置完后就可以通過${name}的方式獲取參數值。
Nlog已定義的一些參數可以到查看
規則
通過target我們可以自定義輸出方式。同時我們可以創建一系列規則約束輸出的內容。
??<rules>????<logger?name="*"?minlevel="Debug"?writeTo="f"?/>??</rules>在Nlog節點下添加rules節點,rules節點下可以配置多個logger節點,每個logger節點即為一條約束。
name:logger名稱,若為*則表示適用于所有日志,若我們某個target專門用于logdemo.test類的日志輸出,則那么可以設置為logdemo.test.*,表示當前約束只允許命名空間為logdemo.test開頭的日志輸出。
minlevel:表示當前約束的最小等級,只有等于或大于該值的日志等級才會被記錄。
writeTo:表示當前規則約束哪個target。
更多其他規則參數可以看這里
日志分發
通過以上設置,我們可以通過各種targets將日志存放到不同地方,通過rules指定保存不同等級的日志。日志本地文件存放主要是用于進行系統排查錯誤用的,有時候我們可能希望將日志合并存放或查看。NLog本身就支持通過Tcp或Udp將日志分發到其他地方。
我們在保存文件的同時只需要添加一條target,同時將其類型設置為Network,在通過設置rules對其進行必要約束就可以將日志分發到其他地方。由于我們前面設置了async參數異步保存日志,因此網絡好壞并不會影響我們業務處理時效。
<?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="Info"?internalLogFile="./logs/nlog-internal.log">????...????<targets?async="true">????...????</targets>????<targets?async="true">????????<target?xsi:type="Network"?address="udp://127.0.0.1:878"?name="network"?newLine="false"?maxMessageSize="65000"?encoding="gbk"?layout="${log4jxmlevent:includeCallSite=true:includeNLogData=true}"/>????</targets>????<rules>????????<logger?name="*"?minlevel="Info"?writeTo="network"?/>????????...????</rules></nlog>為了和文件區分,我們我們新增了一個targets專門用于Network。
xsi:type:通過設置類型為Network表示通過網絡傳輸日志。
address:設置地址格式為協議://ip:端口。
maxMessageSize:表示最大傳輸消息大小,默認為65000。
newLine:表示日志消息末尾追加換行符。
encoding:表示日志傳輸的編碼,默認為UTF-8,中文需要設置為GBK編碼,否則在對端可能會出現亂碼的情況。
具體完整參數可以看這里
通過以上設置,就可以將日志發送到指定地址了,通過Log4JXml格式發送到對端。
日志收集
我們通過Log4View收集日志進行查看。目前官網最新的是Log4View2版本,有30天的免費使用時間,30天自動變為社區版本,依然可以免費使用,但是想使用一些高級功能則需要付費使用。
Log4View支持Nlog和Log4Net,同時支持查找,過濾等功能。
從官網下載后需要進行安裝,目前Log4View不支持中文。
Log4View2支持多種目標的文件輸入,可以通過文件,數據庫或網絡等途徑輸入日志。
打開后界面如圖所示
在File-Receiver添加一個接收者
通過以上設置即可在Log4View接收數據了。我們發送幾條消息
Logger?logger?=?NLog.LogManager.GetLogger("test");logger.Trace("測試test");logger.Info("測試test");logger.Warn("測試test");logger.Error("測試test");logger.Fatal("測試test");try{????throw?new?Exception("錯誤test");}catch?(Exception?exception){????logger.Error(exception);}由于我們設置的日志等級為Info,因此Trace等級的日志不會傳輸過來。
在界面左下角可以添加過濾器,支持多種篩選模式。
結語
本文對Nlog的簡單使用進行了探究,通過配置的方式將文件異步保存到本地和通過udp的方式發送到Log4View2進行更方便的查看,同時Nlog也支持通過代碼的方式進行控制,但是使用配置修改相比代碼更為靈活,因此本文對代碼修改配置的方式不做探討。
總結
以上是生活随笔為你收集整理的NLog日志框架使用探究的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 场景编辑器开发第五天,设计架构重回fla
- 下一篇: iOS新版微信底部返回横条问题