Создание собственного аппендера для logback

в 10:32, , рубрики: java, logback, метки: ,

Уверен, многие пользуются при разработке своих приложений и систем реализацией SLF4J API — logback-ом. Данный пост пишется для тех, кто более менее знаком этой технологией, но сталкивается с необходимостью разработки собственных аппендеров (от англ. appender).

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

Цель данной статьи — показать, с чего вообще начинать работу над собственным аппендером. На страницах подробных описаний того, как работает logback и что там есть что я, к сожалению, не нашел достаточно короткого и понятного how-to. Постараюсь восполнить этот пробел своей заметкой.

Собственно, работа состоит из двух частей: во-первых, это написание необходимых Java классов и, во-вторых, это описание конфигурации нашего аппендера в logback.xml.

Реализация интерфейса Appender

Первое, что нужно сделать, это реализовать интерфейс ch.qos.logback.core.Appender. Проще всего воспользоваться готовой реализацией ch.qos.logback.core.AppenderBase. В этой реализации есть только один abstract метод:
protected abstract void append(E eventObject)
Он вызывается logback-ом при появлении события логирования. В этом методе как раз и нужно писать свой кастомный код по логированию информации, пришедшей в составе объекта eventObject. Абстрактный класс AppenderBase является generic-классом. В нашей простой реализации можно унаследоваться от AppenderBase<ILoggingEvent>.
Пока получается такой класс:

package ru.habrahabr.journaling;

import ch.qos.logback.classic.spi.ILoggingEvent;
import ch.qos.logback.core.AppenderBase;

public class CustomLogAppender extends AppenderBase<ILoggingEvent> {
  @Override
  protected void append(ILoggingEvent eventObject) {
    // код логирования
  }
}

Предположим, что для работы нашего журналирования нам понадобятся настройки, которые удобно будет указывать в файле logback.xml — аналогично тому, как это делается для стандартных аппендеров. Для этого добавим в класс поля: например, одну строковую переменную и одну булеву переменную — а также снабдим класс set-методами.

  ...
public class CustomLogAppender extends AppenderBase<ILoggingEvent> {
  private String simpleConfig;
  private Boolean toggleSomething;
  ...
  public void setSimpleConfig(String simpleConfig) {
    this.simpleConfig = simpleConfig;
  }
  public void setToggleSomething(Boolean toggleSomething) {
    this.toggleSomething = toggleSomething;
  }
}

Эти set-методы будут вызываться тогда, когда logback будет перегружать свой конфигурационный файл.

Настройка аппендера в logback.xml

Перейдем теперь к тому, как описать наш аппендер в logback.xml. Для этого используется тег <appender />: нам потребуется указать имя аппендера (для последующего использования в логгерах) и класс реализации. Кроме этого нужно будет указать значения для настроек нашего аппендера:

<appender name="CustomAppender" class="ru.habrahabr.journaling.CustomLogAppender">
  <simpleConfig>very important string</simpleConfig>
  <toggleSomething>true</toggleSomething>
</appender>

С такими простыми параметрами, как в нашем примере все достаточно очевидно: мы просто добавляем внутри тега <appender /> вложенные теги вида <имяПараметра>значение</имяПараметра>. При загрузке/обновлении конфигурации logback вызывает соответствующие set-методы (этим методы должны иметь названия в соответствии с правилами наименования методов Java бинов).

Помимо работы с простыми настройками logback умеет также работать с коллекциями настроек и с настройками, значением которых является экземпляр определенного класса.

Пусть у нас есть класс ru.habrahabr.journaling.ComplexConfig со своими полями. Установить значение свойства нашего аппендера:

  ...
public class CustomLogAppender extends AppenderBase<ILoggingEvent> {
  private ComplexConfig сomplexConfig;
  ...
  public void setComplexConfig(String complexConfig) {
    this.complexConfig = complexConfig;
  }
}

Через logback.xml можно следующим образом:

<appender name="CustomAppender" class="ru.habrahabr.journaling.CustomLogAppender">
  <simpleConfig>very important string</simpleConfig>
  <toggleSomething>true</toggleSomething>
  <complexConfig class="ru.habrahabr.journaling.ComplexConfig">
    <setting>...</setting>
  </complexConfig>
</appender>

Здесь logback при парсинге logback.xml сначала создаст экземпляр класс ComplexConfig, потом установит значения его полей в соответствии с тегами, вложенными внутри тега <complexConfig />, имя которого совпадает с именем переменной класса CustomLogAppender нашего аппендера.

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

package ru.habrahabr.journaling;
public class Item {
  private String param;
  public void setParam(String param) {
    this.param = param;
  }
  public String getParam() {
    return param;
  }
}

А также класс, содержащий в себе элементы коллекции и имеющий метод для добавления элемента, начинающийся с «add». Для нашего класса Item этот метод должен называться «addItem».

package ru.habrahabr.journaling;

public class ItemCollection {
  ...
  public void addItem(Item item) {
    ...
  }
}

В logback.xml конфигурация будет выглядеть следующим образом:

<appender name="CustomAppender" class="ru.habrahabr.journaling.CustomLogAppender">
  <simpleConfig>very important string</simpleConfig>
  <toggleSomething>true</toggleSomething>
  <complexConfig class="ru.habrahabr.journaling.ComplexConfig">
    <setting>...</setting>
  </complexConfig>
  <itemCollection class="ru.habrahabr.journaling.ItemCollection">
    <item class="ru.habrahabr.journaling.Item">
      <param>test</param>
    </item>
    <item class="ru.habrahabr.journaling.Item">
      <param>live</param>
    </item>
  </itemCollection>
</appender>

Как и раньше, имя тега <itemCollection /> совпадает с именем соответствующей переменной класса CustomLogAppender. Кроме этого мы указываем имя класса реализации холдера для элементов нашей коллекции. У каждого элемента коллекции также требуется указать класс, если это, конечно, не простой параметр.

С map-ками в настройках logback, к сожалению, пока не умеет работать.

Автор: scrutari


  1. Andrey:

    Спасибо, мил человек

* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js