0020. Nlog + Sqlite3微型DB模組化Log記錄方式

情境說明: 1. Nlog是一套紀錄Log的開源(Open Source)工具,通常可以記錄各種應用程式的Log紀錄。

                   2. Log通常用於追蹤程式工作或者使用者操作的紀錄,便於我們開發者解決問題、改進程式效能的紀錄資料。

                   3. Log最傳統都是用.txt 文字格式存在於站台或程式目錄底下,但資料都未經整理,本篇使用Sqlite3將log的紀錄進行整理便於追蹤。

目的:本篇介紹基於Web網站的NLog + Sqlite3 的方式記錄Log

 

本篇分為三部分:

一、建立網站 - Nlog 設定 + Sqlite的Sql撰寫

二、網站的C# 程式

三、參考文獻與資料備註


一、建立網站 - Nlog 設定 + Sqlite的Sql撰寫


 

Step 1.  開啟Visual Studio (本篇使用2015)  -> Asp.net應用程式 -> 輸入名稱 -> 確定

Step 2. 對專案的參考 -> 滑鼠右鍵 -> 選擇管理NuGet套件

Step 3. 安裝Sqlite ,如下畫面,請選擇System.Data.SqLite

Step 4. 安裝時會將其他的項目一併安裝 -> 請選擇確定

Step 5. 再接著安裝NLog ,如下畫面

Step 6. 再接著安裝 NLog.Config ,安裝了這個就不用自己全部重刻一次設定檔。

Step 7. 安裝完成後,我們的專案就多了NLog.config的設定檔,請打開他

Step 8. NLog.config這篇我們只會應用到 <targets></targets> 與 <rules><rules> 兩個區塊

targets 區塊 Log紀錄的方式、寫入的位置
rules  區塊

何種Log等級才要記錄

順序: Debug < Info <Warm <Error = Fatal

Step 9. 請在rules 區塊內貼上以下代碼 ,如下圖顯示,當發生至少要大於warn等級的資料才進行寫入

<logger name="*" minlevel="warn" writeTo="Database_SQLite" />

Step 10 - 1. 請在targets 將Sqlite3 的代碼插入,如下圖

※本篇是使用基本的Log 追蹤與資訊紀錄,如果要擴充可以參考第三部分的文獻,將自己想要紀錄的資訊帶入

    <target xsi:type="Database" name="Database_SQLite" keepConnection="false" useTransactions="false">
      <dbProvider>
        System.Data.SQLite.SQLiteConnection, System.Data.SQLite, Version=1.0.105.2, Culture=neutral, PublicKeyToken=db937bc2d44ff139
      </dbProvider>
      <connectionString>
        data source=|DataDirectory|NLog_Record.s3db;
      </connectionString>
      <commandText>

        CREATE TABLE IF NOT EXISTS NLog_Record_${date:format=yyyyMMdd} (sequence_id INTEGER  PRIMARY KEY AUTOINCREMENT
        UNIQUE
        NOT NULL,
        time_stamp  DATETIME NOT NULL,
        level       TEXT     NOT NULL,
        host        TEXT     NOT NULL,
        url         TEXT     NOT NULL,
        type        TEXT     NOT NULL,
        source      TEXT     NOT NULL,
        logger      TEXT     NOT NULL,
        message     TEXT     NOT NULL,
        stacktrace  TEXT     NOT NULL,
        detail      TEXT     NOT NULL);

        insert into NLog_Record_${date:format=yyyyMMdd} (time_stamp, level, host, url, type, source, logger, message, stacktrace, Detail)
        Values(@time_stamp, @level, @host, @url, @type, @source, @logger, @message, @stacktrace, @detail);
      </commandText>
      <parameter name="@time_stamp" layout="${date:format=yyyy-MM-dd HH\:mm\:ss.fff}" />
      <parameter name="@level" layout="${level}" />
      <parameter name="@host" layout="${machinename}" />
      <parameter name="@url" layout="${callsite}" />
      <parameter name="@type" layout="${exception:format=type}" />
      <parameter name="@source" layout="${callsite:className=true}" />
      <parameter name="@logger" layout="${logger}" />
      <parameter name="@message" layout="${message}" />
      <parameter name="@stacktrace" layout="${exception:stacktrace}" />
      <parameter name="@detail" layout="${exception:format=tostring}" />

Step 10 - 2. 以下分成4大區塊,解釋說明各執行的工作

dbProvider

區塊

 使用的Sqlite的package版本   ※可參考Step10 - 3.

connectionString

區塊

紀錄資料的位置

|DataDirectory|  =>表示網站的App_Data目錄

NLog_Record.s3db => 表示紀錄於哪個檔案中

CommanText

區塊

 分成Create 與 Insert 

Create 部分 : 判斷是否已經有產生以當天(年月日 yyyyMMdd )格式的資料表,如果沒有則建立新的資料表

Insert 部分 : 如果已經有產生當天的資料表,則將目前的紀錄寫入

Parameter

區塊

 與CommanText 欄位呼應,將資料依照Nlog 提供的參數寫入,可參考第三部分

Step 10 -3 . 點開專案的 pcakage.config ,可以找到對應的Sqlite 版本資訊

 


二、網站的C# 程式


Step 1:  為了讓網站啟動的時候會自動建立Sqlite資料庫,請先回到專案 -> Global.asax ->Global.asax.cs

Step 2: 撰寫啟動時的執行Sqlite3的函式,如下圖:

private void SqliteDBInitinal()
{
            //建立DB
            try
            {
                //Sqlite3DB的建立路徑 - Nlog的路徑
                var nlogSqlitePath = HttpContext.Current.Server.MapPath("~/App_Data/NLog_Record.s3db");
                //
                SQLiteConnection.CreateFile(nlogSqlitePath);
            }
            catch (Exception ex)//當發生錯誤時
            {
                //使用Nlog內建的Error Exception紀錄
                LogManager.GetLogger("MyNlog").ErrorException("建立.s3db時發生例外", ex);
            }
}

Step 3:  啟動我們的網站 ,可以看到專案的 App_data底下自動建立 NLog_Record.s3db 檔案

             但也可以發現,因為目前沒有記錄任何資料所以大小為0

Step 4: HomeController.cs -> 寫入以下程式碼 ,當開啟網站時,會發生 1. Info事件 (※記錄好人一生平安的資訊)  2.接著會跳到Exception 

public ActionResult Index()
{
            try
            {
                LogManager.GetLogger("Action Index").Info("好人一生平安");
                //以下故意將型別設成Null 再塞值,造成Exception
                List<object> testObject = new List<object>();
                testObject = null;
                testObject.Add(null);
            }
            catch (Exception ex)
            {
                LogManager.GetLogger("Action Index").ErrorException("Title:測試發生錯誤", ex);
            }
            return View();
}

Step 5: 請先安裝 Sqlite 瀏覽工具 ,這邊推薦 SqliteStudio ,有多國語言

https://sqlitestudio.pl/index.rvt

 

Step 6: 使用工具開啟NLog_Record.s3db,以下是畫面,請選擇OK即可

Step 7: 可以看到我們資料表名稱 & 欄位資訊

Step 8:  選擇數據 -> 可以發現只有一筆 Error紀錄  ,這是因為Info 的級別 小於 warn,所以不會顯示。

Step 9: 將Nlog.config 的 minLevel 改為 Debug ,如下圖 -> 然後在運行一次網站

Step 10: 此時就可以看到 Info 的資訊也記錄在 Sqlite3 的Log 紀錄中 。 我們完成Log紀錄模組化的功能了~ 


三、參考文獻與資料備註


Nlog 的參數設定 : https://github.com/nlog/nlog/wiki/Layout-Renderers

檔案提供下載 : https://github.com/gotoa1234/WebSiteNLogWithSqlite3

今天剛好參加2017年的DevOps ,以下圖片是擷取講師的ptt 圖片(※這位講師講得很讚,ptt是開放式下載的,如果有需要可以到 https://devopsdays.tw/agenda.html 下載)

讓Log 紀錄整理清晰就如投影片的重點提示,如果是長遠運行的系統而非拋棄式的系統,能有完整的紀錄可以增加穩定性,在持續完整架構後,最好的回饋是在系統發生問題前可以反饋我們資訊。