Уверен, многие пользуются при разработке своих приложений и систем реализацией 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
Спасибо, мил человек