2009-05-25 93 views
0

我正在尝试将特定方法的输入和输出记录到数据库。我希望将这些信息分列。我已经调查的PatternLayout和它似乎只迎合单个%的消息参数,这意味着,如果你这样做:log4net:在数据库的一行中记录两条消息?

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

然后log4net的看到“这是一个消息”作为要记录的消息。我想要做类似的事情:

log.Debug(request, response); 

这可能使用log4net吗?请记住,我的目标是在单独的列中有“请求”和“响应”列。

回答

3

你PatternConverter方式是朝着正确的方向迈出了一步,尽管使用了静态的输入和输出属性所有有点不稳定(线程安全明智)。

这里的技巧是要认识到logger.Debug(...)上的消息参数是对象,并且您可以传入任何您喜欢的东西。

你可以自定义一个消息类型

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并添加转换器在该类的构造函数。这样你也可以减少你的配置。这将而不是导致您丢失%消息令牌,您的%输入和%输出令牌将附加到PatternLayout支持的所有令牌。所以,你实际上可以有这样一个规律:

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

这里有一个快速的实现自定义的模式布局:

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

要使使用较少冗余,您可以将此作为ILogger接口的扩展方法来实现两个参数。然后用法如下:logger.Debug(input,output); – 2009-05-26 09:28:53

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 ... – 2009-05-26 09:24:17

相关问题