2012年6月21日 星期四

NLog - 將 Log 記錄儲存在 SQLite 中

為什麼要把 NLog 的 Log 記錄給儲存在 SQLite 中呢?

因為有時候我們所建置的網站資料庫環境並非那麼容易就可以讓我們建立一個 Database 或是 Table,有的公司或是有的環境,對於資料庫的管理會相當嚴謹,凡是要建立一個新的 Database 或是 Table 都需要層層關卡,甚至於會因為提出的申請需求不明確或是他們覺得沒必要而駁回。

雖然說把 Log 記錄儲存成一個個的文字檔案也是可以,但是事後的 Log 記錄的追查就不是那麼方便,甚至於如果想要自己建立一個瀏覽 NLog 記錄的功能網站或是導入使用 Log Reporting Dashboard,不把 Log 記錄給放到資料庫中是不太可行的,而把 Log 記錄給儲存到 SQLite 的話,在這樣資料庫嚴謹管控的情況下,使用 SQLite 就會是一個蠻適合的解決方案。

這一篇就說明如何將 NLog 的 Log 記錄儲存到 SQLite 中。


在開始說明之前,這邊也稍微提一下把 Elamh 的 Log 記錄儲存在 SQLite 的方法,twMVC 成員之一 Bibby 的部落格「Simple Thoughts on Everything」中有介紹到將 Elmah Log 記錄儲存到 SQLite 的方法,文章連結「Simple Thoughts on Everything - Set Up Elmah Under SQLite

BTW… 歡迎各位可以前往 Bibby 的部落格中留言督促他的發文進度,他已經快要半年沒發文章囉 ~

 

回到主題……

其實 NLog 把 Log 記錄儲存到 SQLite 的方式也跟上述的文章內容差不多,不過最大的差別在於,如果我們指定把 Elmah 儲存到 SQLite,而尚未建立好 sqlite db 檔案時,Elmah 第一次執行時會幫我們建立 sqlite db 檔案,而這個 db 檔案也會建立好要儲存的 Table,然而 NLog 就不會幫我們這樣做了,所以 NLog 的 Log 記錄要儲存在 sqlite db 前就必須要先建立好 db 檔案以及 Table。

 

SQLite

如果你的環境下並未安裝過 SQLite,那麼大家可以參考以下的文章內容:

Kurt Schindler - Getting started with SQLite and .NET

如果要下載 System.Data.SQLite 的相關檔案或是安裝檔案,可以到以下連結頁面中下載符合 .NET 的檔案:

http://system.data.sqlite.org/index.html/doc/trunk/www/downloads.wiki

當然也可以透過 NuGet 安裝 System.Data.SQLite 的組件檔,

image

可以透過 Visual Studio 的伺服器總管來建立 sqlite db 檔案,不過我還是習慣使用 SQLite GUI 工具來建立 db 檔案,建立完檔案之後就順便建立 Table,

有關 SQLite 的 GUI Tools 我會建議使用以下幾個:


以下我就使用 SQLite Administrator 來建立 db 檔案與 Table(只有圖沒有文字說明)

SNAGHTMLef5c37

SNAGHTMLf0984d

image

SNAGHTMLf25fa1

or

CREATE TABLE [NLog_Record] (
[sequence_id] INTEGER  NOT NULL PRIMARY KEY AUTOINCREMENT,
[time_stamp] datetime  NOT NULL,
[level] nvarchar  NOT NULL,
[host] nvarchar  NOT NULL,
[url] nvarchar  NOT NULL,
[type] nvarchar  NOT NULL,
[source] nvarchar  NOT NULL,
[logger] nvarchar  NOT NULL,
[message] nvarchar  NOT NULL,
[stacktrace] nvarchar  NOT NULL,
[detail] nvarchar  NOT NULL,
[allxml] nvarchar  NOT NULL
);

SNAGHTMLf6cb3f

SNAGHTMLf7d656

SNAGHTMLf87736

 

SQLite db 檔案與 Table 都建立完成之後,接下來就是要修改 NLog.Config,增加 target 以及 rule 的設定內容。

 


NLog Target

image

(1) dbprovider

我們使用 SQLite 為 target,target type 一樣還是 Database,而 dbprovider 的部份就要改使用 SQLite,如果不清楚你所使用的 SQLite 版本為何,可以查看 Web.Config 下的內容,或是查看專案參考目錄中 System.Data.SQLite 的屬性內容。

(2) connectionstring

再來就是修改資料庫連接字串,其實網路上有很多的範例介紹都是直接使用檔案位置的絕對路徑,例如:

data source=D:\Develope\twMVC\MvcApplication1\MvcApplication1\App_Data\NLog_Record.s3db;

但是使用絕對路徑的一個大問題就是當網站佈署到其他的環境時,就必須要去修改這個資料庫的連接字串內容,而 Elmah 使用 SQLite 的資料庫連接字串會是類似這樣的方式,

<add name="elmah" connectionString="data source=~/App_Data/Elmah.Errors/elmah.db" />

但是這樣的資料課連接字串的設定只有在 Web.Config 內才有作用,這樣的寫法在 NLog.Config 中是不行的,在 NLog.Config 可以使用 sql server 資料庫檔案的連接設定方式,我們是把 NLog_Record.s3db 檔案放在 ~/App_Data 目錄下,所以可以用「|DataDirectory|」

使用|DataDirectory| 連接字串變數來取代應用程式 App_Data 目錄的檔案路徑

所以我們就可以把資料庫連接字串修改為下面的內容:

<connectionString>
    data source=|DataDirectory|NLog_Record.s3db;
</connectionString>

所以修改後完整 target 設定內容為:

<target name="Database_SQLite" type="Database" keepConnection="false" useTransactions="false">
    <dbprovider>
        System.Data.SQLite.SQLiteConnection, System.Data.SQLite, Version=1.0.81.0, Culture=neutral, PublicKeyToken=db937bc2d44ff139
    </dbprovider>
    <connectionString>
        data source=|DataDirectory|NLog_Record.s3db;
    </connectionString>
    <commandText>
        insert into NLog_Record (time_stamp, level, host, url, type, source, logger, message, stacktrace, Detail, allxml)
        Values(@time_stamp, @level, @host, @url, @type, @source, @logger, @message, @stacktrace, @detail, @allxml);
    </commandText>
    <parameter name="@time_stamp" layout="${utc_date}" />
    <parameter name="@level" layout="${level}" />
    <parameter name="@host" layout="${machinename}" />
    <parameter name="@url" layout="${aspnet-request:serverVariable=url}" />
    <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}" />
    <parameter name="@allxml" layout="${web_variables}" />
</target>

 

NLog rule

設定好 target 之後就是接著設定 NLog rule 內容,這個就比較簡單,看我們要儲存哪些 Log Level 的 Log 記錄,這邊我就只儲存 Log Level: Warn 以上的 Log 記錄,

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

 


我們在程式中故意產生幾個 Exception 錯誤,

image

 

然後開啟 NLog_Record.s3db 來看看 Table 所記錄的內容(我還是喜歡用 Navicate)

SNAGHTML146091a

這樣我們就完成了將 NLog 的 Log 記錄儲存到 SQLite 的需求!

 


最後就不多廢話了,SQLite 可以應用的地方相當地多,有的時候網站使用資料庫會受到很多的限制,像這樣的情況下,Log 訊息記錄就適合儲存在 SQLite 之中,就不用再把 Log 訊息存放到文字檔裡,日後如果要追查 Log 記錄時就會相當方便了。

 

以上

1 則留言:

提醒

千萬不要使用 Google Talk (Hangouts) 或 Facebook 及時通訊與我聯繫、提問,因為會掉訊息甚至我是過了好幾天之後才發現到你曾經傳給我訊息過,請多多使用「詢問與建議」(在左邊,就在左邊),另外比較深入的問題討論,或是有牽涉到你實作程式碼的內容,不適合在留言板裡留言討論,請務必使用「詢問與建議」功能(可以夾帶檔案),謝謝。

最近的留言