3

我需要帮助将错误写入单独的文本文件并将该文件通过电子邮件发送给我。实际上,我已经创建了 Windows 应用程序,但我没有添加任何异常或将错误写入单独的文件。现在,我希望每当我的应用程序因任何错误而中断时,应将错误记录到单独的文本文件中,并且该文件应通过电子邮件发送给我。

我对错误日志文件进行了研究,所有我发现创建单独的类用于将错误日志写入文本文件并将该文件调用到所有方法的 try-catch 块中。但是我的程序/应用程序已经变得庞大,我需要添加它的中间部分。另外,我发现了 log4net,但它仍然以相同的方式工作。

谁能指导我如何在应用程序级别或应用程序收到任何错误消息时编写错误日志?

感谢帮助。

4

5 回答 5

1

如果您还没有连接到任何系统,我建议您查看log4net,因为它可以满足您的要求,方式,方式,更多,并且是一个流行的库,因此它可以被其他人识别和扩展您团队中的专业人士。此外,由于其他人维护它,您偶尔会获得免费的错误修复。

于 2012-07-18T16:47:28.930 回答
1

据我所知,您只需要处理AppDomain.UnhandledException Event。它将为您提供有关崩溃的最常见信息。您可以使用它来开始研究崩溃原因。

当然,在UnhandledException处理程序中,您可以使用任何您想要的,log4net或自定义记录器。

于 2012-07-18T16:48:23.953 回答
0

我创建了一个用于 WPF 项目的日志记录助手。这是一个包含许多不同组件的大型项目。这是在我学会如何使用 MVVM 之前,所以如果这打破了模式,请原谅。该系统不断扩展新组件以处理不同的任务。您可以将组件视为处理特定任务的独立单元,主组件是所有组件的主人。这种日志记录使我们能够记录错误,无论它们发生在哪个组件中。这可能有点矫枉过正,但对我们来说效果很好。

我使用相同的原则来记录所有系统范围的事件(用户操作、数据更改..等)

在我的 App.xaml.cs 中,我捕获了所有未处理的错误。请注意,这是日志记录的最后手段,我使用 try catch 任何我希望发生异常的地方(例如数据库连接)。

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

ErrorEvent 是我的 Utilities 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

}
于 2012-07-18T17:09:02.280 回答
0

尝试

Log4Net

SMTP 记录器:

<appender name="SmtpAppender" type="log4net.Appender.SmtpAppender">
<to value="to@domain.com" />
<from value="from@domain.com" />
<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>

于 2012-07-18T16:49:04.413 回答
0

要处理其他地方未捕获的所有异常,请考虑为Application.ThreadException实现处理程序

于 2012-07-18T16:49:15.713 回答