利用C#自带组件强壮程序日志

 

在项目正式上线后,如果出现错误,异常,崩溃等情况

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

所以日志对于一个系统的维护是非常重要的

声明

正文中的代码只是一个栗子,一个非常简单的栗子,只是说明这个框架是怎么工作的

具体实现可以自由发挥~~~~

贯穿所有的日志系统

日志系统,往往是贯穿一个程序的所有代码的;

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

那么就意味着,你的所有项目都必须引用这个dll;

也许你会说自己可以2次封装,那么依然需要所有项目都引用你的这个封装后的log项目

另一方面

一些log组件需要实例化后才可以使用,比如log4net,这又意味着你得有一个全局的静态变量,或者你自己二次封装

但其实微软已经为我们提供了2个十分方便的静态类,用于日志的记录

System.Diagnostics.Trace和System.Diagnostics.Debug

关于这2个类的文档可以去看MSDN

System.Diagnostics.Trace

System.Diagnostics.Debug

他的使用真的是非常的方便,以至于你只要使用一次就会爱上他

不用引用任何dll,因为他是微软自家的东西,就在System.dll中

调用他的方法也很简单

  1. using System.Diagnostics;
  2.  
  3. ...
  4. ...
  5. Trace.TraceError("这是一个Error级别的日志");
  6. Trace.TraceWarning("这是一个Warning级别的日志");
  7. Trace.TraceInformation("这是一个Info级别的日志");
  8. Trace.WriteLine("这是一个普通日志");
  9. Trace.Flush();//立即输出
  10. ...
  11. ...

当然方法不止只有4个,更多的可以参考MSDN

Trace,Debug的调用方式完全相同,不同的地方在于

Debug的所有方法都有

  1. [Conditional("DEBUG")]

表明了,在Release模式下(没有定义DEBUG常量时),该方法不会被编译的(不是不执行,而是根本不会编译到程序中去)

也就是说 Debug.XXX() 方法仅在Debug模式下运行,这个又可以为我们省下很多事

重写日志实现

Trace和Debug中的方法的默认行为是输出到控制台Console,和Console.Write是一样的

但是我们通过改变他的监听器TraceListener,来实现更多的操作

必须实现的方法有

  1. void Write(string message);
  2. void WriteLine(string message);

不过也可以主动重写其他方法

随便写一个MyTraceListener

  1. class MyTraceListener : TraceListener
  2. {
  3. public override void Write(string message)
  4. {
  5. File.AppendAllText("d:\\1.log",message);
  6. }
  7.  
  8. public override void WriteLine(string message)
  9. {
  10. File.AppendAllText("d:\\1.log", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss ") + message + Environment.NewLine);
  11. }
  12. }

现在程序入口中初始化监听器Trace.Listeners

PS下:Trace和Debug的监听器的共用的

  1. static void Main(string[] args)
  2. {
  3. Trace.Listeners.Clear(); //清除系统监听器 (就是输出到Console的那个)
  4. Trace.Listeners.Add(new MyTraceListener()); //添加MyTraceListener实例
  5. }

在随便来个方法测试下

  1. private static void Test()
  2. {
  3. try
  4. {
  5. int i = 0;
  6. Console.WriteLine(5 / i); //出现除0异常
  7. }
  8. catch (Exception ex)
  9. {
  10. Trace.TraceError("出现异常:" + ex.Message);//记录日志
  11. }
  12. }

由于大部分方法都是可重写的,所以其实最终输出什么都是可以灵活处理的

例如这样

  1. public override void Write(object o, string category)
  2. {
  3. string msg = "";
  4. if (string.IsNullOrWhiteSpace(category) == false) //category参数不为空
  5. {
  6. msg = category + " : ";
  7. }
  8. if (o is Exception) //如果参数o是异常类,输出异常消息+堆栈,否则输出o.ToString()
  9. {
  10. var ex = (Exception)o;
  11. msg += ex.Message + Environment.NewLine;
  12. msg += ex.StackTrace;
  13. }
  14. else if(o != null)
  15. {
  16. msg = o.ToString();
  17. }
  18. WriteLine(msg);
  19. }
  1. private static void Test()
  2. {
  3. try
  4. {
  5. int i = 0;
  6. Console.WriteLine(5 / i); //出现除0异常
  7. }
  8. catch (Exception ex)
  9. {
  10. Trace.Write(ex, "计算员工工资出现异常");
  11. }
  12. }

其他的就自己举一反三了

通过配置文件初始化监听器

通过配置文件初始化监听器比直接写代码稍稍复杂一点,但是也更方便,我们可以快速的,不重新编译系统,即可进行对日志监听器进行设定

特别是在Web项目中,这将变得更加方便

我把刚才的MyTraceListener独立成一个项目,编译为dll

并且为他增加一个构造函数和FilePath属性用于设置将log文件的位置

  1. public class MyTraceListener : TraceListener
  2. {
  3. public string FilePath { get; private set; }
  4.  
  5. public MyTraceListener(string filepath)
  6. {
  7. FilePath = filepath;
  8. }
  9.  
  10. public override void Write(string message)
  11. {
  12. File.AppendAllText(FilePath, message);
  13. }
  14.  
  15. public override void WriteLine(string message)
  16. {
  17. File.AppendAllText(FilePath, DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss ") + message + Environment.NewLine);
  18. }
  19.  
  20. public override void Write(object o, string category)
  21. {
  22. string msg = "";
  23.  
  24. if (string.IsNullOrWhiteSpace(category) == false) //category参数不为空
  25. {
  26. msg = category + " : ";
  27. }
  28.  
  29. if (o is Exception) //如果参数o是异常类,输出异常消息+堆栈,否则输出o.ToString()
  30. {
  31. var ex = (Exception)o;
  32. msg += ex.Message + Environment.NewLine;
  33. msg += ex.StackTrace;
  34. }
  35. else if (o != null)
  36. {
  37. msg = o.ToString();
  38. }
  39.  
  40. WriteLine(msg);
  41. }
  42. }
配置文件
  1. <?xml version="1.0" encoding="utf-8" ?>
  2. <configuration>
  3. <system.diagnostics>
  4. <trace autoflush="false" indentsize="4">
  5. <listeners>
  6. <clear /><!--清除默认监听器-->
  7. <!--添加自定义监听器 initializeData 就是初始化参数-->
  8. <add name="MyTraceListener" type="MyLog.MyTraceListener, MyLog, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" initializeData="d:\1.log" />
  9. </listeners>
  10. </trace>
  11. <switches>
  12. <!--这里可以设定监听级别,可以设置Error,Warning,Info或者留空-->
  13. <add name="MyTraceListener" value="Error" />
  14. </switches>
  15. </system.diagnostics>
  16. </configuration>

其中type参数可以这样获得

  1. typeof(MyLog.MyTraceListener).AssemblyQualifiedName

Version,Culture,PublicKeyToken 也可以忽略

测试一下

没有任何问题

而且如果你用了log4net等第三方组件的话,只需要在实现TraceListener的项目中引用log4net就可以了

说完了...拜拜~~

代码下载

LogDemo.rar

  1. public class MyTraceListener : TraceListener
  2. {
  3. log4net _log = new log4net();
  4.  
  5. public MyTraceListener(string filepath)
  6. {
  7. _log = new log4net();
  8. _log.FilePath = filepath;
  9. }
  10.  
  11. public override void Write(string message)
  12. {
  13. _log.Info(message);
  14. }
  15.  
  16. public override void WriteLine(string message)
  17. {
  18. _log.Info(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss ") + message + Environment.NewLine);
  19. }
  20. }

这样是不是就可以用log4net了啊,是不是就可以用其他log系统了啊 ,是不是就想写数据库就写数据库 想写文件就写文件, 写干啥就干啥了啊~~~~~~

[转]利用C#自带组件强壮程序日志的更多相关文章

  1. 转载——利用C#自带组件强壮程序日志

    利用C#自带组件强壮程序日志   在项目正式上线后,如果出现错误,异常,崩溃等情况 我们往往第一想到的事就是查看日志 所以日志对于一个系统的维护是非常重要的 声明 正文中的代码只是一个栗子,一个非常简 ...

  2. 利用C#自带组件强壮程序日志

    在项目正式上线后,如果出现错误,异常,崩溃等情况 我们往往第一想到的事就是查看日志 所以日志对于一个系统的维护是非常重要的 声明 正文中的代码只是一个栗子,一个非常简单的栗子,只是说明这个框架是怎么工 ...

  3. 利用Linux自带的logrotate管理日志

    日常运维中,经常要对各类日志进行管理,清理,监控,尤其是因为应用bug,在1小时内就能写几十个G日志,导致磁盘爆满,系统挂掉. nohup.out,access.log,catalina.out 本文 ...

  4. 利用Qt自带工具发布程序

    Qt官方开发环境生成的exe发布方式--使用windeployqt 从开始菜单-->Qt 5.4.0-->5.4-->MinGW 4.9 (32-bit)-->Qt 5.4 f ...

  5. 利用vs自带工具分析程序性能

    测试程序写好后可以通过VS2010分析菜单里选择启用性能向导 选择CPU采样后就选择需要分析的项目 测试项目选择完成后就可以运行分析,结束分析后VS2010会提供个详细报告文档 从分析结果来看GetC ...

  6. 利用jdk自带的运行监控工具JConsole观察分析Java程序的运行

    利用jdk自带的运行监控工具JConsole观察分析Java程序的运行 原文链接 一.JConsole是什么 从Java 5开始 引入了 JConsole.JConsole 是一个内置 Java 性能 ...

  7. 如何利用OpenCV自带的级联分类器训练程序训练分类器

    介绍 使用级联分类器工作包括两个阶段:训练和检测. 检测部分在OpenCVobjdetect 模块的文档中有介绍,在那个文档中给出了一些级联分类器的基本介绍.当前的指南描述了如何训练分类器:准备训练数 ...

  8. 利用win10自带的系统配置禁止开机启动项和程序

    一.利用win10自带的系统配置禁止开机启动项和程序     首先打开"运行"对话框,可以通过开始菜单打开运行,也可以按下快捷键WIN+R打开"运行".如下图. ...

  9. Android入门(四):链接接口组件和程序代码

    编写好layout中的接口组件之后,下一步就是编写控制接口组件的程序代码.上一章,我们使用了三种接口组件,在使用者输入性别和年龄之后点击“健康建议按钮”,程序会读取用户所填入的性别和年龄,然后显示判断 ...

随机推荐

  1. html头标签meta实现refresh重定向

    <html> <head> <meta http-equiv="content-type" content="text/html; char ...

  2. PAT 5-9 输出华氏-摄氏温度转换表   (10分)

    输入2个正整数lower和upper(lower≤\le≤upper≤\le≤100),请输出一张取值范围为[lower,upper].且每次增加2华氏度的华氏-摄氏温度转换表. 温度转换的计算公式: ...

  3. [python]自问自答:python -m参数? (转) ( python2.7 版本 )

    原文地址: http://www.cnblogs.com/xueweihan/p/5118222.html python -m xxx.py 作用是:把xxx.py文件当做模块启动 但是我一直不明白当 ...

  4. Ubuntu python-opcua Test

    /********************************************************************************* * Ubuntu python-o ...

  5. Spring boot 2.1.0 -- swagger2 整合

    依赖版本信息 Spring boot 2.1.0.RELEASE swagger2 2.7.0 1. mvn 配置  pom.xml 包引入 <!--swagger2依赖--> <d ...

  6. MySQL主从复制报错及解决方法

    mysql> show slave status \G *************************** 1. row *************************** Slave_ ...

  7. hdu2083 简易版之最短距离 排序水题

    给出数轴n个坐标,求一个点到所有点距离总和最小.排序后最中间一个点或两个点之间就是最优 #include<stdio.h> #include<algorithm> using ...

  8. 剑指offer-int类型负数补码中1的个数-位操作

    在java中Interger类型表示的最大数是 System.out.println(Integer.MAX_VALUE);//打印最大整数:2147483647 这个最大整数的二进制表示,头部少了一 ...

  9. 剑指offer-青蛙变态跳台阶-全概率公式

  10. leetcode:Pascal's Triangle II【Python版】

    1.将tri初始化为[1],当rowIndex=0时,return的结果是:1,而题目要求应该是:[1],故将tri初始化为[[1]],返回结果设置为tri[0]即可满足要求: 2.最开始第二层循环是 ...