系统日志

轻松背后的N+疲惫——系统日志

2014-04-16 00:41 by 螺丝钉想要螺丝帽, 324 阅读, 1 评论, 收藏编辑

相信很多coder都有这样的癖好:“自恋”!!对自己编写的code总是那么的自信,自豪,Always believe it to be so perfect!!

不喜欢做单元测试(总觉得它就那样了能出什么错?),不喜欢做日志(总觉得他没有什么用!),不做日志也就算了还把异常给“吃”了(只是为了让别人看不到那又黄又红的像坨屎一样的页面),最终只能独自一人默默的抓狂,累的像那什么一样,自作孽不可活!!

其实......饿......我就是这样的啦(ˉ▽ˉ;)...

为了让生活的幸福美满,为了工作的轻松快乐,我决定虔诚的忏悔,痛定思痛,写一个简单日志!(◎﹏◎)...

基于TraceSource的系统日志

TraceSource官方给出的描述是这样的:“提供一组方法和属性,利用这些方法和属性,应用程序可以跟踪代码的执行并将跟踪消息和它们的源关联起来”。总觉得这描述跟系统日志挂不上勾额,但事实它是用来做系统日志的一个不错的东西;

首先为了迎合当今编程思想,先来建2个接口:

1.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
/// <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();
     }
}   

结果为:

 

太晚了,该睡觉了哦!!

 

 
 
分类:  ASP.NET 代码库

你可能感兴趣的:(日志)