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
Look into utilizing the Logging App Block.
The Enterprise Library Logging Application Block simplifies the implementation of common logging functions. Developers can use the Logging Block to write information to a variety of locations:
- The event log
- An e-mail message
- A database
- A message queue
- A text file
- A WMI event
- Custom locations using application block extension points
Let's take a step back here:
The system event log is there to alert the system administrator that there was a problem with something on the system. You should allow the service start to fail. This will show up in the system error log with a reported source of "Service Control Manager". This means that the sys admin will know about the failure.
Next, if you need to troubleshoot then you should log exceptions to a file on disk at the top level of your program. You should also rethrow them so that the service start fails.
You can then identify any problems in the system event logs and cross reference the time of the failure into your application logs.
Can't you just use the default event-log mechanism that the ServiceBase class already provides? If your service doesn't start that will automatically write an entry to the event log stating so (with stacktrace).
Apart from that, and concerning the comments about log4net (or any other best-effort like logging-system), I think it really depends what you are trying to achieve.
In your example using log4net (or the builtin support for eventlogging of ServiceBase) is most likely OK.
However, there are situations where even the fact that an error occurred and that that fact could not be logged somewhere is a problem. For example, assume an authentication or authorization system. If you cannot successfully and reliably log that a, say, password authentication failed because of wrong credentials, you're maybe not allowed to continue (same so BTW if you the password authentication would have been successful).
So, sometimes you need to know when a logging attempt failed and handle that by itself. There are limits to this of course (chicken-egg-problem), and what you do is highly specific to the particular application or scenario.
System.Diagnostics.EventLog log =
new System.Diagnostics.EventLog("YourLogNameHere");
log.ModifyOverflowPolicy(
System.Diagnostics.OverflowAction.OverwriteAsNeeded, 0);
This should fix your overflow problem. The event log is generally extremely reliable, once it's configured correctly. When using the event log, I used to add a quick emergency backup logger that simply wrote to a text file (this takes about 5 minutes to write). It never got called.
I think logging exceptions is one of the rare cases where you are better off swallowing the exception. In most cases you don't want your app to fail on this.
But why are you writing your logging code yourself anyway? Use a framework like NLog or Log4Net! These also swallow exceptions like I just said but you can redirect the logging output to a different location (file, messagebox etc.) with just a configuration change. This makes solving problems like this much easier.
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 log4net-user@logging.apache.org 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.