log4net:在数据库中的一行中记录两条消息?

时间:2009-05-25 15:16:25

标签: log4net

我正在尝试将特定方法的输入和输出记录到数据库中。我想将这些信息放在不同的专栏中。我已经调查了PatternLayout,它似乎只适合单个%消息参数,这意味着如果你这样做:

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

然后log4net将“这是一条消息”视为要记录的消息。我想做点什么:

log.Debug(request, response);

这可以使用log4net吗?请注意,我的目标是在单独的列中添加“请求”和“响应”。

2 个答案:

答案 0 :(得分: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并在该类的构造函数中添加转换器。这样你也可以减少你的配置。这将导致您丢失%消息令牌,除了PatternLayout支持的所有令牌之外,您的%输入和%输出令牌将会出现。所以你实际上可以有这样的模式:

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

以下是自定义模式布局的快速实现:

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

答案 1 :(得分: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规范:

<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("");