2012-07-18 47 views
1

我需要幫助,將錯誤寫入單獨的文本文件並將該文件發送給我。其實,我已經創建了Windows應用程序,但我沒有添加任何異常或將錯誤寫入單獨的文件。現在,我希望每當我的應用程序由於任何錯誤而中斷時,應將錯誤記錄到單獨的文本文件中,並且該文件應該通過電子郵件發送給我。如何在C#.NET中將錯誤日誌或異常寫入文件

我對錯誤日誌文件進行了研究,並且我發現所有創建單獨的類用於將錯誤日誌寫入文本文件並將該文件調用到所有方法的try-catch塊中。但是我的程序/應用程序已經變得龐大,我需要添加中間件。此外,我發現有關log4net,但它仍然以相同的方式工作。

任何人都可以指導我如何在應用程序級別編寫錯誤日誌或當應用程序獲取任何錯誤消息?

感謝您的幫助。

+0

你並不需要把嘗試趕上無處不在,也許需要了解處理異常的最佳做法;請參閱http://stackoverflow.com/questions/183589/best-practice-for-exception-handling-in-a-windows-forms-application – 2012-07-18 16:58:40

回答

0

據我所見,你需要的只是處理AppDomain.UnhandledException Event。它會給你最常見的崩潰信息。你可以用它來開始研究碰撞原因。

當然,在UnhandledException處理程序中,您可以使用任何您想要的,log4net或自定義記錄器。

+0

謝謝AppDomain.UnhandledException解決了我的查詢。 – 2012-07-19 20:37:34

1

如果你還沒有附加到任何系統,我建議你看看log4net,因爲它會按照你要求的方式,方式,方式,多,並且是一個流行的庫,因此它將被識別並且可以由團隊中的其他專業人員進行擴展。另外,由於其他人維護它,你偶爾會得到免費的錯誤修復。

+0

他的問題說,我引用,「另外,我發現有關log4net,但仍然它以相同的方式工作「。 – 2012-07-18 16:48:54

+0

@Yuriy謝謝,錯過了他所說的那句話,他表示對try-catch的依賴讓我覺得他沒有看到它。考慮到這一點,顯然有一個關於appender如何工作的想法。馬上改進我的答案。 – tmesser 2012-07-18 17:03:48

0

嘗試

Log4Net

Smtp Logger:

<appender name="SmtpAppender" type="log4net.Appender.SmtpAppender"> 
<to value="[email protected]" /> 
<from value="[email protected]" /> 
<subject value="test logging message" /> 
<smtpHost value="SMTPServer.domain.com" /> 
<bufferSize value="512" /> 
<lossy value="true" /> 
<evaluator type="log4net.Core.LevelEvaluator"> 
    <threshold value="WARN"/> 
</evaluator> 
<layout type="log4net.Layout.PatternLayout"> 
    <conversionPattern value="%newline%date [%thread] %-5level %logger [%property{NDC}] - %message%newline%newline%newline" /> 
</layout> 

0

要隨時隨地處理所有異常其他地方沒有抓到,考慮執行處理程序Application.ThreadException

+0

感謝您的回覆。我認爲Application.ThreadException可能是我的查詢的答案,但我沒有太多的想法或知識,所以讓我閱讀整篇文章,如果我有任何進一步的問題,我會回覆你。 – 2012-07-18 16:54:53

0

我創建了一個用於我的WPF項目的日誌助手。這是一個包含許多不同組件的大型項目。這是在我學習如何使用MVVM之前,所以請原諒,如果這打破了這種模式。這個系統正在不斷擴大,新組件可以處理不同的任務。您可以將組件視爲處理特定任務的獨立單元,其中主要組件是它們的主要組件。這個記錄允許我們記錄錯誤,不管它們發生在哪個組件中。這可能是一種矯枉過正,但對我們來說工作得非常好。

我使用的是同樣的原理來記錄所有系統級事件(用戶操作,數據Changes..etc)

在我App.xaml.cs我捕捉所有未處理的錯誤。請注意,這是日誌記錄的最後手段,我使用嘗試捕獲任何我希望發生異常的地方(例如db連接)。

public partial class App : Application 
{ 
    void Application_DispatcherUnhandledException(object sender, DispatcherUnhandledExceptionEventArgs e) 
    { 
     ErrorEvent errorEvent = new ErrorEvent(); 
     errorEvent.LogErrorEvent(e.Exception); 
     e.Handled = true; 
    } 
} 

ErrorEvent是我的公用事業DLL中的一個類,它使用事件路由記錄錯誤。根據嚴重程度,我有不同類型的錯誤。所有這些錯誤都記錄在數據庫中,唯一知道數據庫連接的組件是主要的。這就是爲什麼我使用路由事件將異常發送到要記錄的主要組件。ErrorEventHelper被填充並路由到主要組件。在使用try catch的情況下,我創建EventHelper並使用LogErrorEvent方法將其傳遞給日誌。 ShowMessage屬性用於決定用戶是否會通知異常,或者是否僅記錄。

public class ErrorEvent : UserControl 
{ 
    public delegate void ErrorEventEventHandler(object sender, RoutedCustomEventArgs e); 

    public static readonly RoutedEvent EventOccuredEvent = EventManager.RegisterRoutedEvent(
    "EventOccured", RoutingStrategy.Bubble, typeof(ErrorEventEventHandler), typeof(ErrorEvent)); 

    // Provide CLR accessors for the event 
    public event RoutedEventHandler EventOccured 
    { 
     add { AddHandler(EventOccuredEvent, value); } 
     remove { RemoveHandler(EventOccuredEvent, value); } 
    } 

    public void LogErrorEvent(ErrorEventHelper occuredEventDetails) 
    { 
     RoutedEventArgs newEventArgs = new RoutedCustomEventArgs(ErrorEvent.EventOccuredEvent, occuredEventDetails); 
     RaiseEvent(newEventArgs); 
    } 

    public void LogErrorEvent(Exception exception) 
    { 
     ErrorEventHelper occuredEventDetails = new ErrorEventHelper(); 
     occuredEventDetails.ErrorType = ErrorEventHelper.EventTypes.Critical; 
     occuredEventDetails.ErrorValue = exception.Message; 
     occuredEventDetails.ErrorStack = exception.StackTrace; 
     occuredEventDetails.ShowMessage = true; 

     RoutedEventArgs newEventArgs = new RoutedCustomEventArgs(ErrorEvent.EventOccuredEvent, occuredEventDetails); 
     RaiseEvent(newEventArgs); 

     if (exception.InnerException != null) 
     { 
      LogErrorEvent(exception.InnerException); 
     } 
    } 

    public class RoutedCustomEventArgs : RoutedEventArgs 
    { 
     public ErrorEventHelper OccuredEventDetails { get; private set; } 

     public RoutedCustomEventArgs(RoutedEvent routedEvent, ErrorEventHelper occuredEventDetails) 
      : base(routedEvent) 
     { 
      this.OccuredEventDetails = occuredEventDetails; 
     } 
    } 

} 

public class ErrorEventHelper 
{ 
    public string ErrorValue { get; set; } 
    private EventTypes _ErrorType = EventTypes.Critical; 
    public EventTypes ErrorType 
    { 
     get 
     { 
      return _ErrorType; 
     } 
     set 
     { 
      _ErrorType = value; 
     } 
    } 
    public string ErrorStack { get; set; } 
    public bool ShowMessage { get; set; } 

    public enum EventTypes 
    { 
     Critical, 
     Warning, 
     Information 
    } 

    public void SendMessage() 
    { 
     ErrorEvent newEvent = new ErrorEvent(); 
     newEvent.LogErrorEvent(this); 
    } 
} 

在MainWindow中,我註冊了事件處理程序。

EventManager.RegisterClassHandler(typeof(ErrorEvent), 
         ErrorEvent.EventOccuredEvent, new ErrorEvent.ErrorEventEventHandler(LogOccuredErrors)); 

最後處理:

private void LogOccuredErrors(object sender, ErrorEvent.RoutedCustomEventArgs e) 
{ 
    ErrorEventHelper eventHelper = e.OccuredEventDetails; 

//Call Database Helper to log to database or output to file and email 
    StringBuilder builder = new StringBuilder(); 
    builder.AppendLine(eventHelper.ErrorType); 
    builder.AppendLine(eventHelper.ErrorValue); 
    builder.AppendLine(eventHelper.ErrorStack); 
    if (eventHelper.ShowMessage) 
    { 
     MessageBox.Show(eventHelper.ErrorValue); 
    } 

//Create your log file and email it 
    File.WriteAllText(@"C:\log.txt", ControllerBuilder.ToString()) 
//email here 

}