C# 将跟踪方法添加到System.Diagnostics.TraceListener

C# 将跟踪方法添加到System.Diagnostics.TraceListener,c#,.net,system.diagnostics,C#,.net,System.diagnostics,我编写了一个从System.Diagnostics.TraceListener派生的日志类,如下所示 public class Log : TraceListener 它充当Log4Net的包装器,允许人们像这样使用System.Diagnostics跟踪 Trace.Listeners.Clear(); Trace.Listeners.Add(new Log("MyProgram")); Trace.TraceInformation("Program Starting"); 请求添加额外的

我编写了一个从System.Diagnostics.TraceListener派生的日志类,如下所示

public class Log : TraceListener
它充当Log4Net的包装器,允许人们像这样使用System.Diagnostics跟踪

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) {}
}

但在传入的跟踪实例上未显示任何内容:(

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

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

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

这已经很晚了,但是您是否考虑过使用TraceSource?TraceSource为您提供了可用于记录到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);
    }
  }
}
正如我前面提到的,每个TraceSource通常在app.config文件中配置,以及日志记录“级别”和应该接收输出的侦听器

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

public static class TraceSourceExtensions
{
  public static void TraceVerbose(this TraceSource ts, string message)
  {
    ts.TraceEvent(TraceEventType.Verbose, 0, message);
  }
}
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进行更多的定制(如添加额外的级别),这是一篇非常好的文章,介绍了如何做到这一点:

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

最后,您可以通过TraceSource实例进行日志记录,而不是通过静态跟踪对象进行日志记录。如果配置了一个TraceSource且其名称众所周知,则可以在任何位置创建有效的TraceSource(用于日志记录),如下所示:

public static class TraceSourceExtensions
{
  public static void TraceVerbose(this TraceSource ts, string message)
  {
    ts.TraceEvent(TraceEventType.Verbose, 0, message);
  }
}
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与静态跟踪类的关系。

然后问题是每个人都必须使用我的记录器。通过在日志框架内工作,人们可以使用它。例如System.Diagnostics.Trace.TraceWarning(“警告!”)。此外,任何使用System.Diagnostics.Trace的第三方程序集将自动向我们的记录器发送消息,无需修改。