2010-01-16 30 views
24

Tôi đang cố gắng tạo giải pháp ghi nhật ký liên quan đến nhiều quy trình trên nhiều máy. Tôi đã lên kế hoạch sử dụng UDPAppender để gửi tất cả các thông điệp tường trình tới một máy duy nhất có thể quản lý chúng. Tôi có một vài câu hỏi về patternstrings vs patternlayouts.thông tin id quá trình log4net

Vì tôi cần biết cả máy nào và quá trình xử lý thông điệp tường trình đó đến từ đâu, tôi cũng muốn bao gồm thông tin đó trong nhật ký. Tôi đã tìm thấy% thuộc tính {log4net: Tên máy chủ} cho tên máy chủ và hoạt động tốt. Tuy nhiên, tôi không thấy bất cứ điều gì cho id quá trình trong PatternLayouts. Tôi làm, tất nhiên, thấy một cái gì đó như thế trong PatternString. Từ FAQ:

<appender name="LogFileAppender" type="log4net.Appender.FileAppender"> 
    <file type="log4net.Util.PatternString" value="log-file-[%processid].txt" /> 

    <layout type="log4net.Layout.PatternLayout" value="%date [%thread] %-5level %logger - %message%newline" /> 
</appender> 

Nhưng tôi không chắc chắn nếu hoặc làm thế nào để trộn và kết hợp hai (hoặc thậm chí nếu điều này là cách kinh điển để làm như vậy).

Vì vậy, câu hỏi của tôi là:

  1. sự khác biệt giữa PatternString và PatternLayout là gì? Tại sao có cả hai?

  2. Tôi thấy% processid trong PatternString, làm thế nào để tôi nhận được điều tương tự trong PatternLayout? Đây là bố cục thử nghiệm của tôi:

    <layout type="log4net.Layout.PatternLayout"> 
        <conversionPattern value="%date [%thread] [%property{log4net:HostName}] %-5level %logger - %message%newline" /> 
    </layout> 
    
  3. Cuối cùng, bạn nên sử dụng bố cục XML cho trình bổ sung UDP. Có vẻ như XmlLayoutSchemaLog4j đã thêm HostNameProperty vào thông báo XML. Nếu tôi không muốn thêm ID tiến trình mới này (và có thể là Process Name) vào thông báo XML, cách tốt nhất để làm điều này là gì? Tôi có nên chỉ cần sao chép src \ Layouts \ XmlLayoutSchemaLog4j.cs, sửa đổi nó, và để cho log4net biết rằng tôi đã tạo Layout mới này (như SampleLayoutsApp)?

Nhờ sự giúp đỡ của bạn

Trả lời

39

Bạn có thể thêm bất kỳ thuộc tính nào bạn muốn vào GlobalContext.Tôi sử dụng bối cảnh này để lưu trữ các quá trình id, như thế này:

log4net.GlobalContext.Properties["pid"] = Process.GetCurrentProcess().Id; 

Sau đó, bạn tham khảo thuộc tính này từ appender của bạn sử dụng một mô hình thường xuyên, như thế này:

<layout type="log4net.Layout.PatternLayout"> 
    <conversionPattern value="%date %property{pid} %level %logger - %message%newline" /> 
</layout> 

Bạn có thể thêm bao nhiêu tài sản như bạn muốn, nhưng vì bản chất toàn cầu, nó hoạt động tốt nhất cho các thuộc tính không thay đổi trong quá trình thực thi ứng dụng của bạn.

+0

thử tất cả mọi thứ% pid,% ProcessID và nhiều hơn nữa, không có gì làm việc. Giải pháp của bạn hoạt động. Cảm ơn. – Nemo

3

Rõ ràng PatternString chỉ có thể được sử dụng để tạo tên đăng nhập (ví dụ: tên tập tin, vv) trong khi bố trí cho phép bạn định dạng thông điệp thực tế xâm nhập vào nhật ký. Nếu không có sẵn mẫu cho id quá trình trong quá trình bố trí, thì bạn có thể dễ dàng thêm nó. Nó đơn giản hơn nhiều so với việc tạo toàn bộ bố cục.

Sau đây là cách để làm điều đó:

Tạo riêng chuyển đổi mô hình tùy chỉnh của bạn (ví dụ dưới đây cố gắng để có được tên của ứng dụng cho dù thắng hay web):

internal sealed class ApplicationNamePatternConverter : PatternLayoutConverter 
{ 
    /// <summary> 
    /// Write the event application name to the output 
    override protected void Convert(TextWriter writer, LoggingEvent loggingEvent) 
    { 
     string name = string.Empty; 
     if(System.Web.HttpContext.Current != null) 
     { 
      string[] applicationPath = System.Web.HttpContext.Current.Request.ApplicationPath.Split('/'); 
      name = applicationPath[applicationPath.Length - 1]; 
     } 
     else 
     { 
      if(System.Reflection.Assembly.GetEntryAssembly() != null) 
      { 
       name = System.Reflection.Assembly.GetEntryAssembly().GetName().Name; 
      } 
     } 
     writer.Write(name); 
    } 
} 

Thêm mục nhập cho công cụ chuyển đổi của bạn vào sổ đăng ký của lớp PatternLayout

static PatternLayout() 
{ 
... 
    s_globalRulesRegistry.Add("ApplicationName", typeof(ApplicationNamePatternConverter)); 
} 

Bây giờ bạn có thể sử dụng %ApplicationName trong giá trị PatternLayout để nhận được những gì bạn cần.

Tôi khuyên bạn không nên sử dụng bố cục XmlLayoutSchemaLog4j vì nó rất nặng và có thể làm giảm hiệu suất của ứng dụng nếu được sử dụng thường xuyên.

15

Bạn có thể ăn một PatternString thành một PatternLayout:

<layout type="log4net.Layout.PatternLayout"> 
     <conversionPattern type="log4net.Util.PatternString" value="%processid" /> 
    </layout> 
+0

Điều đó thực sự hiệu quả. Cảm ơn. –

+3

Hãy nhớ thoát khỏi ký tự phần trăm cho các thuộc tính bạn muốn trích xuất từ ​​sự kiện, ví dụ: để bao gồm id quá trình làm một trong các tệp nhật ký cột – Pelle

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