3

WCF 要求を受け取る Windows サービス プロセスがあります。リクエストごとに、何らかの作業を行う新しいスレッドを作成します。ホスト プロセス用に 1 つのログ ファイルを作成し、スレッド インスタンスごとに個別の一意のログ ファイルを作成したいと考えています。たとえば、ログ ファイルを「%date{yyyyMMdd}_%property{UniqueId}.log」のようなものにしたいと考えています。これが私がこれまでに持っているものです。

<appender name="ThreadAppender" type="log4net.Appender.RollingFileAppender">
      <file type="log4net.Util.PatternString" value="c:\Logs\%date{yyyyMMdd}\%date{HHmmss}_%property{FileID}.log"/>
      <appendToFile value="true"/>
      <maxSizeRollBackups value="10"/>
      <maximumFileSize value="10MB"/>
      <rollingStyle value="Size"/>
      <staticLogFileName value="true"/>
      <layout type="log4net.Layout.PatternLayout">
        <header value="[Header]
"/>
        <footer value="[Footer]
"/>
        <conversionPattern value="[%date] [%thread] [%-5level] %logger  - %message%newline"/>
      </layout>
    </appender>
    <appender name="ServiceAppender" type="log4net.Appender.RollingFileAppender">
      <file value="C:\Logs\Service.log"/>
      <appendToFile value="true"/>
      <maxSizeRollBackups value="10"/>
      <maximumFileSize value="10MB"/>
      <rollingStyle value="Size"/>
      <staticLogFileName value="true"/>
      <layout type="log4net.Layout.PatternLayout">
        <header value="[Header]
"/>
        <footer value="[Footer]
"/>
        <conversionPattern value="[%date] [%thread] [%-5level] %logger  - %message%newline"/>
      </layout>
    </appender>
    <root>
      <level value="ALL"/>
      <appender-ref ref="ThreadAppender"/>
    </root>
    <logger name="ServiceLogger" additivity="false">
      <level value="INFO"/>
      <appender-ref ref="ServiceAppender"/>
    </logger>

次に、私のスレッドでは、 を使用しますLogicalContext.Properties["FileID"] = <some id>[assembly: log4net.Config.XmlConfigurator(Watch = true)]assemblyinfo.cs ファイルにも行があります。

すべてがほぼ機能します:)。1 つの問題は、Windows サービスを開始すると、新しい %date{HHmmss}_(null).log ファイルが自動的に作成されることです。log4net がこのダミー ファイルを作成しないようにするには、何を設定する必要がありますか? また、ServiceAppender と ThreadAppender のファイル ロックを指定する必要がありますか?

4

2 に答える 2

1

同時実行の問題により、そのコードは期待どおりに機能しません。log4net.Config.XmlConfigurator.Configure は強制的に新しいプロパティ値を適用しますが、すべてのスレッドに影響するため、他の同時リクエストのメッセージは新しいファイルにリダイレクトされます。

私がする唯一の実用的な解決策は、ILoggerRepository を使用することです。

于 2015-04-09T10:27:22.887 に答える
0

WCF サービスでスレッドごとに一意のログ ファイルを作成する

log4net で FileID が空のファイル (例: c:\Logs\19850101\131510_null.log) を作成したくない場合は
、最初にプロパティを設定してから log4net を構成する必要があります。

WCF サービスでは、次の手順を実行できます。
1. ファイル 'AssemblyInfo.cs' 内の XmlConfigurator への呼び出しを削除します。
2. グローバル アプリケーション クラス (Global.asax) をサービスに追加します。
3. 新しく作成したクラスに次のコードを追加します。

    /// <summary>
    /// Begins the application request.
    /// </summary>
    /// <param name="sender">The source of the event.</param>
    /// <param name="e">A <see cref="EventArgs"/> that contains the event data.</param>
    protected void Application_BeginRequest(object sender, EventArgs e)
    {
        log4net.LogicalContext.Properties["FileID"] = <some id>;

        // Configure log4net. Log4net will load settings and create a new 
        //   file if it does not exist yet.
        log4net.Config.XmlConfigurator.Configure();
        log4net.ILog logger = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
        logger.Debug(<some id>);
    }

ロギングを開始

次のスニペットを使用して、すべてのクラスにロガーを作成します。

    /// <summary>
    /// Logger that can be used to report messages, errors, etc.
    /// </summary>
    private static log4net.ILog Logger = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);

ロックについて

ServiceAppender と ThreadAppender にロックを使用する必要があるかどうかわかりません。
すべての WCF サービスは、デフォルトで「同時実行モード」を「Single」に、
「インスタンス コンテキスト モード」を「PerSession」に設定します。

つまり、任意の時点で処理されるリクエストは 1 つだけです。
サービスを使用して 1 つのクライアントを持つ仮想マシンでこれをテストしたところ、ログは正常に機能しているよう
です。したがって、デフォルトでは、ロックする必要はありません。

于 2014-02-26T15:48:35.543 に答える