1

ここでバグを見つけましたか、それともこの構成で何か問題がありますか?

<appender name="ConsoleAppender" type="log4net.Appender.ConsoleAppender">
  <layout type="log4net.Layout.PatternLayout">
    <conversionPattern value="%message%newline" />
  </layout>
</appender>
<logger name="MyApp.Common">
  <level value="WARN" />
  <appender-ref ref="ConsoleAppender" />
</logger>
<logger name="MyApp.Common.Namespace.SomeGenericClass`1">
  <level value="INFO" />
  <appender-ref ref="ConsoleAppender" />
</logger>

標準の「...DeclaringType」命名スキームに従ってロガーに名前を付けたと仮定すると、ここでの私の期待は、警告以上である限り、MyApp.Common名前空間の下のすべてがコンソールに記録されることです。SomeGenericClass`1のすべては、INFO以上の場合はログに記録されます(WARNロガーのためにWARN以上の場合は2回ログに記録されます)。

何が起こっているのかというと、INFOにログインしたSomeGenericClass`1のすべてが、予想された1回ではなく、2回コンソールにパイプアウトされます。より具体的なロガーを削除すると、何もログに記録されません。また、より具体的でないロガーを削除すると、両方とも期待どおりに1回だけログに記録されます。さらに、構成ファイル内のロガーの順序を逆にしても何も起こりません(私が予想するように、順序は重要ではないと思うので)。

ここでバグを見つけましたか、それとも階層の動作に重要な何かが欠けていますか?

4

2 に答える 2

2

複数のロガー ノードを使用した私の実験的な経験では、log4net は特定のロガーで設定した最低レベルを使用します。そのため、MyApp.Common で WARN を指定したにもかかわらず、MyApp.Common.SomeGenericClass で INFO を使用すると、グローバル (?) レベルの設定が WARN に低下しました。したがって、アペンダー ConsoleAppender が 2 回起動されたため、MyApp.Common と MyApp.Common.SomeGenericClass からエントリを取得しました。

私が求めていたのは、ログのサブセットを別のファイルに移動することでした。あなたが質問で述べたこととはまったく異なりますが、それはあなたがやりたいことを網羅しています。そして、自分の利益のために、自分の解決策をどこかで再び見つけることができる場所に文書化したいと思いました;-)。

上記のような2つの異なるロガーを作成しましたが、1つはルートですが、同じように機能します。次に、それぞれが異なるエラー レベルでフィルタリングする 2 つの異なるアペンダーを作成し、2 つのロガーで別々に参照しました。私が取得するのは、1 つのファイルにある OtherNamespace からのログと、他のすべてのファイルにあるログです。そのためのコードを以下に示します。

<log4net>
<logger name="OtherNamespace">
  <appender-ref ref="OtherNamespaceAppender"/>
</logger>
<root>
  <level value="WARN"/>
  <appender-ref ref="MyRollingFileAppender"/>
</root>
<appender name="MyRollingFileAppender" type="log4net.Appender.RollingFileAppender">
  <file type="log4net.Util.PatternString" value="C:\Comanche\mylogfileFor_%property{User}.log" />
  <appendToFile value="true" />
  <rollingStyle value="Size" />
  <threshold value="ERROR" />
  <countDirection value="3" />
  <maxSizeRollBackups value="2" />
  <maximumFileSize value="200KB" />
  <staticLogFileName value="true" />
  <layout type="log4net.Layout.PatternLayout">
    <param name="ConversionPattern" value="%-6level%utcdate{ABSOLUTE} – %location :: %message%newline" />
  </layout>
</appender>
<appender name="OtherNamespaceAppender" type="log4net.Appender.RollingFileAppender">
  <file value="C:\Comanche\OtherNamespace.log" />
  <appendToFile value="true" />
  <rollingStyle value="Size" />
  <threshold value="WARN" />
  <countDirection value="3" />
  <maxSizeRollBackups value="2" />
  <maximumFileSize value="200KB" />
  <staticLogFileName value="true" />
  <filter type="log4net.Filter.LoggerMatchFilter">
    <acceptOnMatch value="true" />
    <LoggerToMatch value="OtherNamespace" />
    <!-- set your class name here -->
  </filter>

  <filter type="log4net.Filter.DenyAllFilter" />

  <layout type="log4net.Layout.PatternLayout">
    <param name="ConversionPattern" value="%-6level%utcdate{ABSOLUTE} :: %message%newline" />
  </layout>
</appender>

「その他すべて」は別の名前空間にあったため、OtherNamespace ロガーにシャントされなかったことに注意してください。これは、何らかの名前の一致があった場合に発生する可能性があります。また、すべてが root から継承されるため、root が参照するアペンダーのログ レベルを WARN に変更した場合は、OtherNamespace ログも取得していたことに注意してください。私が達成したかったのは、より詳細なログを他のすべてのものとは別のファイルに記録することだけでした。

于 2011-11-28T20:09:32.513 に答える
0

これはあなたが望むことをするはずだと思います(テストしませんでした):

<logger name="MyApp.Common">
     <level value="WARN" />
     <appender-ref ref="ConsoleAppender" />
</logger>
<logger name="MyApp.Common.Namespace.SomeGenericClass`1">
     <level value="INFO" />  
</logger>

アペンダーを再度参照する必要はありません。additivity を false に設定しない限り、自動的に継承さます。

于 2011-04-21T14:21:31.923 に答える