Включить ведение журнала в два разных места в log4net

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

У каждого класса есть статический конструктор, который выглядит так

static Logger() {
    _Logger = new X.LoggingService.AppLogger(
                X.UtilityServer.Configuration.ConfigInfo.LoggerConfigFile);
}

кроме как с другими значениями конфигурации; оба этих статических класса инициализируют один и тот же вспомогательный класс AppLogger. Второй класс для инициализации перезаписывает инициализацию первого. Я думаю, что я отследил проблему здесь:

private  ILog Log  {
    get {
        if (!_ConfiguratorSet) {
            _ConfiguratorSet = true;
            XmlConfigurator.Configure(new FileInfo(_ConfigFile)); //<--- STATIC
        }
        return _log; 
    }
}

Поскольку я абсолютно не обязан поддерживать безопасность потоков, должен ли я просто удалить оператор if? Будет ли вызов XmlConfigurator.Configure каждый раз, когда мне нужно что-то регистрировать, будет непомерно дорогим? Есть ли способ лучше? Этот код был написан с использованием log4net версии 1.2.10.


person Adam Rackis    schedule 06.12.2011    source источник


Ответы (1)


В идеале должно происходить следующее:

  1. Настройте log4net (сделайте это один раз при запуске приложения — это очень медленно)
  2. Используйте внедрение зависимостей для передачи ILog в классы (лучше) или локатор сервисов (хуже), чтобы получить ILog в нужном классе
  3. Одна конфигурация может предоставить вам несколько регистраторов, которые, в свою очередь, могут иметь несколько приложений, которые могут регистрировать различные выходные данные (база данных, консоль, очереди и т. д.). Это дает вам большую гибкость, управляемую одним файлом конфигурации. У вас может быть один файл конфигурации с двумя файловыми логгерами с разными именами, которые будут использовать два разных приложения для вывода данных, ну, в два файла.

Код

private  ILog Log  {
    get {
        if (!_ConfiguratorSet) {
            _ConfiguratorSet = true;
            XmlConfigurator.Configure(new FileInfo(_ConfigFile)); //<--- STATIC
        }
        return _log;
    }
}

действительно запутанно и неправильно. Вы должны вернуть туда только журнал, так что вообще никаких ifs. Это нарушение принципа единой ответственности и, возможно, причина ошибки, которую вы видите.

person oleksii    schedule 06.12.2011
comment
Как мне выполнить пункт 1 — настроить log4net один раз? В этой кодовой базе много местоположений XML-файлов, хранящихся в качестве настроек конфигурации. Когда проекту X необходимо войти в журнал, он извлекает путь к файлу конфигурации и передает его этому вспомогательному классу, который вызывает XmlConfigurator.Configure и передает ему фактический файл (новый FileInto (_ConfigFile). Есть ли простой способ исправить это без переделывать много вещей? - person Adam Rackis; 07.12.2011
comment
В своих проектах я использовал подход, при котором одно решение VS содержит проект, который обычно используется другими проектами в рамках решения. Проект обычно называется Core или Commons. Здесь я бы оставил статический класс, который предоставляет статический метод для настройки log4net и статический метод для получения журнала по имени. Обычно одно решение имеет единственную точку входа, поэтому я вызываю метод Configure там. У вас много точек входа в одном решении VS (например, веб-проект, службы, приложения Win)? - person oleksii; 07.12.2011
comment
Таким образом, проект X может передавать только имя нужного ему логгера, или это более сложный случай? - person oleksii; 07.12.2011
comment
Я думаю, что это было просто написано плохо. Весь смысл этого кода в том, чтобы иметь возможность динамически изменять информацию о конфигурации — просто он был плохо выполнен. Я думаю, мне нужно заглянуть в log4net и посмотреть, как настроить нужные разделы конфигурации в ... файле конфигурации, а затем попросить любого, кто хочет войти, указать, какой раздел конфигурации им нужен. - person Adam Rackis; 07.12.2011