web-dev-qa-db-ja.com

log4netプロセスID情報

複数のマシンで複数のプロセスを含むロギングソリューションを作成しようとしています。 UDPAppenderを使用して、すべてのログメッセージをそれらを管理する単一のマシンに送信することを計画しました。 patternstringsとpatternlayoutsについていくつか質問があります。

そのログメッセージがどのマシンとどのプロセスから来たのかを知る必要があるので、それもログに含めたいと思います。ホスト名に%property {log4net:HostName}が見つかりましたが、これはうまく機能します。ただし、PatternLayoutsのプロセスIDには何も表示されません。もちろん、PatternStringにはそのようなものがあります。 FAQから:

<appender name="LogFileAppender" type="log4net.Appender.FileAppender">
    <file type="log4net.Util.PatternString" value="log-file-[%processid].txt" />

    <layout type="log4net.Layout.PatternLayout" value="%date [%thread] %-5level %logger - %message%newline" />
</appender>

しかし、2つを組み合わせるかどうか、またはどのように組み合わせるかはわかりません(または、これが標準的な方法である場合でも)。

だから、私の質問は次のとおりです。

  1. PatternStringとPatternLayoutの違いは何ですか?なぜ両方を持っているのですか?

  2. PatternStringに%processidが表示されますが、PatternLayoutで同じものを取得するにはどうすればよいですか?これが私のテストレイアウトです:

    <layout type="log4net.Layout.PatternLayout">
        <conversionPattern value="%date [%thread] [%property{log4net:HostName}] %-5level %logger  - %message%newline" />
    </layout>
    
  3. 最後に、UDPアペンダーにXMLレイアウトを使用することは理にかなっています。 XmlLayoutSchemaLog4jがすでにHostNamePropertyをXMLメッセージに追加しているようです。この新しいプロセスID(およびおそらくプロセス名)をXMLメッセージに追加したくない場合、これを行うための最良の方法は何ですか? src\Layouts\XmlLayoutSchemaLog4j.csをコピーして変更し、この新しいレイアウト(SampleLayoutsAppなど)を作成したことをlog4netに通知する必要がありますか?

ご協力いただきありがとうございます

31
teleball

GlobalContextには任意のプロパティを追加できます。このコンテキストを使用して、次のようにプロセスIDを格納します。

log4net.GlobalContext.Properties["pid"] = Process.GetCurrentProcess().Id;

次に、次のような通常のパターンを使用して、アペンダーからこのプロパティを参照します。

<layout type="log4net.Layout.PatternLayout">
    <conversionPattern value="%date %property{pid} %level %logger - %message%newline" />
</layout>

プロパティはいくつでも追加できますが、グローバルな性質があるため、アプリケーションの実行中に変更されないプロパティに最適です。

48
jvilalta

PatternStringをPatternLayoutにフィードできます。

    <layout type="log4net.Layout.PatternLayout">
      <conversionPattern type="log4net.Util.PatternString" value="%processid" />
    </layout>
17
Doug W

どうやらPatternStringはログ名(つまりファイル名など)を作成するためにのみ使用できますが、layoutではログに入る実際のメッセージをフォーマットできます。プロセスレイアウトにプロセスIDの組み込みパターンがない場合は、簡単に追加できます。レイアウト全体を作成するよりもはるかに簡単です。

これを行う方法は次のとおりです。

独自のカスタムパターンコンバーターを作成します(以下の例では、winまたはwebに関係なく、アプリケーションの名前を取得しようとします)。

internal sealed class ApplicationNamePatternConverter : PatternLayoutConverter 
{
    /// <summary>
    /// Write the event application name to the output
    override protected void Convert(TextWriter writer, LoggingEvent loggingEvent)
    {
        string name = string.Empty;
        if( System.Web.HttpContext.Current != null )
        {
            string[] applicationPath = System.Web.HttpContext.Current.Request.ApplicationPath.Split('/');
            name = applicationPath[applicationPath.Length - 1];
        }
        else
        {
            if( System.Reflection.Assembly.GetEntryAssembly() != null )
            {
                name = System.Reflection.Assembly.GetEntryAssembly().GetName().Name;
            }
        }
        writer.Write(name);
    }
}

コンバータのエントリをPatternLayoutクラスのレジストリに追加します

static PatternLayout()
{
...
  s_globalRulesRegistry.Add("ApplicationName", typeof(ApplicationNamePatternConverter));
}

これで、PatternLayout値で%ApplicationNameを使用して、必要なものを取得できます。

XmlLayoutSchemaLog4jレイアウトは非常に重く、頻繁に使用するとアプリのパフォーマンスが低下する可能性があるため、使用しないことをお勧めします。

3
Konrad