2008-12-02 33 views
52

Chơi với log4net, tôi đã thấy khả năng sử dụng một chồng các nhãn ngữ cảnh được gọi là NDC.Khi nào sử dụng 'bối cảnh chẩn đoán lồng nhau' (NDC)?

Nhãn được đẩy trên ngăn xếp này được hiển thị trong PatternLayout bằng cách chỉ định thông số %x hoặc %ndc.

Việc sử dụng là một cái gì đó như:

ILog log = log4net.LogManager.GetLogger(...) ; 

//pattern layout format: "[%ndc] - %message%newline" 

log.Info("message 1"); 
using(log4net.NDC.Push("context") 
{ 
    using(log4net.NDC.Push("inner_context") 
    { 
     log.Info("message 2"); 
    } 
    log.Info("message 3"); 
} 
log.Info("message 4"); 

Các đầu ra được cái gì đó như:

null - message 1 
context inner_context - message 2 
context - message 3 
null - message 4 

Theo kinh nghiệm lập trình của bạn với log4net, khi nào bạn tìm thấy tính năng này có ích?

+3

Dường như log4net đã bị phản đối NDC nghiêng về bối cảnh mục đích chung ngăn xếp. Lời khuyên trong câu trả lời vẫn đúng, nhưng http://logging.apache.org/log4net/release/manual/contexts.html nói "NDC (Ngữ cảnh Chẩn đoán lồng nhau) tồn tại để tương thích với các phiên bản cũ hơn của log4net.Lớp helper này triển khai một ngăn xếp được lưu trữ trong thuộc tính bối cảnh luồng có tên là NDC. ” –

Trả lời

24

Trong ứng dụng máy chủ chẳng hạn như ASP.NET.

Ví dụ: bạn có thể đẩy thông tin về yêu cầu hiện tại vào NDC.

+3

Một liên kết đến ví dụ sẽ hữu ích –

+5

Tôi không có liên kết, nhưng hãy nghĩ về tình huống mà bạn có ứng dụng ASP.NET với nhiều Nếu bạn đẩy ID yêu cầu (hoặc được tạo hoặc sử dụng một số định danh từ yêu cầu) vào NDC, bạn có thể tương ứng với tất cả các thông điệp tường trình cho một yêu cầu cho trước thông qua tất cả các cấp ứng dụng của bạn. các thành phần cấp thấp mà không biết gì về ASP.NET có thể được tương quan ngược lại với yêu cầu khởi tạo –

+0

@Johnny_D, ví dụ? [link to example below] (http://stackoverflow.com/a/17344012/939250) –

18

Tính năng này có ích khi bạn có nhiều nhật ký cần thực hiện. Khi nào bạn có nhiều nhật ký? Chẩn đoán lỗi lạ trên hệ thống sản xuất với các đầu ra xen kẽ. Có nhiều ngữ cảnh hơn cho bạn cách lọc đầu ra hoặc không xuất nhật ký không cần thiết.

Một trường hợp khác ngữ cảnh lồng nhau có thể hữu ích là nếu một phương pháp hoặc một số tính năng được gọi nhiều lần trong các ngữ cảnh khác nhau và bạn cần một cách để phân biệt giữa chúng.

71

Muốn có ví dụ?

Hãy API Web sau đây viết bằng ASP.NET MVC4:

// GET api/HypervResource 
public string Get() 
{ 
    logger.Debug("Start of service test"); 
    System.Threading.Thread.Sleep(5000); // simulate work 
    logger.Debug("End of service test"); 
    return "HypervResource controller running, use POST to send JSON encoded RPCs"; 
} 

Khi máy chủ yêu cầu HTTP đồng thời được thực hiện, khai thác gỗ có thể nhận được xen kẽ. Ví dụ.

2013-06-27 13:28:11,967 [10] DEBUG HypervResource.WmiCalls [(null)] - Start of service test 
2013-06-27 13:28:12,976 [12] DEBUG HypervResource.WmiCalls [(null)] - Start of service test 
2013-06-27 13:28:14,116 [13] DEBUG HypervResource.WmiCalls [(null)] - Start of service test 
2013-06-27 13:28:16,971 [10] DEBUG HypervResource.WmiCalls [(null)] - End of service test 
2013-06-27 13:28:17,979 [12] DEBUG HypervResource.WmiCalls [(null)] - End of service test 
2013-06-27 13:28:19,119 [13] DEBUG HypervResource.WmiCalls [(null)] - End of service test 

Trong ví dụ đơn giản này, bạn có thể sử dụng id luồng để phân biệt các yêu cầu, nhưng có thể phức tạp khi tệp nhật ký phát triển phức tạp.

Một lựa chọn tốt hơn là cung cấp số nhận dạng duy nhất nhóm các thông điệp nhật ký nhóm lại cho cùng một yêu cầu. Chúng tôi có thể cập nhật mã như sau:

// GET api/HypervResource 
public string Get() 
{ 
    using(log4net.NDC.Push(Guid.NewGuid().ToString())) 
    { 
     logger.Debug("Start of service test"); 
     System.Threading.Thread.Sleep(5000); // simulate work 
     logger.Debug("End of service test"); 
     return "HypervResource controller running, use POST to send JSON encoded RPCs"; 
    } 
} 

Điều này tạo ra nhật ký bạn có thể grep để xem các vấn đề liên quan đến yêu cầu cụ thể. Ví dụ.

2013-06-27 14:04:31,431 [11] DEBUG HypervResource.WmiCalls [525943cb-226a-43c2-8bd5-03c258d58a79] - Start of service test 
2013-06-27 14:04:32,322 [12] DEBUG HypervResource.WmiCalls [5a8941ee-6e26-4c1d-a1dc-b4d9b776630d] - Start of service test 
2013-06-27 14:04:34,450 [13] DEBUG HypervResource.WmiCalls [ff2246f1-04bc-4451-9e40-6aa1efb94073] - Start of service test 
2013-06-27 14:04:36,434 [11] DEBUG HypervResource.WmiCalls [525943cb-226a-43c2-8bd5-03c258d58a79] - End of service test 
2013-06-27 14:04:37,325 [12] DEBUG HypervResource.WmiCalls [5a8941ee-6e26-4c1d-a1dc-b4d9b776630d] - End of service test 
2013-06-27 14:04:39,453 [13] DEBUG HypervResource.WmiCalls [ff2246f1-04bc-4451-9e40-6aa1efb94073] - End of service test 
0

NDC.Push không được dùng nữa. Cách ưa thích bây giờ (ThreadContext.Stacks["NDC"]) là thế này:

var disposable = ThreadContext.Stacks["NDC"].Push("context"); 
try 
{ 
    Log.Info("begin"); // optional, but nice 
    ... 
} 
finally 
{ 
    Log.Info("end"); // optional, but nice 
    disposable.Dispose(); 
} 

Nhớ kiểm tra mô hình chuyển đổi của bạn để nó bao gồm %property{NDC}:

<layout type="log4net.Layout.PatternLayout"> 
    <conversionPattern 
    value="%date [%2thread] %-5level [%property{NDC}] - %.10240message%newline" /> 
</layout> 
Các vấn đề liên quan