Trace、Debug和TraceSource的使用以及日志设计

 

.NET Framework 命名空间 System.Diagnostics 包含用于跟踪执行流程的 Trace、Debug 和 TraceSource 类,以及用于分析代码的 Process、EventLog 和 PerformanceCounter 类。

跟踪是一种在应用程序运行时监视其执行情况的方式。当开发 .NET Framework 应用程序时,可以在其中添加跟踪和调试检测功能,并且在开发应用程序时和部署应用程序后,都可以使用该检测功能。利用 Trace 和 Debug 类,可以将有关错误和应用程序执行的信息记录到日志、文本文件或其他设备中,以便在随后进行分析。

下面列出了六个写入跟踪信息的 Debug Members 和 Trace 方法。

Assert:指定的文本;如果未指定任何文本,则为“调用堆栈”。只有当 Assert 语句中以参数形式指定的条件为 false 时,才会写入输出。

Fail:指定的文本;如果未指定任何文本,则为“调用堆栈”。

Write:指定的文本。

WriteIf:如果满足 WriteIf 语句中以参数形式指定的条件,则为指定的文本。

WriteLine:指定的文本和一个回车。

WriteLineIf:如果满足 WriteLineIf 语句中以参数形式指定的条件,则为指定的文本和一个回车。

1:Trace 和 Debug区别

Trace 和 Debug 类基本相同,不同的只是 Trace 类的过程和函数默认为编译成发布版本。

2:什么是Listeners

Listenters属性,它是TraceListenerCollection类型(TraceSource类和TraceListener类),给类属性控制跟踪信息输出的方向,可以是控制台(add(TextWriterTraceListener(newConsole.Out))),文件(add(TextWriterTraceListener(newIO.File.CreateText(“output.txt”))等。Listenters集合中的成员包括TextWriterTraceListener,DefaultTraceListener,EventLogTraceListener,WebPageTraceListener等。而TextWriterTraceListener的子类又有ConsoleTraceListener, DelimitedListTraceListener,XmlWriterTraceListener,EventSchemaTraceListener。

您可以通过实现您自己的侦听器来生成自定义的结果。 所有自定义侦听器都应支持文章开头表中的六个方法。

以下的例子说明输出的消息将会在控制台、TXT文件以及系统日志中均被记录。

TextWriterTraceListener tr1 = new TextWriterTraceListener(System.Console.Out);

Debug.Listeners.Add(tr1);

TextWriterTraceListener tr2 = newTextWriterTraceListener(System.IO.File.CreateText("output.txt"));

Debug.Listeners.Add(tr2);

EventLogTraceListener tr3 = newEventLogTraceListener();

Debug.Listeners.Add(tr3);

3:跟踪开关

除了指定Listener外,要控制消息是否被输出,还需要指定跟踪开关。跟踪开关用于启用、禁用和筛选跟踪输出。

Framework 中提供了三种类型的跟踪开关:BooleanSwitch 类、TraceSwitch 类和 SourceSwitch 类。BooleanSwitch是最简单的跟踪开关,可以指定是否输出消息。TraceSwitch 和 SourceSwitch 类用于为特定的跟踪级别启用跟踪开关,以便显示为该级别及其下的所有级别指定的 Trace 或 TraceSource 消息。

3.1:使用BooleanSwitch开关

以下是使用BooleanSwitch的例子:

TextWriterTraceListenertr1 = newTextWriterTraceListener(System.Console.Out);

Debug.Listeners.Add(tr1);

TextWriterTraceListenertr2 = new TextWriterTraceListener(System.IO.File.CreateText("output.txt"));

Debug.Listeners.Add(tr2);

EventLogTraceListenertr3 = new EventLogTraceListener();

Debug.Listeners.Add(tr3);

bool someBizCondition = true;

BooleanSwitch bs = new BooleanSwitch("DataMessageSwitch", "DataMessageSwitch des");

bs.Enabled = true;

Debug.WriteLineIf(someBizCondition, "log....");

Debug.Flush();

bs.Enabled设置为true或者false,并不会使程序自动决定是否输出信息。

如果不使用代码方式,而是使用配置文件的方式,是在<configuration> 标记之后,但在</configuration> 标记之前添加相应的 XML 来配置您的开关。如下:

<system.diagnostics>

<switches>

<add name="DataMessagesSwitch" value="1" />

</switches>

</system.diagnostics>

3.2:使用TraceSwitch开关

TraceSwitch类可以通过使用跟踪开关来筛选消息,通过Level属性来获取或设置开关级别。0、1、2、3 和 4 分别对应于 OffErrorWarningInfo 和 Verbose。任何大于 4 的数字都会被当作 Verbose,任何小于零的数字都会被当作 Off

以下的例子,用代码的方式来演示使用TraceSwitch来设置跟踪开关:

TextWriterTraceListenertr1 = new TextWriterTraceListener(System.Console.Out);

Debug.Listeners.Add(tr1);

TextWriterTraceListenertr2 = newTextWriterTraceListener(System.IO.File.CreateText("output.txt"));

Debug.Listeners.Add(tr2);

EventLogTraceListenertr3 = new EventLogTraceListener();

Debug.Listeners.Add(tr3);

bool someBizCondition = true;

TraceSwitch ts = new TraceSwitch("mySwitch", "in the Config file");

ts.Level =TraceLevel.Verbose;

Debug.WriteLineIf(ts.TraceError&& someBizCondition, "Error!!!");

Debug.WriteLineIf(ts.TraceWarning && someBizCondition, "Warning!!!");

Debug.WriteLineIf(ts.TraceInfo && someBizCondition, "Info!!!");

Debug.WriteLineIf(ts.TraceVerbose&& someBizCondition, "Verbose!!!");

Debug.Flush();

使用XML来配置,如下:

<system.diagnostics>

<switches>

<add name="mySwitch" value="1" />

</switches>

</system.diagnostics>

4:使用TraceSource代替Trace和Debug

从FRAMEWORK2.0开始,就不建议使用Trace和Debug了,而改而用TraceSouce。TraceSource 旨在用作增强的跟踪系统,并且可代替较旧的 Trace 和 Debug 跟踪类的静态方法使用。熟悉的 Trace 和 Debug 类仍然存在,不过建议的做法是使用 TraceSource 类进行跟踪。

下面的例子演示使用代码来实现消息的输出:

private static TraceSource mySource = new TraceSource("TraceSourceApp");

static void Main(string[] args)

{

mySource.Switch = new SourceSwitch("sourceSwitch", "Error");

mySource.Listeners.Remove("Default");

TextWriterTraceListenertextListener =  new TextWriterTraceListener("myListener.log");

textListener.TraceOutputOptions = TraceOptions.DateTime | TraceOptions.Callstack;

textListener.Filter = new EventTypeFilter(SourceLevels.Error);

mySource.Listeners.Add(textListener);

ConsoleTraceListenerconsole = new ConsoleTraceListener(false);

console.Filter = newEventTypeFilter(SourceLevels.Information);

console.Name = "console";

mySource.Listeners.Add(console);

Activity1();

// Set the filter settings for the

// console trace listener.

mySource.Listeners["console"].Filter =  new EventTypeFilter(SourceLevels.Critical);

Activity2();

// Allow the trace source to send messagesto

// listeners for all event types.

mySource.Switch.Level = SourceLevels.All;

// Change the filter settings for theconsole trace listener.

mySource.Listeners["console"].Filter = newEventTypeFilter(SourceLevels.Information);

Activity3();

mySource.Close();

return;

}

static void Activity1()

{

mySource.TraceEvent(TraceEventType.Error, 1, "Error message.");

mySource.TraceEvent(TraceEventType.Warning, 2, "Warning message.");

}

static void Activity2()

{

mySource.TraceEvent(TraceEventType.Critical, 3, "Critical message.");

mySource.TraceInformation("Informational message.");

}

static void Activity3()

{

mySource.TraceEvent(TraceEventType.Error, 4, "Error message.");

mySource.TraceInformation("Informational message.");

}

以上代码,如果使用配置文件的方式实现,如下:

<system.diagnostics>

<sources>

<source name="TraceSourceApp" switchName="sourceSwitch" switchType="System.Diagnostics.SourceSwitch">

<listeners>

<add name="console" type="System.Diagnostics.ConsoleTraceListener">

<filter type="System.Diagnostics.EventTypeFilter" initializeData="Warning"/>

</add>

<add name="myListener" type="System.Diagnostics.TextWriterTraceListener" initializeData="myListener.log"

traceOutputOptions="Callstack">

<filter type="System.Diagnostics.EventTypeFilter" initializeData="Error"></filter>

</add>

<remove name="Default"/>

</listeners>

</source>

</sources>

<switches>

<add name="sourceSwitch" value="Warning"/>

</switches>

</system.diagnostics>

配置文件实现的对应代码部分为:

private static TraceSource mySource = new TraceSource("TraceSourceApp");

static void Main(string[] args)

{

Activity1();

Activity2();

Activity3();

mySource.Close();

return;

}

static void Activity1()

{

mySource.TraceEvent(TraceEventType.Error, 1, "Error message.");

mySource.TraceEvent(TraceEventType.Warning, 2, "Warning message.");

}

static void Activity2()

{

mySource.TraceEvent(TraceEventType.Critical, 3, "Critical message.");

mySource.TraceInformation("Informational message.");

}

static void Activity3()

{

mySource.TraceEvent(TraceEventType.Error, 4, "Error message.");

mySource.TraceInformation("Informational message.");

}

5:设计一个日志系统

有了以上的知识之后,我们就可以来设计一个应用程序的日志系统(是的,我们不在需要LOG4NET)。我们来假设这个日志系统最基础的功能:

1、以日期来创建日志名,以免历史日志全部写入一个文件中去;

2、可以配置想要输出的日志类别,如Warning或者Error等;

3、可以配置想要的日志内容:如StackTrace或者错误信息等;

思路:

1、在应用程序启动代码中,设置文件名。因为文件名要根据日期动态生成,所以不能使用配置文件;

2、其它配置可以配置文件实现;

3、DO IT;

6:关于EventLog

EventLog 类提供了C#与Windows事件日志交互的功能。 很多时候我们可以把日志写到windows事件日志中.

说明:EventLog 使您可以访问或自定义Windows 事件日志。通过C#提供的EventLog类,可以读取现有日志,向日志中写入项,创建或删除事件源,删除日志,以及响应日志项。也可在创建事件源时创建新日志。

打开Windows事件日志的方法

右击我的电脑->管理->事件日志就可以了.

CreateEventSource
已重载。 建立一个能够将事件信息写入到系统的特定日志中的应用程序。

Delete
已重载。 移除日志资源。

DeleteEventSource
已重载。 从事件日志中移除应用程序的事件源注册。

SourceExist
已重载。 在计算机的注册表中搜索给定的事件源。

WriteEntry
已重载。 将项写入事件日志。

WriteEvent
已重载。 向事件日志写入本地化事件项。

为了能够使用EventLog,我们需要引入usingSystem.Diagnostics命令空间.下面两个方法在你捕获到异常或其他时可以调用.

privatevoid WriteError(string sText)
{
if (!EventLog.SourceExists(sEventSource))
EventLog.CreateEventSource(sEventSource, sEventLog);
EventLog.WriteEntry(sEventSource,sText, EventLogEntryType.Error);

}

privatevoid WriteInfo(string sText)
{
if (!EventLog.SourceExists(sEventSource))
EventLog.CreateEventSource(sEventSource, sEventLog);
EventLog.WriteEntry(sEventSource,sText, EventLogEntryType.Information); 
}

下面是一个简单使用的例子.

try

{

//操作

}

catch(Excepetionex)

{

WriteError(ex.message);

}

这样我们就可以成功的写入到Windows事件中..:)

EventLog(事件日志)的读写方法

在C#中读写EventLog(事件日志)挺简单的,代码量也比较小。

1.加入System.DiagnosticsName Space;

usingSystem.Diagnostics;

2.声明一个EventLog类的实例。

EventLogeventLog;
eventLog=newEventLog("TestEvent",".","mySource");

"TestEvent"是建立一个新的EventLog名,
".": 表示本机
"mySource": 源名
如果以上不设参数,就默认为"Application"

设好以后,就可以读写了。

写:

eventLog.Source="mySource";
eventLog.WriteEntry("Log text");
MessageBox.Show("Write Complete!")

读:

lstEvent.Items.Clear();
eventLog.Log="TestEvent";
foreach(EventLogEntry eventlogEntry in eventLog.Entries)
{
lstEvent.Items.Add(eventlogEntry.Message);
}

关于EventLog更多内容,可参考:http://msdn.microsoft.com/zh-cn/library/aaaxk5bx(VS.80).aspx

7: 如何创建和初始化跟踪源

使用配置文件创建和初始化跟踪源

1.      Create a VisualStudio console application project and replace the supplied code with thefollowing code.

using System;

using System.Diagnostics;

class TraceTest

{

private static TraceSource mySource =

new TraceSource("TraceSourceApp");

static void Main(string[] args)

{

// Issue an error and a warningmessage. Only the error message

// should be logged.

Activity1();

// Save the original settings from theconfiguration file.

EventTypeFilter configFilter =

(EventTypeFilter)mySource.Listeners["console"].Filter;

// Create a new event type filter thatensures

// warning messages will be written.

mySource.Listeners["console"].Filter =

newEventTypeFilter(SourceLevels.Warning);

// Allow the trace source to sendmessages to listeners

// for all event types. This statementwill override

// any settings in the configurationfile.

// If you do not change the switchlevel, the event filter

// changes have no effect.

mySource.Switch.Level = SourceLevels.All;

// Issue a warning and a criticalmessage. Both should be logged.

Activity2();

// Restore the original filtersettings.

mySource.Listeners["console"].Filter = configFilter;

Activity3();

mySource.Close();

return;

}

static void Activity1()

{

mySource.TraceEvent(TraceEventType.Error, 1,

"Error message.");

mySource.TraceEvent(TraceEventType.Warning, 2,

"Warning message.");

}

static void Activity2()

{

mySource.TraceEvent(TraceEventType.Critical, 3,

"Critical message.");

mySource.TraceEvent(TraceEventType.Warning, 2,

"Warning message.");

}

static void Activity3()

{

mySource.TraceEvent(TraceEventType.Error, 4,

"Error message.");

mySource.TraceInformation("Informationalmessage.");

}

}

2.      Add an applicationconfiguration file to the project to initialize the trace source named TraceSourceApp in the code examplein step 1.

3.      初始化控制台跟踪侦听器和文本编写器跟踪侦听器的跟踪源的步骤 1 中创建以下设置替换默认的配置文件设置。

复制

<configuration>

<system.diagnostics>

<sources>

<sourcename="TraceSourceApp"

switchName="sourceSwitch"

switchType="System.Diagnostics.SourceSwitch">

<listeners>

<add name="console"

type="System.Diagnostics.ConsoleTraceListener">

<filtertype="System.Diagnostics.EventTypeFilter"

initializeData="Error"/>

</add>

<addname="myListener"/>

<removename="Default"/>

</listeners>

</source>

</sources>

<switches>

<add name="sourceSwitch"value="Error"/>

</switches>

<sharedListeners>

<add name="myListener"

type="System.Diagnostics.TextWriterTraceListener"

initializeData="myListener.log">

<filter type="System.Diagnostics.EventTypeFilter"

initializeData="Error"/>

</add>

</sharedListeners>

</system.diagnostics>

</configuration>

除了配置跟踪侦听器,配置文件的两个侦听器创建筛选器,并创建一个源开关的跟踪源。其中演示了两种添加跟踪侦听器的技术:将侦听器直接添加到跟踪源,以及将侦听器添加到共享的侦听器集合,然后按名称将它添加到跟踪源。为这两个侦听器标识的筛选器用不同的源级别进行初始化。这样导致某些消息仅由其中一个侦听器编写。

配置文件在初始化应用程序时初始化跟踪源的设置。应用程序可以动态更改配置文件设置的属性,以重写用户指定的任何设置。例如对于您可能希望确保重要的邮件始终发送到一个文本文件而不考虑当前的配置设置。该代码示例演示如何重写配置文件设置,以确保重要邮件的跟踪侦听器的输出。

在应用程序执行时更改配置文件设置不会更改初始设置。若要将该设置必须重新启动该应用程序或以编程方式刷新应用程序,通过使用Trace.Refresh方法。

不使用配置文件初始化跟踪源、侦听器和筛选器

·              使用下面的代码示例不使用配置文件启用跟踪源跟踪。这不是建议的做法,但可能在其中您不想依赖于配置文件,以确保跟踪的情况。

using System;

using System.Diagnostics;

using System.Threading;

namespace TraceSourceApp

{

class Program

{

private static TraceSource mySource =

new TraceSource("TraceSourceApp");

static void Main(string[] args)

{

mySource.Switch = new SourceSwitch("sourceSwitch", "Error");

mySource.Listeners.Remove("Default");

TextWriterTraceListenertextListener =

new TextWriterTraceListener("myListener.log");

ConsoleTraceListener console =

new ConsoleTraceListener(false);

console.Filter =

newEventTypeFilter(SourceLevels.Information);

console.Name = "console";

textListener.Filter =

new EventTypeFilter(SourceLevels.Error);

mySource.Listeners.Add(console);

mySource.Listeners.Add(textListener);

Activity1();

// Allow the trace source to sendmessages to

// listeners for all event types.Currently only

// error messages or higher go to thelisteners.

// Messages must get past the sourceswitch to

// get to the listeners, regardless ofthe settings

// for the listeners.

mySource.Switch.Level =SourceLevels.All;

// Set the filter settings for the

// console trace listener.

mySource.Listeners["console"].Filter =

newEventTypeFilter(SourceLevels.Critical);

Activity2();

// Change the filter settings for theconsole trace listener.

mySource.Listeners["console"].Filter =

new EventTypeFilter(SourceLevels.Information);

Activity3();

mySource.Close();

return;

}

static void Activity1()

{

mySource.TraceEvent(TraceEventType.Error, 1,

"Error message.");

mySource.TraceEvent(TraceEventType.Warning,2,

"Warning message.");

}

static void Activity2()

{

mySource.TraceEvent(TraceEventType.Critical, 3,

"Critical message.");

mySource.TraceInformation("Informationalmessage.");

}

static void Activity3()

{

mySource.TraceEvent(TraceEventType.Error, 4,

"Error message.");

mySource.TraceInformation("Informationalmessage.");

}

}

}

纸上得来终觉浅,绝知此事要躬行。

C#学习笔记14——TRACE、DEBUG和TRACESOURCE的使用以及日志设计的更多相关文章

  1. 【转】 C#学习笔记14——Trace、Debug和TraceSource的使用以及日志设计

    [转] C#学习笔记14——Trace.Debug和TraceSource的使用以及日志设计 Trace.Debug和TraceSource的使用以及日志设计   .NET Framework 命名空 ...

  2. Trace、Debug和TraceSource的使用以及日志设计 .

    [-] Trace 和 Debug区别 什么是Listeners 跟踪开关 使用BooleanSwitch开关 使用TraceSwitch开关 使用TraceSource代替Trace和Debug 设 ...

  3. mybatis学习笔记(14)-查询缓存之中的一个级缓存

    mybatis学习笔记(14)-查询缓存之中的一个级缓存 标签: mybatis mybatis学习笔记14-查询缓存之中的一个级缓存 查询缓存 一级缓存 一级缓存工作原理 一级缓存測试 一级缓存应用 ...

  4. 并发编程学习笔记(14)----ThreadPoolExecutor(线程池)的使用及原理

    1. 概述 1.1 什么是线程池 与jdbc连接池类似,在创建线程池或销毁线程时,会消耗大量的系统资源,因此在java中提出了线程池的概念,预先创建好固定数量的线程,当有任务需要线程去执行时,不用再去 ...

  5. Ext.Net学习笔记14:Ext.Net GridPanel Grouping用法

    Ext.Net学习笔记14:Ext.Net GridPanel Grouping用法 Ext.Net GridPanel可以进行Group操作,例如: 如何启用Grouping功能呢?只需要在Grid ...

  6. SQL反模式学习笔记14 关于Null值的使用

    目标:辨别并使用Null值 反模式:将Null值作为普通的值,反之亦然 1.在表达式中使用Null: Null值与空字符串是不一样的,Null值参与任何的加.减.乘.除等其他运算,结果都是Null: ...

  7. golang学习笔记14 golang substring 截取字符串

    golang学习笔记14 golang substring 截取字符串golang 没有java那样的substring函数,但支持直接根据 index 截取字符串mystr := "hel ...

  8. Python3+Selenium3+webdriver学习笔记14(等待判断 鼠标事件 )

    !/usr/bin/env python -*- coding:utf-8 -*-'''Selenium3+webdriver学习笔记14(等待判断 鼠标事件 )'''from selenium im ...

  9. [C++学习笔记14]动态创建对象(定义静态方法实现在map查找具体类名对应的创建函数,并返回函数指针,map真是一个万能类)good

    [C++学习笔记14]动态创建对象   C#/Java中的反射机制 动态获取类型信息(方法与属性) 动态创建对象 动态调用对象的方法 动态操作对象的属性 前提:需要给每个类添加元数据 动态创建对象 实 ...

随机推荐

  1. SQL注入--SQLMap过WAF

    单引号被过滤情况: 空格.等号未被过滤情况: select被过滤情况: 以此类推,当sqlmap注入出现问题时,比如不出数据,就要检查对应的关键词是否被过滤. 比如空格被过滤可以使用space2com ...

  2. 如何清空css 的默认边距

    在网页开发中,html的元素,有部分元素默认是有内外边距的,例如body 元素,是有默认边距的 所以在通常情况下,我们都要先清空元素的内外边距:使用通配符选择器* 清空元素的内边距和外边距 ;; } ...

  3. Dashboard安装配置

    获取dashboard yaml文件 curl -O https://raw.githubusercontent.com/kubernetes/dashboard/master/src/deploy/ ...

  4. MySQL InnoDB 事务实现过程相关内容的概述

    MySQL事务的实现涉及到redo和undo以及purge,redo是保证事务的原子性和持久性:undo是保证事务的一致性(一致性读和多版本并发控制):purge清理undo表空间背景知识,对于Inn ...

  5. Mongodb到mysql数据库的数据迁移(Java,Windows)

    运行环境为windows 测试过260万的数据表,迁移大概要10分钟左右,当然肯定和网络,字段大小什么的有关系. 遇到的坑和注意点都用紫色标记了(对,就是我大乃团的高冷紫--Nogizaka 46) ...

  6. 实现对Java配置文件Properties的读取、写入与更新操作

    /** * 实现对Java配置文件Properties的读取.写入与更新操作 */ package test; import java.io.BufferedInputStream; import j ...

  7. Unity shader 官网文档全方位学习(二)

    摘要: 这篇文章主要介绍Lighting model及自定义Lighting model 上文咱们学了surface shader.这玩意在开始的时候啊,在定义哪个函数处理surface时用一定要指定 ...

  8. linux 下导出oracle数据库

    #变更用户su - oracle <<EOF#添加用户名/密码,目标文件地址和文件名 ,保存记录日志地址/文件名  full=y表示数据库全部导出,默认导出连接数据库的用户数据库对象 ex ...

  9. Python-cookie,session

    前言: 其实cookie这个词对于我们并不陌生,经常就听见说网页加载慢了,清理一下浏览器的缓存和cookie,cookie就是一个特殊数据验证类型,一般存储在客户端的浏览器上面,比如我们登录某宝后,下 ...

  10. 大数据入门到精通19--mysql 数据导入到hive数据中

    一.正常按照数据库和表导入 \\前面介绍了通过底层文件得形式导入到hive的表中,或者直接导入到hdfs中,\\现在介绍通过hive的database和table命令来从上层操作.sqoop impo ...