views:

1409

answers:

3

I am creating a Windows service. When an exception occurrs, I handle it appropriately and create a log. I am using the decorator pattern, as there are many different ways people will be looking at these logs. I have an email logger, a file logger, and a windows event logger, all which inherit from LoggingDecorator, which implements ILogger. So, no logger knows about any other logger.

My question is: How should I handle logging exceptions?

If writing to a file fails, or sending an email fails, what should I do? I want to log the initial log content with the other loggers, but what do I do with the logging exception? Doesn't it also depend on the order of the loggers in the constructor?

Right now, I'm just wrapping try/catch blocks with empty catch(Exception) statements, which just feels dirty and makes FxCop yell at me. However, is this one of those "it depends" moments?

[Flags]
public enum LoggingCategories
{
    None = 0,
    ServiceEvents = 1, 
    ProcessingInformation = 2,
    ProcessingErrors = 4,
    UnexpectedErrors = 8
}

public interface ILogger
{
    void LogMessage(LoggingCategories category, string message);
}

public abstract class LoggerDecorator : ILogger
{
    private ILogger _decoratedLogger;
    private LoggingCategories _categories;

    protected LoggerDecorator(ILogger logger, LoggingCategories categories)
    {
        this._decoratedLogger = logger;
        this._categories = categories;
    }

    protected bool ShouldLogCategory(LoggingCategories category)
    {
        return ((this._categories & category) == category);
    }

    public virtual void LogMessage(LoggingCategories category, string message)
    {
        _decoratedLogger.LogMessage(category, message);
    }

}

public class ControlLogger : ILogger
{
    public ControlLogger()
    {
    }

    public void LogMessage(LoggingCategories category, string message)
    {
        Console.WriteLine(LoggingHelper.ConstructLog(category, message));
    }
}

(questionable code in WindowsEventLogger)

try
{
    this._eventLog.WriteEntry(log, type);
}
catch (Exception)
{
    //Even if this logging fails, we do not want to halt any further logging/processing.
}

(code in service constructor)

ILogger controlLogger = new ControlLogger();
ILogger windowsEventLogger = new WindowsEventLogger(controlLogger, windowsEventLogCategories, windowsEventLogSource);
ILogger emailLogger = new EmailLogger(windowsEventLogger, emailCategories, emailSubject, emailAddresses);
ILogger fileLogger = new FileLogger(emailLogger, fileCategories, logDirectory, logFileNamePrefix, logFileExtension);

this._logger = fileLogger;
+3  A: 

Why don't put it in the actual Windows Event log if logger fails?

BobbyShaftoe
Quiet you! We will not tolerate common sense here! +1
George Stocker
A: 

Create separate ping service on a well behaving machine which you trust to be very reliable. If your primary service fails then ping also fails and control service then should send you e-mail with warning.

Din
A: 

Its not an answer, but curious why did you choose to not utilize the existing System.Diagnostics.Trace methods. You could implement some type of categorization of log types on top it it perhaps?

chris raethke