Логирование в Java: Использование slf4j
В этой заметке я расскажу о фасаде для систем логирования, SLF4J, опишу его особенности и использование.
SLF4J (Simple Logging Facade for Java) – библиотека для логгирования, ставящая своей целью предоставить максимально простой, но при этом мощный фасад для различных систем логгирования на Java. Чем же это лучше чем использование какой-либо распространенной библиотеки для логгирования?
Если сравнить использование различных систем логгирования, как log4j и обощенных фасадов, таких как, например, slf4j, то можно найти следующие отличия:
Использование конкретной реализации:
- Зависимость от этой конкретной реализации
- Необходимость искать адаптеры, при необходимости использования компонент, разработанных, для других реализаций логгирования
- Меньше компонент в зависимостях
Использование фасада:
- Возможность использования различных реализаций
- Большое число компонент (фасад + реализация)
- Возможность быстро менять реализацию, возможно даже не меняя не строчки кода
Дополнительно к этому, SLF4J предоставляет возможность интегрировать компоненты, зависимые от других систем логирования (Log4J, JCL), подставляя реализации, направляющие логи этих систем в SLF4J.
Таким образом, небольшой ценой использование фасада для логирования значительно увеличивает возможности для интегрирования компонента в другие системы, что особенно важно, если неизвестно, где компонент будет использован (например, если это какая-та библиотека).
Использование
Для использования SLF4J, classpath проекта должен включать библиотеку slf4j-api.jar, которая содержит классы фасада. Для использования логирования в коде рассмотрим следующий пример кода:
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
class MyClass {
private Logger log = LoggerFactory.getLogger( MyClass.class ); // 1. Объявляем переменную логгера
...
log.debug( "..." ); // 2. Выводим строку в debug
...
log.info( "Some object: {}", object ); // 3. Выводим в info строку с аргументом, подставляемым в нее
...
log.error( "Error during some job!!", e ); // 4. Выводим в error ошибку, вместе с исключением
}
Теперь рассмотрим, что же в этом примере делалось:
- Объявление переменной логгера. Логгер имеет тип org.slf4j.Logger и создается вызовом метода getLogger() у класса org.slf4j.LoggerFactory. В качестве параметра методу передается класс, в этом случае имя логгера совпадает с полным именем класса. Также можно передать строку, которая будет именем логгера.
- Вывод строки в лог. Методом debug в лог выводится запись с уровнем DEBUG, в точности такая, как была передана в качестве аргумента. Аналогично, существуют методы info, warn и error.
- Вывод в лог строки с аргументом. В запись в логе вместо {} подставляется второй аргумент метода. Таким образом можно передать до двух параметров, большее число необходимо оборачивать в массив. Чем такая передача лучше, чем просто "Some object: " + object? Тем, что в случае, когда записи с уровнем info не выводятся в лог, преобразование объекта object в строку и склеивание с "Some object: " может не производится, что может дать выигрыш в производительности.
- Вывод в лог строки с исключением. Вторым аргументом метода может так же быть исключение. Причем, исключение можно добавлять не только к ошибкам, но и к любым записям.

on March 22, 2009 at 15:03 c0nst wrote:
В JDK уже есть классы для логирования - java.util.logging. Пока что там много недоделок - например нет поддержки Pattern Layout как в log4j и нет некоторых важных аппендеров (SMTPAppender, DailyRollingAppender). Но это дело попроавимое. Пишешь один раз, оттачиваешь и потом можно во всех своих проектах использовать. И нет внешних dependency.
on March 25, 2009 at 09:03 Alno wrote:
Да, есть такие классы. Только, я не встречал проектов, которые бы их использовали. В отличие от Log4J и SLF4J.
Ну и, если честно, SLF4J выглядит для меня несколько более удобным (хотя кому-то может казаться наоборот):
Во-первых, достаточно прозрачный интерфейс логгера.
Во-вторых, возможность установить любую реализацию.
Еще в SLF4J есть интересная возможность - маркеры, которых нет ни в LogJ4, ни в JDK Logging.