Отключение трассировки через приложение.конфиг

Я пытаюсь использовать System.Диагностика для выполнения очень простого ведения журнала. Я полагаю, что буду использовать то, что в коробке, а не брать дополнительную зависимость, такую как Log4Net или EntLib.

Я все настроил, трассировка работает замечательно. Фрагмент кода:

Trace.TraceInformation("Hello World")

App.config:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <system.diagnostics>
    <trace autoflush="true" indentsize="4">
      <listeners>
        <add name="TraceListener" type="System.Diagnostics.TextWriterTraceListener" initializeData="Trace.log" traceOutputOptions="DateTime" />
        <remove name="Default" />
      </listeners>
    </trace>
  </system.diagnostics>
</configuration>

и мой маленький "Hello World" хорошо проявляется в моем следе.журнал. Но теперь я хотел бы отключить трассировку, поэтому я копаюсь в MSDN и нахожу как настроить трассировку Переключатели . Я добавляю <switches> элемент, а теперь мое приложение.конфигурация выглядит так:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <system.diagnostics>
    <trace autoflush="true" indentsize="4">
      <listeners>
        <add name="TraceListener" type="System.Diagnostics.TextWriterTraceListener" initializeData="Trace.log" traceOutputOptions="DateTime" />
        <remove name="Default" />
      </listeners>
    </trace>
    <switches>
      <add name="Data" value="0" />
    </switches>
  </system.diagnostics>
</configuration>

на value="0" нужно отключить трассировку - по крайней мере, если вы следуете как: создание и инициализация коммутаторов трассировки, который говорит вам, чтобы добавить эту строку кода:

Dim dataSwitch As New BooleanSwitch("Data", "DataAccess module")

это не имеет смысла для меня: я просто должен объявить экземпляр BooleanSwicth чтобы иметь возможность управлять (отключить) трассировку через .файл config? Мне бы хотелось ... использовать ... объект где-то?

в любом случае, я уверен, что пропустил что-то действительно очевидное. Пожалуйста помочь.

Как отключить трассировку в приложении.конфиг?

5 ответов


Я согласен с рекомендацией @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);
  }
}

Источник Трассировки.Вызов TraceEvent автоматически проверяет уровень сообщения (TraceEventType.Информация) против настроенного уровня связанного коммутатора и определит, должно ли сообщение фактически быть записано из.

С помощью другого имени TraceSource для каждого типа можно управлять журналированием из этих классов по отдельности. Вы можете включить ведение журнала MyClass1, или вы можете отключить его, или вы можете включить его, но иметь его журнал только в том случае, если уровень сообщения (TraceEventType) больше определенного значения (возможно, только журнал "предупреждение" и выше). В то же время вы можете включить или выключить вход в MyClass2 или установить уровень, полностью независимо от MyClass1. Все это включение/отключение / уровень вещи происходит в приложении.конфигурационный файл.

С помощью приложения.файл конфигурации, вы также можете управлять всеми 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" вашего журнала приложений на одном уровне, а часть "анализ" вашего приложения другой уровень (конечно, любая или обе части вашего приложения могут быть настроены так, что ведение журнала отключено).

вот часть приложения.файл конфигурации, который настраивает 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 логически, чтобы вы могли иметь желаемую степень контроля над входом в приложение), вы получите значительную гибкость в конечном счете.

вот несколько ссылок, которые могут помочь вам с системой.Диагностика по мере продвижения вперед:

рекомендации по диагностике .net?

лучшие практики ведения журнала

каков наилучший подход к регистрации?

имеет ли .NET tracesource/tracelistener framework что-то похожее на Форматеры log4net?

в ссылках, которые я написал, Есть часто обсуждается" лучшая " структура ведения журнала. Я не пытаюсь убедить вас отказаться от системы.Диагностика. Ссылки также имеют хорошую информацию об использовании системы.Диагностика, вот почему я их разместил.

несколько ссылок, которые я разместил, содержат ссылку на Ukadc.Диагностика. Это действительно круто добавить на библиотеку для системы.Диагностика, которая добавляет богатые возможности форматирования, подобно тому, что вы можете сделать с log4net и NLog. Эта библиотека устанавливает config-только зависимость от вашего приложения, а не зависимость от кода или ссылки.


вы не отключаете трассировку глобально таким образом.

вы должны
1) объявить переключатель и установите его значение:

<switches>
  <add name="MySwitch" value="Information"/>
</switches>

2) связать этот переключатель с TraceSource вы используете:

<sources>
  <source name="MySource" switchName="MySwitch"/>
</source>

Итак, все, что вы пишете через TraceSource с именем "MySource", фильтруется в соответствии со значением коммутатора.

если вы используете статические методы, такие как Trace.Write, Я полагаю, вы не можете использовать коммутаторы вообще, потому что нет TraceSource для применения фильтр.
Если вы хотите отключить трассировку статическими методами, просто удалите все прослушиватели:<listeners> <clear/> </listeners>.


его атрибут switchValue исходного узла:

<system.diagnostics>
<sources>
  <source name="System.ServiceModel"
          switchValue="Off"
          propagateActivity="true">
    <listeners>
      <add name="traceListener"
          type="System.Diagnostics.XmlWriterTraceListener"
          initializeData= "somePath" />
    </listeners>
  </source>
</sources>
<trace autoflush="true" />


проверьте состояние dataSwitch, когда вам нужно войти в систему, согласно:

http://msdn.microsoft.com/en-us/library/aa984285%28v=VS.71%29.aspx

тем не менее, это довольно неприятно, чтобы поставить эти чеки везде. Является ли их причиной, по которой вы не хотите просто удалить TraceListener из коллекции listeners в приложении.конфиг?

кроме того, я бы исследовал использование .NET 2.0 + трассировки, которая включает в себя TraceSource. Новый (er) материал предлагает гораздо более высокую степень конфигурации, и вы можете найти его более подходящим.

http://msdn.microsoft.com/en-us/library/ms228993.aspx


позднее присоединение с быстрой сноской о приложении.config, в случае, если это спасает пару дней от жизни кого-то там:

Предположим, у вас есть стартап (.exe) projectA, содержащий classA, который использует projectB (.dll), содержащий classB.

ClassB в свою очередь использует новый экземпляр TraceSource("classB"). Для того, чтобы настроить его, вам нужно изменить приложение.config или projectA. Настройка приложения.конфигурация projectB не приведет везде.

Также обратите внимание, что размещение

<system.diagnostics>

раздел внутри приложения.config, похоже, вызывает проблемы, если помещен перед разделом:

<configSections>

или после раздела:

<userSettings>

по крайней мере, в моем случае я получал ошибки, когда пытался разместить его в этих местах в приложении.конфигурация моего проекта. Макет, который работал для меня было:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
    <configSections>
         ...config sections here if any...
     </configSections>
     <system.diagnostics>
         <trace autoflush="true"/>
         <sources>
             <source name="classB"
                 switchName="mySwitch"
                 switchType="System.Diagnostics.SourceSwitch" >
                 <listeners>
                    <clear/>
                    <add name="textwriterListener"
                         type="System.Diagnostics.TextWriterTraceListener"
                         initializeData="ClassBLog.txt"
                         traceOutputOptions="DateTime" />
                 </listeners>
             </source>
          </sources>
          <switches>
             <add name="mySwitch" value="Verbose" />
          </switches>
     </system.diagnostics>
     <runtime>
         ...runtime sections here if any...
     </runtime>
     <userSettings>
         ...usersettings sections here if any...
     </userSettings>
 </configuration>