Аппендер java что это
Логирование в Java – Logger
При создании приложений мы часто сталкиваемся с ошибками, которые необходимо отлаживать. Итак, с помощью логов мы можем легко получить информацию о том, что происходит в приложении, с записью ошибок и необычных обстоятельств. Теперь вам может показаться, что почему бы не использовать оператор System.out.print() в Java.
Проблема с этими утверждениями состоит в том, что сообщения журнала будут печататься только на консоли. Поэтому, как только вы закроете консоль автоматически, все журналы будут потеряны. Они не хранятся постоянно и будут отображаться один за другим, так как это однопоточная среда.
Компоненты
Компоненты ведения журнала помогают разработчику создавать их, передавать в соответствующее место назначения и поддерживать надлежащий формат. Ниже приведены три компонента:
Вы можете обратиться к изображению ниже для работы всех трех компонентов:
Когда приложение выполняет вызов регистрации, компонент Logger записывает событие в LogRecord и перенаправляет его соответствующему Appender. Затем он форматировал запись, используя формат в соответствии с требуемым форматом. Помимо этого, вы также можете использовать более одного фильтра, чтобы указать, какие Appenders следует использовать для событий.
Что такое Логгеры (Logger) в Java?
Логгеры (Logger) в Java – это объекты, которые запускают события журнала. Они создаются и вызываются в коде приложения, где генерируют события журнала перед передачей их следующему компоненту, который является Appender.
Вы можете использовать несколько логгеров в одном классе для ответа на различные события или использовать в иерархии. Они обычно называются с использованием иерархического пространства имен, разделенных точками. Кроме того, все имена Logger должны основываться на классе или имени пакета зарегистрированного компонента.
Кроме того, каждый логгер отслеживает ближайшего существующего предка в пространстве имен, а также имеет связанный с ним «уровень».
Как создать?
Синтаксис
Здесь SampleClass – это имя класса, для которого мы получаем объект Logger.
Уровни
Уровни журналов используются для классификации их по степени серьезности или влиянию на стабильность приложения. Пакет org.apache.log4j.* и java.util.logging предоставляют разные уровни ведения журнала.
Пакет org.apache.log4j.* предоставляет следующие уровни в порядке убывания:
Пакет java.util.logging предоставляет следующие уровни в порядке убывания:
Помимо этого, вышеприведенный пакет также предоставляет два дополнительных уровня ALL и OFF используются для регистрации всех сообщений и отключения регистрации соответственно.
Пример с использованием пакета org.apache.log4j.*
Таким образом, если в нашем файле log4j.properties ваш вывод является корневым логгером уровня WARN, то все сообщения об ошибках с более высоким приоритетом, чем WARN, будут напечатаны, как показано ниже:
Пример с использованием пакета java.util.logging
Файл свойств пакета Log4j и Java Util
Пример файла свойств Log4j
Пример файла свойств пакета Java Util
Регистрация событий
Чтобы регистрировать события в Java, вы должны убедиться, что вы назначаете уровень, чтобы легко отфильтровать события. Чтобы назначить уровень и упомянуть сообщение, вы можете использовать следующие методы:
Способ 1
Способ 2
Чтобы убедиться, что Logger регистрирует только события, которые находятся на уровне или выше уровня INFO, вы можете использовать метод setLevel(), описанный выше.
Appender или Handlers
Appender или Handlers отвечают за запись событий журнала в пункт назначения. Каждый регистратор имеет доступ к нескольким обработчикам и получает сообщение журнала от регистратора. Затем Appenders используют средства форматирования или макеты для форматирования событий и отправки их в соответствующее место назначения.
Appender можно отключить с помощью метода setLevel (Level.OFF). Два наиболее стандартных обработчика в пакете java.util.logging :
Layout или Formatters
Используются для форматирования и преобразования данных в журнале событий. Каркасы журналов предоставляют макеты для HTML, XML, Syslog, JSON, простого текста и других журналов.
Java logging. Hello World
Вступление
Думаю, ни для кого не секрет, что такое логгеры и для чего они нужны. За время существования 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:
Методы логгера могут принимать в качестве аргументов строковые сообщения, шаблоны сообщений, исключения, ресурсы локализованных текстовок сообщений, а также, начиная с Java 8, поставщиков строковых сообщений:
Выделяется две группы методов: название которых соответствует уровню логгирования и методы log, loggp, logrb, принимающие уровень логгирования в качестве параметра с типом Level. Первая группа содержит методы двух типов: принимающих строковое сообщение или поставщика строковых сообщений:
Вторая группа методов имеет следующие вариации:
Теперь обратимся к конфигурации фреймворка. По умолчанию JUL будет выводить сообщения на консоль, однако можно задать конфигурацию в файле свойств. Для задания способа вывода сообщений необходимо для вашего логгера указать какие хендлеры он будет использовать. Существует следующие классы хендлеров: FileHandler, ConsoleHandler, StreamHandler, SocketHandler, MemoryHandler. Особенностью JUL является то, что настройки хендлеров задаются в целом для всего класса, а не для конкретного экземпляра, что может порождать не мало проблем, например если вам потребуется сообщения различных логгеров выводить в различные файлы или с различным форматированием. Рассмотрим простой пример конфигурационного файла:
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 выглядят так:
Commons-logging
Довольно старый проект, который представляет собой обертку над JUL и log4j, не привносящая никакого дополнительного функционала. Уровни логгирования у JCL совпадают с log4j, а в случае взаимодействия с JUL происходит следующее сопоставление:
Для использования JCL подключаем commons-logging-1.x.jar. Создаем логгер вызовом метода фабрики:
Методы JCL очень простые, совпадают с названием уровней логгирования, принимают только объекты и исключения и имеют две вариации:
Конфигурация JCL содержит отдельные блоки для log4j, JUL и собственной реализации. Если не задать конфигурацию, то используется собственная реализация, именуемая SimpleLog, которая выводит сообщения на консоль. Рассмотрим пример конфигурационного файла:
Указать файл конфигурации JCL можно следующим образом:
Logback
Данный фреймворк используется только в связке с оберткой SLF4J, которую мы будем рассматривать позднее. Для начала работы вам необходимы logback-core-1.x.jar и logback-classic-1.x.x.jar, а также slf4j-api-1.x.x.jar.
Взаимодействие с логгером мы будем осуществлять через API предоставляемый оберткой SLF4J. Уровни логгирования совпадают с log4j. Создание логгера в таком случае выглядит следующим образом:
API позволяет выводить строковые сообщения, шаблоны строковых сообщений, исключения, а также использовать маркеры:
Названия методов совпадают с уровнями логгирования и имеют вид:
SLF4J
Как уже говорилось ранее SLF4J является оберткой над logback, а также над JUL, log4j, или JCL, а также над любым логгером, который реализует ее интерфейс. Для работы с SLF4J нужны библиотека slf4j-api-1.x.x.jar и реализация одного из логгеров либо заглушка. Как правило реализации всех логгеров ( кроме logback) поставляются вместе с SLF4J и имеют названия на подобии slf4j-jcl-1.x.jar, slf4j-log4j12-1.x.jar, slf4j-nop-1.x.jar и т.п. Если в classpath не будет найдена реализация логгера ( или заглушка nop) SLF4J гневно ругнется и работать откажется. Конфигурация соответственно будет искаться в зависимости от положенной в classpath реализации.
API SLF4J мы рассмотрели в предыдущем пункте, поэтому давайте рассмотрим еще одну возможность обертки. В идеальном мире мы должны выводить сообщения через интерфейс обертки, и тогда у нас все будет хорошо, но реальный жестокий мир говорит о том, что всем нам приходится взаимодействовать со сторонними библиотеками или кодом, в которых используются другие логгеры и которые знать не знают о SLF4J. Что бы не подстраиваться под каждый логгер, а пустить все сообщения через одну реализацию интерфейса SLF4J, можно использовать bridging. В поставке обертки содержаться библиотеки jcl-over-slf4j.jar, log4j-over-slf4j.jar и jul-to-slf4j.jar, которые переопределяют поведение соответствующих логгеров и перенаправляют сообщения в обертку.
Что бы стало понятнее выше сказанное, рассмотрим пример. Допустим у нас имеются следующие логгеры:
Мы хотим, что бы сообщение от JUL записывались в один файл, от log4j в другой, а от slf4j выводились на консоль. В качестве реализации обертки будем использовать logback, конфигурация сего безобразия будет выглядеть следующим образом:
Для того, что бы мост заработал необходимо выполнить код:
Аппендер java что это
Логирование в Java
Хотя правильнее было бы говорить наверное журналирование/протоколирование и вести журнал/протокол соответственно.
Но так никто никогда не говорит, конечно ¯\(ツ)/¯
Поэтому «логи всякие нужны, логи всякие важны».
Все ли нужно логировать?
Если вы вдруг залогируете в общий файл-лога пароль и логин пользователя, то никто такому рад не будет, что подводит нас к мысли, что логировать надо тоже с умом.
Т.е возникает требование управления информацией, которая нам нужна в данный момент, а также форматом ее вывода.
При этом, логично, что изменения этого формата и того, что мы хотим видеть в логе не должны требовать перекомпиляции всего проекта или изменения кода.
Уровень логирования | Описание |
---|---|
ALL | Все сообщения |
TRACE | Сообщение для более точной отладки |
DEBUG | Дебаг-сообщение, для отладки |
INFO | Обычное сообщение |
WARN | Предупреждение, не фатально, но что-то не идеально |
ERROR | Ошибка |
FATAL | Фатальная ошибка, дело совсем плохо |
OFF | Без сообщения |
Если проиллюстрировать это:
Принципы и понятия
Логер создается с помощью фабрики и на этапе создания ему присваивается имя. Имя может быть любым, но по стандарту имя должно быть сопряжено с именем класса, в котором вы собираетесь что-то логировать:
Почему так рекомендуется делать?
Получается выстраивается следующая иерархия логеров:
И каждому логеру можно выставить свой уровень. Установленный логгеру уровень вывода распространяется на все его дочерние логгеры, для которых явно не выставлен уровень.
При этом во главе иерархии логеров всегда стоит некотрый дефолтный рутовый(корневой) логер.
Поэтому у всех логеров будет уровень логирования, даже если явно мы не прописали для ru.aarexer.example.SomeClass его, то он унаследуется от рутового.
Вопрос:
Логер | Назначенный уровень |
---|---|
root | INFO |
ru | Не назначен |
ru.aarexer | DEBUG |
ru.aarexer.example | Не назначен |
Какой у какого логера будет уровень логирования?
Ответ:
Вспоминаем, что, если уровень логирования не назначен для логера, то он унаследует его от родительского, смотрим на иерархию:
Logger | Назначенный уровень | Уровень, который будет |
---|---|---|
root | Все сообщения | INFO |
ru | Не назначен | INFO |
ru.aarexer | DEBUG | DEBUG |
ru.aarexer.example | Не назначен | DEBUG |
Это событие по сути состоит из двух полей:
Аппендер – это та точка, куда события приходят в конечном итоге. Это может быть файл, БД, консоль, сокет и т.д.
У одного логгера может быть несколько аппендеров, а к одному аппендеру может быть привязано несколько логгеров.
Логеры при этому наследуют от родительских не только уровни логирования, но и аппендеры.
Например, если к root-логгеру привязан аппендер A1, а к логгеру ru.aarexer – A2, то вывод в логгер ru.aarexer попадет в A2 и A1, а вывод в ru – только в A1.
Вопрос:
Пусть у нас есть несколько аппендеров и логеров
Logger | Appender |
---|---|
root | А1 |
ru.aarexer | А2 |
ru.aarexer.example.SomeClass | А3 |
В какой аппендер попадет лог-сообщение:
Ответ:
Это говорит о том, что логер-наследник будет свои события передавать логеру-родителю.
Смотрим на иерархию:
Из всего вышесказанного делаем вывод, что событие «hello» с уровнем Level.INFO попадет во все три аппендера.
Но такое наследование аппендеров можно отключить через конфигурацию, для этого стоит посмотреть в сторону выставления флага additivity=»false» на логгерах.
Т.е как лог-сообщения будут отформативарованы, соответственно тут у каждой библиотеки свой набор доступных форматов.
Библиотеки логирования в Java
Однако он не отвечает всем тем требованиям, которые мы сформулировали выше, поэтому рассмотрим альтернативы.
Наиболее популярные библиотеки логирования в Java :
И поэтому появились еще две библиотеки:
Это самая первая библиотека логирования, появилась еще в 1999 году.
Поддерживает большое количество способов вывода логов: от консоли и файла до записи в БД.
Благодаря подобной иерархии лишнее отсекается и поэтому логер работает быстро.
Проект сейчас не развивается и по сути заброшен, с версией Java 9 уже не совместим.
Вклад log4j в мир логирования настолько велик, что многие идеи были взяты в библиотеки логирования для других языков.
Чувствуете насколько все переосложнено?
Так как стандартных средств форматирования логов недостаточно, то все сводилось к тому, что писались свои. Это при том, что log4j предоставлял больший функционал, работал как минимум не медленнее и в целом себя чувствовал хорошо.
Уровни логгирования у JCL совпадают с log4j, а в случае взаимодействия с JUL происходит следующее сопоставление:
JCL | JUL |
---|---|
ALL | Все сообщения |
TRACE | Level.FINEST |
DEBUG | Level.FINE |
INFO | Level.INFO |
WARN | Level.WARNING |
ERROR | Level.SEVERE |
FATAL | Level.SEVERE |
OFF | Без сообщения |
С уверенностю можно сказать сейчас, что в эту сторону даже смотреть не стоит. Пациент мертв.
Лицензия | Apache License Version 2.0 |
Последняя версия | 1.2 |
Дата выпуска последней версии | июль 2014 |
Но добавили много нового, парочка из них:
Правда перестали поддерживать properties конфигурации и конфигурации от log4j на xml надо было переписывать заново.
Лицензия | Apache License Version 2.0 |
Последняя версия | 2.11.2 |
Дата выпуска последней версии | февраль 2019 |
Лицензия | MIT License |
Последняя версия | 2.0.0-alpha0 |
Дата выпуска последней версии | июнь 2019 |
При этом, logback не является частью Apache или еще какой-то компании и независим.
Лицензия | EPL/LGPL 2.1 |
Последняя версия | 1.3.0-alpha4 |
Дата выпуска последней версии | февраль 2018 |
Так как из адаптеров это по сути единственный выбор, да и встречается slf4j все чаще, то стоит рассмотреть его устройство.
Вопрос:
Ответ:
Вроде все проблемы решены, пусть и такими радикальными способоами.
Таким образом, чтобы работать со Spring получается надо сделать CLASSPATH подобным образом:
Если конфигурация сделана программно, то bridge не будет работать.
Бесконтрольно подтягиваемые транзитивные зависимости библиотек, которые вы используете в своем проекте, рано или поздно принесут какие-то свои библиотеки логирования, отчего могут открыться врата прямиком в ад.
При этом, если вы разрабатываете библиотеку, то:
Очень важно также не забывать о том, что такое логирование и для чего оно нужно.
Поэтому нельзя скатываться в бесмысленные записи в лог, вывод личных данных и так далее.
Думайте о том что вы пишите в лог!
Быстрый старт с Log4j
Обзор
Первый источник это Wikipedia, в ней мы сможем почерпнуть достаточно скудную информацию лишь о компании разработчике и целях проекта.
Log4j — библиотека журналирования Java программ, часть общего проекта «Apache Logging Project».
Apache log4j | |
Тип | Журналирование |
Разработчик | Apache Software Foundation |
Написана на | Java |
ОС | Кроссплатформенное ПО |
Версия | 1.2.15 — 29 сентября 2007 |
Тестовая версия | 2.0 |
Лицензия | Apache License 2.0 |
Сайт | http://logging.apache.org/log4j (англ.) |
Log4j первоначально развивался в рамках зонтичного Apache Jakarta Project, ответственного за все Java-проекты Apache, но впоследствии выделился в отдельный, очень популярный проект журналирования (стандарт де-факто).
Ознакомившись с двумя предыдущими источниками подключить и выполнить примеры Вы конечно же сможете, но что это нам даст, спросите Вы, вряд ли кто то будет выкладывать у себя примеры со сложными реализациями. Да примеры и должны быть простыми, сразу возразят поклонники простоты и лаконичности. Но как это обычно бывает, все примитивные примеры носят мало практической пользы и любой «шаг вправо или шаг влево» повлечет за собой поиски новых источников с описанием настроек и подводных камней. Принимая во внимание все выше сказанное, начнем сначала.
Каким образом хранить конфигурацию журналирования?
Как конфигурировать файл 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» ?>
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
Журналирование событий это лишь часть функциональности Вашего приложения, не стоит ставить приоритет этой задачи выше приоритета основной функциональности.
Как использовать Log4J в Java приложениях?
Для использования всех функциональных возможностей фрейворка необходимо создать объект журнала.
Пример для Java Application.