我同意@Alex Humphrey 的建议,即尝试使用 TraceSources。使用 TraceSources,您可以更好地控制日志记录/跟踪语句的执行方式。例如,你可以有这样的代码:
public class MyClass1
{
private static readonly TraceSource ts = new TraceSource("MyClass1");
public DoSomething(int x)
{
ts.TraceEvent(TraceEventType.Information, "In DoSomething. x = {0}", x);
}
}
public class MyClass2
{
private static readonly TraceSource ts = new TraceSource("MyClass2");
public DoSomething(int x)
{
ts.TraceEvent(TraceEventType.Information, "In DoSomething. x = {0}", x);
}
}
TraceSource.TraceEvent 调用将根据关联 Switch 的配置级别自动检查消息的级别 (TraceEventType.Information),并确定是否应实际写出消息。
通过为每种类型使用不同名称的 TraceSource,您可以单独控制这些类的日志记录。您可以启用 MyClass1 日志记录,也可以禁用它,或者您可以启用它但仅在消息级别 (TraceEventType) 大于某个值时才记录(可能只记录“警告”或更高)。同时,您可以打开或关闭 MyClass2 的登录或设置到一个级别,完全独立于 MyClass1。所有这些启用/禁用/级别的东西都发生在 app.config 文件中。
使用 app.config 文件,您还可以以相同的方式控制所有 TraceSource(或 TraceSource 组)。因此,您可以配置 MyClass1 和 MyClass2 都由同一个 Switch 控制。
如果您不想为每种类型使用不同名称的 TraceSource,您可以在每个类中创建相同的 TraceSource:
public class MyClass1
{
private static readonly TraceSource ts = new TraceSource("MyApplication");
public DoSomething(int x)
{
ts.TraceEvent(TraceEventType.Information, "In DoSomething. x = {0}", x);
}
}
public class MyClass2
{
private static readonly TraceSource ts = new TraceSource("MyApplication");
public DoSomething(int x)
{
ts.TraceEvent(TraceEventType.Information, "In DoSomething. x = {0}", x);
}
}
这样,您可以使应用程序中的所有日志记录发生在同一级别(或关闭或使用相同的 TraceListener,或其他)。
您还可以将应用程序的不同部分配置为可独立配置,而不必为每种类型定义唯一的 TraceSource 带来“麻烦”:
public class Analysis1
{
private static readonly TraceSource ts = new TraceSource("MyApplication.Analysis");
public DoSomething(int x)
{
ts.TraceEvent(TraceEventType.Information, "In DoSomething. x = {0}", x);
}
}
public class Analysis2
{
private static readonly TraceSource ts = new TraceSource("MyApplication.Analysis");
public DoSomething(int x)
{
ts.TraceEvent(TraceEventType.Information, "In DoSomething. x = {0}", x);
}
}
public class DataAccess1
{
private static readonly TraceSource ts = new TraceSource("MyApplication.DataAccess");
public DoSomething(int x)
{
ts.TraceEvent(TraceEventType.Information, "In DoSomething. x = {0}", x);
}
}
public class DataAccess2
{
private static readonly TraceSource ts = new TraceSource("MyApplication.DataAccess");
public DoSomething(int x)
{
ts.TraceEvent(TraceEventType.Information, "In DoSomething. x = {0}", x);
}
}
通过以这种方式检测您的类,您可以将应用日志的“数据访问”部分设置在一个级别,而将应用的“分析”部分记录在不同的级别(当然,您的应用中的一个或两个部分)可以配置为禁用日志记录)。
这是配置 TraceSources 和 TraceSwitches 的 app.config 文件的一部分:
<system.diagnostics>
<trace autoflush="true"></trace>
<sources>
<source name="MyClass1" switchName="switch1">
<listeners>
<remove name="Default"></remove>
<add name="console"></add>
</listeners>
</source>
<source name="MyClass2" switchName="switch2">
<listeners>
<remove name="Default"></remove>
<add name="console"></add>
</listeners>
</source>
</sources>
<switches>
<add name="switch1" value="Information"/>
<add name="switch2" value="Warning"/>
</switches>
<sharedListeners>
<add name="console"
type="System.Diagnostics.ConsoleTraceListener">
</add>
<add name="file"
type="System.Diagnostics.TextWriterTraceListener"
initializeData="trace.txt">
</add>
</sharedListeners>
</system.diagnostics>
如您所见,您可以配置单个 TraceSource 和单个 Switch,并且所有日志记录都将通过单个控制级别进行(即您可以关闭所有日志记录或使其在某个级别记录)。
或者,您可以定义多个 TraceSource(并在您的代码中引用相应的 TraceSource)和多个 Switch。 Switch 可以共享(即多个 TraceSource 可以使用同一个 Switch)。
最终,现在通过付出更多努力来使用 TraceSources 并在您的代码中引用适当命名的 TraceSources(即在逻辑上定义 TraceSource 名称,以便您可以对应用程序中的日志进行所需程度的控制),您从长远来看,将获得显着的灵活性。
这里有一些链接可能会在您继续使用 System.Diagnostics 时为您提供帮助:
.net Diagnostics best practices?
Logging best practices
What's the best approach to logging?
Does the .Net TraceSource/TraceListener framework have something similar to log4net's Formatters?
在我发布的链接中,经常讨论“最佳”日志框架。我并不是要说服你改变 System.Diagnostics。这些链接也往往包含有关使用 System.Diagnostics 的良好信息,这就是我发布它们的原因。
我发布的几个链接包含指向Ukadc.Diagnostics 的链接。这是一个非常酷的 System.Diagnostics 库插件,它添加了丰富的格式化功能,类似于您可以使用 log4net 和 NLog 执行的操作。该库对您的应用施加了仅配置依赖,而不是代码或引用依赖。