简体   繁体   中英

How to write error log or exception into file in C#.NET

I need help in writing error into separate text file and Email that file to me. Actually, I had created windows application but I didn't add any exception or writing error into separate file. Now, I want whenever my application is interrupted because of any error then error should be noted into separate text file and that file should be email to me.

I did research on error log file and all I found that create separate Class for writing Error Log into text file and call that file into try-catch block of all the methods. But my program/application has grown vast and I need to add intermediate of it. Also, I found about log4net but still it works in same manner.

Can anyone guide me how to write error log at application level or when application get any error message?

Thanks for help.

If you are not attached to any system already, I'd suggest you look at log4net , since it will do what you're asking for, way, way, more, and is a popular library so it will be recognizable and extensible by other professionals on your team. Also since someone else maintains it you will occasionally get free bug fixes.

As far as I can see, all you need is to handle AppDomain.UnhandledException Event . It will give you most common information about crash. You can use it to start the research of crash reasons.

And of course in the UnhandledException handler you can use whatever you want, log4net or custom logger.

try

Log4Net

Smtp Logger:

<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>

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

I created a logging helper that I use for my WPF project. This is a large project with many different components. This was before I learned how to work with MVVM so please excuse if this breaks the pattern. This system is continuously expanding with new components to handle different tasks. You can think of a component as a standalone unit which handles a specific task, with the Main Component being the master of them all. This logging allowed us to log errors no matter in which component they occurred. It may be an overkill, but worked very well for us.

I am using the same principle to log all system wide events (User Actions, Data Changes..etc)

In my App.xaml.cs I catch all unhandled errors. Note that this is last resort of logging, I use try catch wherever I would expect exceptions to occur (db connections for example).

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

ErrorEvent is a class within my Utilities dll that uses Event Routing to log the errors. I have different type of errors, depending on severity. All these errors are logged into a database, and the only component aware of the database connections is the main one. This is why I use Routing Event to send the exception to the Main Component to be logged. The ErrorEventHelper gets populated and routed to the Main Component. In situations where I am using try catches, I create the EventHelper and pass it to be logged using LogErrorEvent method. The ShowMessage property is used to decide if the user will be inform of the exception, or if it will only be logged.

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);
    }
}

In the MainWindow I register the event handler.

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

And finally handle it:

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

}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM