Log4j настройка вывода в файл

Обновлено: 05.07.2024

Думаю, ни для кого не секрет, что такое логгеры и для чего они нужны. За время существования java было создано немало фреймворков логгирования. Среди самых известных можно выделить:

  • JUL — java.util.logging
  • log4j
  • JCL — jakarta commons logging
  • Logback
  • SLF4J — simple logging facade for java

System.err.println

Первым и самым примитивным способом логгирования был метод System.err.println. Думаю, комментарии излишние, достаточно взглянуть на приведенный ниже код:

Java.util.logging

Данный фреймворк включен в стандарт и поставляется вместе с JDK, поэтому ничего дополнительно скачивать и подключать вам не надо. JUL имеет следующие уровни логгирования по возрастанию: FINEST, FINER, FINE, CONFIG, INFO, WARNING, SEVERE, а так же ALL и OFF, включающий и отключающий все уровни соответственно.
Логгер создается вызовом одного из статических методов класса java.util.logging.Logger:


Вторая группа методов имеет следующие вариации:


Для того что бы JUL применил данную конфигурацию нужно передать параметр -Djava.util.logging.config.file = <путь до файла>, либо при старте приложения выполнить код:

Log4j

Данный фреймворк на текущий момент имеет уже вторую версию, которая увы не совместима с первой. Поскольку первая версия log4j существует достаточно давно и, в виду ее большой популярности, существует не мало статей на просторах интернета, сегодня мы рассмотрим вторую. Для использования log4j2 вам необходимо подключить библиотеки log4j-api-2.x и log4j-core-2.x. Log4j имеет несколько отличное от JUL именование уровней логгирования: TRACE, DEBUG, INFO, WARN, ERROR, FATAL, а так же ALL и OFF включающий и отключающий все уровни соответственно.
Логгер создается вызовом статического метода класса org.apache.logging.log4j.Logger:


Логгер умеет принимать помимо привычных нам String, Object и Throwable еще два новых типа — MapMessage и Marker:


В классическом для логгеров стиле методы делятся на два типа: совпадающие с названием уровня логгирования и методы log, принимающие уровень логгирования в качестве параметра. Первые имеют вид:


Методы log в log4j2 выглядят так:

  • BurstFilter
  • CompositeFilter
  • DynamicThresholdFilter
  • MapFilter
  • MarkerFilter
  • RegexFilter
  • StructuredDataFilter
  • ThreadContextMapFilter
  • ThresholdFilter
  • TimeFilter
  • AsyncAppender
  • ConsoleAppender
  • FailoverAppender
  • FileAppender
  • FlumeAppender
  • JDBCAppender
  • JMSAppender
  • JPAAppender
  • MemoryMappedFileAppender
  • NoSQLAppender
  • OutputStreamAppender
  • RandomAccessFileAppender
  • RewriteAppender
  • RollingFileAppender
  • RollingRandomAccessFileAppender
  • RoutingAppender
  • SMTPAppender
  • SocketAppender
  • SyslogAppender

Commons-logging

Довольно старый проект, который представляет собой обертку над JUL и log4j, не привносящая никакого дополнительного функционала. Уровни логгирования у JCL совпадают с log4j, а в случае взаимодействия с JUL происходит следующее сопоставление:


Для использования JCL подключаем commons-logging-1.x.jar. Создаем логгер вызовом метода фабрики:


Методы JCL очень простые, совпадают с названием уровней логгирования, принимают только объекты и исключения и имеют две вариации:


Указать файл конфигурации JCL можно следующим образом:

Logback

Данный фреймворк используется только в связке с оберткой SLF4J, которую мы будем рассматривать позднее. Для начала работы вам необходимы logback-core-1.x.jar и logback-classic-1.x.x.jar, а также slf4j-api-1.x.x.jar.
Взаимодействие с логгером мы будем осуществлять через API предоставляемый оберткой SLF4J. Уровни логгирования совпадают с log4j. Создание логгера в таком случае выглядит следующим образом:


Названия методов совпадают с уровнями логгирования и имеют вид:

SLF4J

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

Log4j — библиотека журналирования Java программ, часть общего проекта «Apache Logging Project».

Log4j первоначально развивался в рамках зонтичного Apache Jakarta Project, ответственного за все Java-проекты Apache, но впоследствии выделился в отдельный, очень популярный проект журналирования (стандарт де-факто).

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

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

  • Выбор хранилища – консоль, файл, СУБД;
  • Конфигурация хранилища – именование хранилища, объем хранилища, путь к хранилищу, сохранение конфигурации;
  • Форматирование записей журнала – дата/время, класс/метод и т.д., гибкое форматирование.
  • загрузить библиотеку фреймворка;
  • создать конфигурационный файл с параметрами журналирования;
  • создать объект журнала (лога) в своем приложении;
  • воспользоваться методами для записи в журнал.

Каким образом хранить конфигурацию журналирования?

Есть два типа конфигурационных файлов формат XML и формат PROPERTIES. В случае одноименных файлов выше приоритет у файлов XML.

Как конфигурировать файл log4j.properties или log4j.xml?

log4j.properties

1 log4j.rootCategory=DEBUG, console

4 log4j.appender.console.layout.ConversionPattern= %p %c: %m%n

<? xml version= "1.0" encoding= "UTF-8" ?>
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
< log4j:configuration xmlns:log4j= "http://jakarta.apache.org/log4j/" >
< appender name= "console" class= "org.apache.log4j.ConsoleAppender" >
< param name= "Target" value= "System.out" />
< layout class= "org.apache.log4j.PatternLayout" >
< param name= "ConversionPattern" value= "%p %c: %m%n" /> </ layout >
</ appender >
<!-- Корневой logger-->
< root > < priority value = "debug" />
< appender-ref ref= "console" />
</ root >
</ log4j:configuration >

Советы по использованию Log4J

  • Определите События, подлежащие записи в журнал;
  • Определите ключевые Параметры, для каждого События;
  • Определите Источники Событий – это самое важное, иначе ваша система логирования превратится в свалку не нужных Событий с таким же перечнем ненужных Параметров;
  • Не старайтесь разделить системы логирования по приоритетам (FATAL or INFO), разделите по функциональным модулям или ключевым Объектам системы;
  • Выполняйте логирование жизненного цикла Объекта;

Журналирование событий это лишь часть функциональности Вашего приложения, не стоит ставить приоритет этой задачи выше приоритета основной функциональности.

Как использовать Log4J в Java приложениях?

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

public static void main(String[] args) throws FileNotFoundException, IOException 1:String nameFile = "log4j.properties";
2:PropertyConfigurator.configure(nameFile);
/*1*/Logger LOG = Logger.getRootLogger();
/*2*/Logger localLog2 = Logger.getLogger("logfile");
/*3*/Enumeration append = LOG.getAllAppenders();
/*3*/while (append.hasMoreElements())

/*3*/LOG.info("Available appender " + append.nextElement());
/*3*/>

log4j.rootLogger = TRACE, console log4j.appender.console=org.apache.log4j.ConsoleAppender

log4j.appender.console.layout.ConversionPattern=[%p] %d (%F:%M:%L)%m %n%n

log4j.appender.logfile.layout.ConversionPattern=%d [%t] %-5p %c - %m%n

Вывод на консоль :

1: [INFO] 10:07:06 (Main.java:main:43)Available appender org.apache.log4j.ConsoleAppender@10b4199

2: [INFO] 10:07:06 (Main.java:main:45)Hi Logger info!

3: [DEBUG] 10:07:06 (Main.java:main:47)osdebug write!

4: [WARN] 10:07:06 (Main.java:main:48)logfile write!

Вывод в лог-файл D:\infolog.txt:

2009-09-15 10:07:06,811 [main] WARN logfile - logfile write!

Вывод в лог-файл D:\debuglog.txt:

2009-09-15 10:07:06,811 [main] DEBUG osdebug - osdebug write!

В строке 1 перечислены типы категорий, которые были указаны в глобальном объекте.

localLog.debug("osdebug write!");

localLog2.warn("logfile write!");

Вывод перенаправленный в лог файл, форматируется по отдельным правилам , которые указаны в категории log4.j.logger.logfile=INFO, logfile , а строка форматируется на основании шаблона

log4j.appen der.logfile.layout.ConversionPattern=%d [%t] %-5p %c - %m%n

В файле конфигураций указана категория log4.j.logger.logfile=INFO, logfile

но вывод не будет направлен, даже если Вы замените строку вызова Logger localLog = Logger.getLogger("logfile");

В примере создано два объекта журнала, строки помечены как /*1*/ и /*2*/ , оба они ссылаются на разные объекты! В строках /*3*/ создаётся объект enumeration ? если вы вдруг просто слили чей-то конфиг и хотите посмотреть что и как внутри , он выведет все доступные(описанные) в файле конфигураций объекты appender.

Будьте внимательны при указании приоритета в вызове объекта журнала, при указании приоритета ,который не соответствует описанному в конфигурации, данные не будут записаны в журнал. Пример такого описания:

Давайте научимся следить за выполнением логики в нашей программе, для этого мы научимся использовать логирование, поймем зачем оно и где используется.

Шаг 0. Обзор

Зачем нужно логирование и что оно даёт?

Вы, как человек который администрирует магазин начнет разбераться в чем же проблема. Неопытный человек будет долго искать проблему, а опытный сразу полезет в логи сервера, но там все логи сервера и найти то что нужно вам сложно.


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

В данном уроке мы рассмотрим как сконфигурировать и начать использовать Log4j.

Шаг 1. Создаем проект и добавляем завимости

Запускаем всеми любимую Intellij IDEA и тыкаем New Project выбираем Maven Module и называем его :


Теперь в pom.xml жлбавим зависимость:

Это все зависимости, которые надо было подключить.

Шаг 2. Создание примитивной логики для примера

Давайте создадим класс в котором была бы бизнес-логика, назовем его OrderLogic:

Хочу обратить ваше внимание на то, что логика данного проекта не важна, так как мы рассматриваем логирование, для этого я и подготовил примитивную логику класса OrderLogic.

И теперь создаем Main класс:

В результате выполнения данного кода, мы получим следующее:

Как видите пока ничего нового.

Шаг 3. Конфигурируем Log4j

Чтобы гибко управлять логированием стоит создать в resources/ файл log4j.properties:


Теперь в этот файл добавим пару строк конфигураций:

Теперь давайте более детальней разберем строку формирования шаблона:

Давайте разберем реальные случаи, в которых логирование решало бы проблему. Вот пример из моей работы. Есть точки приложений, которые интегрируются с другими сервисами. Я использую логирование этих точек для “алиби”: если интеграция не сработает, будет легко разобраться, с какой стороны возникла проблема. Еще желательно логировать важную информацию, которая сохраняется в базу данных. Например создание пользователя администратора. Это как раз то, что хорошо бы логировать.

Инструменты для логирования в Java

  • log4j
  • JUL — java.util.logging
  • JCL — jakarta commons logging
  • Logback
  • SLF4J — simple logging facade for java

System.err.println

Первоначально был, разумеется, System.err.println (вывод записи в консоль). Его и сейчас используют для быстрого получения лога при дебаге. Конечно, говорить о каких-то настройках здесь не приходится, поэтому просто запомним его и пойдем дальше.

Log4j

Это уже было полноценное решение, которое создавалось из потребностей разработчиков. Получился действительно интересный инструмент, который можно использовать. В силу разных обстоятельств это решение так и не попало в JDK, чем очень расстроило все комьюнити. В log4j были возможности по конфигурации таким образом, чтобы можно было включить логирование в пакете com.example.type и выключить его в подпакете com.example.type.generic . Это позволяло быстро отсечь то, что нужно логировать, от того, что не нужно. Здесь важно отметить, что есть две версии log4j: 1.2.х и 2.х.х, которые несовместимы друг с другом. log4j добавил такое понятие как appender, то есть инструмент, с помощью которого записываются логи и layout — форматирование логов. Это позволяет записывать только то, что нужно и как нужно. Больше о appender поговорим чуть позже.

JUL — java.util.logging

Одно из ключевых преимуществ это решения — JUL включен в JDK (Java development kit). К сожалению, при его разработке за основу взяли не популярный log4j, а решение от IBM, что и повлияло на его развитие. По факту на данный момент JUL есть, но им никто не пользуется. Из “такого себе”: в JUL уровни логирования отличаются от того, что есть в Logback, Log4j, Slf4j, и это ухудшает понимание между ними. Создание логгера более менее похожее. Для этого нужно сделать импорт: Имя класса специально передается для того, чтобы знать, откуда идет логирование. Начиная с Java 8, можно передавать Supplier<String> . Это помогает считать и создавать строку только в тот момент, когда это действительно нужно, а не каждый раз, как это было до этого. Только с выходом Java 8 разработчики решили важные проблемы, после чего JUL по-настоящему стало возможно в использовании. А именно, методы с аргументом Supplier<String> msgSupplier , как показано ниже:

JCL — jakarta commons logging

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

Logback

  • улучшена производительность;
  • добавлена нативная поддержка slf4j;
  • расширена опция фильтрации.

SLF4J — simple logging facade for java

Что нужно логировать

  1. Начало/конец работы приложения. Нужно знать, что приложение действительно запустилось, как мы и ожидали, и завершилось так же ожидаемо.
  2. Вопросы безопасности. Здесь хорошо бы логировать попытки подбора пароля, логирование входа важных юзеров и т.д.
  3. Некоторые состояния приложения. Например, переход из одного состояния в другое в бизнес процессе.
  4. Некоторая информация для дебага, с соответственным уровнем логирования.
  5. Некоторые SQL скрипты. Есть реальные случаи, когда это нужно. Опять-таки, умелым образом регулируя уровни, можно добиться отличных результатов.
  6. Выполняемые нити(Thread) могут быть логированы в случаях с проверкой корректной работы.

Популярные ошибки в логировании

  1. Избыток логирования. Не стоит логировать каждый шаг, который чисто теоретически может быть важным. Есть правило: логи могут нагружать работоспособность не более, чем на 10%. Иначе будут проблемы с производительностью.
  2. Логирование всех данных в один файл. Это приведет к тому, что в определенный момент чтение/запись в него будет очень сложной, не говоря о том, что есть ограничения по размеру файлов в определенных системах.
  3. Использование неверных уровней логирования. У каждого уровня логирования есть четкие границы, и их стоит соблюдать. Если граница расплывчатая, можно договориться какой из уровней использовать.

Уровни логирования

  • OFF: никакие логи не записываются, все будут проигнорированы;
  • FATAL: ошибка, после которой приложение уже не сможет работать и будет остановлено, например, JVM out of memory error;
  • ERROR: уровень ошибок, когда есть проблемы, которые нужно решить. Ошибка не останавливает работу приложения в целом. Остальные запросы могут работать корректно;
  • WARN: обозначаются логи, которые содержат предостережение. Произошло неожиданное действие, несмотря на это система устояла и выполнила запрос;
  • INFO: лог, который записывает важные действия в приложении. Это не ошибки, это не предостережение, это ожидаемые действия системы;
  • DEBUG: логи, необходимые для отладки приложения. Для уверенности в том, что система делает именно то, что от нее ожидают, или описания действия системы: “method1 начал работу”;
  • TRACE: менее приоритетные логи для отладки, с наименьшим уровнем логирования;
  • ALL: уровень, при котором будут записаны все логи из системы.

Запись и отправка логов: Appender

  • для записи в файл — решение DailyRollingFileAppender;
  • для получения данных в консоль приложения — ConsoleAppender;
  • для записи логов в базу данных — JDBCAppender;
  • для контроля передачи через TCP/IP — TelnetAppender;
  • для того, чтобы запись логов не била по быстродействию — AsyncAppender.

Узлы логирования

Читайте также: