4.7 KiB
跟踪日志学习
从设计的角度来讲,跟踪诊断采用观察者模式。 应用程序利用 Source 将希望写入的日主以事件的形式发布出去,Listener 作为观察者在接收到日志之后执行一些过滤逻辑,并将活合的日志写入各自的输出渠道,不适合日志的则直接忽略。
每一条日志可以认为是对某一个事件的记录,所以日主大都有一个事件 ID。按照重要程度和反映问题的严重级别,我们赋予日志事件一个等级或者类型。 对于以 TaceSource 来说,日志事件等级或者类型通过 TraceEventType 枚举类型事示。除此之外,它还提供了一个 SourceLevels 类型的枚举来完成基于等级的日主事件过滤。
在利用 TraceSource 来记录日志时,我们需要做的就是根据名称和最低日志等级创建一个 TraceSource 对象,并将事件ID、事件类型和日志消息作为参数调用它的 TraceEvent 方法。
如下面的代码片段所示,创建一个 TraceSource对象,并将名称和最低日志等级分别设置为 Foobar 与 SourceLevels.All,后者决定了所有等级的日本都会地记录下来,我们针对每种事件类型记录了一条日志消息,而事件ID被设置为一个自增的整数
using System.Diagnostics;
var source = new TraceSource("TraceLog", SourceLevels.All);
var eventTypes = (TraceEventType[])Enum.GetValues(typeof(TraceEventType));
var eventId = 1;
Array.ForEach(eventTypes, it =>
{
source.TraceEvent(it, eventId++, $"这是一个 {eventTypes} 跟踪日志信息");
});
日志框架大都采用订阅发布模式来记录日志,但是上面的程序只涉及作为发布者的 TraceSource 对象,作为真正完成日志写入的订阅者(监听器)没有出现。 如果以Debug的方式运行程序,就会发现相应的日志输出到 Visual Studio 的输出窗口中,这是因为日志框架会默认注册一个类型为 DefaultTraceListener 的监听器,它将日志作为调试信息进行了输出。 TraceEventType 枚举类型共定义了10种事件类型,并且对应的枚举项是从高到低排列的(Critical 最高,Transfer最低),所以上面的演示程序会按照等级的高低输出10条日志。 如果只希望部分事件类型的日志被记录下来则应该如何做呢?一般来说,等级越高越应该被记录下来。创建 TraceSource对象时指定的 SourceLevels枚举表示需要被记录下来的最低日志等级。 如果只希望记录Warning等级以上的日志,则可以将演示程序进行如下改写。
using System.Diagnostics;
var source = new TraceSource("TraceLog", SourceLevels.Warning);
var eventTypes = (TraceEventType[])Enum.GetValues(typeof(TraceEventType));
var eventId = 1;
Array.ForEach(eventTypes, it =>
{
source.TraceEvent(it, eventId++, $"这是一个 {eventTypes} 跟踪日志信息");
});
由于将最低日志等级设置成 SourceLevels.Warning,当以Debug模式运行程序后,只有等级不低于 Warning(Warning、Error和Critical)的3条日志消息写入 Visual Studio 的调试输出窗口。
到目前为止,我们都在使用系统默认注册的 DefaultTraceListener 监听器来完成对日志消息的输出。 DefaultTraceListener 除了调用 Debug 的 Write 方法将指定的消息作为调试信息进行输出,它还支持物理文件的输出方式。 如果需要,则还可以针对期望的输出渠道注册自定义的 TraceListerner.
public class ConsoleTraceListener : TraceListener
{
public override void Write(string? message)
{
Console.Write(message);
}
public override void WriteLine(string? message)
{
Console.WriteLine(message);
}
}
在上面的代码片段中,,我们通过继承抽象类 Tacetistener 自定义了一个 ConsoleListener 类型。 它通过重写的 Write 方法和 WriteLine 方法将分发给它的日志输出到控制台上。 这个自定义的ConsoleListener可以通过如下方式来使用。
using System.Diagnostics;
var source = new TraceSource("ConsoleTraceLog", SourceLevels.All);
source.Listeners.Add(new ConsoleListener());
var eventTypes = (TraceEventType[])Enum.GetValues(typeof(TraceEventType));
var enentId = 1;
Array.ForEach(eventTypes, it =>
{
source.TraceEvent(it, enentId++, $"这是一个 {eventTypes} 跟踪日志信息");
});
如上面的代码片段所示,TraceSource 对象的 Listeners 属性维护了一组注册的 TraceListener 对象。我们只需要将创建的 ConsoleListener 对象添加到这个列表。 由于这个针对控制台的 TraceListener 的存在,所以满足过滤条件的3条日志消息输出到控制台上。