Добавить методы трассировки в System.Diagnostics.TraceListener
Я написал класс 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 ответа
Это слишком поздно, но вы рассматривали возможность использования 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
Если вы в конечном итоге используете 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.
Ваша проблема в том, что вы не можете добавить методы расширения для работы со статическими классами. Первый параметр метода расширения - это экземпляр, с которым он должен работать. Так как Trace
класс статичен, такого экземпляра нет. Возможно, вам лучше создать свою собственную оболочку статического журнала, раскрывая методы, которые вы хотите иметь, такие как TraceVerbose
:
public static class LogWrapper
{
public static void TraceVerbose(string traceMessage)
{
Trace.WriteLine("VERBOSE: " + traceMessage);
}
// ...and so on...
}
Это также отсоединит ваш код регистрации от фактической используемой среды ведения журнала, так что вы сможете позже переключиться с ведения журнала трассировки на использование log4net или чего-то еще, если хотите.