C# 日志記錄分級功能使用 按照日期,大小,或是單文件存儲


本文將使用一個Nuget的一個組件庫來實現一個簡單強大的日志記錄功能,包采用線程安全實現,所有的記錄在后台完成,即使您在前台調用100萬次方法,耗時也不過1000ms(具體時間依照電腦性能決定),支持日志等級,並提供了一個控件用於分析所有的日志消息。

在visual studio 中的Nuget管理器中可以下載安裝,也可以直接在Nuget控制台輸入下面的指令安裝:

Install-Package HslCommunication

 Nuget安裝教程:http://www.cnblogs.com/dathlin/p/7705014.html

 聯系作者及加群方式(激活碼在群里發放):http://www.hslcommunication.cn/Cooperation

 

本組件提供了一個日志功能,實現了常用的3中日志模式:

  • 單日志文件模式,日志始終都向該文件寫入,需要程序中自行清除或手動編寫代碼清空,不然文件會很大。
  • 根據文件大小存儲的多文件模式,一個日志文件寫入達到某個數值時,創建新文件寫入。
  • 根據時間日期的多文件模式,每條日志將根據寫入的時間日志來判斷文件名,比如創建按每天存儲的日志。

我也曾使用過.net中大名鼎鼎的log4net日志組件,一般使用起來確實方便,但是我在諸如實現上述的需求的時候就特別麻煩,而且log4net功能眾多,大多數功能並不是我所需要的,我就需要一個實現txt日志的存儲方式,簡單高效,多種模式即可。於是就自行開發了一個簡單高效的日志組件,並集成到了該通信庫中,本日志組件還提供了一個分析控件及窗口,可以對一個長長的日志文件進行分析統計(只對本組件生成的日志有效),快速定位需要查找的日志信息,支持使用正則表達式來篩選,本日志組件也提供了分級存儲。

 

Demo程序下載 HslCommunicationDemo.zip

 

 

 

使用之前先要進行命名控件的引用,如下:

using HslCommunication.LogNet;

  

實例化

首先先實例化一個對象,如果您用於整個application的日志存儲,可以定義成靜態對象。或者直接定義在form窗口的下面也可以。此處先實例化單文件存儲的機制

private ILogNet logNet = new LogNetSingle("D:\\123.txt");

  

我們通常的做法是日志文件存儲在exe程序目錄下的Logs文件夾中,無論在服務器端還是客戶端都是非常適用的,所以

private ILogNet logNet = new LogNetSingle(Application.StartupPath + "\\Logs\\123.txt");

  

寫日志

接下來你就可以在窗口的其他地方進行寫入日志了,本組件提供了5個等級的日志寫入功能,名稱參考了常規的日志等級,有 DEBUG , INFO, WARN , ERROR , FATAL ,根據需要進行存儲,還提供了對exception異常的方法支持和自定義的描述化文本寫入,該文本不屬於日志范疇,在日志分析中會被忽略,如下代碼演示幾種不同的寫入(寫入的方式采用統一的接口實現,對於三種日志模式都是適用的):

        private void userButton1_Click(object sender, EventArgs e)
        {
            // 一般日志寫入
            logNet.WriteDebug("調試信息");
            logNet.WriteInfo("一般信息");
            logNet.WriteWarn("警告信息");
            logNet.WriteError("錯誤信息");
            logNet.WriteFatal("致命信息");
            logNet.WriteException(null, new IndexOutOfRangeException());

            // 帶有關鍵字的寫入,關鍵字建議為方法名或是類名,方便分析的時候歸類搜索
            logNet.WriteDebug("userButton1_Click", "調試信息");
            logNet.WriteInfo("TestForm", "一般信息");
            logNet.WriteWarn("隨便什么", "警告信息");
            logNet.WriteError("userButton1_Click", "錯誤信息");
            logNet.WriteFatal("userButton1_Click", "致命信息");
            logNet.WriteException("userButton1_Click", new IndexOutOfRangeException());
        }

 

寫入異常時會被自動賦予 FATAL 等級。寫入效果如下:

下面再說明寫入描述文本的時候發生的事情:

logNet.WriteDescrition("這是一條描述文本");

 


描述性文本的前面會再新增一行作為明顯的區分。描述性文本不列入到日志分析工具中,會被自動被過濾。

 

 

設置等級

為什么要實現日志分級呢?有兩個巨大的好處。第一個好處是方便在日志追述的時候進行篩選,比如我需要查看日志中致命錯誤的時候就尤為重要,可以進行快速的篩選。第二個好處就是用於開發的時候調試使用,有時候我們為了快速的找到程序問題的時候,會對程序運行中各種數據狀態,系統狀態進行輸出,然后分析日志得出結論。當你已經寫了很多很多的

logNet.WriteDebug("調試信息");

代碼后,准備發布使用的時候不想輸出這種僅用於調試的時候的日志,總不可能取消所有的調試日志吧?效率太低,萬一以后需要恢復輸出就麻煩了,所以本日志組件支持寫入日志的時候的等級設置,如果我們把日志的等級設置為INFO級別,那么所有的DEBUG級別的日志都不會存儲,所以我們在發布軟件的時候,只要設置等級就行。

下面再來說明下如何設置日志存儲等級。使用方法:

logNet.SetMessageDegree(HslMessageDegree.DEBUG);//所有等級存儲
logNet.SetMessageDegree(HslMessageDegree.INFO);//除DEBUG外,都存儲
logNet.SetMessageDegree(HslMessageDegree.WARN);//除DEBUG和INFO外,都存儲
logNet.SetMessageDegree(HslMessageDegree.ERROR);//只存儲ERROR和FATAL
logNet.SetMessageDegree(HslMessageDegree.FATAL);//只存儲FATAL
logNet.SetMessageDegree(HslMessageDegree.None);//不存儲任何等級

選擇上面的一行代碼執行就行。

 

自定義事件

組件默認存儲所有的等級,如果需要設置,在實例化后即可設置等級。日志組件支持一個事件,在所有的日志進行存儲前(被日志等級過濾掉的不會觸發)會報告事件,可以用於其他操作或是控制台的顯示等等,注意: 如果在事件關聯方法中直接訪問UI線程,會異常

這個事件有個非常大的好處,可以統一輸出顯示你的程序中所有地方的日志,方便統一的控制和處理。

 

logNet.BeforeSaveToFile += LogNet_BeforeSaveToFile;

 

private void LogNet_BeforeSaveToFile(object sender, HslEventArgs e)
{
    // 如果需要UI顯示,就要取消注釋下方的代碼

    //if(InvokeRequired)
    //{
    //    Invoke(new Action(() =>{
    //        LogNet_BeforeSaveToFile(sender, e);
    //    }));
    //    return;
    //}

    string degree = e.HslMessage.Degree.ToString();//獲取等級
    DateTime time = e.HslMessage.Time;//獲取時間
    string text = e.HslMessage.Text;//日志文本
    int threadId = e.HslMessage.ThreadId;//記錄日志的線程id
}

  

這個事件在2019年2月10日 16:36:41上新增了一個額外的功能,就是允許你手動取消當前日志的存儲

        private void LogNet_BeforeSaveToFile( object sender, HslEventArgs e )
        {
            e.HslMessage.Cancel = checkBox1.Checked;
        }

假設這樣設置后,所有的日志都不存儲到文件中去。

        private void LogNet_BeforeSaveToFile( object sender, HslEventArgs e )
        {
            if (e.HslMessage.Degree != HslMessageDegree.INFO)
            {
                e.HslMessage.Cancel = checkBox1.Checked;
            }
        }

如果這么寫,就是只存儲INFO等級的日志信息。

 

過濾指定的關鍵字日志存儲

有些日志數據可能我們想要觸發BeforeSaveToFile事件,但是不能存儲到日志文件里,那么可以直接按照如下的配置進行設置,會過濾掉存儲到文件中,如下就是過濾掉關鍵字的信息

logNet.FiltrateKeyword( "123" );

 

 

 

按文件大小存儲的實例化

若要按照文件大小進行存儲,例如日志存儲2M后,自動生成新的文件,然后存滿2M后生成新文件,如此重復,則需要指定文件的 存儲路徑大小 ,這種方式存儲的文件名稱不可控制,自動定義為 Logs_20170903170604.txt 的格式,會以當前時間自動命名,如下舉例了實例化一個2M大小的對象:

ILogNet logNet = new LogNetFileSize(Application.StartupPath + "\\customer1", 2 * 1024 * 1024);

  

只要定義了對象,就可以按照上述寫入日志的代碼來寫了。

按時間日期存儲的實例化

也是一種多文件的存儲機制,和按照大小的存儲非常類似,此處可以配置按照每小時生成新的文件,每天新的文件,每月新的文件,每季度新的文件,每年新的文件,生成的文件名稱也是固定的,需要指定 路徑存儲模式

ILogNet logNet = new LogNetDateTime(Application.StartupPath + "\\customer2",GenerateMode.ByEveryHour);//按每小時
ILogNet logNet = new LogNetDateTime(Application.StartupPath + "\\customer2", GenerateMode.ByEveryDay);//按每天
ILogNet logNet = new LogNetDateTime(Application.StartupPath + "\\customer2", GenerateMode.ByEveryMonth);//按每月
ILogNet logNet = new LogNetDateTime(Application.StartupPath + "\\customer2", GenerateMode.ByEverySeason);//按每季度
ILogNet logNet = new LogNetDateTime(Application.StartupPath + "\\customer2", GenerateMode.ByEveryYear);//按每年

  

單文件模式

單文件的模式在上述已經作為演示說明過了,但是單文件模式提供了兩個額外的方法:

  • 獲取該文件日志中所有的內容
  • 清空該文件的所有數據

具體的代碼如下所示: 

LogNetSingle logNetSingle = logNet as LogNetSingle;
if (logNetSingle != null)
{
    string logData = logNetSingle.GetAllSavedLog();//獲取所有的日志信息
    logNetSingle.ClearLog();//清除所有的日志信息
}

  

日志查看器

如果只提供了一個日志的寫入而沒有分析工具,那么本組件就是沒什么競爭力的,本日志組件提供了一個大殺器,日志分析控件!您可以集成到您自己的系統中,該控件只需要接受一個 日志源字符串 (就是日志文件的所有字符串數據,服務器讀取文件發送給遠程客戶端就可以現實遠程查看日志分析!棒不棒!)原先的 ClientServerProject 項目中已經帶有了2個日志查看器,一個服務器端使用了本組件提供的標准form窗口,客戶端使用了日志分析控件實現遠程查看功能,具體代碼可以參照 ClientServerProject 項目的代碼。

功能概述

  • 對日志文件中的所有等級日志進行分析,每種等級多少個
  • 可以同時根據日志等級和時間區段來篩選日志,比如查看某一時間段的 DEBUG 等級日志
  • 可以進行可視化分析,查看日志數據的時間分布情況
  • 在可視化的界面,如果某個區間段的某日數量特別高,鼠標移動上去后還可以自動跳轉

此處直接演示一個組件標准的日志查看窗口,這個窗口也可以在wpf項目中顯示:

        private void userButton13_Click(object sender, EventArgs e)
        {
            // 日志查看器
            using (HslCommunication.LogNet.FormLogNetView form = new HslCommunication.LogNet.FormLogNetView())
            {
                form.ShowDialog();
            }
        }

 

效果上圖

查看日志信息

上圖中點擊了 信息 按鈕后,顯示的圖形發生了變化,只顯示了 信息 等級日志

光標移動到某一區間后,下方會有該區間的日志數量和時間范圍,雙擊后的操作就您自己去發現了。^_^

 

控件的方式,新建一個窗口,將組件的控件給拖進去,如果這個組件在工具箱不顯示,那么需要將dll文件拖到工具箱。

至於顯示信息代碼:

        private void FormLogNetTest_Load(object sender, EventArgs e)
        {
            // 該source可以是本地讀取的文件,也可以是網絡發送過來的數據
            string source = Encoding.UTF8.GetString(System.IO.File.ReadAllBytes("123.txt"));   // 傳入路徑
            logNetAnalysisControl1.SetLogNetSource(source);
        }

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM