2009-05-25 19 views
0

私は、データベースへの特定のメソッドの入力と出力をログに記録しようとしています。私は別々の列にこの情報を載せたいと思います。私はPatternLayoutはを調査したのだが、それだけであなたがしなければということを意味し、単一%のメッセージパラメータのために食料調達するようだ:log4net:2つのメッセージをデータベースの1つの行に記録しますか?

log.Debug("This is a message"); 

その後、log4netのメッセージがログに記録されるよう、「これはメッセージである」見ています。私は次のようなことをしたい:

log.Debug(request, response); 

これはlog4netを使って可能ですか?私の目標は、「要求」と別々列に「応答」を持つことであることに留意してください。

答えて

3

あなたPatternConverterの方法があります静的な入力と出力のプロパティを使用すると、正しい方向へのステップになりますすべてのビットが不安定(スレッドセーフな賢明)。

ここでのトリックは、logger.Debug(...)のmessageパラメータがオブジェクトであり、好きなものを渡すことができることを認識することです。

カスタムメッセージの種類

public class InputOutput 
{ 
    public string Input {get;set;} 
    public string Output {get;set;} 
} 

を定義し、あなたのコンバータは、プロパティのいずれかを読んで

public class InputPatternConverter : PatternConverter 
{ 
    protected override void Convert(System.IO.TextWriter writer, object state) 
    { 
     var msg = ((LoggingEvent)state).MessageObject as InputOutput; 
     if (msg != null) 
      writer.Write(msg.Input); 
    } 
} 

public class OutputPatternConverter : PatternConverter 
{ 
    protected override void Convert(System.IO.TextWriter writer, object state) 
    { 
     var msg = ((LoggingEvent)state).MessageObject as InputOutput; 
     if (msg != null) 
      writer.Write(msg.Output); 
    } 
} 

ロギングは、あなたの設定は次のようになり非常にクリーン

logger.Debug(new InputOutput { Input = ..., Output = ...}); 

になってみましょうことができ同じ。

先端しかしPatternLayoutはサブクラスを、そのクラスのコンストラクタにコンバータを追加することです。そのようにして、設定をトリミングすることもできます。これはではありません。は、%messageトークンを失ってしまいます。%inputと%outputトークンは、PatternLayoutがサポートするすべてのトークンに追加されます。

"%date %message %newline%newline %input %newline%newline %output 

ここではカスタムパターンレイアウトの迅速な実装です:

public class InputOutputPatternLayout : PatternLayout 
{ 
    public InputOutputPatternLayout() 
    { 
     AddConverter("input", typeof(InputPatternConverter)); 
     AddConverter("output", typeof(OutputPatternConverter)); 
    } 
} 
+1

ようにするにですから、実際にこのようなパターンを持つことができます2つのパラメータを取ってILoggerインターフェースへの拡張メソッドとしてこれを実装することができます。次に、使用法は次のようになります:logger.Debug(input、output); –

+1

もう一つの制限はありますが、別のパターンコンバータ(またはPatterLayout?のサブクラス)と別のプロパティを追加しない限り、 "@メッセージ"パラメータを失うことです。私はこれが動作するかどうかはテストしていませんが、ToString()メソッドをオーバーライドして@messageを返すことをお勧めします。 – ilitirit

+0

ああ、ちょうど修正: "状態としてInputOutput"は "((LoggingEvent)状態).MessageObjectとしてInputOutput"のようにする必要があります。 – ilitirit

0

私は、カスタムPatternConvertersを使用して

public class InputPatternConverter : PatternConverter 
{ 
    private static string _input; 

    public static string Input 
    { 
     get { return _input; } 
     set { _input = value; } 
    } 

    protected override void Convert(System.IO.TextWriter writer, object state) 
    { 
     writer.Write(Input); 
    } 
} 

public class OutputPatternConverter : PatternConverter 
{ 
    private static string _output; 

    public static string Output 
    { 
     get { return _output; } 
     set { _output = value; } 
    } 

    protected override void Convert(System.IO.TextWriter writer, object state) 
    { 
     writer.Write(Output); 
    } 
} 

アペンダの仕様を、これを行うための一つの方法を作ってみた:

<appender name="ADONetAppender" type="log4net.Appender.AdoNetAppender"> 
    <bufferSize value="1" /> 
    <connectionType value="System.Data.SqlClient.SqlConnection, System.Data, Version=1.0.3300.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" /> 
    <connectionString value="data source=servername;initial catalog=database;Integrated Security=SSPI;" /> 
    <commandText value="INSERT INTO RequestLog ([input], [output]) VALUES (@input, @output)" /> 
    <parameter> 
    <parameterName value="@input" /> 
    <dbType value="String" /> 
    <size value="4000" /> 
    <layout type="log4net.Layout.PatternLayout"> 
     <converter> 
     <name value="input" /> 
     <type value="InputPatternConverter, ApplicationName" /> 
     </converter> 
     <conversionPattern value="%input" /> 
    </layout> 
    </parameter> 
    <parameter> 
    <parameterName value="@output" /> 
    <dbType value="String" /> 
    <size value="4000" /> 
    <layout type="log4net.Layout.PatternLayout"> 
     <converter> 
     <name value="output" /> 
     <type value="OutputPatternConverter, ApplicationName" /> 
     </converter> 
     <conversionPattern value="%output" /> 
    </layout> 
    </parameter> 
</appender> 

使用してそれを呼び出します。

InputPatternConverter.Input = inputString; 
OutputPatternConverter.Output = outputString; 

XmlConfigurator.Configure(); 
ILog logger = LogManager.GetLogger(typeof(ApplicationClassName)); 
logger.Debug(""); 
+0

私はそれらの静力学を使用してthreadsafetyを心配するだろう... –

関連する問題