NLog 除了支援 file 寫入之外,也提供了許多 target 的寫入方式,這篇就來介紹客製化寫入 DB 與在某種條件下寫入
對NLog 有興趣的話可以參考前一篇的基本介紹
NLog 支援的寫入DB模版是這樣的, 可以參考官方的寫法
<target xsi:type="Database"
name="db"
connectionStringName="LogDBConnection"
commandText="Layout"
installConnectionString="Layout">
<commandText>
INSERT INTO LogTable(CreateTime,Logger,Message) VALUES(@time_stamp, @logger, @message);
</commandText>
<parameter name="@time_stamp" layout="${date}" />
<parameter name="@logger" layout="${logger}" />
<parameter name="@message" layout="${message}" />
</target>
<target name="file" xsi:type="File"
fileName="${basedir}/App_Data/Logs/${shortdate}/log.txt"
layout="${longdate} | ${level:uppercase=true} | ${logger:shortName=true} | ${message} ${newline}" encoding="utf-8"/>
在這邊我們定義了兩個 target,一個是 file, 一個是 db
如果是要採取 file 寫入的方式,將會在自己的本地端新建目錄
如果是要在 db 端寫入的,LogDBConnection記得在 web.config 補上你的 LogDBConnection
而上述的這些參數都是NLog 內建的參數,下面會介紹如果要傳入自定義的參數該怎麼處理
在 rule 端,我們可以指定在 namespace 是什麼的情況下,以及最低的層級下,可以寫到多重目標 (寫到 file, db)
更可以設定如果記的內文裡,如果有 test 的字樣的話,action 即設成 ignore,就是不記的意思
官方更是定義了這幾種 action,可以參考這裡
Ignore
- The message should not be logged.IgnoreFinal
- The message should not be logged and processing should be finished.Log
- The message should be logged.LogFinal
- The message should be logged and processing should be finished.Neutral
- The filter doesn't want to decide whether to log or discard the message.
<rules>
<!-- add your logging rules here -->
<logger name="TestNameSpace.*" minlevel="Info" writeTo="db, file" >
<filters>
<when condition="contains('${message}', 'test')" action="Ignore" />
</filters>
</logger>
</rules>
在這裡,如果你的 nlog 是在TestNameSpace.* 建立起來的,假若 nlog instance 是在 B.Namespace 建立的,那就不會被記進來。亦或是要記的是全部的話,那就標示為 *
首先先需建立一個 nlog extension
public static class NLogExtension
{
public static void LogExt(this NLog.Logger logger, NLog.LogLevel level, String message, String userName)
{
NLog.LogEventInfo theEvent = new NLog.LogEventInfo(level, logger.Name, message);
theEvent.Properties["UserName"] = userName;
logger.Log(theEvent);
}
}
原本 Nlog 的寫法為
_logger.Info("測試訊息");
在使用 Nlog時需改為
_logger.LogExt(LogLevel.Info, "測試訊息", "aceTest");
在 Nlog.config 也需修改為
<target xsi:type="Database"
name="dbExt"
connectionStringName="LogDBConnection"
commandText="Layout"
installConnectionString="Layout">
<commandText>
INSERT INTO LogTable(CreateTime,Logger,Message, UserName) VALUES(@time_stamp, @logger, @message, @UserName);
</commandText>
<parameter name="@time_stamp" layout="${date}" />
<parameter name="@logger" layout="${logger}" />
<parameter name="@message" layout="${message}" />
<parameter name="@userName" layout="${event-properties:item=UserName}" />
</target>
rule端也可以修改為這樣, 同時寫到 db, dbExt, file 這三個地方
<rules>
<!-- add your logging rules here -->
<logger name="TestNameSpace.*" minlevel="Info" writeTo="db, dbExt, file" >
<filters>
<when condition="contains('${message}', 'test')" action="Ignore" />
</filters>
</logger>
</rules>
可以讓你任意抽換 target,甚至之後要再加新的欄位
比方說是新增了 MethodName 這個欄位, 想要追蹤是由哪一個 method 發出的話,可以讓 MethodName 允許 null,這樣可以達到尚未上線的程式不會讓現行的 log 機制死掉
而同時上線後也會自動記上相對應的資料,可說是相當方便
參考文件
https://dotblogs.com.tw/acelee/2018/03/27/120704
https://github.com/NLog/NLog/wiki/Database-target