程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> C# >> C#入門知識 >> 利用C#自帶組件強壯程序日志,

利用C#自帶組件強壯程序日志,

編輯:C#入門知識

利用C#自帶組件強壯程序日志,


在項目正式上線後,如果出現錯誤,異常,崩潰等情況

我們往往第一想到的事就是查看日志

所以日志對於一個系統的維護是非常重要的

聲明

正文中的代碼只是一個栗子,一個非常簡單的栗子,只是說明這個框架是怎麼工作的

具體實現可以自由發揮~~~~

貫穿所有的日志系統

日志系統,往往是貫穿一個程序的所有代碼的;

試想一下,如果你的日志完全是由第三方組件提供的;

那麼就意味著,你的所有項目都必須引用這個dll;

也許你會說自己可以2次封裝,那麼依然需要所有項目都引用你的這個封裝後的log項目

另一方面

一些log組件需要實例化後才可以使用,比如log4net,這又意味著你得有一個全局的靜態變量,或者你自己二次封裝

 

但其實微軟已經為我們提供了2個十分方便的靜態類,用於日志的記錄

System.Diagnostics.Trace和System.Diagnostics.Debug

關於這2個類的文檔可以去看MSDN

System.Diagnostics.Trace

System.Diagnostics.Debug

他的使用真的是非常的方便,以至於你只要使用一次就會愛上他

不用引用任何dll,因為他是微軟自家的東西,就在System.dll中

調用他的方法也很簡單

復制代碼
using System.Diagnostics;

...
...
     Trace.TraceError("這是一個Error級別的日志");
     Trace.TraceWarning("這是一個Warning級別的日志");
     Trace.TraceInformation("這是一個Info級別的日志");
     Trace.WriteLine("這是一個普通日志");
     Trace.Flush();//立即輸出
...
...
復制代碼

當然方法不止只有4個,更多的可以參考MSDN

Trace,Debug的調用方式完全相同,不同的地方在於

Debug的所有方法都有

[Conditional("DEBUG")]

表明了,在Release模式下(沒有定義DEBUG常量時),該方法不會被編譯的(不是不執行,而是根本不會編譯到程序中去)

也就是說 Debug.XXX() 方法僅在Debug模式下運行,這個又可以為我們省下很多事

重寫日志實現

Trace和Debug中的方法的默認行為是輸出到控制台Console,和Console.Write是一樣的

但是我們通過改變他的{敏感詞}TraceListener,來實現更多的操作

必須實現的方法有

void Write(string message);
void WriteLine(string message);

不過也可以主動重寫其他方法

隨便寫一個MyTraceListener

復制代碼
class MyTraceListener : TraceListener
{
    public override void Write(string message)
    {
        File.AppendAllText("d:\\1.log",message);
    }

    public override void WriteLine(string message)
    {
        File.AppendAllText("d:\\1.log", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss    ") + message + Environment.NewLine);
    }
}
復制代碼

現在程序入口中初始化{敏感詞}Trace.Listeners

PS下:Trace和Debug的{敏感詞}的共用的

static void Main(string[] args)
{
    Trace.Listeners.Clear();  //清除系統{敏感詞} (就是輸出到Console的那個)
    Trace.Listeners.Add(new MyTraceListener()); //添加MyTraceListener實例
}

在隨便來個方法測試下

復制代碼
private static void Test()
{
    try
    {
        int i = 0;
        Console.WriteLine(5 / i); //出現除0異常
    }
    catch (Exception ex)
    {
        Trace.TraceError("出現異常:" + ex.Message);//記錄日志
    }
}
復制代碼

由於大部分方法都是可重寫的,所以其實最終輸出什麼都是可以靈活處理的

例如這樣

復制代碼
public override void Write(object o, string category)
{
    string msg = "";
    if (string.IsNullOrWhiteSpace(category) == false) //category參數不為空
    {
        msg = category + " : ";
    }
    if (o is Exception) //如果參數o是異常類,輸出異常消息+堆棧,否則輸出o.ToString()
    {
        var ex = (Exception)o;
        msg += ex.Message + Environment.NewLine; 
        msg += ex.StackTrace;
    }
    else if(o != null)
    {
        msg = o.ToString();
    }
    WriteLine(msg);
}
復制代碼 復制代碼
private static void Test()
{
    try
    {
        int i = 0;
        Console.WriteLine(5 / i); //出現除0異常
    }
    catch (Exception ex)
    {
        Trace.Write(ex, "計算員工工資出現異常");
    }
}
復制代碼

其他的就自己舉一反三了

通過配置文件初始化{敏感詞}

通過配置文件初始化{敏感詞}比直接寫代碼稍稍復雜一點,但是也更方便,我們可以快速的,不重新編譯系統,即可進行對日志{敏感詞}進行設定

特別是在Web項目中,這將變得更加方便

 

我把剛才的MyTraceListener獨立成一個項目,編譯為dll

並且為他增加一個構造函數和FilePath屬性用於設置將log文件的位置

 MyTraceListener 配置文件 復制代碼
xml version="1.0" encoding="utf-8" ?>
<configuration>
  <system.diagnostics>
    <trace autoflush="false" indentsize="4">
      <listeners>
        <clear />
        
        <add name="MyTraceListener" type="MyLog.MyTraceListener, MyLog, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" initializeData="d:\1.log" />
      listeners>
    trace>
    <switches>
      
      <add name="MyTraceListener" value="Error" />
    switches>
  system.diagnostics>
configuration>
復制代碼

其中type參數可以這樣獲得

typeof(MyLog.MyTraceListener).AssemblyQualifiedName

Version,Culture,PublicKeyToken 也可以忽略

測試一下

沒有任何問題

而且如果你用了log4net等第三方組件的話,只需要在實現TraceListener的項目中引用log4net就可以了

復制代碼
public class MyTraceListener : TraceListener
{
    log4net _log = new log4net();

    public MyTraceListener(string filepath)
    {
        _log = new log4net();
        _log.FilePath = filepath;
    }

    public override void Write(string message)
    {
        _log.Info(message);
    }

    public override void WriteLine(string message)
    {
        _log.Info(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss    ") + message + Environment.NewLine);
    }
}
復制代碼

這樣是不是就可以用log4net了啊,是不是就可以用其他log系統了啊 ,是不是就想寫數據庫就寫數據庫 想寫文件就寫文件, 寫干啥就干啥了啊~~~~~~

兄弟們啊~~~~~~~

說完了...拜拜~~

本文轉載至:http://www.lupaworld.com/article-237418-1.html

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved