Текущее ведение журнала Java с помощью Flogger

Flogger, разработанный, используемый и рекомендуемый Google, является API-интерфейсом для журналирования в стиле Fluent для Java. Помимо Fluency, Flogger предлагает гораздо больше других функций, чем существующие фреймворки для журналирования, которые мы изучим в этом руководстве.

1. Зависимости от флоггера

Flogger, подобно SLF4J, действует как абстракция и использует базовую структуру журналирования в качестве реализации. Мы можем использовать Flogger с Java Logging API, Log4j2 и даже SLF4J. По умолчанию flogger использует Java Util Logging API(JUL).

1.1. Ядро Флоггера

Чтобы добавить flogger в приложение, нам необходимо добавить зависимости com.google.flogger:flogger и com.google.flogger:flogger-system-backend, которые предоставляют основные классы и интерфейсы для записи сообщений журнала.

<dependency><groupId>com.google.flogger</groupId><artifactId>flogger</artifactId><version>0.7.4</version></dependency><!-- The Java Util Logging backend --><dependency><groupId>com.google.flogger</groupId><artifactId>flogger-system-backend</artifactId><version>0.7.4</version></dependency>

API Flogger внутренне зависят от flogger-system-backend, который транзитивно подключается для любой добавляемой нами платформы ведения журналов.

1.2. Базовый бэкэнд для ведения журнала

Далее нам нужно добавить зависимость времени выполнения от данных платформ ведения журналов. Мы будем использовать ее файлы конфигурации для настройки уровней журналов, аппендеров и т. д.

Например, если мы используем Flogger с Log4j2, то нам нужно добавить зависимость flogger-log4j2-backend. После импорта этой зависимости мы можем управлять уровнями логирования, аппендеры, макеты и т. д. из файла log4j2.xml.

<!-- The SLF4J backend --><dependency><groupId>com.google.flogger</groupId><artifactId>flogger-slf4j-backend</artifactId><version>0.7.4</version></dependency><!-- The Log4j backend --><dependency><groupId>com.google.flogger</groupId><artifactId>flogger-log4j-backend</artifactId><version>0.7.4</version></dependency><!-- The Log4j2 backend --><dependency><groupId>com.google.flogger</groupId><artifactId>flogger-log4j2-backend</artifactId><version>0.7.4</version></dependency>

2. API Флоггера

2.1. FluentLogger

Использование API Fluent, предоставляемого Flogger в классах приложений, начинается с создания экземпляра FluentLogger.

import com.google.common.flogger.FluentLogger;public class Main {private static final FluentLogger logger = FluentLogger.forEnclosingClass();}

Далее мы можем начать использовать экземпляр FluentLogger для записи сообщений журнала.

Обратите внимание, что мы не используем фигурные скобки {} для заполнителей данных, мы можем использовать любой из спецификаторов формата printf() Java, например %s, %d и т. д.

logger.atWarning().log("Warning message");Article a = Article.builder(1L).title("Test Article").tag("Data").build();logger.atInfo().log("Article found : %s", a);

Это позволит распечатать сообщения журнала в настроенных приложениях и макете.

 2022-01-10 20:34:37.621 WARN [main] [com.howtodoinjava.demo.flogger.Main.main(Main.java:17)] - Предупреждающее сообщение2022-01-10 20:34:37.632 ИНФОРМАЦИЯ [main] [com.howtodoinjava.demo.flogger.Main.main(Main.java:20)] - Найдена статья: Статья(id=1, title=Тестовая статья, tags=[Данные])

2.2 Уровни журнала

На уровне API Flogger поддерживает уровни журналирования, предоставляемые JDK Logging.

  • ВЫКЛ: отключить ведение журнала.
  • СЕРЬЕЗНЫЙ:(наивысшее значение): серьезный сбой.
  • ВНИМАНИЕ: потенциальная проблема.
  • ИНФОРМАЦИЯ: информационные сообщения.
  • CONFIG: регистрировать статические сообщения конфигурации.
  • FINE: информация о трассировке журнала.
  • FINER: зарегистрировать достаточно подробное сообщение об отслеживании.
  • FINEST:(наименьшее значение): регистрировать очень подробное сообщение об отслеживании.
  • ВСЕ: включить регистрацию всех сообщений.

Для регистрации сообщений на определенном уровне мы можем использовать следующие вызовы методов.

logger.atInfo().log("...");logger.atWarning().log("...");logger.atSevere().log("...");logger.atFine().log("...");logger.atFiner().log("...");logger.atFinest().log("...");logger.atConfig().log("...");//Can be used for any log levellogger.at(Level.SEVERE).log("...");

Уровень ведения журнала можно задать с помощью файлов конфигурации базовой платформы ведения журнала(logging.properties, log4j.properties и т. д.).

2.3. Регистрация исключений

Используйте метод withStackTrace() для регистрации экземпляра Throwable.

logger.atInfo().withStackTrace(StackSize.SMALL).withCause(new NullPointerException()).log("NullPointerException Received");
2022-01-10 21:14:49 INFO Main:26 - NullPointerException Receivedjava.lang.NullPointerException: nullat com.howtodoinjava.demo.flogger.Main.main(Main.java:26) [classes/:?]

Перечисление StackSize имеет 3 константы:

  • StackSize.SMALL: Создает небольшой стек, подходящий для более детальной отладки.
  • StackSize.MEDIUM: создает стек среднего размера, подходящий для предоставления контекстной информации для большинства операторов журнала.
  • StackSize.LARGE: создает большой стек, подходящий для предоставления очень подробной контекстной информации.
  • StackSize.FULL: Предоставляет полную трассировку стека.
  • StackSize.NONE: Не предоставляет трассировку стека. Это полезно, когда размер стека условен.
logger.atWarning().withStackTrace(showTrace ? StackSize.MEDIUM : StackSize.NONE).log("message");

2.4 Ограничение скорости

Это интересная функция, где мы не хотим регистрировать сообщение для каждого появления оператора. Мы хотим регистрировать сообщение при каждом n-ном появлении.

В данном примере мы регистрируем сообщение на каждой 10-й итерации.

IntStream.range(0, 50).forEach(value -> {logger.atInfo().every(10).log("The counter is => %d", value);});
 2022-01-10 21:13:23 ИНФОРМАЦИЯ Main:30 - Счетчик => 02022-01-10 21:13:23 ИНФОРМАЦИЯ Main:30 - Счетчик => 102022-01-10 21:13:23 ИНФОРМАЦИЯ Main:30 - Счетчик => 202022-01-10 21:13:23 ИНФОРМАЦИЯ Main:30 - Счетчик => 302022-01-10 21:13:23 ИНФОРМАЦИЯ Main:30 - Счетчик => 40

3. Преимущества Flogger перед другими фреймворками для ведения журналов

Теперь, когда у нас есть базовое понимание API Flogger, давайте разберемся, что делает его настолько полезным, что Google рекомендует использовать его внутри организации.

3.1.Производительность

По данным Google, Flogger был разработан и реализован для высокопроизводительного ведения журнала путем создания набора тщательно продуманных API, как на внешнем, так и на внутреннем интерфейсе.

API-интерфейсы Flogger работают поверх платформы ведения журналов, обеспечивая максимально возможную производительность.

3.2 Стоимость отключенных сообщений журнала

Большинство фреймворков журналирования широко используют varargs в таких методах, как info(), debug() и т. д. Эти методы требуют выделения и заполнения нового Object[] перед вызовом вызываемого метода. Кроме того, любые основные типы, переданные в них, должны быть автоматически упакованы.

По этой причине простой подход log.info(String, Object…) к ведению журнала лаконичен на уровне исходного кода, но может внести неожиданные затраты в байт-код. Чтобы сделать ситуацию еще хуже, этот накладной байт-код будет выполняться, даже если оператор журнала отключен.

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

При использовании Flogger's fluent API logger.atInfo().log(«My message: %s», arg); мы можем узнать, отключено ли ведение журнала в момент вызова селектора уровня с помощью метода atInfo(). Таким образом, если ведение журнала отключено, мы можем выбрать возврат другой реализации контекста ведения журнала, которая просто отбрасывает все свои аргументы для каждого последующего вызова метода(экземпляр «No-Op»).

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

4. Заключение

Flogger кажется очень многообещающим API с некоторыми большими преимуществами, обсуждаемыми выше. Чтобы сделать его еще более знакомым, мы можем использовать существующие конфигурации Log4j2 или SLF4J для более простых миграций.

В этом уроке мы научились импортировать зависимости Flogger и использовать API Flogger для регистрации различных сообщений. Подробнее о Flogger можно прочитать на его официальной странице Github.

Исходный код Скачать

Прокрутить вверх