What is the best way to write event log entries?

Treb picture Treb · Nov 24, 2008 · Viewed 19.3k times · Source

I recently had a problem during the deployment of a windows service. Four computers did not cause any problems, but on the fifth any attempt to start the service failed due to an exception. The exception stack trace is written to the event log, so I though it should be easy to identify the cause:

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

But alas, no information was ever written to the log. I finally traced it to the first log entry being written. It threw an exception because the application event log was full with recent entries, and configured to only overwrite entries older than 7 days.

What are the best practices on writing to the event log, considering that I can not change the configuration of the application event log?

Should I always put EventLog.WriteEntry in a try block, if yes, how should I handle the exception (writing it to the event log is probably a bad idea), should I check on the event log status in my OnStart method, or do you have any better suggestion?

Answer

anonymous picture anonymous · Nov 24, 2008

Use log4net

The advantage of using log4net is that you can check the logging and control it with far more flexibility than you will account for within your code.

If you were logging to the event log, and seeing problems and no event log entries, you could always have switched to a file-appender log and have seen it working... which would have then told you that it was something to do with the event log.

log4net is also defensive, it won't crash your program if it fails to write the log entry. So you wouldn't have seen this happen (so you wouldn't have your logs files, but your program would be running and again you could've specified a second logging method to get log files).

The key bit in the log4net documentation is this:

[log4net] is a best-effort and fail-stop logging system.

By fail-stop, we mean that log4net will not throw unexpected exceptions at run-time potentially causing your application to crash. If for any reason, log4net throws an uncaught exception (except for ArgumentException and ArgumentNullException which may be thrown), please send an email to the [email protected] mailing list. Uncaught exceptions are handled as serious bugs requiring immediate attention.

Moreover, log4net will not revert to System.Console.Out or System.Console.Error when its designated output stream is not opened, is not writable or becomes full. This avoids corrupting an otherwise working program by flooding the user's terminal because logging fails. However, log4net will output a single message to System.Console.Error and System.Diagnostics.Trace indicating that logging can not be performed.

(my emphasis)

For most things, there is a library that does it better than you will. The best thing is to never re-invent, log4net solves logging in .Net and will make your life easier.