I'm currently using castle windsor, along with it's logging facility in my application.
However, in my logging I would like to include some contextual information that is not within the logged message, but stored within the CallContext
.
I have tried to do this by intercepting the calls to ILogger
using the following:
internal class Program
{
private static void Main(string[] args)
{
var container = new WindsorContainer();
container.AddFacility<LoggingFacility>(f => f.UseNLog());
container.Kernel.Resolver.AddSubResolver(new LoggerResolver(container.Kernel));
var logger = container.Resolve<ILogger>();
}
}
public class LoggerResolver: ISubDependencyResolver
{
private readonly IKernel _kernel;
private static ProxyGenerator _proxyGenerator;
static LoggerResolver()
{
_proxyGenerator = new ProxyGenerator();
}
public LoggerResolver(IKernel kernel)
{
_kernel = kernel;
}
public bool CanResolve(CreationContext context, ISubDependencyResolver contextHandlerResolver, ComponentModel model, DependencyModel dependency)
{
return dependency.TargetType == typeof(ILogger);
}
public object Resolve(CreationContext context, ISubDependencyResolver contextHandlerResolver, ComponentModel model, DependencyModel dependency)
{
return _proxyGenerator.CreateInterfaceProxyWithTarget(_kernel.Resolve<ILogger>(), new LoggingInterceptor());
}
}
public class LoggingInterceptor: IInterceptor
{
public void Intercept(IInvocation invocation)
{
//Some modification to message here
invocation.Proceed();
}
}
But the variable logger
is of type NLog.Loggger
rather than the dynamic proxy I was expecting.
Some digging with ILSpy seems to show that you won't be able to intercept calls to the
ILogger
instantiation. TheILogger
intance is created directly by theNLogFactory
(same thing for all logging factories I looked into, log4net, console, etc)If this is really necessary you should be able to inherit the factories you're interested into (basically,
NLogFactory
andExtendedNLogFactory
) in order to override theILogger
creation. Then create a instance-based proxy of the ILogger and plug in your custom interceptors. Finally inform theLoggingFacility
that you want to use a custom factory.I started being pessimist about your problem but I found the solution to be quite simple to implement, so you shouldn't have too many problems to achieve what you want. Code? Of course :)