Добавить методы трассировки в System.Diagnostics.TraceListener - PullRequest
3 голосов
/ 19 марта 2010

Я написал класс Log, производный от System.Diagnostics.TraceListener, вот так

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 ]

11 голосов
/ 25 августа 2010

Это слишком поздно, но вы рассматривали возможность использования 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 вместе с журналом "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

Если вы в конечном итоге используете log4net внутри своего TraceListener (и используете его для определения именованных регистраторов, уровней ведения журналов и т. Д.), Вам может не потребоваться настройка многих TraceSources. Возможно, вам даже удастся настроить только один (имя которого будет общеизвестно), или вы можете создать его программно, настроить его на запись «всего» и подключить его к вашему конкретному TraceListener.

В конце концов, вместо входа через статический объект Trace, вы можете войти через экземпляры TraceSource. Если настроен один 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.

0 голосов
/ 19 марта 2010

Ваша проблема в том, что вы не можете добавить методы расширения для работы со статическими классами. Первый параметр метода расширения - это экземпляр, с которым он должен работать. Поскольку класс Trace является статическим, такого экземпляра не существует. Возможно, вам лучше создать свою собственную оболочку статического журнала, раскрывая методы, которые вы хотите иметь, такие как TraceVerbose:

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

Это также отсоединит ваш код регистрации от фактической используемой среды ведения журнала, так что вы сможете позже переключиться с ведения журнала трассировки на использование log4net или чего-то еще, если хотите.

...