我正在尝试将特定方法的输入和输出记录到数据库中。我想将这些信息放在不同的专栏中。我已经调查了PatternLayout,它似乎只适合单个%消息参数,这意味着如果你这样做:
log.Debug("This is a message");
然后log4net将“这是一条消息”视为要记录的消息。我想做点什么:
log.Debug(request, response);
这可以使用log4net吗?请注意,我的目标是在单独的列中添加“请求”和“响应”。
答案 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("");