2010-07-09 22 views
18

Tôi hiện đang điều tra nhiều khả năng ghi nhật ký cho các dự án .net và tôi không thể quyết định giữa các tính năng System.Diagnostics.Debug/Trace và thư viện của bên thứ ba như log4net, MS doanh nghiệp Thư viện, NLog vv
Tại thời điểm này tôi đã phát hiện ra điều này:System.Diagnostics.Debug không gian tên vs Các giải pháp ghi nhật ký khác (log4net, MS Enterprise Library, v.v.)

  • System.Diagnostics là khá khó khăn để cấu hình và sử dụng kể từ khi bạn cần phải cấu hình một cách rõ ràng tất cả người nghe, bộ lọc, nguồn, vv Có vẻ như nó cũng thiếu chèn số lượng lớn cho DB (suy nghĩ về việc viết 100'000 mục nhập nhật ký với Chèn riêng của nó, đáng sợ, phải không?). Nhưng bởi một số người, nó được coi là 'tuyệt vời', không sử dụng các lib bổ sung cho một thứ "thô sơ" như Logging (tất nhiên, tại một số điểm, nó làm giảm số lượng thư viện của bên thứ 3 mà dự án của bạn dựa vào, nhưng không phải lúc này, tôi giả sử)
  • Các bên thứ ba mạnh hơn, thường nhanh hơn, dễ sử dụng hơn nhiều, nhưng cấu hình đôi khi cũng có thể gây đau đớn và thường các thư viện này kém đáng tin cậy hơn (chẳng hạn như dừng đột ngột ghi nhật ký bởi EntLib, vv)
  • Còn Common.Logging thì sao? là nó có giá trị cố gắng (kể từ khi, như tôi đã nghe, nó cung cấp plug-in khuôn khổ đăng nhập khác nhau và hành động như một giao diện giữa các ứng dụng và lib mong muốn)?


Tôi thực sự biết ơn nếu ai đó có thể chỉ cho tôi đúng hướng hoặc chính xác (hoặc thêm điều gì đó) vào so sánh của tôi ở trên! Có lẽ nếu bạn khuyến khích tôi sử dụng bên thứ 3, bạn có thể tư vấn cho một số người cụ thể (có tính đến các ứng dụng của chúng tôi có thể sẽ không cần bất kỳ thứ gì ưa thích như UDP, tệp cuộn, v.v.- chỉ đơn giản là tệp, email, DB và Nhật ký sự kiện)?
Cảm ơn trước!

+0

Không phải là System.Diagnostics.Debug/Dấu vết duy nhất có liên quan (hoặc thậm chí được biên soạn vào mã) bất cứ khi nào hằng DEBUG/TRACE được xây dựng vào mã của bạn (ví dụ: một Debug, không phải là một phát hành, xây dựng)? Vì vậy, lợi ích từ việc sử dụng S.D.Debug là khá nhỏ so với một khung khai thác đầy đủ tính năng. – Andreas

+0

Như tôi biết, S.D.Debug chỉ hoạt động khi bạn xây dựng ứng dụng của bạn trong chế độ Debug, nhưng nếu bạn xây dựng nó trong chế độ Release, bạn sẽ chỉ nhận được các thông điệp được ghi với S.D.Trace (trông gần giống như Debug). – timurso

Trả lời

23

Bạn có thể tìm thấy nhiều thông tin về log4net và NLog hoặc ở đây trên StackOverflow bởi thường googling hơn.

Bạn cũng có thể tìm thấy nhiều thông tin về System.Diagnostics. Một điều cần lưu ý về System.Diagnostics, tôi nghĩ rằng bạn sẽ tìm thấy rất nhiều tài liệu tham khảo ở đây trên StackOverflow về việc sử dụng Debug.Write/WriteLine và Trace.Write/WriteLine. Một cách "tốt hơn" được cho là sử dụng TraceSources. TraceSources tương tự như logger trong log4net và NLog. TraceSources cho phép bạn có mức độ chi tiết cao hơn cho các thông điệp ghi nhật ký của bạn, giúp dễ dàng bật một số lần đăng nhập và một số đăng nhập (theo lớp hoặc danh mục, ngoài cấp độ). TraceSources có một nhược điểm, so với log4net và NLog, trong đó mỗi TraceSource mà bạn tạo trong mã của bạn phải được cấu hình rõ ràng trong app.config (nếu bạn muốn nó thực sự đăng nhập).

log4net và NLog có khái niệm phân cấp, nếu trình ghi nhật ký chính xác mà bạn yêu cầu không được định cấu hình rõ ràng, "tổ tiên" được chọn để xem liệu "tổ tiên" nào được định cấu hình hay không, nếu có, trình ghi nhật ký được yêu cầu "kế thừa" những cài đặt đó. Tổ tiên chỉ đơn giản là các phần của tên logger được phân cách bằng dấu ".". (Vì vậy, nếu bạn yêu cầu một logger gọi là "ABC.DEF.GHI", tổ tiên sẽ là "ABC.DEF""ABC"). Nó cũng có thể (yêu cầu?) để có cấu hình "root" logger trong app.config rằng tất cả các yêu cầu logger sẽ rơi trở lại nếu chúng không được cấu hình rõ ràng và không có tổ tiên nào được cấu hình. Vì vậy, bạn có thể cấu hình chỉ là một "root" logger để đăng nhập ở một mức độ nhất định và tất cả các logger của bạn trong mã của bạn sẽ đăng nhập ở cấp đó. Ngoài ra, bạn có thể cấu hình bộ ghi "root" để "tắt" và sau đó bật một hoặc nhiều logger một cách rõ ràng (hoặc bằng cách cấu hình một tổ tiên). Bằng cách này, NO logger sẽ đăng nhập EXCEPT cho những người được cấu hình.

Nếu bạn nhìn here, bạn sẽ tìm thấy một trình bao bọc thú vị xung quanh System.Diagnostics TraceSources cung cấp khả năng thừa kế rất giống với log4net và NLog.

Để minh họa:

Một mô hình sử dụng phổ biến đối với người khai thác gỗ trong log4net và NLog là để có được một logger như thế này:

//log4net 
static ILog logger = LogManager.GetLogger(
        System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); 

//NLog 
static Logger logger = LogManager.GetCurrentClassLogger(); 

Trong cả hai trường hợp tên của logger sẽ là tên loại đầy đủ.

Trong tệp app.config, bạn có thể, nếu bạn muốn, chỉ định cấu hình trình ghi nhật ký "root" và cả hai trình ghi nhật ký sẽ kế thừa cài đặt của trình ghi nhật ký (cấp, trình phụ/mục tiêu, v.v.). Hoặc bạn có thể cấu hình một trình ghi nhật ký cho một số không gian tên. Bất kỳ logger nào có kiểu được định nghĩa trong không gian tên đó sẽ kế thừa các thiết lập logger đó.

Đủ log4net và NLog, có thể bạn đã biết cách chúng hoạt động.

Liên kết ở trên minh họa trình bao bọc dựa trên TraceSource cho phép cấu hình tương tự. Vì vậy, nếu bạn muốn, bạn có thể làm một cái gì đó như thế này trong lớp học của bạn:

static TraceSource ts = new TraceSource(
       System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); 

Với wrapper liên kết ở trên, bạn có thể cấu hình một TraceSource ở mức cao hơn (lớp/namespace hệ thống cấp bậc khôn ngoan, chứ không phải mức độ) và kế thừa các cài đặt đó trong trình ghi nhật ký cấp thấp hơn. Vì vậy, nếu tên loại đủ điều kiện của bạn là một cái gì đó như thế này: ABC.DEF.GHI, sau đó bạn có thể cấu hình một TraceSource cho ABC hoặc ABC.DEF (mức không gian tên) và lớp "GHI" sẽ kế thừa các thiết lập. Điều này thực sự có thể làm giảm số lượng cấu hình mà bạn phải làm.

Lưu ý rằng bạn không bị giới hạn (với bất kỳ nền tảng ghi nhật ký nào) để sử dụng loại hoặc loại tên của lớp để lấy trình ghi nhật ký. Bạn có thể định nghĩa sơ đồ đặt tên trình ghi log của riêng mình, có thể dựa trên các vùng chức năng ("Giao tiếp", "Communication.Send", "Communication.Receive", v.v.). Một lần nữa, bạn có thể yêu cầu một logger/TraceSource ở mức độ cao nhất của granualarity (hoặc không) và sau đó cấu hình ở bất kỳ mức độ chi tiết nào có ý nghĩa.

Vì vậy, bạn có thể yêu cầu người khai thác gỗ trong mã của bạn như thế này:

ILog logger = LogManager.GetLogger("Communication.Receive"); 
ILog logger = LogManager.GetLogger("Communication.Send"); 

Logger logger = LogManager.GetLogger("Communication.Receive"); 
Logger logger = LogManager.GetLogger("Communication.Send"); 

TraceSource ts = new TraceSource("Communication.Receive"); 
TraceSource ts = new TraceSource("Communication.Send"); 

Nếu bạn cấu hình chỉ "Truyền thông" trong file app.config của bạn, sau đó tất cả logger sẽ thừa hưởng những thiết lập (vì chúng là con cháu của "Giao tiếp"). Nếu bạn chỉ cấu hình "Commuincation.Receive", thì chỉ có logger "Communication.Receive" mới đăng nhập được. Máy ghi nhật ký "Communication.Send" sẽ bị tắt. Nếu bạn cấu hình cả "Giao tiếp" và "Commuincation.Receive", thì logger "Communication.Receive" sẽ đăng nhập vào các thiết lập "Communication.Receive" trong khi logger "Communication.Sender" sẽ đăng nhập vào các thiết lập "Communication". Trong log4net và NLog có thể có nhiều thừa kế hơn thế, nhưng tôi không biết đủ để đi vào nó.

Một điều bạn bỏ lỡ khi sử dụng Hệ thống.Chẩn đoán là sự linh hoạt để định dạng định dạng đầu ra ghi nhật ký của bạn rất dễ dàng. Có một thư viện của bên thứ ba cung cấp định dạng cấu hình rất đẹp cho việc ghi nhật ký dựa trên TraceSource. Bạn có thể tìm thấy nó here.

Tôi đã sử dụng Common.Logging một số. Chủ yếu là trong prototyping, nhưng tôi có thể sử dụng nó trong dự án tiếp theo của chúng tôi. Nó hoạt động khá tốt và nó tương đối dễ dàng để viết khai thác đăng nhập của riêng bạn để cắm vào nó (chẳng hạn như nếu bạn muốn viết một trừu tượng TraceSource tương tự như những gì tôi đã liên kết ở trên). Hai điều quan trọng bị thiếu trong Common.Logging ngay bây giờ (mặc dù trang web của họ nói rằng chúng được lên kế hoạch cho bản phát hành "kế tiếp") là các bối cảnh đăng nhập (như log4net và NLog NDC/MDC/GDC objects và System.Diagnostics.CorrelationManger.LogicalOperationStack) và khả năng tương thích Silverlight. Bạn vẫn có thể tương tác với các đối tượng bối cảnh log4net hoặc NLog trong mã của bạn trong khi sử dụng Common.Logging, nhưng loại đó đánh bại mục đích của nó, đúng không.

Tôi không biết tôi có giúp hay không!

Dưới đây là một số điểm chính mà tôi sẽ làm về log4net, NLog, và TraceSource:

log4net - rất phổ biến, có lẽ cần một số cập nhật - ít nhất là được xây dựng trên .NET 4.0, phát hành cuối cùng một vài năm trước, rất linh hoạt.

NLog - rất giống với log4net trong nhiều khía cạnh, phiên bản mới bây giờ (beta của NLog 2.0 vừa xuất hiện)

TraceSource - không phụ thuộc bên thứ ba, nếu không có nỗ lực từ phía bạn (hoặc ai đó) không phải là mạnh mẽ như log4net hoặc NLog (thiếu sót quan trọng - phân cấp logger, định dạng đầu ra - cả hai đều dễ dàng định địa chỉ thông qua một liên kết ở trên), Microsoft có rất nhiều thành phần của chúng với System.Diagnostics để bạn có thể nhận được kết quả ghi nhật ký của Microsoft và kết quả đăng nhập của bạn xen kẽ. (Nói chung, nó rất dễ dàng để nắm bắt System.Diagnostics trong các hệ thống đăng nhập khác, do đó có thể không phải là vấn đề lớn).

Trong khi tôi đã không sử dụng log4net hoặc NLog rất nhiều, giữa hai tôi sẽ nghiêng về phía NLog, chủ yếu là do phiên bản mới vừa ra mắt (beta). Tôi nghĩ rằng TraceSource cũng là một hợp lý, nếu thô sơ hơn, sự lựa chọn, đặc biệt là nếu bạn thực hiện phân cấp logger và sử dụng Ukadc.Diagnostics libary liên kết ở trên.

Hoặc sử dụng Common.Logging và bạn có thể tránh hoặc trì hoãn đưa ra quyết định cho nền tảng đăng nhập cơ bản của mình cho đến khi bạn sẵn sàng. Tuy nhiên, một khía cạnh rất hữu ích của Common.Logging là bạn có thể "thử nghiệm" các nền tảng ghi nhật ký khi bạn đang phát triển sản phẩm của mình mà không phải thay đổi bất kỳ mã ứng dụng nào. Bạn không phải đợi cho đến khi bạn quyết định một nền tảng ghi nhật ký cụ thể để thêm ghi nhật ký vào mã của bạn. Thêm nó ngay bây giờ thông qua api Common.Logging. Khi bạn nhận được gần đến giao hàng, bạn nên đã thu hẹp sự lựa chọn nền tảng đăng nhập của bạn. Phân phối với nền tảng đó (nếu bạn phân phối lại nền tảng ghi nhật ký) và bạn đã hoàn tất. Bạn vẫn có thể thay đổi sau này nếu bạn muốn.

-1

Từ quan điểm của nhà phát triển, chẳng hạn như ghi nhật ký, tương tự như orm, không nên viết tay. Có rất nhiều thư viện của bên thứ ba vững chắc. Chắc chắn có đôi khi một chút công việc cấu hình phải được thực hiện nhưng so sánh với tay lăn bạn là giải pháp riêng của nó chỉ là một giọt trong nước.

Sở thích cá nhân của tôi là log4net nhưng tùy thuộc vào nhu cầu của bạn. Lời khuyên tốt nhất của tôi là xem xét tài liệu về các giải pháp như log4net hoặc EntLib Logging Application Block và đưa ra quyết định về những gì tốt nhất cho bạn.

-1

Ghi nhật ký và truy tìm là các mối quan tâm khác nhau. Ghi nhật ký liên quan đến phản hồi hoạt động. Truy tìm (bao gồm cả các phương thức do Debug cung cấp) liên quan đến phát triển và thử nghiệm. Mã truy tìm không nên được biên dịch vào các bản phát hành. Các lớp Trace và Debug đạt được điều này với chú giải trình biên dịch (ConditionalAttribute). Mã như vậy nên được tối ưu hóa để thu thập nhiều dữ liệu, không phải cho hiệu suất. Mặt khác, hoạt động khai thác gỗ cần phải được tối ưu hóa cho hiệu suất và cho một loạt các cơ chế lưu trữ rộng hơn theo yêu cầu của nhóm sysadmin/hoạt động.

Vì vậy, tôi khuyên bạn nên sử dụng cả Trace/Debug để phát triển cũng như các gói ghi nhật ký mạnh mẽ hơn cho các hoạt động.

+1

Tôi thực sự nghi ngờ rằng một số cổng java của bên thứ ba mạnh mẽ hơn là một phần của BCL – vittore

0

Tôi biết điều này là cũ, nhưng System.Diagnostics.Trace là khá dễ dàng để cấu hình nếu bạn giữ nó đơn giản.Tôi đã sử dụng khối cấu hình trình soạn thảo văn bản đơn giản trong nhiều năm, được sao chép ngay từ tài liệu MSDN.

Không ai đề cập đến điều này rất thường xuyên, nhưng trong mã của bạn, bạn có thể sử dụng được xây dựng trong Trace.TraceInformation, Trace.TraceWarning, và Trace.TraceError dễ dàng cô lập 3 cấp dấu vết đầu ra và sau đó trong cấu hình tập tin chọn mức độ đầu ra (xem cấu hình dưới đây). Nếu bạn chọn Thông tin trong "EventTypeFilter" của cấu hình, bạn nhận được tất cả 3 trong đầu ra của bạn. Nếu bạn chọn Lỗi, bạn sẽ chỉ nhận được thông báo TraceError trong đầu ra của bạn. Hầu hết thời gian, tôi chỉ để lại lỗi của tôi, vì vậy nếu có điều gì đó xảy ra trong ứng dụng của tôi, tôi sẽ có đầu ra đó trong tệp theo dõi của mình. Bên trong các khối Catch của tôi, tôi sẽ thêm mã TraceError để xuất thông tin hữu ích. TraceInformation là tốt cho xuất ra những thứ như thời gian hoặc điểm trong mã mà bạn đã vượt qua, và bán phá giá trị biến trên đường đi. TraceWarning rất tốt cho những thứ dễ sử dụng, nhưng không được mong muốn - như có thể một dịch vụ web mất nhiều thời gian để hoàn thành hoặc số lượng bản ghi dữ liệu được trả về vượt quá ngưỡng có thể gây ra các vấn đề trong tương lai.

Có một nhược điểm nhỏ, trong đó tất cả các dòng mã theo dõi này vẫn thực thi bất kể mức biên dịch. Nếu chúng được thiết lập để không đầu ra, mà nên giảm chi phí khá một chút. Nhưng nếu bạn đang viết mã hiệu năng cao, bạn có thể muốn bọc những dòng đó trong các dấu biên dịch có điều kiện.

<system.diagnostics> 
    <sharedListeners> 
    <add name="MyTraceListener" traceOutputOptions="DateTime" type="System.Diagnostics.TextWriterTraceListener, System, Version=2.0.3600.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" initializeData="MyApplicationName_Trace.log"> 
    <!-- 
     Off - Does not allow any events through. 
     Error - Allows Error events through. 
     Warning - Allows Error, and Warning events through. 
     Information - Allows Error, Warning, and Information events through. 
    --> 
    <filter type="System.Diagnostics.EventTypeFilter" initializeData="Error" /> 
    </add> 
    </sharedListeners> 
    <trace autoflush="true" indentsize="4"> 
    <listeners> 
     <add name="MyTraceListener" /> 
    </listeners> 
    </trace> 
</system.diagnostics> 
Các vấn đề liên quan