前言
在项目正式上线后,如果出现错误、异常、崩溃等情况,
我们往往第一想到的事就是查看日志。
所以日志对于一个系统的维护是非常重要的。
声明
本文中的示例代码旨在这个框架是怎么工作的,具体实现可以自由发挥。
贯穿所有的日志系统
日志系统,往往是贯穿一个程序的所有代码的;
试想一下,如果你的日志完全是由第三方组件提供的;
那么就意味着,你的所有项目都必须引用这个dll;
也许你会说自己可以2次封装,那么依然需要所有项目都引用你的这个封装后的log项目,
另一方面
一些log组件需要实例化后才可以使用,比如log4net,这又意味着你得有一个全局的静态变量,或者你自己二次封装,
但其实微软已经为我们提供了2个十分方便的静态类,用于日志的记录。
关于这2个类的文档可以去看MSDN
System.Diagnostics.Trace
System.Diagnostics.Debug
它使用非常方便,不用引用任何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);//记录日志
}
}
由于大部分方法都是可重写的,所以其实最终输出什么都是可以非常灵活。
通过配置文件初始化监听器比直接写代码稍稍复杂一点,但是也更方便,我们可以快速的,不重新编译系统,即可进行对日志监听器进行设定。
演示如下:
示例:
我们将ProjectTraceListener独立成一个项目,编译为dll。
ProjectTraceListener.cs
1: using System;
2: using System.Collections.Generic;
3: using System.Text;
4: using System.Diagnostics;
5: using System.IO;
6:
7: namespace ProjectLog
8: {
9: public class ProjectTraceListener : TraceListener
10: {
11: public string FilePath { get; private set; }
12:
13: public ProjectTraceListener(string filePath)
14: {
15: FilePath = filePath;
16: }
17:
18: public override void Write(string message)
19: {
20: File.AppendAllText(FilePath, message);
21: }
22: public override void WriteLine(string message)
23: {
24: File.AppendAllText(FilePath, DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss ") + message + Environment.NewLine);
25: }
26: public override void Write(object o, string category)
27: {
28: string message = string.Empty;
29: if (!string.IsNullOrEmpty(category))
30: {
31: message = category + ":";
32: }
33: if (o is Exception)//如果参数对象o是与Exception类兼容,输出异常消息+堆栈,否则输出o.ToString()
34: {
35: var ex = (Exception)o;
36: message += ex.Message + Environment.NewLine;
37: message += ex.StackTrace;
38: }
39: else if(null != o)
40: {
41: message += o.ToString();
42: }
43:
44: WriteLine(message);
45: }
46: }
47: }
在控制台项目中测试:
App.config
1: <?xml version="1.0" encoding="utf-8" ?>
2: <configuration>
3: <system.diagnostics>
4: <trace autoflush="false" indentsize="4">
5: <listeners>
6: <clear/>
7: <!--清除默认监听器-->
8: <!--添加自定义监听器 initializeData 就是初始化参数-->
9: <add name="ProjectTraceListener" type="ProjectLog.ProjectTraceListener, ProjectLog, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" initializeData="d:/Error.log" />
10: </listeners>
11: </trace>
12: <switches>
13: <!--这里可以设定监听级别,可以设置Error,Warning,Info或者留空-->
14: <add name="ProjectTraceListener" value="Error" />
15: </switches>
16: </system.diagnostics>
17: </configuration>
Program.cs
1: using System;
2: using System.Collections.Generic;
3: using System.Text;
4: using System.Diagnostics;
5: using ProjectLog;
6:
7: namespace ProjectLogDemo
8: {
9: class Program
10: {
11: static void Main(string[] args)
12: {
13: //删除初始化代码,改为在配置文件中设置
14: //Trace.Listeners.Clear(); //清除系统监听器 (就是输出到Console的那个)
15: //Trace.Listeners.Add(new ProjectTraceListener(@"d:/Error.log")); //添加ProjectTraceListener实例
16: Test();
17: }
18:
19: private static void Test()
20: {
21: try
22: {
23: int i = 0;
24: Console.WriteLine(5 / i); //出现除0异常
25: }
26: catch (Exception ex)
27: {
28: Trace.Write(ex, "计算员工工资出现异常");
29: }
30: }
新闻热点
疑难解答