C#使用log4net結(jié)合sqlite數(shù)據(jù)庫(kù)實(shí)現(xiàn)記錄日志
0 前言
為什么要把日志存到數(shù)據(jù)庫(kù)里?
因?yàn)榻Y(jié)構(gòu)化的數(shù)據(jù)庫(kù)存儲(chǔ)的日志信息,可以寫(xiě)專門(mén)的軟件讀取歷史日志信息,通過(guò)各種條件篩選,可操作性極大增強(qiáng),有這方面需求的開(kāi)發(fā)人員可以考慮。
為什么選擇SQLite?
輕量級(jí)數(shù)據(jù)庫(kù),免安裝,數(shù)據(jù)庫(kù)的常用的基本功能都有,可以隨程序遷移到不同的電腦上使用。
1 安裝包
兩個(gè)包:
- log4net
- System.Data.SQLite
第二個(gè)包也可以使用Microsoft.Data.Sqlite
,查到的資料顯示如果環(huán)境使用的是 .NET Core 或 .NET 5+,建議使用Microsoft.Data.Sqlite
。但是我并沒(méi)有測(cè)試第二個(gè)包,可能使用上有區(qū)別。
2 下載Sqlite
如果本地沒(méi)有sqlite環(huán)境的話,需要先下載。官網(wǎng)下載鏈接
進(jìn)去之后直接找各自環(huán)境對(duì)應(yīng)的版本,如果是windows環(huán)境的話,直接下載下圖中標(biāo)記的tool,中間那個(gè)下載鏈接是下載sqlite3.dll
,不過(guò)我并不清楚如何使用,有知道的大佬可以在評(píng)論區(qū)交流一下。
tool解壓之后有如下幾個(gè)文件,雙擊打開(kāi)sqlite3.exe即可。
3 Sqlite常用命令
打開(kāi)是一個(gè)命令行界面,可以使用.help查看常用的命令及解釋。
.help
創(chuàng)建數(shù)據(jù)庫(kù)文件使用.open xxx
,這條語(yǔ)句,如果發(fā)現(xiàn)數(shù)據(jù)庫(kù)文件存在,就會(huì)直接打開(kāi),如果不存在,就會(huì)先創(chuàng)建再打開(kāi)。
.open test.db
在目錄內(nèi)可以看到創(chuàng)建的數(shù)據(jù)庫(kù)文件。(劃重點(diǎn),這個(gè)文件拷到程序中就可以直接使用sqlite數(shù)據(jù)庫(kù),充分體現(xiàn)了輕量級(jí)的魅力)
.databases
可以查詢所有數(shù)據(jù)庫(kù)文件
.tables
可以查詢所有表(我還未創(chuàng)建,所以目前還沒(méi)有表)
sql語(yǔ)句請(qǐng)自行查詢相關(guān)資料。
查詢的數(shù)據(jù)以標(biāo)準(zhǔn)格式顯示。
.header on .mode column SELECT * FROM COMPANY;
當(dāng)然sqlite也有可視化的軟件,但是我目前沒(méi)用到,所以沒(méi)有下載安裝,需要的話可以自行查詢。
4 創(chuàng)建日志相關(guān)基本表
使用命令創(chuàng)建日志表,包含id(使用自增,當(dāng)然可以換成uuid或者其它形式)、日期、線程號(hào)、級(jí)別(info、error這些)、記錄者、具體記錄的信息、異常信息。具體內(nèi)容要對(duì)應(yīng)log4net的配置。
CREATE TABLE Log ( Id INTEGER PRIMARY KEY AUTOINCREMENT, Date DATETIME, Thread VARCHAR(255), Level VARCHAR(50), Logger VARCHAR(255), Message TEXT, Exception TEXT );
5 log4net配置
更換數(shù)據(jù)庫(kù)連接。sql語(yǔ)句的內(nèi)容一定要對(duì)應(yīng)數(shù)據(jù)庫(kù)基本表的字段。
<configuration> <configSections> <section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net" /> </configSections> <log4net> <appender name="AdoNetAppender" type="log4net.Appender.AdoNetAppender"> <bufferSize value="1" /> <connectionType value="System.Data.SQLite.SQLiteConnection, System.Data.SQLite" /> <connectionString value="Data Source=./database/logs.db;Version=3;" /> <commandText value="INSERT INTO Log (Date, Thread, Level, Logger, Message, Exception) VALUES (@log_date, @thread, @log_level, @logger, @message, @exception)" /> <parameter> <parameterName value="@log_date" /> <dbType value="DateTime" /> <layout type="log4net.Layout.RawTimeStampLayout" /> </parameter> <parameter> <parameterName value="@thread" /> <dbType value="String" /> <size value="255" /> <layout type="log4net.Layout.PatternLayout"> <conversionPattern value="%thread" /> </layout> </parameter> <parameter> <parameterName value="@log_level" /> <dbType value="String" /> <size value="50" /> <layout type="log4net.Layout.PatternLayout"> <conversionPattern value="%level" /> </layout> </parameter> <parameter> <parameterName value="@logger" /> <dbType value="String" /> <size value="255" /> <layout type="log4net.Layout.PatternLayout"> <conversionPattern value="%logger" /> </layout> </parameter> <parameter> <parameterName value="@message" /> <dbType value="String" /> <size value="4000" /> <layout type="log4net.Layout.PatternLayout"> <conversionPattern value="%message" /> </layout> </parameter> <parameter> <parameterName value="@exception" /> <dbType value="String" /> <size value="2000" /> <layout type="log4net.Layout.ExceptionLayout" /> </parameter> </appender> <root> <level value="ALL" /> <appender-ref ref="AdoNetAppender" /> </root> </log4net> </configuration>
6 日志記錄
把生成的db文件拷到程序里,這個(gè)文件就是記錄文件的數(shù)據(jù)庫(kù)了,其它的都不重要。當(dāng)然,如果想查看數(shù)據(jù)庫(kù)的話,也可以把sqlite3.exe拷過(guò)來(lái)。
讀取log4net的配置建議寫(xiě)在AssemblyInfo.cs,這樣程序啟動(dòng)時(shí)會(huì)默認(rèn)加載配置文件。
//Log4net配置[assembly: log4net.Config.XmlConfigurator(ConfigFile = "log4net.config", Watch = true)]
具體程序如下:
private static readonly ILog log = LogManager.GetLogger(typeof(Form1)); log.Info("這是一條info語(yǔ)句"); log.Warn("這是一條warn語(yǔ)句"); log.Error("這是一條錯(cuò)誤語(yǔ)句", new Exception("測(cè)試異常"));
查看日志是否正常寫(xiě)入數(shù)據(jù)庫(kù)。
7 使用C#程序查詢sqlite
程序如下(不過(guò)感覺(jué)GetString(index)這種方式有點(diǎn)別扭吧,有沒(méi)有GetString(key)的這種形式,歡迎大佬們補(bǔ)充)
// 構(gòu)建連接字符串 string connectionString = "Data Source=./database/SoftWareBaseLog.db;Version=3;"; // 創(chuàng)建 SQLite 連接 using (var connection = new SQLiteConnection(connectionString)) { connection.Open(); // 創(chuàng)建 SQL 命令 string sql = "SELECT Message FROM Log where Level='ERROR'"; using (var command = new SQLiteCommand(sql, connection)) { // 執(zhí)行命令并讀取數(shù)據(jù) using (var reader = command.ExecuteReader()) { while (reader.Read()) { string msg = reader.GetString(0); Console.WriteLine(msg); } } } }
8 實(shí)時(shí)顯示日志
現(xiàn)在所有日志都寫(xiě)到數(shù)據(jù)庫(kù)里了,那要是還想實(shí)時(shí)顯示到界面上,當(dāng)然也有很多方式實(shí)現(xiàn),不過(guò)我這里建議實(shí)時(shí)顯示可以使用log4net的自有功能。
比如我想使用winform中的listbox來(lái)實(shí)時(shí)顯示日志,可以建立一個(gè)Appender(附加),繼承于log4net的AppenderSkeleton
,這是一個(gè)抽象類,有一個(gè)抽象方法。
具體的,可以參考以下程序,這里會(huì)顯示所有的日志,如果需要過(guò)濾的話,可以在這個(gè)基礎(chǔ)上改。另外,一定一定一定要給this.Layout賦值,這是日志在界面上的顯示方式,如果沒(méi)有寫(xiě)的話,就會(huì)收獲一個(gè)報(bào)錯(cuò):“A layout must be set”,去網(wǎng)上搜這條內(nèi)容,不一定能找到解決方案。
public class ListBoxAppender : AppenderSkeleton { private ListBox _ListBox; public ListBoxAppender(ListBox box) { _ListBox = box; this.Layout = new PatternLayout("%date [%thread] %-5level %logger - %message%newline"); } protected override void Append(LoggingEvent loggingEvent) { // 獲取日志信息 string logMessage = RenderLoggingEvent(loggingEvent); // 更新 UI 控件 if (_ListBox.InvokeRequired) { _ListBox.Invoke(new Action(() => AppendText(logMessage))); } else { AppendText(logMessage); } } private void AppendText(string text) { _ListBox.Items.Add(text); } }
只需要給log4net配置一次就可以使用,這樣,每次調(diào)用日志記錄,界面上的lbxLog控件就可以一直顯示最新的日志信息。
// 添加自定義 Appender var listBoxAppender = new ListBoxAppender(lbxLog); log4net.Config.BasicConfigurator.Configure(listBoxAppender);
但是,我并不建議使用log4net直接操作控件顯示日志信息,在多線程短時(shí)間寫(xiě)較多日志的情況下,可能會(huì)導(dǎo)致軟件卡死,更佳的方式是增加緩存機(jī)制。
以上就是C#使用log4net結(jié)合sqlite數(shù)據(jù)庫(kù)實(shí)現(xiàn)記錄日志的詳細(xì)內(nèi)容,更多關(guān)于C# log4net結(jié)合sqlite記錄日志的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
C#通過(guò)重寫(xiě)Panel改變邊框顏色與寬度的方法
這篇文章主要介紹了C#通過(guò)重寫(xiě)Panel改變邊框顏色與寬度的方法,涉及C#針對(duì)Panel控件的重寫(xiě)與屬性設(shè)置技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下2015-08-08c# in depth的泛型實(shí)現(xiàn)實(shí)例代碼
這篇文章主要介紹了c# in depth的泛型實(shí)現(xiàn)實(shí)例代碼,學(xué)C#的同學(xué)一定會(huì)用到泛型實(shí)現(xiàn)的,這里我們提供了泛型實(shí)現(xiàn)的程序代碼,大家參考使用2013-11-11C# Web應(yīng)用調(diào)試開(kāi)啟外部訪問(wèn)步驟解析
本文主要介紹了C# Web應(yīng)用調(diào)試開(kāi)啟外部訪問(wèn)的實(shí)現(xiàn)過(guò)程與方法。具有一定的參考價(jià)值,下面跟著小編一起來(lái)看下吧2017-01-01C# 實(shí)現(xiàn)QQ式截圖功能實(shí)例代碼
本篇文章主要介紹了C# 實(shí)現(xiàn)QQ式截圖功能實(shí)例代碼,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-02-02Unity3D實(shí)現(xiàn)簡(jiǎn)易五子棋源碼
這篇文章主要為大家詳細(xì)介紹了Unity3D實(shí)現(xiàn)簡(jiǎn)易五子棋源碼,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-09-09c#實(shí)現(xiàn)ini文件讀寫(xiě)類分享
c#實(shí)現(xiàn)ini文件讀寫(xiě)類分享,大家參考使用吧2013-12-12C# 系統(tǒng)全局的異常處理實(shí)現(xiàn)
在C#應(yīng)用程序中,異??赡茉谌魏蔚胤桨l(fā)生,本文主要介紹了C# 系統(tǒng)全局的異常處理實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2025-01-01