我使用Log4Net作为服务,使用StructureMap注入其他服务。
如何确保日志文件包含调用log4net的调用服务类上下文(类名和/或线程)?
调用类或线程肯定会是日志服务,它无法帮助我理解日志记录调用的来源。
修改
注册码:
ObjectFactory.Initialize(x =>
{
x.For<ILog>().AlwaysUnique().Use(s => s.ParentType == null ?
LogManager.GetLogger(s.BuildStack.Current.ConcreteType) :
LogManager.GetLogger(s.ParentType));
});
服务层:
public class LoggerService : ILoggerService
{
private readonly ILog log;
public LoggerService(ILog logger)
{
log = logger;
log.Info("Logger started {0}".With(logger.Logger.Name));
}
public void Info(string message)
{
log.Info(message);
}
}
在日志记录中,我仍然总是将LoggerService作为上下文,所以我永远不会看到实际上称为记录器的内容。它似乎没有正常工作。我觉得我在这里错过了什么......
编辑2: 我在这里为控制台应用添加了一个贴心链接:
我希望记录父类,但它不能在最简单的级别上工作。
答案 0 :(得分:0)
您可能需要查看Castle Dynamic proxy才能使用AOP解决问题。结构图Google组中的结构图使用它an example。
Ayende使用Log4Net和Windsor进行an example基于AOP的日志记录。
答案 1 :(得分:0)
我在我生成的很多代码中使用了StructureMap,并且我有一个StructureMap注册表,我用它将记录器挂钩到注入它的类的上下文中。
作为参考,我正在使用2.6.2版本的StructureMap,但在使用新的.For&lt;&gt;()。使用&lt;&gt;()格式时,应该可以使用2.5+。
public class CommonsRegistry : Registry
{
public CommonsRegistry()
{
For<ILogger>().AlwaysUnique().Use(s => s.ParentType == null ? new Log4NetLogger(s.BuildStack.Current.ConcreteType) : new Log4NetLogger(s.ParentType.UnderlyingSystemType.Name));
XmlConfigurator.ConfigureAndWatch(new FileInfo(Path.Combine(Path.GetDirectoryName(Assembly.GetAssembly(GetType()).Location), "Log.config")));
}
}
此注册表正在执行的操作是注入ILogger的任何位置,使用它注入的类是将日志消息记录到/ context的位置。
*此外,在第二行(XmlConfigurator.ConfigureAndWatch)中,我告诉Log4Net从文件“Log.config”而不是应用程序配置文件中获取日志信息,您可能会也可能不会喜欢它,并且可以删去。
我使用的代码是一个常见的IOC.Startup例程,如果我想使用默认的注册表,我将通过该例程。
ObjectFactory.Initialize(x =>
{
x.AddRegistry<CommonsRegistry>();
...
}
这为我提供了记录实例中的调用类名称,其中消息被自动记录,所需的只是将记录器注入到类中。
class foo
{
private readonly ILogger _log;
public foo(ILogger log)
{
_log = log;
}
}
现在消息被记录为context / class“foo”。