Как вы выводите класс контекста, используя log4net в качестве службы? - PullRequest
2 голосов
/ 10 мая 2011

Я использую Log4Net как сервис, который внедряется в другие сервисы с использованием StructureMap.

Как мне убедиться, что файл журнала включает контекст вызывающего класса обслуживания (имя класса и / или поток), который выполняет вызовы log4net?

Конечно, вызывающим классом или потоком всегда будет служба ведения журнала, которая не помогает мне понять, откуда на самом деле поступают вызовы для ведения журнала.

EDIT:

Регистрационный код:

  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: Я добавил ссылку на pastie для консольного приложения здесь:

http://pastie.org/1897389

Я ожидаю, что родительский класс будет зарегистрирован, но он не работает на простейших уровнях.

Ответы [ 2 ]

0 голосов
/ 11 мая 2011

Я использую StructureMap во многих кодах, которые я генерирую, и у меня есть реестр StructureMap, который я использую, чтобы подключить регистратор к контексту класса, в который он внедряется.

Для справки, я 'm использует версию StructureMap версии 2.6.2, но должно работать с 2.5+, если используется новый формат .For <> (). Use <> ().

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 of.

* Кроме того, во второй строке (XmlConfigurator.ConfigureAndWatch) я сообщаю Log4Net:получить информацию журнала из файла "Log.config" вместо файла конфигурации приложения, вам это может понравиться или не понравиться, и его можно опустить.

Код, который я использую, представляет собой обычную процедуру IOC.Startup, в которой япрошло бы, если бы я хотел использовать регистр по умолчанию.

ObjectFactory.Initialize(x =>
{
  x.AddRegistry<CommonsRegistry>();
  ...
}

Это дает мне имя вызывающего класса в экземпляре регистрации, где сообщения регистрируются в autи все, что требуется, это ввести логгер в класс.

class foo
{
  private readonly ILogger _log;

  public foo(ILogger log)
  {
    _log = log;
  }
}

Теперь сообщения регистрируются как контекст / класс "foo".

0 голосов
/ 10 мая 2011

Возможно, вы захотите взглянуть на Castle Dynamic proxy , чтобы решить его с помощью AOP. пример использования его со структурной картой на структурной карте Google Group.

У Ayende есть пример ведения журнала на основе AOP с использованием Log4Net и Windsor.

...