Ответ 1
Я согласен с рекомендацией @Alex Humphrey попробовать использовать TraceSources. С помощью TraceSources вы получаете больше контроля над выполнением операторов ведения журнала/трассировки. Например, у вас может быть такой код:
public class MyClass1
{
private static readonly TraceSource ts = new TraceSource("MyClass1");
public DoSomething(int x)
{
ts.TraceEvent(TraceEventType.Information, "In DoSomething. x = {0}", x);
}
}
public class MyClass2
{
private static readonly TraceSource ts = new TraceSource("MyClass2");
public DoSomething(int x)
{
ts.TraceEvent(TraceEventType.Information, "In DoSomething. x = {0}", x);
}
}
Вызов TraceSource.TraceEvent автоматически проверяет уровень сообщения (TraceEventType.Information) на настроенном уровне соответствующего коммутатора и определяет, действительно ли сообщение должно быть записано.
Используя другой тип TraceSource для каждого типа, вы можете управлять журналом из этих классов отдельно. Вы можете включить ведение журнала MyClass1, или вы можете отключить его, или вы можете включить его, но он должен регистрироваться, только если уровень сообщения (TraceEventType) больше определенного значения (возможно, только журнал "Предупреждение" и выше). В то же время вы можете включить или отключить вход в MyClass2 или установить уровень, полностью независимо от MyClass1. Все это включение/отключение/уровень материала происходит в файле app.config.
Используя файл app.config, вы также можете управлять всеми TraceSources (или группами TraceSources) таким же образом. Таким образом, вы можете настроить так, чтобы MyClass1 и MyClass2 управлялись одним и тем же коммутатором.
Если вы не хотите, чтобы каждый тип TraceSource по-разному назывался TraceSource, вы могли бы просто создать тот же TraceSource в каждом классе:
public class MyClass1
{
private static readonly TraceSource ts = new TraceSource("MyApplication");
public DoSomething(int x)
{
ts.TraceEvent(TraceEventType.Information, "In DoSomething. x = {0}", x);
}
}
public class MyClass2
{
private static readonly TraceSource ts = new TraceSource("MyApplication");
public DoSomething(int x)
{
ts.TraceEvent(TraceEventType.Information, "In DoSomething. x = {0}", x);
}
}
Таким образом, вы можете сделать все записи в вашем приложении на одном уровне (или отключить его или пойти тем же TraceListener или что-то еще).
Вы также можете настроить различные части вашего приложения независимо друг от друга без необходимости "проблемы" с определением уникального TraceSource в каждом типе:
public class Analysis1
{
private static readonly TraceSource ts = new TraceSource("MyApplication.Analysis");
public DoSomething(int x)
{
ts.TraceEvent(TraceEventType.Information, "In DoSomething. x = {0}", x);
}
}
public class Analysis2
{
private static readonly TraceSource ts = new TraceSource("MyApplication.Analysis");
public DoSomething(int x)
{
ts.TraceEvent(TraceEventType.Information, "In DoSomething. x = {0}", x);
}
}
public class DataAccess1
{
private static readonly TraceSource ts = new TraceSource("MyApplication.DataAccess");
public DoSomething(int x)
{
ts.TraceEvent(TraceEventType.Information, "In DoSomething. x = {0}", x);
}
}
public class DataAccess2
{
private static readonly TraceSource ts = new TraceSource("MyApplication.DataAccess");
public DoSomething(int x)
{
ts.TraceEvent(TraceEventType.Information, "In DoSomething. x = {0}", x);
}
}
С помощью этого класса вы можете сделать "DataAccess" частью вашего журнала приложений на одном уровне, в то время как часть "Анализ" вашего приложения регистрируется на другом уровне (разумеется, обе или обе части вашего приложения может быть настроен так, что ведение журнала отключено).
Вот часть файла app.config, который настраивает TraceSources и TraceSwitches:
<system.diagnostics>
<trace autoflush="true"></trace>
<sources>
<source name="MyClass1" switchName="switch1">
<listeners>
<remove name="Default"></remove>
<add name="console"></add>
</listeners>
</source>
<source name="MyClass2" switchName="switch2">
<listeners>
<remove name="Default"></remove>
<add name="console"></add>
</listeners>
</source>
</sources>
<switches>
<add name="switch1" value="Information"/>
<add name="switch2" value="Warning"/>
</switches>
<sharedListeners>
<add name="console"
type="System.Diagnostics.ConsoleTraceListener">
</add>
<add name="file"
type="System.Diagnostics.TextWriterTraceListener"
initializeData="trace.txt">
</add>
</sharedListeners>
</system.diagnostics>
Как вы можете видеть, вы можете настроить один TraceSource и один коммутатор, и все протоколирование будет происходить с одним уровнем управления (т.е. вы можете отключить все протоколирование или сделать его журналом на определенном уровне).
В качестве альтернативы вы можете определить несколько TraceSources (и ссылаться на соответствующие TraceSources в коде) и несколько переключателей. Коммутаторы могут использоваться совместно (например, несколько TraceSources могут использовать один и тот же коммутатор).
В конечном счете, добавив немного больше усилий, чтобы использовать TraceSources и ссылаться на правильно названные TraceSources в вашем коде (т.е. определять имена TraceSource логически, чтобы вы могли иметь желаемую степень контроля за протоколированием в вашем приложении), вы в долгосрочной перспективе обеспечит значительную гибкость.
Вот несколько ссылок, которые могут помочь вам с System.Diagnostics по мере продвижения вперед:
.net Рекомендации по диагностике?
Каков наилучший способ ведения журнала?
Имеет ли структура .Net TraceSource/TraceListener нечто похожее на Formatters log4net?
В ссылках, которые я опубликовал, часто обсуждается "лучшая" структура ведения журнала. Я не пытаюсь убедить вас перейти от System.Diagnostics. Ссылки также имеют хорошую информацию об использовании System.Diagnostics, поэтому я разместил их.
Несколько ссылок, которые я разместил, содержат ссылку на Ukadc.Diagnostics. Это действительно классная добавленная библиотека для System.Diagnostics, которая добавляет возможности форматирования, аналогичные тому, что вы можете делать с log4net и NLog. Эта библиотека накладывает зависящую от конфигурации зависимость от вашего приложения, а не зависимость от кода или ссылки.