Log4j2 настройка конфигурационного файла
Обновлено: 03.07.2024
Давайте разберем реальные случаи, в которых логирование решало бы проблему. Вот пример из моей работы. Есть точки приложений, которые интегрируются с другими сервисами. Я использую логирование этих точек для “алиби”: если интеграция не сработает, будет легко разобраться, с какой стороны возникла проблема. Еще желательно логировать важную информацию, которая сохраняется в базу данных. Например создание пользователя администратора. Это как раз то, что хорошо бы логировать.
Инструменты для логирования в 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
Что нужно логировать
- Начало/конец работы приложения. Нужно знать, что приложение действительно запустилось, как мы и ожидали, и завершилось так же ожидаемо.
- Вопросы безопасности. Здесь хорошо бы логировать попытки подбора пароля, логирование входа важных юзеров и т.д.
- Некоторые состояния приложения. Например, переход из одного состояния в другое в бизнес процессе.
- Некоторая информация для дебага, с соответственным уровнем логирования.
- Некоторые SQL скрипты. Есть реальные случаи, когда это нужно. Опять-таки, умелым образом регулируя уровни, можно добиться отличных результатов.
- Выполняемые нити(Thread) могут быть логированы в случаях с проверкой корректной работы.
Популярные ошибки в логировании
- Избыток логирования. Не стоит логировать каждый шаг, который чисто теоретически может быть важным. Есть правило: логи могут нагружать работоспособность не более, чем на 10%. Иначе будут проблемы с производительностью.
- Логирование всех данных в один файл. Это приведет к тому, что в определенный момент чтение/запись в него будет очень сложной, не говоря о том, что есть ограничения по размеру файлов в определенных системах.
- Использование неверных уровней логирования. У каждого уровня логирования есть четкие границы, и их стоит соблюдать. Если граница расплывчатая, можно договориться какой из уровней использовать.
Уровни логирования
- OFF: никакие логи не записываются, все будут проигнорированы;
- FATAL: ошибка, после которой приложение уже не сможет работать и будет остановлено, например, JVM out of memory error;
- ERROR: уровень ошибок, когда есть проблемы, которые нужно решить. Ошибка не останавливает работу приложения в целом. Остальные запросы могут работать корректно;
- WARN: обозначаются логи, которые содержат предостережение. Произошло неожиданное действие, несмотря на это система устояла и выполнила запрос;
- INFO: лог, который записывает важные действия в приложении. Это не ошибки, это не предостережение, это ожидаемые действия системы;
- DEBUG: логи, необходимые для отладки приложения. Для уверенности в том, что система делает именно то, что от нее ожидают, или описания действия системы: “method1 начал работу”;
- TRACE: менее приоритетные логи для отладки, с наименьшим уровнем логирования;
- ALL: уровень, при котором будут записаны все логи из системы.
Запись и отправка логов: Appender
- для записи в файл — решение DailyRollingFileAppender;
- для получения данных в консоль приложения — ConsoleAppender;
- для записи логов в базу данных — JDBCAppender;
- для контроля передачи через TCP/IP — TelnetAppender;
- для того, чтобы запись логов не била по быстродействию — AsyncAppender.
Узлы логирования
Пример Log4j2. Учебник по Log4j2. Конфигурация Log4j2. log4j2.xml пример. Уровни Log4j2, Приложения Log4j2, Поисковые запросы, Фильтры, Макет, Отображение шаблонов.
Многие платформы предоставляют какой-либо способ ведения журнала по умолчанию, но всегда лучше использовать стандартный отраслевой механизм ведения журнала. Apache Log4j-одна из наиболее широко используемых систем ведения журнала. Apache Log4j 2-это следующая версия, которая намного лучше, чем Log4j.
Пример учебника Log4j
В этом примере урока Log4j2 вы узнаете, как начать работу с Apache Log4j2 . Мы также рассмотрим архитектуру Log4j2, конфигурацию log4j2, уровни ведения журнала log4j2, приложения, фильтры и многое другое.
- Обзор Log4j2
- Архитектура Log4j2
- Конфигурация Log4j2
- Уровни Log4j2
- Поиск в журнале 4j2
- Приложения Log4j2
- Фильтры Log4j2
- Макеты Log4j2
- Какой уровень Log4j2 вы должны использовать
- Краткое описание учебного пособия Log4j2
Обзор Log4j2
Вы можете отлаживать приложение с помощью отладки Eclipse или некоторых других инструментов, но этого недостаточно и невозможно в рабочей среде.
Механизм ведения журнала предоставит вам несколько преимуществ, которых вы не найдете при обычной отладке.
Нет необходимости в человеческом вмешательстве | Существует необходимость в человеческом вмешательстве | Вмешательство человека |
Может быть интегрирован с постоянным хранилищем (файлы, база данных, база данных NoSQL и т.д.) | Не может быть интегрирован с постоянным хранилищем | Стойкая Среда |
Может быть использован для достижения аудита, если он используется эффективно | Не может быть использован для достижения аудита | Может использоваться для аудита |
Достаточный | Недостаточно; вы можете заблудиться в потоке. | Достаточно для сложной структуры и потока |
Более продуктивно | Менее продуктивно | Производительность |
Как вы можете видеть выше, использование механизма ведения журнала будет более эффективным при меньших затратах на техническое обслуживание.
Apache Log4j-это передовой инструмент для входа в Java-приложения, поэтому вам следует его использовать.
Архитектура Log4j2
Прежде чем мы перейдем к учебнику по примеру Log4j, полезно изучить архитектуру Log4j2. На рисунке ниже показаны важные классы в API Log4j2.
Вот подробное объяснение архитектуры, показанной выше:
- Приложения будут запрашивать LogManager для Регистратора с определенным именем.
- LogManager найдет соответствующий LoggerContext и затем получит Logger из него.
Если регистратор еще не создан, он будет создан и связан с LoggerConfig в соответствии с тремя вариантами ниже:
- Экземпляр регистратора будет создан и связан с LoggerConfig , имеющим то же имя. Например App.class в getLogger(App.class) будет оцениваться как строка com.journaldev.Приложение . Имя LoggerConfig идентично полному имени класса (программный компонент).
- Экземпляр регистратора будет создан и связан с LoggerConfig , имеющим тот же родительский пакет регистраторов. Например com.journaldev в getLogger("com.journaldev")
- Экземпляр регистратора будет создан и связан с корневым LoggerConfig . Корневой LoggerConfig будет использоваться, когда нет файла конфигурации или когда вы получаете регистратор с именем, не определенным в объявлениях регистратора.
Каждый регистратор связан с объектом LoggerConfig, набор объектов LoggerConfig составляет Иерархию регистраторов. Эта концепция известна как Иерархия регистраторов .
Регистратор состояния ошибок Не найден файл конфигурации log4j2. Использование конфигурации по умолчанию: запись только ошибок в консоль.
Ребенок | X | потомок | Корень | потомок |
X | Родитель | Ребенок | ком | потомок |
Родитель | Предок | X | ком | Ребенок |
Предок | Предок | Родитель | ком | X |
Чтобы прояснить отношения между родителями и детьми, приведенную выше таблицу следует читать следующим образом:
- Root является родителем для com.
- Корень является предком для com.journaldev.
- Корень является предком для com.journaldev.logging.
- com является дочерним для Root.
- com является родительским для com.journaldev.
- com является предком com.journaldev.logging.
- com.journaldev.logging является дочерним для com.journaldev и так далее.
Экземпляр LoggerConfig считается предком другого LoggerConfig; если его имя, за которым следует точка, является префиксом для имени потомка.
Экземпляр LoggerConfig считается родительским для другого LoggerConfig; если между ними обоими нет чередующихся имен.
Конфигурация Log4j2
Существует множество способов использования конфигурации Log4j2 в вашем приложении.
- Используя файл конфигурации, написанный в XML, JSON, YAML или файле свойств.
- Программно, путем создания фабрики конфигурации и реализации конфигурации.
- Программно, вызывая API, доступные в интерфейсе конфигурации.
- Программно, вызывая методы внутреннего класса регистратора.
Мы сосредоточимся в основном на файле конфигурации. Однако полезно также знать подход к программированию, если вы хотите настроить определенную стратегию ведения журнала для какого-либо конкретного регистратора.
Прежде всего, давайте рассмотрим случай, когда вы не предоставили файл конфигурации. Реализация Log4j2 предполагает, что существует системная переменная с именем Файл конфигурации log4j. , указывающая местоположение файла конфигурации log4j2.
Простой файл конфигурации log4j2 будет выглядеть следующим образом.
А вот подробное объяснение кода, перечисленного выше:
- Приложение ссылается на корневой регистратор, вызвав метод LogManager getRootLogger .
- Обращение к регистратору из LogManager запустило систему Log4j.
- Log4j проверит системное свойство файла конфигурации log4j., чтобы определить файл конфигурации log4j2. Конфигурация Log4j может быть записана в формате JSON, YAML и XML.
- Мы можем задать системное свойство log4j.configurationFile с помощью System.setproperty("Файл конфигурации log4j","ПУТЬ к файлу") или передав его в качестве параметра JVM, как показано на рисунке ниже. Обратите внимание также на префикс протокола файла.
В случае, если системное свойство не определено порядок конфигурации имеет приоритет ниже:
- Свойство ConfigurationFactory будет искать log4j2-test.properties в пути к классу.
- Фабрика конфигурации YAML будет искать log4j2-тест.yaml или log4j2-test.yml в пути к классу.
- JSONConfigurationFactory будет искать log4j2-test.jsn или log4j2-test.json в пути к классу.
- XMLConfigurationFactory будет искать log4j2-test.xml в пути к классу.
- Свойство ConfigurationFactory будет искать log4j2.properties в пути к классу
- Фабрика конфигурации YAML будет искать log4j2.yml или log4j2.yaml в пути к классу.
- JSONConfigurationFactory будет искать log4j2.jsn или log4j2.json в пути к классу.
- XMLConfigurationFactory будет искать log4j2.xml в пути к классу.
Если файл конфигурации не был предоставлен, выполняется Конфигурация по умолчанию , и это приведет вас к набору поведений по умолчанию:
Использование файла конфигурации log4j2 делает конфигурацию log4j2 такой простой, но давайте посмотрим, как мы можем настроить ее программно. Все дело в использовании ConfigurationFactory.
Ту же конфигурацию можно выполнить с помощью YAML, JSON или файла свойств. Однако конфигурация файла свойств log4j2 отличается от файла свойств log4j, поэтому убедитесь, что вы не пытаетесь использовать конфигурацию файла свойств log4j с log4j2. Это приведет к ошибке ниже;
При обработке приведенного выше кода вы получите следующий вывод:
Изложенный в статье материал предназначен для новичков и, возможно, как и мне сэкономит несколько часов поисков на StackOverFlow и других сайтах с целью получить удобную систему логирования, которая сама поймет куда логировать — в консоль, файл или logstash.
На старте проекта всегда возникает задача правильно настроить логирование, при этом на локальном окружении логи должны выводиться в консоль и в файл для удобства в процессе отладки, а на удаленном сервере выводить логи в консоль крайне не желательно, но вместо этого их надо писать в файл, logstash или в БД. А если у вас локально Windows, а на удаленной машине Linux, то отличается и адрес расположения этого файла с логами.
Постоянно помнить и комментировать appender'ы в своё время мне надоело и я выработал способ настройки Log4j2 так, чтобы в зависимости от выбранного Maven-профиля автоматически включались только нужные appender'ы.
Ниже приведена инструкция по настройке проекта с использованием Spring Boot + Maven + Log4j2, результатом выполнения которой будет настроенная система логирования и два appender'а: CONSOLE и SOCKET.
В первую очередь внесём изменения в конфигурацию Maven (pom.xml):
В переменные на уровне всего pom.xml добавляем адрес host для logstash-appender:
Добавляем необходимые для работы зависимости:
Обратите внимание, что из spring-boot-starter-web мы исключаем зависимость spring-boot-starter-logging.
Настроим Maven-профили, чтобы динамически управлять подключенными appender'ами. На уровне каждого профиля задаем переменные logstash.port, logger.console.tresholdFilter, logger.socket.tresholdFilter .
logstash.port — порт, на который нужно отправлять логи.
logger.console.tresholdFilter — значение задаёт уровень фильтрации логов, выводимых на консоль. В нашем случае ALL означает, что лог-записи всех уровней будут выводиться в консольный аппендер.
logger.socket.tresholdFilter — значение задает уровень фильтрации логов, которые отправляются в logstash. OFF — означает, что никакие записи отправлены в этот аппендер не пройдут.
Теперь нам необходимо внести изменения в application.properties, чтобы из файла Log4j2.xml можно было получить доступ к значению переменных, указанных в pom.xml:
logstash.host=@logstash.host@
logstash.port=@logstash.port@
logger.console.tresholdFilter=@logger.console.tresholdFilter@
logger.socket.tresholdFilter=@logger.socket.tresholdFilter@
И, наконец, настраиваем конфигурацию самого Log4j2 в файле log4j2.xml:
Теперь, чтобы вызвать логер в своём классе необходимо создать его экземпляр:
Давайте научимся следить за выполнением логики в нашей программе, для этого мы научимся использовать логирование, поймем зачем оно и где используется.
Шаг 0. Обзор
Зачем нужно логирование и что оно даёт?
Вы, как человек который администрирует магазин начнет разбераться в чем же проблема. Неопытный человек будет долго искать проблему, а опытный сразу полезет в логи сервера, но там все логи сервера и найти то что нужно вам сложно.
В этом случае решение следующее, выводить нужные вам логи в отдельный файл. Но как понять, какие из всех логов, которые сыпятся в общий лог сервера нужны вам? Для этого нужно реализовать свою систему логирования, где вы сможите указать какие логи куда выводить, или же настроить уровни логирования.
В данном уроке мы рассмотрим как сконфигурировать и начать использовать Log4j.
Шаг 1. Создаем проект и добавляем завимости
Запускаем всеми любимую Intellij IDEA и тыкаем New Project выбираем Maven Module и называем его :
Теперь в pom.xml жлбавим зависимость:
Это все зависимости, которые надо было подключить.
Шаг 2. Создание примитивной логики для примера
Давайте создадим класс в котором была бы бизнес-логика, назовем его OrderLogic:
Хочу обратить ваше внимание на то, что логика данного проекта не важна, так как мы рассматриваем логирование, для этого я и подготовил примитивную логику класса OrderLogic.
И теперь создаем Main класс:
В результате выполнения данного кода, мы получим следующее:
Как видите пока ничего нового.
Шаг 3. Конфигурируем Log4j
Чтобы гибко управлять логированием стоит создать в resources/ файл log4j.properties:
Теперь в этот файл добавим пару строк конфигураций:
Теперь давайте более детальней разберем строку формирования шаблона:
Читайте также: