diff --git a/LogStudy.TraceLog/CustomTraceListener.cs b/LogStudy.TraceLog/CustomTraceListener.cs
new file mode 100644
index 0000000..c98b14e
--- /dev/null
+++ b/LogStudy.TraceLog/CustomTraceListener.cs
@@ -0,0 +1,22 @@
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace LogStudy.TraceLog
+{
+    public class CustomTraceListener : TraceListener
+    {
+        public override void Write(string? message)
+        {
+           Console.Write(message);
+        }
+
+        public override void WriteLine(string? message)
+        {
+            Console.WriteLine(message);
+        }
+    }
+}
diff --git a/LogStudy.TraceLog/Program.cs b/LogStudy.TraceLog/Program.cs
index 1bc52a6..040e011 100644
--- a/LogStudy.TraceLog/Program.cs
+++ b/LogStudy.TraceLog/Program.cs
@@ -1 +1,41 @@
-Console.WriteLine("Hello, World!");
+using System.Diagnostics;
+using LogStudy.TraceLog;
+
+Console.WriteLine("======== 跟踪日志学习 ========");
+
+//UseDefaultListener();
+
+UseCustomListener();
+
+//使用默认监听器
+void UseDefaultListener()
+{
+	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} 跟踪日志信息");
+	});
+}
+
+//使用自定义监听器
+void UseCustomListener()
+{
+	var source = new TraceSource("ConsoleListenerTraceLog", SourceLevels.All);
+	source.Listeners.Clear();
+	source.Listeners.Add(new DefaultTraceListener() { LogFileName="DefaultListenerTrace.log"});
+	source.Listeners.Add(new CustomTraceListener() { IndentSize=8,IndentLevel=3}) ;
+
+	var eventTypes = (TraceEventType[])Enum.GetValues(typeof(TraceEventType));
+	var eventId = 1;
+
+	Array.ForEach(eventTypes, it =>
+	{
+		source.TraceEvent(it, eventId++, $"这是一个 {it} 跟踪日志信息");
+	});
+}
+
+
+
diff --git a/LogStudy.TraceLog/study.md b/LogStudy.TraceLog/study.md
new file mode 100644
index 0000000..5218465
--- /dev/null
+++ b/LogStudy.TraceLog/study.md
@@ -0,0 +1,85 @@
+# 跟踪日志学习
+从设计的角度来讲,跟踪诊断采用观察者模式。
+应用程序利用 Source 将希望写入的日主以事件的形式发布出去,Listener 作为观察者在接收到日志之后执行一些过滤逻辑,并将活合的日志写入各自的输出渠道,不适合日志的则直接忽略。
+
+
+每一条日志可以认为是对某一个事件的记录,所以日主大都有一个事件 ID。按照重要程度和反映问题的严重级别,我们赋予日志事件一个等级或者类型。
+对于以 TaceSource 来说,日志事件等级或者类型通过 TraceEventType 枚举类型事示。除此之外,它还提供了一个 SourceLevels 类型的枚举来完成基于等级的日主事件过滤。
+
+在利用 TraceSource 来记录日志时,我们需要做的就是根据名称和最低日志等级创建一个 TraceSource 对象,并将事件ID、事件类型和日志消息作为参数调用它的 TraceEvent 方法。
+
+如下面的代码片段所示,创建一个 TraceSource对象,并将名称和最低日志等级分别设置为 Foobar 与 SourceLevels.All,后者决定了所有等级的日本都会地记录下来,我们针对每种事件类型记录了一条日志消息,而事件ID被设置为一个自增的整数
+```csharp
+
+	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等级以上的日志,则可以将演示程序进行如下改写。
+
+```csharp
+	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.
+
+```csharp
+	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可以通过如下方式来使用。
+
+```csharp
+	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条日志消息输出到控制台上。
diff --git a/LogStudy.sln b/LogStudy.sln
index e3b5919..0c01e79 100644
--- a/LogStudy.sln
+++ b/LogStudy.sln
@@ -6,6 +6,9 @@ MinimumVisualStudioVersion = 10.0.40219.1
 Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LogStudy.WebApp", "LogStudy.WebApp\LogStudy.WebApp.csproj", "{8516CD13-0513-46AF-897F-05FCD66933A2}"
 EndProject
 Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "DebugLog", "DebugLog", "{2319453B-2895-48E4-99A3-123ADED51280}"
+	ProjectSection(SolutionItems) = preProject
+		README.md = README.md
+	EndProjectSection
 EndProject
 Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "TraceLog", "TraceLog", "{353B9475-1064-473D-B3EE-CF3A9BBA4102}"
 EndProject
@@ -13,13 +16,13 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "EventLog", "EventLog", "{78
 EndProject
 Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "DiagnosticLog", "DiagnosticLog", "{D91AB187-F922-47DE-87ED-D3785F4E8D7B}"
 EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LogStudy.DebugLog", "LogStudy.DebugLog\LogStudy.DebugLog.csproj", "{A4CF5770-2855-44C7-B9DA-27332670D03D}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LogStudy.DebugLog", "LogStudy.DebugLog\LogStudy.DebugLog.csproj", "{A4CF5770-2855-44C7-B9DA-27332670D03D}"
 EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LogStudy.TraceLog", "LogStudy.TraceLog\LogStudy.TraceLog.csproj", "{3D1FA013-7BAC-4D62-B35B-8B444DB7FE8C}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LogStudy.TraceLog", "LogStudy.TraceLog\LogStudy.TraceLog.csproj", "{3D1FA013-7BAC-4D62-B35B-8B444DB7FE8C}"
 EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LogStudy.EventLog", "LogStudy.EventLog\LogStudy.EventLog.csproj", "{372EA389-4C91-4B05-8270-86788D48F45D}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LogStudy.EventLog", "LogStudy.EventLog\LogStudy.EventLog.csproj", "{372EA389-4C91-4B05-8270-86788D48F45D}"
 EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LogStudy.DiagnosticLog", "LogStudy.DiagnosticLog\LogStudy.DiagnosticLog.csproj", "{73AC3F84-DC11-4F53-A729-0EA09E124E6E}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LogStudy.DiagnosticLog", "LogStudy.DiagnosticLog\LogStudy.DiagnosticLog.csproj", "{73AC3F84-DC11-4F53-A729-0EA09E124E6E}"
 EndProject
 Global
 	GlobalSection(SolutionConfigurationPlatforms) = preSolution
diff --git a/PerfView/PerfView.exe b/PerfView/PerfView.exe
new file mode 100644
index 0000000..eb6ec85
Binary files /dev/null and b/PerfView/PerfView.exe differ