gpt4 book ai didi

c# - 拦截或修饰对 ILogger 的调用

转载 作者:行者123 更新时间:2023-11-30 12:27:15 25 4
gpt4 key购买 nike

我目前正在使用 caSTLe windsor,以及它在我的应用程序中的日志记录工具。

但是,在我的日志记录中,我想包含一些上下文信息,这些信息不在记录的消息中,但存储在 CallContext 中。 .

我尝试通过使用以下命令拦截对 ILogger 的调用来做到这一点:

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

但是变量 logger 的类型是 NLog.Loggger 而不是我期望的动态代理。

最佳答案

对 ILSpy 的一些挖掘似乎表明您将无法拦截对 ILogger 实例化的调用。 ILogger 实例是由 NLogFactory 直接创建的(对于我调查过的所有日志工厂、log4net、控制台等都是一样的)

// Castle.Services.Logging.NLogIntegration.NLogFactory
public override ILogger Create(string name)
{
Logger logger = LogManager.GetLogger(name);
return new NLogLogger(logger, this);
}

如果这真的有必要,您应该能够继承您感兴趣的工厂(基本上是 NLogFactoryExtendedNLogFactory)以覆盖 ILogger 创建。然后创建 ILogger 的基于实例的代理并插入您的自定义拦截器。最后通知 LoggingFacility 您要使用自定义工厂。

我开始对你的问题持悲观态度,但我发现解决方案实现起来非常简单,所以你不应该有太多问题来实现你想要的。代码?当然:)

public class MyFactory : NLogFactory
{
public override ILogger Create(string name)
{
var il = base.Create(name);
var pg = new ProxyGenerator();
return pg.CreateInterfaceProxyWithTarget<ILogger>(il, new LoggingInterceptor());
}
}

public class LoggingInterceptor : IInterceptor
{
public void Intercept(IInvocation invocation)
{
//Some modification to message here
invocation.Proceed();
}
}

internal class Program
{
private static void Main(string[] args)
{
var container = new WindsorContainer();
container.AddFacility<LoggingFacility>(f => f.UseNLog().LogUsing<MyFactory>());

var logger = container.Resolve<ILogger>();
logger.Debug("data"); // we intercept this call, success
Console.ReadLine();
}
}

关于c# - 拦截或修饰对 ILogger 的调用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25790258/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com