輕鬆背後的N+疲憊——系統日誌

相信不少coder都有這樣的癖好:「自戀」!!對本身編寫的code老是那麼的自信,自豪,Always believe it to be so perfect!!html

不喜歡作單元測試(總以爲它就那樣了能出什麼錯?),不喜歡作日誌(總以爲他沒有什麼用!),不作日誌也就算了還把異常給「吃」了(只是爲了讓別人看不到那又黃又紅的像坨屎同樣的頁面),最終只能獨自一人默默的抓狂,累的像那什麼同樣,自做孽不可活!!數據庫

其實......餓......我就是這樣的啦(ˉ▽ˉ;)...編程

爲了讓生活的幸福美滿,爲了工做的輕鬆快樂,我決定虔誠的懺悔,痛定思痛,寫一個簡單日誌!(◎﹏◎)...數組

基於TraceSource的系統日誌安全

TraceSource官方給出的描述是這樣的:「提供一組方法和屬性,利用這些方法和屬性,應用程序能夠跟蹤代碼的執行並將跟蹤消息和它們的源關聯起來」。總以爲這描述跟系統日誌掛不上勾額,但事實它是用來作系統日誌的一個不錯的東西;編輯器

首先爲了迎合當今編程思想,先來建2個接口:ide

1.ILogger:用於實現日誌的寫入源post

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
/// <summary>
   /// 系統日誌接口
   /// </summary>
   public interface ILogger
   {
       /// <summary>
       /// 系統崩潰錯誤日誌
       /// </summary>
       /// <param name="message">錯誤信息</param>
       /// <param name="args">設置格式的對象的數組</param>
       void Fatal( string message, params object [] args);
 
       /// <summary>
       /// 系統崩潰錯誤日誌
       /// </summary>
       /// <param name="message">錯誤信息</param>
       /// <param name="exception">異常對象</param>
       /// <param name="args">設置格式的對象的數組</param>
       void Fatal( string message, Exception exception, params object [] args);
 
       /// <summary>
       /// 系統消息日誌
       /// </summary>
       /// <param name="message">要記錄的信息</param>
       /// <param name="args">設置格式的對象的數組</param>
       void Infomation( string message, params object [] args);
 
       /// <summary>
       /// 系統警告日誌
       /// </summary>
       /// <param name="message">警告信息</param>
       /// <param name="args">設置格式的對象的數組</param>
       void Warning( string message, params object [] args);
 
       /// <summary>
       /// 系統錯誤日誌
       /// </summary>
       /// <param name="message">錯誤信息</param>
       /// <param name="args">設置格式的對象的數組</param>
       void Error( string message, params object [] args);
 
       /// <summary>
       /// 系統錯誤日誌
       /// </summary>
       /// <param name="message">錯誤信息</param>
       /// <param name="exception">異常對象</param>
       /// <param name="args">設置格式的對象的數組</param>
       void Error( string message, Exception exception, params object [] args);
   }

2.ILoggerFactory:用於生產指定的日誌寫入源單元測試

?
1
2
3
4
5
6
7
8
9
10
/// <summary>
   /// 系統日誌工廠
   /// </summary>
   public interface ILoggerFactory
   {
       /// <summary>
       /// 建立一個系統日誌
       /// </summary>
       ILogger Create();
   }

爲了方便編碼和保持日誌的統一性,咱們再建一個日誌上下文測試

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
/// <summary>
   /// 系統日誌上下文.
   /// </summary>
   public static class LoggerContext
   {
       static ILoggerFactory _currentLogFactory = null ;
 
       /// <summary>
       /// 設置固然上下文使用的日誌工廠
       /// <remarks>
       /// 該上下文始終使用一個日誌工廠進行建立日誌,建議在系統啓動時進行設置,設置後將沒法再進行設置
       /// </remarks>
       /// </summary>
       /// <param name="factory">日誌工廠</param>
       public static void SetCurrent(ILoggerFactory factory)
       {
           if (_currentLogFactory != null )
               throw new ArgumentException( "該日誌上下文已經設置使用的日誌工廠,沒法進行再次設置,如需使用其餘日誌工廠,請直接實例日誌工廠進行操做。" , "factory" );
           
           _currentLogFactory = factory;
       }
 
       /// <summary>
       /// 建立一個日誌
       /// </summary>
       public static ILogger CreateLog()
       {
           if (_currentLogFactory == null )
               throw new NullReferenceException( "該日誌上下文還沒有設置日誌工廠,請使用SetCurrent方法進行設置。" );
 
           return _currentLogFactory.Create();
       }
   }

好的,如今咱們進入正題,使用TraceSource進行日誌記錄,不要介意哈,進入正題前總要有些前奏, 目的你懂得o(^▽^)o.....

TraceSource 位於命名空間System.Diagnostics下,該命名空間在System.dll中,因此無需添加引用,比較方便。

下面是基於TraceSource的ILogger實現:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
public sealed class TraceSourceLogger
     :ILogger
{
     private const string EXCEPTION_FORMAT = "{0} 捕獲異常信息:{1}" ;
 
     TraceSource _source;
 
     public TraceSourceLogger()
     {
         _source = new TraceSource( "Bulrush" );
     }
 
     public void Fatal( string message, params object [] args)
     {
         if (String.IsNullOrWhiteSpace(message))
             return ;
 
         string messageToTrace = String.Format(CultureInfo.InvariantCulture, message, args);
         Trace(TraceEventType.Critical, messageToTrace);
     }
 
     public void Fatal( string message, Exception exception, params object [] args)
     {
         if (String.IsNullOrWhiteSpace(message) || exception == null )
             return ;
 
         string messageToTrace = String.Format(CultureInfo.InvariantCulture, message, args);
         string exceptionString = exception.ToString();
         Trace(TraceEventType.Critical, String.Format(CultureInfo.InvariantCulture, EXCEPTION_FORMAT, messageToTrace, exceptionString));
     }
 
     public void Infomation( string message, params object [] args)
     {
         if (String.IsNullOrWhiteSpace(message))
             return ;
 
         string messageToTrace = String.Format(CultureInfo.InvariantCulture, message, args);
         Trace(TraceEventType.Information, messageToTrace);
     }
 
     public void Warning( string message, params object [] args)
     {
         if (String.IsNullOrWhiteSpace(message))
             return ;
 
         string messageToTrace = String.Format(CultureInfo.InvariantCulture, message, args);
         Trace(TraceEventType.Warning, messageToTrace);
     }
 
     public void Error( string message, params object [] args)
     {
         if (String.IsNullOrWhiteSpace(message))
             return ;
 
         string messageToTrace = String.Format(CultureInfo.InvariantCulture, message, args);
         Trace(TraceEventType.Error, messageToTrace);
     }
 
     public void Error( string message, Exception exception, params object [] args)
     {
         if (String.IsNullOrWhiteSpace(message) || exception == null )
             return ;
 
         string messageToTrace = String.Format(CultureInfo.InvariantCulture, message, args);
         string exceptionString = exception.ToString();
         Trace(TraceEventType.Error, String.Format(CultureInfo.InvariantCulture, EXCEPTION_FORMAT, messageToTrace, exceptionString));
     }
 
     void Trace(TraceEventType eventType, string message)
     {
         if (_source != null )
         {
             try
             {
                 _source.TraceEvent(eventType, ( int )eventType, message);
             }
             catch (SecurityException)
             {
                 //這裏處理寫入是出現的安全問題,如文件沒有寫入權限。
             }
         }
     }
}

這個實現比較簡單,可是這裏有一個很好的哦,那是什麼呢?嘻嘻就TraceSource裏的Listeners傾聽器,微軟給咱們提供了幾個經常使用的傾聽器,我以爲基本已經夠用了,

1.DefaultTraceListener:默認使用這個,這個傾聽器會輸出在調試器的輸出窗口。

2.EventLogTraceListener: 這個是操做系統日誌的傾聽器,會把日誌記錄在操做系統的事件裏,我仍是比較喜歡這個,畢竟比較完善,安全性也比較好。

3.TextWriterTraceListener:這個是文本編輯器的傾聽器,簡單點就是以文件流的形式進行記錄,固然了文件路徑是本身定義的,這個也比較經常使用。

4.XmlWriterTraceListener:這個Xml文件的傾聽器,用法和TextWriterTraceListener差很少,只是使用Xml流格式進行記錄。

等等,固然還有幾個傾聽器,這裏就不一一列出了,有興趣的能夠查看MSDN的System.Diagnostics

若是你想拓展也能夠,如記錄在數據庫,或者使用Log4net等等,只要繼承TraceListener基類進行重寫就能夠了。

下面是一個最簡單的自定義傾聽器:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
public class CustomeTraceListener
     : TraceListener
{
     public override void Write( string message)
     {
         File.AppendAllText( @"d:\log.txt" , message);
     }
 
     public override void WriteLine( string message)
     {
         File.AppendAllText( @"d:\log.txt" , message+ Environment.NewLine);
     }
}

下面咱們在寫一個TraceSourceLogger工廠就能夠了,代碼以下:

?
1
2
3
4
5
6
7
8
9
public class TraceSourceLoggerFactory
     : ILoggerFactory
{
     public ILogger Create()
     {
         var logger = new TraceSourceLogger();
         return logger;
     }
}

OK,代碼已經寫好了,那又的同窗就要問了傾聽器在哪裏設置呢?

這個問題很簡單,固然是在配置文件裏配置了;

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
<configuration>
   <system.diagnostics>
     <sources>
       <source name= "Bulrush" switchName= "SourceSwitch" switchType= "System.Diagnostics.SourceSwitch" >
         <listeners>
           <clear/>
           <add name= "eventLog" ></add>
         </listeners>
       </source>
     </sources>
     <switches>
       <!--這裏設置TraceSource的寫入開關,默認爲Off關閉,不進行寫入,具體值能夠查看SourceLevels枚舉-->
       <add name= "SourceSwitch" value= "All" />
     </switches>
     <sharedListeners>
       <!--
         這裏使用操做系統的事件傾聽器,initializeData屬性是事件源, false 爲默認。
         不一樣的傾聽器initalizeData有不一樣的意義,如TextWriterTraceListnener傾聽器,能夠設置爲「d:\log.txt」,意思就是保存的路徑。
       -->
       <add name= "eventLog"
         type= "System.Diagnostics.EventLogTraceListener"
         initializeData= "false" />
     </sharedListeners>
   </system.diagnostics>
</configuration>

到這裏就結束了,下面作個簡單的測試,是使用EventLogTraceListener傾聽器:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
[ClassInitialize()]
public static void ClassInitialze(TestContext context)
{
     LoggerContext.SetCurrent( new TraceSourceLoggerFactory());
}
 
[TestMethod]
public void TestTraceSourceLogger()
{
     //LoggerContext.CreateLog().Error("錯誤日誌");
 
     var logger = LoggerContext.CreateLog();
 
     try
     {
         logger.Error( "錯誤日誌" );
         logger.Fatal( "系統崩潰日誌" );
         logger.Infomation( "普通消息日誌" );
         logger.Warning( "非關鍵性,警告日誌" );
     }
     catch
     {
         Assert.Fail();
     }
}   

結果爲:

 

太晚了,該睡覺了哦!!

 

出處:http://www.cnblogs.com/zcylife/p/3657579.html

相關文章
相關標籤/搜索