如何在log4net中向多行日志条目添加缩进?
我知道并且同意答案,但是我可以用log4net做以下事情吗 而不是:如何在log4net中向多行日志条目添加缩进?,log4net,multiline,Log4net,Multiline,我知道并且同意答案,但是我可以用log4net做以下事情吗 而不是: 2013-04-09 12:54:47.093 INFO Main: Line 1 Line 1 Line 1 Line 2 Line 2 Line 2 Line 3 Line 3 Line 3 2013-04-09 12:54:47.093 INFO Main: Line 1 Line 1 Line 1 Line 2 Line 2 Line 2 Line 3 Line 3 Line 3 我可以要: 2013-04-09
2013-04-09 12:54:47.093 INFO Main: Line 1 Line 1 Line 1
Line 2 Line 2 Line 2
Line 3 Line 3 Line 3
2013-04-09 12:54:47.093 INFO Main: Line 1 Line 1 Line 1
Line 2 Line 2 Line 2
Line 3 Line 3 Line 3
我可以要:
2013-04-09 12:54:47.093 INFO Main: Line 1 Line 1 Line 1
Line 2 Line 2 Line 2
Line 3 Line 3 Line 3
2013-04-09 12:54:47.093 INFO Main: Line 1 Line 1 Line 1
Line 2 Line 2 Line 2
Line 3 Line 3 Line 3
它已经被支持了吗?或者我需要编写一个自定义的附加器或自定义布局吗?我不想回答我自己的问题,但是因为我自己开发了答案,所以我想与大家分享 我扩展了log4net。解决方案继承自PatternLayout,因此所有PatternLayout功能都可用。此外,还提供了新图案%缩进。要获得上述示例中的日志记录,只需使用:
<conversionPattern value="%date - %indentation%message%newline%exception"/>
当格式化异常时,log4net代码很奇怪(或者我不理解)。所以在这种情况下,您应该始终在模式中放置%exception,因为我硬编码了“IgnoreSceception=false”。当IgnoresException=true时,log4net会完全忽略任何格式设置,从而导致缩进松动
使用下面的代码扩展log4net:
/// <summary>
/// Converts %indentation to string
/// </summary>
public class IndentationPatternConverter : PatternConverter
{
protected override void Convert(TextWriter writer, object state)
{
// do nothing - %indentation is used for indentation, so nothing should be written
}
}
public class IndentationPatternLayout : PatternLayout
{
private PatternConverter m_head;
public override void Format(TextWriter writer, LoggingEvent loggingEvent)
{
if (writer == null)
{
throw new ArgumentNullException("writer");
}
if (loggingEvent == null)
{
throw new ArgumentNullException("loggingEvent");
}
PatternConverter c = m_head;
IndentationWriter indentationWriter = new IndentationWriter(writer);
// loop through the chain of pattern converters
while (c != null)
{
if (c is IndentationPatternConverter)
{
indentationWriter.SetIndentation();
}
c.Format(indentationWriter, loggingEvent);
c = c.Next;
}
indentationWriter.Finish();
}
override public void ActivateOptions()
{
PatternParser patternParser = CreatePatternParser(ConversionPattern);
ConverterInfo converterInfo = new ConverterInfo()
{
Name = "indentation",
Type = typeof(IndentationPatternConverter)
};
patternParser.PatternConverters.Add("indentation", converterInfo);
m_head = patternParser.Parse();
PatternConverter curConverter = m_head;
this.IgnoresException = false;
}
}
public class IndentationWriter : TextWriter
{
TextWriter writer;
int indentation = 0;
List<string> lines = new List<string>();
public IndentationWriter(TextWriter writer)
{
this.writer = writer;
}
public override Encoding Encoding
{
get { return writer.Encoding; }
}
public override void Write(string value)
{
string[] values = value.Split(new string[] { Environment.NewLine }, StringSplitOptions.None);
for (int i = 0; i < values.Length; i++)
{
if (i > 0) values[i] = Environment.NewLine + values[i];
}
lines.AddRange(values);
}
public void Finish()
{
for (int i = 0; i < lines.Count; i++)
{
string line = lines[i];
if (i < lines.Count - 1) line = lines[i].Replace(Environment.NewLine, Environment.NewLine + new string(' ', indentation));
writer.Write(line);
}
lines.Clear();
}
public override void WriteLine(string value)
{
this.Write(value + Environment.NewLine);
}
public void SetIndentation()
{
foreach (string line in lines)
{
indentation += line.Length;
}
}
}
//
///将%缩进转换为字符串
///
公共类IndentationPatternConverter:PatternConverter
{
受保护的覆盖无效转换(TextWriter编写器,对象状态)
{
//不执行任何操作-%缩进用于缩进,因此不应写入任何内容
}
}
公共类缩进PatternLayout:PatternLayout
{
专用转换头;
公共覆盖无效格式(TextWriter编写器、LoggingEvent LoggingEvent)
{
if(writer==null)
{
抛出新的异常(“编写器”);
}
如果(loggingEvent==null)
{
抛出新的ArgumentNullException(“loggingEvent”);
}
模式转换器c=m_头;
缩进写入器缩进写入器=新缩进写入器(写入器);
//循环通过模式转换器链
while(c!=null)
{
如果(c是缩进模式转换器)
{
SetIndentation();
}
c、 格式(indentationWriter、loggingEvent);
c=c.下一步;
}
indentationWriter.Finish();
}
覆盖公共void ActivateOptions()
{
PatternParser PatternParser=CreatePatternParser(转换模式);
ConverterInfo ConverterInfo=新ConverterInfo()
{
Name=“缩进”,
类型=类型(缩进模式转换器)
};
patternParser.PatternConverters.Add(“缩进”,converterInfo);
m_head=patternParser.Parse();
Pattern Converter curConverter=磁头;
this.IgnoresException=false;
}
}
公共类标识编写器:TextWriter
{
文本作者;
int缩进=0;
列表行=新列表();
公共标识编写器(文本编写器)
{
this.writer=writer;
}
公共覆盖编码
{
获取{返回writer.Encoding;}
}
公共重写无效写入(字符串值)
{
string[]values=value.Split(新字符串[]{Environment.NewLine},StringSplitOptions.None);
for(int i=0;i0)值[i]=Environment.NewLine+值[i];
}
行。添加范围(值);
}
公共空间整理()
{
对于(int i=0;i
感谢您分享此信息。在拆分行时,我将其更改为value.Split(新字符串[]{“\r\n”,“\n”},StringSplitOptions.None)
。如果它对您更有效,那就太好了。我倾向于在代码中的任何地方使用Environment.NewLine,因为它总是根据操作系统返回正确的内容。在Windows下它将返回“\r\n”,在Linux(Mono)下它将返回“\n”。但是,如果您需要两者的混合,那么您的解决方案可以解决这一问题。