web-dev-qa-db-ja.com

app.configを介してトレースをオフにする

System.Diagnosticsを使用して、非常に基本的なロギングを実行しようとしています。 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>

そして、私の小さな「HelloWorld」がTrace.logファイルにうまく表示されます。しかし、今度はトレースをオフに切り替えたいので、MSDNを調べて、 方法:トレーススイッチを構成する を見つけます。 <switches>要素を追加すると、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>
    <switches>
      <add name="Data" value="0" />
    </switches>
  </system.diagnostics>
</configuration>

value="0"はトレースをオフにする必要があります-少なくともその後に従う場合 方法:トレーススイッチを作成して初期化する 、これは次のコード行を追加するように指示します:

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

それは私には意味がありません。configファイルを介してトレースを管理(無効化)できるようにするには、BooleanSwicthのインスタンスを宣言する必要がありますか?私は...use...オブジェクトをどこかに好きですか?

とにかく、私はどこかで本当に明白な何かを逃したと確信しています。助けてください。

app.configでトレースをオフにするにはどうすればよいですか?

20
Jakob Gade

TraceSourcesを使用してみるという@AlexHumphreyの推奨に同意します。 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)が特定の値より大きい場合にのみログに記録します(「警告」以上のログのみ)。同時に、MyClass1とは完全に独立して、MyClass2のログインをオンまたはオフにしたり、レベルに設定したりできます。この有効化/無効化/レベル設定はすべて、app.configファイルで行われます。

App.configファイルを使用して、すべてのTraceSource(またはTraceSourceのグループ)を同じ方法で制御することもできます。したがって、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を構成するapp.configファイルの一部を次に示します。

<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と単一のスイッチを構成すると、すべてのログが単一レベルの制御で発生します(つまり、すべてのログをオフにするか、特定のレベルでログに記録することができます)。

または、複数のTraceSourceを定義(およびコード内の対応するTraceSourceを参照)および複数のスイッチを定義することもできます。スイッチは共有できます(つまり、複数のTraceSourceが同じスイッチを使用できます)。

最終的に、TraceSourcesを使用し、コード内で適切な名前のTraceSourcesを参照するためにもう少し努力することで(つまり、TraceSource名を論理的に定義して、アプリへのログインを必要な程度に制御できるようにする)、大幅なメリットが得られます。長期的には柔軟性。

進むにつれてSystem.Diagnosticsに役立つ可能性のあるいくつかのリンクを次に示します。

。net Diagnosticsのベストプラクティス?

ログのベストプラクティス

ロギングへの最善のアプローチは何ですか?

。Net TraceSource/TraceListenerフレームワークにはlog4netのフォーマッターに似たものがありますか?

私が投稿したリンクでは、「最良の」ロギングフレームワークについての議論がよくあります。 System.Diagnosticsから変更するように説得しようとはしていません。リンクには、System.Diagnosticsの使用に関する優れた情報も含まれている傾向があるため、私はそれらを投稿しました。

私が投稿したリンクのいくつかには、 kadc.Diagnostics へのリンクが含まれています。これは、log4netやNLogで実行できるのと同様に、リッチフォーマット機能を追加するSystem.Diagnostics用の非常に優れたアドオンライブラリです。このライブラリは、コードや参照の依存関係ではなく、構成のみの依存関係をアプリに課します。

34
wageoghe

この方法でグローバルにトレースをオフにすることはありません。

必ず
1)スイッチを宣言し、その値を設定します。

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

2)このスイッチを使用するTraceSourceに関連付けます。

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

したがって、「MySource」という名前のTraceSourceを介して記述したものはすべて、スイッチ値に従ってフィルタリングされます。

Trace.Writeのような静的メソッドを使用する場合、フィルターを適用するTraceSourceがないため、スイッチをまったく使用できないと思います。
静的メソッドによるトレースをオフにする場合は、すべてのリスナーを削除します:<listeners> <clear/> </listeners>

3
VladV

これは、ソースノードの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" />
1
tucaz

App.configについての簡単な脚注で遅れて参加します。これにより、誰かの生活から数日を節約できます。

ClassBを含むprojectB(.dll)を利用するclassAを含むスタートアップ(.exe)projectAがあるとします。

次に、ClassBは新しいTraceSource( "classB")インスタンスを利用します。構成するには、app.configまたはprojectAを変更する必要があります。 projectBのapp.configを微調整しても、どこにもつながりません。

また、の配置に注意してください

<system.diagnostics>

App.config内のセクションは、セクションの前に配置すると問題が発生するようです。

<configSections>

またはセクションの後:

<userSettings>

少なくとも私の場合、プロジェクトのapp.configのこれらの場所に配置しようとすると、エラーが発生していました。私のために働いたレイアウトは次のとおりでした:

<?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>
1
XDS

次のように、ログに記録する必要があるときはいつでもdataSwitchの状態を確認してください。

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

しかし、それはかなり厄介で、どこにでもそれらのチェックを入れなければなりません。 app.configのリスナーコレクションからTraceListenerを単純に削除したくない理由はありますか?

それとは別に、TraceSourceを含む.NET2.0以降のトレースを使用して調査します。新しい(より)ものははるかに高度な構成を提供し、あなたはそれがより適切であると思うかもしれません。

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

1
Alex Humphrey

この簡単な解決策を試してください。以下の例では、「SomeNoisyLibrary」がログに多くの役に立たないエントリを散らかしています。 "when condition"でフィルタリングします

https://github.com/NLog/NLog/wiki/When-Filter

<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        internalLogFile="../log/MyApplication.log"
        autoReload="true" throwExceptions="true">

  <targets async="true">
    <target xsi:type="File" 
            name="file"
            layout="${longdate} | ${level:uppercase=true} | ${logger} | ${message} ${exception:format=ToString}"
            fileName="../log/MyApplication.${processid}.${shortdate}.log" keepFileOpen="false"
            maxArchiveFiles="10"
            archiveAboveSize="10024000"
            archiveEvery="Day"
            />
    <target xsi:type="ColoredConsole" 
            name="console" 
            layout="${longdate} | ${level:uppercase=true} | ${logger} | ${message}${exception:format=ToString}" />
  </targets>

  <rules>
    <logger name="*" minlevel="Info" writeTo="file,console">
      <filters defaultAction='Log'>
        <when condition="equals('${logger}','SomeNoisyLibrary')" action="Ignore" />
      </filters>
    </logger>
  </rules>
</nlog>
0
user3761555