что такое logger 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 Logging: история кошмара
Вступление
Тернист и извилист путь Java-платформы к правильному способу записи строчек в лог-файлы. История logging в Java довольно познавательна в плане изучения особенностей Open Source, в том числе его взаимодействия с корпорациями и единичными программистами. Я собираюсь рассказать столько, сколько возможно, об истории развития Java logging, а также о том, к чему все пришло и как жить дальше. Мой анализ ситуации будет довольно субъективен про причине того, что logging — это всегда дело вкуса, а вкусы у меня сформировались свои, взрослые. Я думаю, что это будет познавательно не сколько в плане каких-то технических особенностей всего зоопарка logging frameworks, а в плане политики и психологии разработчиков в модели Open Source.
Начало
Понятно, что любая logging-библиотека должна позволять как минимум печатать строку на консоль/в лог-файл.
Одним из вариантов более продвинутых решений в 1999 году был проект Avalon (и подпроекты, которые назывались Excalibur и Fortress), который помимо сервисов DI предлагал интерфейс LogEnabled. В компонент, который объявлял себя LogEnabled, инжектировался (я применяю это слово вместо «инъектировался», чтобы подчеркнуть его связь с DI) объект типа Logger, куда можно было писать: а) строки б) exceptions. Подход этот по тем временам казался свежим и новаторским, однако с современной точки зрения это чистой воды идиотизм и over-engineering. Использовать DI для логгирования никакого смысла нет, и статический экземпляр этого самого Logger вполне бы всех устроил. В Avalon же приходилось думать, куда этот проклятый Logger сохранить и что же делать, если класс не использует DI (т.е. не управляется контейнером), а логгировать в нем очень хочется.
Приблизительно в 1999 появляется библиотека нового поколения — log4j. Прототип библиотеки был разработан IBM (еще в эпоху, когда голубой гигант пытался втиснуть Java в OS/2), затем эстафету подхватил ASF. Продукт был уже гораздо более продуманный и обкатанный на реальных нуждах. Вообще надо сказать, что серверным приложениям на Java к тому моменту исполнилось всего где-то годик, а логгирование всегда было востребовано именно на сервере. За это время Java-сообщество начало постепенно понимать, что и как им нужно.
log4j разделил понятие логгера или категории (т.е. область приложения, которая хочет записать в лог), собственно записи в лог, которую осуществляют так называемые appenders, и форматирования записей (layout). Конфигурация log4j определяет, какие appenders к каким категориям прикрепляются и сообщения какого уровня (log level) попадают в каждый appender.
Иерархия категорий позволяет довольно эффективно отсекать лишние сообщения, поэтому log4j работал чрезвычайно шустро. Кстати, принципиальной для логгеров является не столько скорость записи, сколько скорость фильтрации ненужного (а ненужного обычно более 90%) и форматирование.
Принципы, заложенные в log4j, были довольно удачно портированы на другие языки: log4cxx, log4net (и свежий детеныш — log4php). Стандартный пакет logging в Python 2.x представляет собой переработанный log4j (с небольшой добавкой других библиотек).
Итак, резюмируем. Удачная архитектура, понятная схема конфигурирования, принцип fail-safe — почему бы не включить такую замечательную библиотеку в состав платформы?
Java Logging API
На деле все получилось странно. IBM, в недрах которой возник log4j, оказалась довольно шустрой в вопросах формирования нового JSR47 (Java Logging API). В частности, ответственный за JSR47 товарищ Graham Hamilton решил взять за основу не log4j, а оригинальный IBM logging toolkit. Причем logging toolkit был использован на полную катушку: совпадали не только имена всех основных классов, но и их реализации; код старались допиливать как можно меньше, видимо, чтобы успеть к очередному релизу платформы. Впрочем, концептуально это было очень похоже на log4j, только вместо appenders это называлось handlers, а вместо layout был formatter.
Нельзя сказать, чтобы JSR47 проигрывал в производительности. Местами он обгонял log4j за счет поддержания в памяти специального представления своей конфигурации (что, кстати, одновременно усложняло эту самую конфигурацию). Однако, как выяснилось, JSR47 в обязательном порядке собирал так называемую Caller Information, то бишь «откуда логгируется данное сообщение». Получение Caller Information — операция довольно дорогостоящая, протекает она с использованием Native-кода. Опытные дяди из log4j это знали, поэтому предоставляли эту возможность с оговоркой «лучше не включайте».
Не будучи способным поддержать большое число лог-писателей (т.е. handlers), JUL выпендрился, определив неимоверное число уровней логгирования. Например, для отладочных сообщений существовало аж 3 уровня — FINE, FINER и FINEST. Видя всё это, разработчики зачастую совершенно не понимали, какой же из трех уровней, чёрт возьми, надо использовать.
Java-сообщество было совершенно дезориентировано появлением «стандартного» логгинга параллельно с популярным, стабильным и развивающимся log4j. Никто не понимал, кто из них двоих жилец. Нередки были ситуации, когда в проекте было собрано несколько библиотек, каждая из которых использовала свой логгинг и свои настройки, записывая совершенно вразнобой свои лог-файлы.
Разумеется, сообщество попыталось исправить эту проблему. Началась оберточная эпидемия. Или, я бы даже сказал, пандемия.
Wrapper Hell
Когда вы подключаете несколько библиотек и пытаетесь соединить их логи в одно целое (а код модифицировать нельзя), это будет называться Adapter. Были написаны переходники из JUL в log4j и наоборот. К сожалению, переходники по функционалу являются «наименьшим общим кратным». Даже когда в log4j появилась поддержка контекста (NDC и MDC), при переливании в JUL она терялась. Хуже того, JUL работал только начиная с JDK 1.4, в то время как неимоверное количество enterprise-приложений все еще сидело на 1.3. В итоге, сообщество стало одержимо идеей создания «общего стандарта де-факто», который бы все стали дружно употреблять и который работал всегда и везде.
Приблизительно в 2002 из группы Jakarta выделился проект под названием commons-logging (JCL = Jakarta Commons Logging). Фактически это была обертка всех существующих на тот момент средств логгинга. Предлагалось писать приложения так, что они обращались к обертке (интерфейсу под названием Log ), которая выбирала «подходящую» систему логгинга и сама к ней подключалась. Обертка была бедновата фунционально и никаких дополнений к существующим средствам логгинга не вносила.
Красиво! Ну то есть было бы красиво, если бы весь софт в мире использовал бы commons-logging. Тогда можно было спокойно собрать JARы, положить в сервер приложений, а там уж JCL подхватит логгинг данного сервера приложений и вуаля!
Полная непредсказуемость выбора логгинга оказалась главной и очень веселой особенностью JCL. Группа log4j разразилась гневной статьей Think again before adopting the commons-logging API, где предлагала остановить эпидемию и сосредоточить внимание на доработке существующего решения — log4j.
К сожалению, было уже поздно. С подачи Jakarta на commons-logging были переведены сотни, а затем тысячи библиотек. В их числе были Hibernate, Spring, Tomcat. После чего многочисленных пользователей этих библиотек захлестнула волна проблем, в целом описываемых как ClassLoader hell. В серверах приложений используется довольно сложная иерархия ClassLoader-ов, причем зачастую с серьезными отклонениями от стандарта J2EE. В этих условиях иногда JCL инициализируется дважды, причем неправильно, приводя к совершенно мистическим stack traces, не позволяющим даже заподозрить, что проблема в лог-обертке.
Новый виток прогресса
Где-то в 2006 году один из отцов-основателей log4j — Ceki Gülcü — решает выйти из стремительно тухнущей команды. Так появляется на свет очередная «обертка всего» под названием SLF4J (Simple Logging Facade for Java). Теперь это обертка вокруг: log4j, JUL, commons-logging и нового логгера под названием logback. Как видно, прогресс быстро дошел до стадии «обертка вокруг обертки». Нетрудно спрогнозировать, что по той же схеме число обертываемых библиотек будет расти как факториал. Однако SLF4J предлагает и другие прочие выверты. Это специальные binary-переходники: из log4j в SLF4J, из commons-logging в SLF4J и тому подобное. Делаются такие переходники для кода, исходники которого недоступны; при этом они должны подменить оригинальные JAR-ы лог-библиотек. Не берусь представить себе, какая каша при этом образуется, но если очень хочется, то можно и так.
Функционально SLF4J поддерживал все современные навороты типа NDC и MDC. Помимо собственно обертывания вызовов, SLF4J предлагал небольшой, но полезный бонус при форматировании строк. Бонус тут в следующем. В коде часто приходится печатать конструкции вида:
SLF4J не был стиснут рамками совместимости со старыми версиями JDK и API, поэтому с ходу предложил более изящное решение:
В общем-то, все просто. В данной строке <> — это ссылки на параметры, которые передаются отдельно. Преобразование параметров в строку и окончательное форматирование лог-записи происходит только при установленном уровне DEBUG. Параметров можно передавать много. Работает! Не надо писать обрамляющий if и прочую тупость!
Короче говоря, SLF4J был сделан грамотно, с заделом на будущее. Это вызвало серьезный рост его популярности среди сообщества: сейчас SLF4J используют такие значимые проекты, как Jetty, Hibernate, Mina, Geronimo, Mule, Wicket, Nexus… в общем, практически все неудачники, зависшие в свое время на commons-logging, перешли на SLF4J. Интересно, что мешало усовершенствовать commons-logging до нужного состояния много лет назад? Но таковы реалии Open Source — развитие софта в нем происходит скорее революционно, чем эволюционно.
Одновременно с SLF4J был подан к столу совершенно новый логгер — Logback. Он был сделан человеком, который на логгировании собаку съел, и на поверку действительно оказался хорошим продуктом. Logback был изначально заточен под JDK 1.5+, одним махом избавившись от всех старческих болезней обратной совместимости, свойственных проекту log4j. А это значит — varargs, java.util.concurrent и прочие прелести. Например, за счет встроенной системы runtime-фильтрации можно менять уровень логгирования в зависимости от пользовательской сессии, разбрасывать пользователей по разным лог-файлам и прочее, прочее.
Я подкину горчички в идиллию, нарисованную автором. Большинство этих возможностей можно реализовать в виде дополнительных appender-ов к log4j. Придется искривить и подпилить конфигурацию, это сложнее, но — факт, что переходить для этого на новый логгер не_обязательно. Таким образом, все рекламируемые Logback фишки — удобные, но не уникальные.
Что касается сообщества, то оно к Logback относится с осторожностью. Во-первых, за несколько лет он добрался до версии 0.9.x, а это пугает некоторых программеров. Во-вторых, Logback не находится ни под зонтиком Apache, ни в области действия Sun. Это смущает людей щепетильных. В-третьих, автору надо кушать, поэтому за некоторые довески к Logback и поддержку он требует денег. Это иногда отпугивает студентов. Помимо всего прочего, Logback имеет довольно сложную двойную лицензию (LGPL/EPL), в то время как log4j — универсальную лицензию Apache. Для библиотек и вообще redistributable софта лицензирование является очень тонким моментом.
Заключение
Интересно посмотреть на историю вопроса под углом психологии программистов. Ведь в принципе всё это спиральное (и вроде как прогрессирующее!) движение — бесконечный «reinvent the wheel». То есть из двух вариантов «доработать существующее» и «сделать свое» всегда выбирался второй. Поэтому ни один из упомянутых проектов не выбился в безусловные лидеры (в те самые стандарты «де-факто»). Вместо этого разработчики были в разное время «нашинкованы» на разные проекты и действовали раздельно, вместо того, чтобы действовать сообща. Хотя не факт, что все авторы смогли бы работать в одной упряжке. Тут действовали и политические моменты (вспомним, как Graham Hamilton любил IBM), и просто банальные ссоры в команде. Стремление же участников Jakarta Commons обеспечить сообществу «свободу выбора» вообще обернулось для сообщества длительной «эпидемией оберток».
В общем-то, все эти пороки типичны для открытого сообщества. Эта более чем 10-летняя история также показывает, насколько ошибочно распространенное сейчас мнение, что Sun как будто бы что-то решало в Java-сообществе. Мы видим, что многие вещи происходили вопреки Sun и независимо от Sun. Одним словом, интересно, как оно пойдет дальше. В одном я уверен — проекты приходят и уходят, люди не меняются 🙂
Что такое logger 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 не будет работать.
Бесконтрольно подтягиваемые транзитивные зависимости библиотек, которые вы используете в своем проекте, рано или поздно принесут какие-то свои библиотеки логирования, отчего могут открыться врата прямиком в ад.
При этом, если вы разрабатываете библиотеку, то:
Очень важно также не забывать о том, что такое логирование и для чего оно нужно.
Поэтому нельзя скатываться в бесмысленные записи в лог, вывод личных данных и так далее.
Думайте о том что вы пишите в лог!