2008-11-24 50 views
14

Gần đây, tôi đã gặp sự cố trong khi triển khai dịch vụ cửa sổ. Bốn máy tính không gây ra bất kỳ vấn đề nào, nhưng vào lần thứ năm, bất kỳ nỗ lực nào để bắt đầu dịch vụ đều thất bại do một ngoại lệ. Theo dõi ngăn xếp ngoại lệ được ghi vào nhật ký sự kiện, vì vậy tôi có thể dễ dàng xác định nguyên nhân:Cách tốt nhất để viết các mục nhật ký sự kiện là gì?

protected override void OnStart(string[] args) 
{ 
    EventLog.WriteEntry("Starting service", EventLogEntryType.Information); 

    try 
    { 
     //... 
     base.OnStart(args); 
    } 
    catch (Exception ex) 
    { 
     EventLog.WriteEntry("Service can not start. Stack trace:" + ex.StackTrace, EventLogEntryType.Error); 
     Stop(); 
     return; 
    } 

    EventLog.WriteEntry("Service started", EventLogEntryType.Information);   
} 

Nhưng than ôi, không có thông tin nào được ghi vào nhật ký. Cuối cùng tôi đã truy tìm nó vào mục nhật ký đầu tiên được viết. Nó đã ném một ngoại lệ vì nhật ký sự kiện ứng dụng đã đầy với các mục nhập gần đây và được cấu hình để chỉ ghi đè lên các mục cũ hơn 7 ngày.

Các phương pháp hay nhất về cách ghi vào nhật ký sự kiện, xem xét rằng tôi không thể thay đổi cấu hình nhật ký sự kiện ứng dụng là gì?

Tôi có nên đặt EventLog.WriteEntry trong một khối thử không, làm cách nào để xử lý ngoại lệ (ghi vào nhật ký sự kiện), tôi nên kiểm tra trạng thái đăng nhập sự kiện theo phương pháp OnStart của mình hoặc bạn có đề nghị nào tốt hơn?

Trả lời

2

Tôi nghĩ rằng ngoại lệ ghi nhật ký là một trong những trường hợp hiếm hoi mà bạn tốt hơn nên tránh ngoại lệ. Trong hầu hết các trường hợp, bạn không muốn ứng dụng của mình thất bại về điều này.

Nhưng tại sao bạn lại tự viết mã đăng nhập? Sử dụng một khung như NLog hoặc Log4Net! Chúng cũng nuốt các ngoại lệ như tôi vừa nói nhưng bạn có thể chuyển hướng đầu ra ghi nhật ký đến một vị trí khác (tệp, hộp thư, v.v.) chỉ với một thay đổi cấu hình. Điều này giúp giải quyết các vấn đề như thế này dễ dàng hơn nhiều.

+15

Viết cho EventLog không phải là "tự viết mã đăng nhập của bạn". – MusiGenesis

+0

@MusiGenesis: Vui lòng giải thích. Đối với tôi, việc ghi nhật ký xử lý ngoại lệ cụ thể là viết mã đã được thực hiện tốt hơn bằng Log4Net hoặc NLog chẳng hạn. Tôi không thấy lý do nào để viết một khung công tác ghi nhật ký khác. – Mendelt

+7

System.Diagnostics.EventLog là lớp .NET được tích hợp sẵn để ghi vào nhật ký sự kiện Windows, không phải thứ gì đó mà chúng đã tự viết. – MusiGenesis

11

Sử dụng log4net

Ưu điểm của việc sử dụng log4net là bạn có thể kiểm tra khai thác gỗ và kiểm soát nó một cách linh hoạt hơn rất nhiều so với bạn sẽ chiếm trong mã của bạn.

Nếu bạn đăng nhập vào nhật ký sự kiện và gặp sự cố và không có mục nhật ký sự kiện, bạn luôn có thể chuyển sang nhật ký của trình chỉnh sửa tệp và đã xem nó hoạt động ... sau đó sẽ thông báo cho bạn biết rằng một cái gì đó để làm với bản ghi sự kiện.

log4net cũng là biện pháp phòng thủ, nó sẽ không làm hỏng chương trình của bạn nếu nó không ghi được mục nhập nhật ký. Vì vậy, bạn sẽ không thấy điều này xảy ra (vì vậy bạn sẽ không có tệp nhật ký của bạn, nhưng chương trình của bạn sẽ chạy và một lần nữa bạn có thể đã chỉ định phương thức ghi nhật ký thứ hai để nhận tệp nhật ký).

Các bit quan trọng trong tài liệu log4net là thế này:

[log4net] là một nỗ lực tốt nhất và hệ thống đăng nhập thất bại ngừng.

Bằng không dừng, chúng tôi có nghĩa là log4net sẽ không ném ngoại lệ không mong muốn vào thời gian chạy có thể khiến ứng dụng của bạn gặp sự cố. Nếu vì bất kỳ lý do nào, log4net sẽ ném một ngoại lệ chưa được khai thác (ngoại trừ ArgumentException và ArgumentNullException có thể được ném), vui lòng gửi email đến danh sách gửi thư [email protected] Các ngoại lệ không bắt buộc được xử lý như các lỗi nghiêm trọng cần chú ý ngay lập tức.

Hơn nữa, log4net sẽ không hoàn nguyên về System.Console.Out hoặc System.Console.Error khi luồng đầu ra được chỉ định của nó không được mở, không thể ghi hoặc đã đầy. Điều này tránh làm hỏng chương trình hoạt động khác bằng cách tràn ngập thiết bị đầu cuối của người dùng vì không đăng nhập được. Tuy nhiên, log4net sẽ xuất một thông điệp duy nhất tới System.Console.Error và System.Diagnostics.Trace chỉ ra rằng việc ghi nhật ký không thể thực hiện được.

(tôi nhấn mạnh)

Đối với hầu hết mọi thứ, có một thư viện nào đó tốt hơn bạn sẽ. Điều tốt nhất là không bao giờ tái phát minh, log4net giải quyết đăng nhập. Net và sẽ làm cho cuộc sống của bạn dễ dàng hơn.

+2

Thực ra, log4net không có khả năng khiến ứng dụng gặp sự cố (ít nhất là ứng dụng dành cho thiết bị di động/khung cửa sổ nhỏ gọn) - sắp xếp. Sử dụng ứng dụng UDP của log4net sẽ làm hỏng ActiveSync (kết nối thiết bị với PC). Tôi đã học được điều này trong một bản demo, nơi chúng tôi mất một số liên lạc lớn. – MusiGenesis

+0

Tôi nghĩ rằng nó là hoàn toàn hợp lý, trong một dịch vụ Windows, để sử dụng log4net và bản ghi sự kiện Windows. Nhật ký sự kiện Windows cho các sự kiện ở mức rất cao, một sysadmin có thể xem nhanh; và nhật ký log4net chi tiết hơn cung cấp chi tiết phong phú về hoạt động của mã của bạn. –

2

Xem xét sử dụng Logging App Block.

Ứng dụng ghi nhật ký thư viện doanh nghiệp Chặn đơn giản hóa việc triển khai chức năng ghi nhật ký chung. Các nhà phát triển có thể sử dụng Khối Logging để viết thông tin vào một loạt các địa điểm:

  • Sự kiện đăng nhập
  • Một e-mail
  • Một cơ sở dữ liệu
  • Một thông báo hàng đợi
  • Một tập tin văn bản
  • Sự kiện WMI
  • Vị trí tùy chỉnh sử dụng điểm mở rộng khối ứng dụng
4
System.Diagnostics.EventLog log = 
    new System.Diagnostics.EventLog("YourLogNameHere"); 
log.ModifyOverflowPolicy(
    System.Diagnostics.OverflowAction.OverwriteAsNeeded, 0); 

Điều này sẽ khắc phục sự cố tràn của bạn. Nhật ký sự kiện nói chung là cực kỳ đáng tin cậy, một khi nó được cấu hình đúng. Khi sử dụng bản ghi sự kiện, tôi đã sử dụng để thêm một logger sao lưu khẩn cấp nhanh chóng mà chỉ đơn giản là viết vào một tập tin văn bản (điều này mất khoảng 5 phút để viết). Nó không bao giờ được gọi.

+0

Rất tiếc, tôi không được phép thay đổi cấu hình của nhật ký sự kiện. – Treb

+0

Bạn có thể tạo nhật ký dành riêng cho ứng dụng và ghi vào nhật ký đó thay vì nhật ký "Ứng dụng" chung không? – MusiGenesis

+1

Mặc dù điều này có thể hoạt động tốt đối với dịch vụ Windows, thường sẽ chạy với đặc quyền nâng cao, ứng dụng dành cho máy tính để bàn chạy bởi người dùng thông thường (không phải là Quản trị viên), có thể thất bại trong lệnh gọi đến 'ModifyOverflowPolicy' vì nó yêu cầu quyền đăng ký mà người dùng thông thường không có theo mặc định. –

3

Bạn không thể chỉ sử dụng cơ chế ghi sự kiện mặc định mà lớp ServiceBase đã cung cấp? Nếu dịch vụ của bạn không bắt đầu, nó sẽ tự động viết một mục vào sổ ghi sự kiện cho biết (với stacktrace).

Ngoài ra, và liên quan đến các nhận xét về log4net (hoặc bất kỳ nỗ lực tốt nhất khác như hệ thống ghi nhật ký), tôi nghĩ nó thực sự phụ thuộc vào những gì bạn đang cố gắng đạt được.

Trong ví dụ của bạn bằng cách sử dụng log4net (hoặc hỗ trợ dựng sẵn cho sự cố của ServiceBase) rất có thể là OK.

Tuy nhiên, có những trường hợp ngay cả khi thực tế xảy ra lỗi và thực tế đó không thể đăng nhập ở đâu đó là một vấn đề. Ví dụ: giả sử hệ thống xác thực hoặc ủy quyền. Nếu bạn không thể ghi nhật ký thành công và đáng tin cậy, xác thực mật khẩu không thành công do thông tin đăng nhập sai, bạn có thể không được phép tiếp tục (tương tự BTW nếu bạn xác thực mật khẩu đã thành công).

Vì vậy, đôi khi bạn cần biết khi nào nỗ lực đăng nhập không thành công và tự xử lý. Có giới hạn đối với khóa học này (vấn đề về trứng gà) và những gì bạn làm là rất cụ thể đối với ứng dụng hoặc kịch bản cụ thể.

0

Hãy lùi lại một bước ở đây: hệ thống

Nhật ký sự kiện là có để cảnh báo cho người quản trị hệ thống có một vấn đề với một cái gì đó trên hệ thống. Bạn nên cho phép dịch vụ bắt đầu thất bại.Điều này sẽ hiển thị trong nhật ký lỗi hệ thống với nguồn được báo cáo là "Trình quản lý kiểm soát dịch vụ". Điều này có nghĩa là quản trị viên sẽ biết về lỗi.

Tiếp theo, nếu bạn cần khắc phục sự cố thì bạn nên ghi ngoại lệ vào tệp trên đĩa ở cấp cao nhất của chương trình. Bạn cũng nên rethrow chúng để dịch vụ bắt đầu thất bại.

Sau đó, bạn có thể xác định mọi sự cố trong nhật ký sự kiện hệ thống và tham khảo chéo thời gian xảy ra lỗi trong nhật ký ứng dụng của bạn.

+1

Với ví dụ cụ thể, tại sao tôi nên để dịch vụ bắt đầu thất bại? Thực tiễn phổ biến là ghi nhật ký sự kiện bắt đầu và dừng dịch vụ, nhưng nhật ký sự kiện đầy đủ không phải là lý do chính đáng để dịch vụ không khởi động. Các dịch vụ đang chạy là quan trọng hơn, sự kiện đăng nhập chỉ là 'tốt đẹp để có'. – Treb

+0

Tôi không nghĩ rằng tôi hoàn toàn hiểu được vấn đề của bạn. Bạn có đăng nhập tất cả ngoại lệ vào nhật ký sự kiện không? Hay chỉ là các ngoại lệ chưa được bắt đầu ở cấp cao nhất trước khi ứng dụng gặp sự cố? –

+1

Câu hỏi của tôi không phải là về ghi nhật ký ngoại lệ, nhưng về các ngoại lệ xảy ra khi ghi vào nhật ký. Trong trường hợp cụ thể của một ngoại lệ trong khi khởi động dịch vụ, tôi đang viết một dịch vụ 'thông điệp tường trình' không thể khởi động ', điều đó cũng chứa các chi tiết về ngoại lệ, nhưng vấn đề ở bàn tay là viết bất kỳ mục nhập nhật ký nào. – Treb

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