2013-04-10 11 views
6

this question'un farkındayım ve cevabı kabul ediyorum, ancak log4net ile aşağıdakileri yapabilir miyim? Bunun yerine sahipLog4net'te çok satırlı günlük girişine girinti nasıl eklenir?

:

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 

zaten destekleniyor mu yoksa özel bir appender veya özel bir düzen yazmak gerekiyor:

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 

alabilir miyim?

cevap

12

Kendi sorularımı cevaplamaktan nefret ediyorum, ama cevabı kendim geliştirdiğimden beri sizinle paylaşmak istedim.

Log4net'i uzattım. Çözüm, PatternLayout'tan miras alır, bu nedenle tüm PatternLayout özellikleri kullanılabilir. Ayrıca yeni bir model % girinti mevcuttur. Yukarıdaki örnekte olduğu gibi günlüğünü almak için sadece kullanım:

<conversionPattern value="%date - %indentation%message%newline%exception"/> 

log4net kod ilginç istisnalar (ya da ben bunu anlamıyorum) biçimlendirme. Bu durumda, her zaman% istisnasını desene koymalıyım çünkü "IgnoresException = false" kodunu yazdım. IgnoresException = true ile, log4net tüm formatları tamamen yok sayar ve girintilemeyi kaybedersiniz. Aşağıda

Kullanılacak kod Log4net uzatmak için:

/// <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; 
     } 
    } 
} 
+1

Teşekkür bu paylaşım için. Satırları ayırırken, onu "value.Split" (yeni string [] {"\ r \ n", "\ n"}, StringSplitOptions.None) olarak değiştirdim. –

+1

Harika, eğer daha iyi çalışırsa. Ortamımın her yerinden Environment.NewLine kullanıyorum, çünkü her zaman işletim sistemine bağlı olarak doğru şeyi döndürüyor. Windows altında "\ r \ n" ve Linux (Mono) altında "\ n" döndürecektir. Ama ikisinin bir karışımına ihtiyacınız varsa, o zaman çözümünüz bununla baş edebilir. – Eiver

İlgili konular