2013-04-10 26 views
6

Tôi biết về this question và tôi đồng ý với câu trả lời, nhưng tôi có thể làm như sau với log4net không?Làm cách nào để thêm thụt đầu dòng vào mục nhập nhật ký nhiều dòng trong log4net?

Thay vì:

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 

Tôi có thể có:

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 

là nó đã được hỗ trợ hay tôi cần phải viết một appender tùy chỉnh hoặc một bố cục tùy chỉnh?

Trả lời

12

Tôi ghét trả lời các câu hỏi của riêng mình, nhưng vì tôi đã tự mình phát triển câu trả lời, tôi muốn chia sẻ câu trả lời đó với bạn.

Tôi đã mở rộng log4net. Giải pháp kế thừa từ PatternLayout, vì vậy tất cả các tính năng của PatternLayout đều khả dụng. Ngoài ra, mẫu mới % thụt đầu dòng cũng có sẵn. Để ghi nhật ký giống như trong ví dụ trên, chỉ cần sử dụng:

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

Khi định dạng ngoại lệ mã log4net là kỳ quặc (hoặc tôi không hiểu). Vì vậy, trong trường hợp này, bạn nên luôn đặt% exception vào mẫu, vì tôi đã mã hóa cứng "IgnoresException = false". Với IgnoresException = true, log4net hoàn toàn bỏ qua bất kỳ định dạng nào và bạn mất thụt đầu dòng.

Sử dụng mã dưới đây để mở rộng 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; 
     } 
    } 
} 
+1

Cám ơn chia sẻ này. Khi tách các dòng, tôi đã thay đổi nó thành 'value.Split (chuỗi mới [] {" \ r \ n "," \ n "}, StringSplitOptions.None)'. –

+1

Tuyệt vời, nếu nó hoạt động tốt hơn cho bạn. Tôi có xu hướng sử dụng Environment.NewLine ở khắp mọi nơi trong mã của tôi, bởi vì nó luôn luôn trả về điều đúng tùy thuộc vào hệ điều hành. Trong Windows nó sẽ trả về "\ r \ n" và dưới Linux (Mono) nó sẽ trả về "\ n". Nhưng nếu bạn cần một sự pha trộn của hai, sau đó giải pháp của bạn có thể đối phó với điều đó. – Eiver

Các vấn đề liên quan