私自身の質問には答えたくありませんが、私は自分自身で答えを作り出しているので、私はあなたと共有したいと思っていました。
私はlog4netを拡張しました。このソリューションはPatternLayoutを継承しているので、すべてのPatternLayout機能を利用できます。さらに、新しいパターン%インデントが利用可能です。上記の例のようにログを取得するには、単純に使用します。
<conversionPattern value="%date - %indentation%message%newline%exception"/>
log4netのコードが風変わりである例外を(または私はそれを理解していない)のフォーマット。だからこの場合は、 "IgnoresException = false"をハードコードしているので、常に%exceptionをパターンに入れるべきです。 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;
}
}
}
感謝。行を分割するとき、私は 'value.Split(new string [] \" \ "、" \ n "}、StringSplitOptions.None)'に変更しました。 –
あなたのためにうまくいくなら、素晴らしい。私は環境に応じて常に正しいものを返すので、Environment.NewLineをコード内のどこでも使用する傾向があります。 Windowsでは "\ r \ n"を返し、Linux(Mono)では "\ n"を返します。しかし、2つが混在する必要がある場合は、そのソリューションで対処できます。 – Eiver