3

我写了一个从 System.Diagnostics.TraceListener 派生的 Log 类,就像这样

public class Log : TraceListener

这充当 Log4Net 的包装器,并允许人们像这样使用 System.Diagnostics Tracing

Trace.Listeners.Clear();
Trace.Listeners.Add(new Log("MyProgram"));
Trace.TraceInformation("Program Starting");

请求添加额外的跟踪级别,然后是默认的跟踪级别(错误、警告、信息)

我想将此添加到 System.Diagnostics.Trace 中,以便可以像这样使用

Trace.TraceVerbose("blah blah");
Trace.TraceAlert("Alert!");

有什么办法可以用扩展类做到这一点吗?我试过

public static class TraceListenerExtensions
{
     public static void TraceVerbose(this Trace trace) {}
}

但是在传入的跟踪实例上没有任何内容被暴露:(

4

2 回答 2

11

这已经很晚了,但是您是否考虑过使用 TraceSource?TraceSources 为您提供可用于登录到 System.Diagnostics 的实际对象实例(这意味着您可以使用您在问题中提出的扩展方法来扩展它们)。TraceSources 通常在 app.config 中配置(类似于配置 log4net 记录器的方式)。您可以控制日志记录的级别以及正在侦听的跟踪侦听器。因此,您可以拥有针对 TraceSource 编程的应用程序代码,看起来可能是这样的:

public class MyClassThatNeedsLogging
{
  private static TraceSource ts = 
          new TraceSource(MethodBase.GetCurrentMethod().DeclaringType.Name);
  //Or, to get full name (including namespace)
  private static TraceSource ts2 = 
          new TraceSource(MethodBase.GetCurrentMethod().DeclaringType.FullName);

  private count;

  public MyClassThatNeedsLogging(int count)
  {
    this.count = count;

    ts.TraceEvent(TraceEventType.Information, 0, "Inside ctor.  count = {0}", count);
  }

  public int DoSomething()
  {
    if (this.count < 0)
    {
      ts.TraceEvent(TraceEventType.Verbose, 0, "Inside DoSomething.  count < 0");
      count = Math.Abs(count);
    }

    for (int i = 0; i < count; i++)
    {
      ts.TraceEvent(TraceEventType.Verbose, 0, "looping.  i = {0}", i);
    }
  }
}

您还可以使用任何名称创建 TraceSources(即不必是类名):

TraceSource ts1 = new TraceSource("InputProcessing");
TraceSource ts2 = new TraceSource("Calculations");
TraceSource ts3 = new TraceSource("OutputProcessing");

正如我之前提到的,每个 TraceSource 通常在 app.config 文件中配置,以及日志记录“级别”和应该接收输出的侦听器。

对于您的扩展方法,您可以执行以下操作:

public static class TraceSourceExtensions
{
  public static void TraceVerbose(this TraceSource ts, string message)
  {
    ts.TraceEvent(TraceEventType.Verbose, 0, message);
  }
}

如果您需要对 TraceSource 进行更多自定义(例如添加其他级别),这是一篇很好的文章,描述了如何做到这一点:

http://msdn.microsoft.com/en-us/magazine/cc300790.aspx

如果您最终在 TraceListener 中使用 log4net(并使用它来定义命名记录器、记录​​级别等),您可能不需要配置许多 TraceSource。您甚至可以只配置一个(其名称将是众所周知的),或者您可以通过编程方式创建一个,将其设置为记录“全部”,并将其连接到您的特定 TraceListener。

In the end, instead of logging through the static Trace object, you can log through TraceSource instances. If there is one TraceSource configured and its name is well known, a valid TraceSource can be created (for logging) anywhere like this:

TraceSource ts = new TraceSource("logger");
ts.TraceEvent(TraceEventType.Information, 0, "Hello World!");
//Or, via your extension method
ts.TraceVerbose(TraceEventType.Verbose, 0, "Logged via extension method");

There may be better ways to accomplish what you are trying to accomplish, but this might give you something to think about regarding using TraceSource vs the static Trace class.

于 2010-08-25T15:50:09.703 回答
-1

您的问题是您无法添加扩展方法来作用于静态类。扩展方法的第一个参数是它应该操作的实例。由于Trace类是静态的,因此没有这样的实例。您最好创建自己的静态日志包装器,公开您想要的方法,例如TraceVerbose

public static class LogWrapper
{
    public static void TraceVerbose(string traceMessage)
    {
        Trace.WriteLine("VERBOSE: " + traceMessage);
    }
    // ...and so on...
}

这也将使您的日志代码与实际使用的日志框架分离,以便您以后可以根据需要从跟踪日志切换到使用 log4net 或其他东西。

于 2010-03-19T17:18:33.733 回答