Преимущества синглтона Log4j? - PullRequest
8 голосов
/ 27 июля 2011

Я недавно унаследовал некоторый код Java и должен интегрировать его в проект, над которым я работаю.Мой проект - сервисный агент, который обрабатывает и преобразует сообщения XML.Просматривая новый код, я обнаружил следующий класс ведения журнала:

import org.apache.log4j.BasicConfigurator;
import org.apache.log4j.Level;
import org.apache.log4j.Logger;

public class MyLogger {

    private static MyLogger instance = null;
    protected final static Logger log = Logger.getLogger(MyLogger.class);

    private MyLogger() {
        super();
    }

    public static MyLogger getInstance(){
        if(instance  == null){
            instance  = new MyLogger();
            BasicConfigurator.configure();
            log.setLevel(Level.ALL);
        }
        return instance;
    }

    public void info(String myclass, String msg) {
        log.info("[" + myclass + "] " + msg);

    }

    public void error(String myclass, String msg, Exception ce) {               
        log.error("[" + myclass + "] " + msg, ce);      
    }

    public void warning(String myclass, String msg) {
        log.warn("[" + myclass + "] " + msg);
    }    
}

Этот класс в основном оборачивает log4j (другим) синглтоном.Все записи в классах, которые мне нужно интегрировать, выглядят примерно так:

public class MyClass {
   private final static MyLogger log = MyLogger.getInstance();
   private final static String myclass = MyClass.class.getName();

   ...

   log.info(myclass, "Information message...");   
}

Я не вижу очевидного преимущества использования дополнительного класса для ведения журнала, поэтому я рассматриваю возможность рефакторинга этого кода для удалениякласс MyLogger и войдите в систему следующим образом:

import org.apache.log4j.Logger;

public class MyClass {
   private static Logger log = Logger.getLogger(MyClass.class);

   ...

   log.info("Information Message...");     
}

Это сделает механизм ведения журнала согласованным для всего проекта.Прежде чем я сделаю это, я хотел бы знать, есть ли какие-либо преимущества для упаковки Log4j с одноэлементным классом, который я могу пропустить.Спасибо!

РЕДАКТИРОВАТЬ: Спасибо всем за полезные ответы - я подобрал несколько новых идей от каждого.Принял ответ Натана Хьюза за то, что он указал на утраченную функциональность, оставив класс нетронутым - я предполагал, что самым большим недостатком в оставлении одного синглтона было просто раздувание кода.Я испорчу класс.

Ответы [ 4 ]

11 голосов
/ 27 июля 2011

Избавься от этого.Использование этого уродства означает, что все журналы, которые проходят через него, будут перечислены с тем же регистратором (MyLogger) и методом (именно поэтому аргументы его методов включают в себя класс регистрируемой вещи).Это означает, что вы не только должны добавлять какую-либо информацию о классе, методе и номере строки к каждому вызову регистратора, но вы не можете выполнять какую-либо фильтрацию на уровнях журнала для различных пакетов, как вы могли бы использовать типичный подход log4j с классами в качестве регистраторов.

Эта штука - хлам, и тебе без нее лучше.

4 голосов
/ 27 июля 2011

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

Тем не менее, я все равно реорганизовал бы код для непосредственного использования log4j.Или, более вероятно, в моем случае, использовать SLF4J .

3 голосов
/ 27 июля 2011

Одна вещь, которую ваш унаследованный код делает, что делает log4j, это делает вещь не поточно-безопасной Поскольку в getInstance() нет блокировки, вы потенциально можете раздать более одного экземпляра и нарушить единственные намерения кода.

Вы также теряете возможность устанавливать уровни ведения журнала для каждого класса в зависимости от того, что вы делаете.

2 голосов
/ 27 июля 2011

Единственный недостаток, который я могу сказать, из-за этой декларации:

protected final static Logger log = Logger.getLogger(MyLogger.class);

Регистратор, по сути, подключен к объекту MyLogger, и вся информация / ошибки / предупреждения и т. Д. Будет «связана» с MyLogger. Вы не представляете, в какой объект добавлена ​​информация о журналировании.

Единственное преимущество, которое я вижу с этим синглтоном, это:

  • Одиночный экземпляр: вам никогда не придется постоянно объявлять о реализации static final Logger.
  • Вам не нужно беспокоиться о том, какой тип регистратора вы используете. Изменить тип Logger можно только в этом классе Singleton. Любые дальнейшие изменения в журнале выполняются только в синглтоне.

Я видел это и в моей компании, но я не предлагаю такой тип настройки. Скорее используйте SLF4J или Java Logging Framework.

...