Я согласен с рекомендацией @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 для каждого класса:
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» частью журнала вашего приложения на одном уровне, в то время как часть «Analysis» вашего приложения регистрируется на другом уровне (конечно, одна или обе части вашего приложения). можно настроить так, чтобы ведение журнала было отключено).
Вот часть файла 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 в вашем коде) и несколько Switch. Коммутаторы могут быть общими (то есть несколько источников могут использовать один и тот же коммутатор).
В конечном итоге, приложив немного больше усилий, чтобы теперь использовать TraceSources и ссылаться на соответствующим образом названные TraceSources в своем коде (т.е. определить имена TraceSource логически, чтобы вы могли иметь желаемую степень контроля над входом в приложение), вы получит значительную гибкость в долгосрочной перспективе.
Вот несколько ссылок, которые могут помочь вам с System.Diagnostics по мере продвижения вперед:
.net Рекомендации по диагностике?
Регистрация лучших практик
Каков наилучший подход к ведению журнала?
Имеет ли платформа .Net TraceSource / TraceListener что-то похожее на средства форматирования log4net?
В ссылках, которые я разместил, часто обсуждается «лучшая» структура ведения журналов. Я не пытаюсь убедить вас перейти от System.Diagnostics. Ссылки, как правило, содержат хорошую информацию об использовании System.Diagnostics, поэтому я разместил их.
Некоторые из размещенных мной ссылок содержат ссылку на Ukadc.Diagnostics . Это действительно классное дополнение для библиотеки System.Diagnostics, которое добавляет расширенные возможности форматирования, аналогично тому, что вы можете делать с log4net и NLog. Эта библиотека налагает зависимость только для конфигурации на ваше приложение, а не код или ссылочную зависимость.