I am using the Castle logging facility with log4net in my application (MVC3 web app). However, rather than using the ILogger interface directly I have abstracted this by creating another interface (IAuditor) with a concrete implementation Log4NetAuditor (see code below).
You may ask why I've done this since the point of ILogger is to abstract the underlying logging implementation. I've done because of strict observation of the onion architecture principle of abstracting all infrastructure concerns.
Now, this works just fine except all loggers are named the same: MyProject.Infrastructure.Log4NetAuditor:
2011-01-24 13:26:11,746 [11] DEBUG MyProject.Infrastructure.Log4NetAuditor [] - Attempting login...
2011-01-24 13:26:11,845 [11] DEBUG MyProject.Infrastructure.Log4NetAuditor [] - Authentication result is Authenticated
The IAuditor is exposed as a property on an AuditableComponent which is an abstract class from which all components that require logging derive.
public abstract class AuditableComponent
{
private IAuditor _auditor = NullAuditor.Instance;
public IAuditor Auditor
{
get { return _auditor; }
set { _auditor = value; }
}
//....
}
The Log4NetAuditor class looks like this:
public class Log4NetAuditor : IAuditor
{
private ILogger _logger = NullLogger.Instance;
public ILogger Logger
{
get { return _logger; }
set { _logger = value; }
}
public void Trace(string message)
{
_logger.Debug(message);
}
}
Now, it's clear why all log statements have the same logger name: ILogger is injected on the Log4NetAuditor class.
How, then, can I ensure the name of the logger corresponds to the name of the class that extends AuditableComponent?