Структура ведения журналов Java, которая не требует объявления LOGGER для каждого класса

Я пробовал следующие регистраторы

  • API ведения журналов Java
  • Log4j
  • slf4j

Все это требует объявления LOGGER на уровне класса, как показано ниже.

private final static java.util.logging.Logger.Logger LOGGER = java.util.logging.Logger.Logger.getLogger(MyClass.class.getName());
private final Logger slf4jLogger = LoggerFactory.getLogger(SLF4JHello.class);
private final static Logger log4jLogger = Logger.getLogger(Log4jHello.class);

Мне это кажется ужасным, есть ли в Java фреймворк, который не требует этого объявления?

Я ищу, у меня может быть глобальное объявление, например

private final static Logger Logger = Logger.getLogger(MyApp.class);

Но когда я вызываю Logger.log (..) из класса XXX.class, регистратор должен использовать имя XXX.class.


person Edi    schedule 24.02.2016    source источник
comment
Это полностью зависит от вас (в любой из этих структур), как вы определяете и называете свои регистраторы. Вы можете использовать один для всего приложения или звонить getLogger по любому вызову.   -  person Thilo    schedule 24.02.2016
comment
По теме: stackoverflow.com/questions/26600757/ stackoverflow.com/questions/27038694/   -  person Thilo    schedule 24.02.2016
comment
@Thilo, имеющий один для всего приложения, будет создавать все журналы с одинаковым именем. Кого я не ищу. Вместо этого фреймворк должен отображать имя класса вызывающего.   -  person Edi    schedule 24.02.2016
comment
Имя регистратора также не обязательно связано с тем, что он отображает. Все это можно настроить.   -  person Thilo    schedule 24.02.2016
comment
вы можете настроить вызывающий класс и имя метода, а также имя файла исходного кода и номер строки, которые будут отображаться в большинстве фреймворков ведения журнала. Но для этого есть некоторая стоимость времени выполнения.   -  person Thilo    schedule 24.02.2016
comment
Основное влияние имени регистратора заключается в том, что оно позволяет применять правила иерархически (например, поднять уровень журнала до DEBUG для org.apache.commons.*). Я бы просто придерживался установленного образца. Самый гибкий, простой, быстрый (и немного уродства, которое можно решить только с помощью макросов, препроцессоров или других мерзостей).   -  person Thilo    schedule 24.02.2016
comment
Все, что я говорю, это: а) что все фреймворки ведения журналов представляют этот шаблон, это ключ к тому, что он работает очень хорошо; б) они не требуют, чтобы вы следовали этому шаблону.   -  person Thilo    schedule 24.02.2016
comment
Современный способ - использовать внедрение зависимостей для установки зависимостей, таких как используемый интерфейс ведения журнала, который поддерживает этот шаблон. Таким образом, никакая современная структура ведения журналов вряд ли будет действовать по-другому.   -  person Raedwald    schedule 25.02.2016
comment
@ Раэдвальд, я не знаю. Ведение журнала кажется одной из тех вещей, где поиск зависимостей все еще широко распространен. И вы можете только внедрить реализацию ведения журнала, интерфейс по-прежнему фиксируется во время компиляции (даже с DI). И эта реализация может быть настроена независимо от кода, который ее использует, все, что было бы исправлено без DI, - это имя регистратора.   -  person Thilo    schedule 26.02.2016


Ответы (2)


Ваша проблема, скорее всего, не в структуре ведения журнала, а в макете.

Конкретный пример

so35592962/App.java

package so35592962;
import org.apache.logging.log4j.*;
import so35592962.sub.OtherClass;
public class App {
  public static final Logger logger = LogManager.getLogger();
  public static void main(String[] args) {
    logger.error("in App.main");
    OtherClass.act();
  }
}

so35592962/sub/OtherClass.java

package so35592962.sub;
import static so35592962.App.logger;

public class OtherClass {
  public static void act() {
    logger.error("OtherClass.act");
  }
}

Итак, вы можете видеть, что это именно то, что вам нужно: классы, использующие один регистратор. Итак, хороший момент, для этого можно использовать Log4J2.

Теперь добавляю волшебный файл log4j2.xml

<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="WARN">
  <Appenders>
    <Console name="Console" target="SYSTEM_OUT">
      <PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %C{36} - %msg%n"/>
    </Console>
  </Appenders>
  <Loggers>
    <Root level="error">
      <AppenderRef ref="Console"/>
    </Root>
  </Loggers>
</Configuration>

Запустив это, вы напечатаете:

12:05:28.834 [main] ERROR so35592962.App - in App.main
12:05:28.836 [main] ERROR so35592962.sub.OtherClass - OtherClass.act

Послушайте, здесь есть разные имена классов! Еще я использовал Log4J2.

Что здесь случилось?

Обратите внимание на шаблон, используемый в теге PatternLayout:

%d{HH:mm:ss.SSS} [%t] %-5level %C{36} - %msg%n

Стандартные примеры и то, что вы обычно видите в Интернете, используют шаблон %L. Этот шаблон показывает имя регистратора. Но ты сказал, что не хочешь этого. К счастью, существуют и другие закономерности. %C покажет имя класса вместо имени регистратора. Это шаблон, который здесь используется.

Согласно PatternLayout документации, шаблон %C выполняет следующий:

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

Важное примечание, также упомянутое в документации:

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

person Olivier Grégoire    schedule 24.02.2016
comment
Но если у вас есть только один регистратор, вы больше не можете назначать разные уровни журнала (или разные средства форматирования или разные приложения) разным регистраторам. - person Thilo; 25.02.2016
comment
Верно, но, как мне кажется, это отвечает на первоначальный вопрос. Один уникальный регистратор, использующий имя класса. - person Olivier Grégoire; 25.02.2016
comment
Кроме того, это не да, конечно, сделайте это, но ваш запрос может быть выполнен, вот как. Я лично не поддерживаю это, но если это работает для OP, я рад, что помог! - person Olivier Grégoire; 25.02.2016

Вы можете изменить оба из них на аннотации классов с помощью Lombok.

person Tyler    schedule 24.02.2016