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

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

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

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

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

那么就意味着,你的所有项目都必须引用这个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

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文件的位置

复制代码
    public class MyTraceListener : TraceListener
    {
        public string FilePath { get; private set; }

public MyTraceListener(string filepath)
        {
            FilePath = filepath;
        }

public override void Write(string message)
        {
            File.AppendAllText(FilePath, message);
        }

public override void WriteLine(string message)
        {
            File.AppendAllText(FilePath, DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss    ") + message + Environment.NewLine);
        }

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);
        }
    }
复制代码
配置文件
复制代码
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <system.diagnostics>
    <trace autoflush="false" indentsize="4">
      <listeners>
        <clear /><!--清除默认监听器-->
        <!--添加自定义监听器 initializeData 就是初始化参数-->
        <add name="MyTraceListener" type="MyLog.MyTraceListener, MyLog, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" initializeData="d:\1.log" />
      </listeners>
    </trace>
    <switches>
      <!--这里可以设定监听级别,可以设置Error,Warning,Info或者留空-->
      <add name="MyTraceListener" value="Error" />
    </switches>
  </system.diagnostics>
</configuration>
复制代码
其中type参数可以这样获得

typeof(MyLog.MyTraceListener).AssemblyQualifiedName
Version,Culture,PublicKeyToken 也可以忽略

测试一下

没有任何问题

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

说完了...拜拜~~

代码下载
LogDemo.rar

利用C#自带组件强壮程序日志相关推荐

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

    文章目录 利用Linux自带的logrotate管理日志 1. logrotate简介 2. logrotate配置参数 3. nginx日志切割实例 4. 其他配置示例 利用Linux自带的logr ...

  2. 利用MATLAB中 MuPADNotebook组件将程序语言表达式转为数学表达式

    前言 在论文写作或数模竞赛中,常需要把已经在程序中列写好的方程或表达式转为数学表达式,呈现在论文或其他书面文本中,利用MATLAB中 MuPADNotebook组件可以在保证高转换准确度的同时,提高我 ...

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

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

  4. 优雅地记录Python程序日志2:模块组件化日志记录器

    本文摘自:https://zhuanlan.zhihu.com/p/32043593 本篇将会涉及: logging的各个模块化组件 构建一个组件化的日志器 logging的模块组件化 在上一篇文章中 ...

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

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

  6. 利用C#线程窗口调试多线程程序

    从网上的资料判断,调试多线程程序似乎就一下3种方法. 1.在日志的某个地方写日志文件. 优点:不会干扰程序的执行,特别是对网络的多线程通信. 缺点:每次都需要打开日志文件以查看进程运行的信息. 2.利 ...

  7. LINE分享android利用系统自带分享实现LINE分享功能

    android利用系统自带分享实现分享功能之LINE分享 最近公司向海外发展,提出了一个国外主流的社交APP分享需求.原来我使用的是第三方分享工具,但是太鸡肋,国内的APP支持的还是不错的,但是国外支 ...

  8. Ext Js MVC系列二 利用Application和Viewport进行应用程序初始化和页面布局

    通过上一篇我们已经对Ext js MVC框架开发有了一个大概的了解,这一篇将利用Application和Viewport进行应用程序的初始化和页面布局.我想从以下几方面来进行总结. 1,通过Ext.L ...

  9. Android利用温度传感器实现带动画效果的电子温度计

    概述 Android利用温度传感器实现带动画效果的电子温度计. 详细 一.准备工作 需要准备一部带有温度传感器的安卓手机,或者使用有温度传感器的模拟器. 二.程序实现 1.需要截图程序结构 2.实现思 ...

最新文章

  1. 000-SQL Server
  2. P2647 最大收益
  3. IPhone鸿蒙系统,iPhone 13外观再次确认,鸿蒙系统也将临世,神仙又打架
  4. javaweb学习总结(十):HttpServletRequest对象(一)
  5. python ide如何运行_ide - 如何运行Python程序?
  6. Hibernate注解方式实现1-1双向关联
  7. mysql 数据目录更换_更改Mysql数据目录,这个坑你可能也趟过~
  8. 全球嵌入式技术与 IoT 产业回顾与展望 | 技术头条
  9. DSP-28027笔记
  10. 图片信息用浏览器显示:data:image/png;base64,+图片内容
  11. linux夏令时配置文件,Linux中有关时区及夏令时设置(TZ环境变量)
  12. java自动填充_java 如何自动填充网页上的用户名和密码?
  13. 使用按键精灵自动截图并保存重命名
  14. 使用HTML及简单的JavaScript脚本制作一个点名器
  15. JavaScript 遍历数组 翻转数组与冒泡排序法
  16. ElementUI分页与增删改合并
  17. 【微信小程序】微信小程序获取当日以后的时间日期天数、星期
  18. 十次方项目开发系列【8】:对评论点赞功能开发 Redis的配置和使用
  19. 武汉牛批的互联网公司基本都在这了~
  20. java k均值相异度计算_K-NN算法与K-Means算法的原理与区别(附带源码示例)

热门文章

  1. 信息学奥赛一本通 1191:流感传染 | OpenJudge NOI 2.3 6262:流感传染
  2. 信息学奥赛一本通 1958:【12NOIP普及组】寻宝 | OpenJudge NOI 1.12 06 | 洛谷 P1076 [NOIP2012 普及组] 寻宝
  3. 信息学奥赛一本通(1162:字符串逆序)
  4. 树形结构 —— 树与二叉树 —— 树的重心
  5. 2019 年“浪潮杯”第十届山东省 ACM 省赛总结
  6. 图论 —— 图的连通性 —— Tarjan 缩点
  7. 信息学奥赛一本通C++语言——1009:带余除法
  8. 45 MM配置-采购-条件-定价过程-定义定价计算方案
  9. OpenVINO 中的BFYX解释
  10. PspNet在MMsegmentation框架下成功训练Pascal VOC2012数据集及踩坑实录