如何使用log4net作为服务输出上下文类?

时间:2011-05-10 13:32:51

标签: dependency-injection log4net structuremap

我使用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: 我在这里为控制台应用添加了一个贴心链接:

http://pastie.org/1897389

我希望记录父类,但它不能在最简单的级别上工作。

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”。