将Trace方法添加到System.Diagnostics.TraceListener

时间:2010-03-19 17:02:16

标签: c# .net system.diagnostics

我编写了一个从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) {}
}

但是传入的跟踪实例没有公开任何内容:(

2 个答案:

答案 0 :(得分:11)

这是迟到的,但你考虑过使用TraceSource吗? TraceSources为您提供了可用于登录System.Diagnostics的实际对象实例(这意味着您可以使用您在问题中提出的扩展方法扩展它们)。 TraceSource通常在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文件中配置,以及日志记录“level”和应该接收输出的监听器。

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

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。您甚至可以只配置一个(其名称将是众所周知的),或者您可能能够以编程方式创建一个,将其设置为记录“all”,并将其连接到您的特定TraceListener。

最后,您可以登录TraceSource实例,而不是记录静态Trace对象。如果配置了一个TraceSource并且其名称是众所周知的,则可以在任何地方创建有效的TraceSource(用于记录):

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");

可能有更好的方法来完成您要完成的任务,但这可能会让您考虑使用TraceSource与静态Trace类。

答案 1 :(得分:-1)

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

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

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