Русские Блоги
Простое использование конфигурации журнала Logback
Logback введение
Преимущества выхода из системы
Инструкция по настройке входа
Что касается описания конфигурации этой части, я просто перечислю некоторые из наиболее часто используемых конфигураций для объяснения. Если вы хотите узнать больше, смотрите официальную документацию.
Описание иерархии входа
Простая иерархическая структура, на самом деле их больше, только для справки.
Конкретные инструкции
Корневой узел конфигурации обычно имеет три атрибута: scan, scanPeriod и debug.
Тогда, если мы хотим использовать это, мы можем сделать следующую конфигурацию:
Подузлы root и logger определяют уровень регистрации входных данных.
объяснениеУровень журнала, заданный параметром: root, является выходом журнала класса, например:
Уровень ведения журнала, указанный в logger, является настраиваемым уровнем, например:
Их использование заключается в следующем:
Дочерний узел свойства обычно используется для определения значения переменной. Есть два атрибута имя и значение. Аналогично ключам и значениям карты в Java.
Использование заключается в следующем:
Примечание. Путь к файлу, указанный значением, будет автоматически создан в том же каталоге проекта, и нет необходимости создавать его вручную.
дочерний узел appender, компонент, отвечающий за запись логов. Есть два атрибута, имя и класс.
Это очень важно, и можно сказать, что это ядро logback. Простое использование заключается в следующем:
объяснениеОпределите имя STDOUT и выведите его на консоль.
макет и рисунок обычно используются вместе.
Простое использование заключается в следующем:
rollPolicy, fileNamePattern, maxFileSize, maxHistory и totalSizeCap, как правило, используются для прокрутки журналов, то есть управления вырезанием журналов и т.п.
Простое использование заключается в следующем:
объяснение: Смысл этой конфигурации заключается в том, что файл журнала создается каждый день. Если он превышает 10 МБ, журнал будет сокращен, а имя файла журнала будет увеличено на единицу. Файл журнала будет храниться до 31 дня, а общий файл журнала будет составлять до 10 ГБ.
Инструкция по возврату
После краткого описания файла конфигурации журнала logback, давайте просто используем logback.
Использование logback.xml зависит от трех пакетов jar: slf4j-api, logback-core и logback-classic.
mavan настраивается следующим образом:
После успешного добавления пакета зависимостей в maven давайте напишем простую демонстрацию, чтобы протестировать его.
определяет три журнала, один основной и два пользовательских журнала.
Общая конфигурация выглядит следующим образом:
Затем выведите в консоль вывод и файл.
Пример кода этой Java:
Каталог генерации журнала:
Объяснение результатов вывода:
другое
Ссылка:
https://logback.qos.ch/documentation.html
https://www.cnblogs.com/warking/p/5710303.html
На этом этапе краткий обзор журнала этой статьи, спасибо за чтение!
Создание журналов с помощью Azure SDK для Java и Logback
В этой статье приводятся общие сведения о добавлении ведения журналов в приложения, использующие Azure SDK для Java, с помощью Logback. Как упоминалось в статье Настройка ведения журнала в Azure SDK для Java, все клиентские библиотеки Azure ведут журналы с использованием SLF4J, поэтому вы можете использовать такие платформы ведения журналов, как Logback.
Чтобы включить ведение журнала с помощью Logback, необходимо выполнить два действия:
Дополнительные сведения о настройке Logback см. в разделе Настройка Logback документации по Logback.
Добавление зависимости Maven
Чтобы добавить зависимость Maven, включите следующий код XML в файл проекта pom.xml. Замените номер версии 1.2.3 номером последней выпущенной версии, показанной на странице классического модуля Logback.
Добавление файла logback.xml в проект
Logback — одна из популярных платформ ведения журналов. Чтобы включить ведение журнала с помощью Logback, создайте файл с именем logback.xml в каталоге проекта ./src/main/resources. Этот файл будет содержать конфигурации ведения журналов для настройки ведения журнала. Дополнительные сведения о настройке logback.xml см. в разделе Настройка Logback документации по Logback.
Журнал консоли
Вы можете создать конфигурацию Logback для создания журналов в консоли, как показано в следующем примере. В этом примере конфигурация приведет к регистрации всех событий ведения журнала уровня INFO или более высокого уровня, независимо от того, что является источником таких событий.
Создание журналов об основных ошибках Azure
Вы сможете тщательно контролировать ведение журнала для конкретных классов или отдельных пакетов. Как показано ниже, com.azure.core будет управлять выходными данными всех основных классов, однако вы можете в равной степени использовать com.azure.security.keyvault или его эквивалент, чтобы управлять выходными данными в соответствии с обстоятельствами, которые являются наиболее информативными в контексте выполняющегося приложения.
Создание журналов в файле с поддержкой смены журнала
В предыдущем примере журнал создается в консоли, что обычно не является предпочтительным расположением для журналов. Используйте приведенную ниже конфигурацию, чтобы записывать данные в файл, а также для почасовой смены и архивации в GZIP-формате:
Приложения Spring
В основе работы платформы Spring лежит считывание данных файла application.properties Spring для различных конфигураций, включая конфигурацию ведения журнала. Приложение Spring также можно настроить, чтобы оно считывало конфигурации Logback из любого файла. Для этого настройте свойство так, logging.config чтобы оно указывало на logging.config файл конфигурации, добавив следующую строку в файл пружины /СРК/Маин/ресаурцес/аппликатион.пропертиес :
Следующие шаги
В этой статье описано, как выполнить конфигурацию Logback и о том, как заставить Azure SDK для Java использовать его для ведения журнала. Поскольку Azure SDK для Java работает со всеми платформами ведения журналов SLF4J, ознакомьтесь с руководством пользователя SLF4J, чтобы получить дополнительные сведения. Если вы используете Logback, на веб-сайте этого средства также можно найти большое количество руководств по настройке. Дополнительные сведения см. в разделеНастройка Logback документации по Logback.
После того как вы научитесь вести журнал, рассмотрите возможность изучения интеграций, предоставляемых Azure для таких платформ, как Spring и MicroProfile.
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, конфигурация сего безобразия будет выглядеть следующим образом:
Для того, что бы мост заработал необходимо выполнить код:
Chapter 3: Logback configuration
In symbols one observes an advantage in discovery which is greatest when they express the exact nature of a thing briefly and, as it were, picture it; then indeed the labor of thought is wonderfully diminished.
—GOTTFRIED WILHELM LEIBNIZ
We start by presenting ways for configuring logback, with many example configuration scripts. Joran, the configuration framework upon which logback relies will be presented in a later chapter.
Configuration in logback
Inserting log requests into the application code requires a fair amount of planning and effort. Observation shows that approximately four percent of code is dedicated to logging. Consequently, even a moderately sized application will contain thousands of logging statements embedded within its code. Given their number, we need tools to manage these log statements.
Logback can be configured either programmatically or with a configuration script expressed in XML or Groovy format. By the way, existing log4j users can convert their log4j.properties files to logback.xml using our PropertiesTranslator web-application.
Let us begin by discussing the initialization steps that logback follows to try to configure itself:
Logback tries to find a file called logback-test.xml in the classpath.
If no such file is found, logback tries to find a file called logback.groovy in the classpath.
If no such file is found, it checks for the file logback.xml in the classpath..
If no such file is found, service-provider loading facility (introduced in JDK 1.6) is used to resolve the implementation of com.qos.logback.classic.spi.Configurator interface by looking up the file META-INF\services\ch.qos.logback.classic.spi.Configurator in the class path. Its contents should specify the fully qualified class name of the desired Configurator implementation.
If none of the above succeeds, logback configures itself automatically using the BasicConfigurator which will cause logging output to be directed to the console.
The last step is meant as last-ditch effort to provide a default (but very basic) logging functionality in the absence of a configuration file.
If you are using Maven and if you place the logback-test.xml under the src/test/resources folder, Maven will ensure that it won’t be included in the artifact produced. Thus, you can use a different configuration file, namely logback-test.xml during testing, and another file, namely, logback.xml, in production.
Fast start-up It takes about 100 miliseconds for Joran to parse a given logback configuration file. To shave off those miliseconds at aplication start up, you can use the service-provider loading facility (item 4 above) to load your own custom Configurator class with BasicConfigrator serving as a good starting point.
Automatically configuring logback
This class defines a static logger variable. It then instantiates a Foo object. The Foo class is listed below:
In order to run the examples in this chapter, you need to make sure that certain jar files are present on the class path. Please refer to the setup page for further details.
Assuming the configuration files logback-test.xml or logback.xml are not present, logback will default to invoking BasicConfigurator which will set up a minimal configuration. This minimal configuration consists of a ConsoleAppender attached to the root logger. The output is formatted using a PatternLayoutEncoder set to the pattern %d
Thus, the output of the command java chapters.configuration.MyApp1 should be similar to:
Except code that configures logback (if such code exists) client code does not need to depend on logback. Applications that use logback as their logging framework will have a compile-time dependency on SLF4J but not logback.
The MyApp1 application links to logback via calls to org.slf4j.LoggerFactory and org.slf4j.Logger classes, retrieve the loggers it wishes to use, and chugs on. Note that the only dependencies of the Foo class on logback are through org.slf4j.LoggerFactory and org.slf4j.Logger imports. Except code that configures logback (if such code exists) client code does not need to depend on logback. Since SLF4J permits the use of any logging framework under its abstraction layer, it is easy to migrate large bodies of code from one logging framework to another.
Automatic configuration with logback-test.xml or logback.xml
As mentioned earlier, logback will try to configure itself using the files logback-test.xml or logback.xml if found on the class path. Here is a configuration file equivalent to the one established by BasicConfigurator we’ve just seen.
Example: Basic configuration file (logback-examples/src/main/resources/chapters/configuration/sample0.xml)
After you have renamed sample0.xml as logback.xml (or logback-test.xml) place it into a directory accessible from the class path. Running the MyApp1 application should give identical results to its previous run.
Automatic printing of status messages in case of warning or errors
If warning or errors occur during the parsing of the configuration file, logback will automatically print its internal status messages on the console.
If warnings or errors occur during the parsing of the configuration file, logback will automatically print its internal status data on the console. Note that to avoid duplication, automatic status printing is disabled if the user explicitly registers a status listener (discussed below).
In the absence of warnings or errors, if you still wish to inspect logback’s internal status, then you can instruct logback to print status data by invoking the print() of the StatusPrinter class. The MyApp2 application shown below is identical to MyApp1 except for the addition of two lines of code for printing internal status data.
If everything goes well, you should see the following output on the console
At the end of this output, you can recognize the lines that were printed in the previous example. You should also notice the logback’s internal messages, a.k.a. Status objects, which allow convenient access to logback’s internal state.
Status data
Enabling output of status data usually goes a long way in the diagnosis of issues with logback.
Enabling output of status data usually goes a long way in the diagnosis of issues with logback. Note that errors can also occur post-configuration, e.g. when a disk a full or log files cannot be archived due to permission errors. As such, it is highly recommended that you register a StatusdListener as discussed below.
Example: Registering a status listener (logback-examples/src/main/resources/chapters/configuration/onConsoleStatusListener.xml)
A StatusListner can be installed using a configuration fileassuming that:
If any of these two conditions is not fulfilled, Joran cannot interpret the configuration file and in particular the element. If the configuration file is found but is malformed, then logback will detect the error condition and automatically print its internal status on the console. However, if the configuration file cannot be found, logback will not automatically print its status data, since this is not necessarily an error condition. Programmatically invoking StatusPrinter.print() as shown in the MyApp2 application above ensures that status information is printed in every case.
Forcing status output In the absence of status messages, tracking down a rogue logback.xml configuration file can be difficult, especially in production where the application source cannot be easily modified. To help identify the location of a rogue configuration file, you can set a StatusListener via the «logback.statusListenerClass» system property (discussed below) to force output of status messages. The «logback.statusListenerClass» system property can also be used to silence output automatically generated in case of errors.
Shorthand
As a shorthand, it is possible to register an OnConsoleStatusListener by setting the debug attribute to true within the element as shown below.
Example: Basic configuration file using debug mode (logback-examples/src/main/resources/chapters/configuration/sample1.xml)
By the way, setting debug=»true» is strictly equivalent to installing an OnConsoleStatusListener as shown previously.
«logback.statusListenerClass» system property
One may also register a status listener by setting the «logback.statusListenerClass» Java system property to the name of the listener class you wish to register. For example,
Logback ships with several status listener implementations. OnConsoleStatusListener prints incoming status messages on the console, i.e. on System.out. OnErrorConsoleStatusListener prints incoming status messages on System.err. NopStatusListener drops incoming status messages.
Note that automatic status printing (in case of errors) is disabled if any status listener is registered during configuration and in particular if the user specifies a status listener via the «logback.statusListenerClass» system. Thus, by setting NopStatusListener as a status listener, you can silence internal status printing altogether.
Viewing status messages
Given a StatusManager you can access all the status data associated with a logback context. To keep memory usage at reasonable levels, the default StatusManager implementation stores the status messages in two separate parts: the header part and the tail part. The header part stores the first H status messages whereas the tail part stores the last T messages. At present time H=T=150, although these values may change in future releases.
Logback-classic ships with a servlet called ViewStatusMessagesServlet. This servlet prints the contents of the StatusManager associated with the current LoggerContext as an HTML table. Here is sample output.
To add this servlet to your web-application, add the following lines to its WEB-INF/web.xml file.
The ViewStatusMessages servlet will be viewable at the URL http://host/yourWebapp/lbClassicStatus
Listening to status messages via code
You may also register a StatusListener via Java code. Here is sample code.
Note that the registered status listener will only receive status events subsequent to its registration. It will not receive prior messages. Thus, it is usually a good idea to place status listener registration directives at top of the configuration file before other directives.
Setting the location of the configuration file via a system property
java -Dlogback.configurationFile=/path/to/config.xml chapters.configuration.MyApp1
Note that the file extension must be «.xml» or «.groovy». Other extensions are ignored. Explicitly registering a status listener may help debugging issues locating the configuration file.
Given that «logback.configurationFile» is a Java system property, it may be set within your application as well. However, the system property must be set before any logger instance is created.
Automatically reloading configuration file upon modification
Logback-classic can scan for changes in its configuration file and automatically reconfigure itself when the configuration file changes.
If instructed to do so, logback-classic will scan for changes in its configuration file and automatically reconfigure itself when the configuration file changes. In order to instruct logback-classic to scan for changes in its configuration file and to automatically re-configure itself set the scan attribute of the element to true, as shown next.
Example: Scanning for changes in configuration file and automatic re-configuration (logback-examples/src/main/resources/chapters/configuration/scan1.xml)
By default, the configuration file will be scanned for changes once every minute. You can specify a different scanning period by setting the scanPeriod attribute of the element. Values can be specified in units of milliseconds, seconds, minutes or hours. Here is an example:
Example: Specifying a different scanning period (logback-examples/src/main/resources/chapters/configuration/scan2.xml)
Note If no unit of time is specified, then the unit of time is assumed to be milliseconds, which is usually inappropriate. If you change the default scanning period, do not forget to specify a time unit.
As it is easy to make errors while editing a configuration file, in case the latest version of the configuration file has XML syntax errors, it will fall back to a previous configuration file free of XML syntax errors.
Enabling packaging data in stack traces
While useful, packaging data is expensive to compute, especially in applications with frequent exceptions.
NOTE As of version 1.1.4, packaging data is disabled by default.
If instructed to do so, logback can include packaging data for each line of the stack trace lines it outputs. Packaging data consists of the name and version of the jar file whence the class of the stack trace line originated. Packaging data can be very useful in identifying software versioning issues. However, it is rather expensive to compute, especially in application where exceptions are thrown frequently. Here is a sample output:
Packaging data is disabled by default but can be enabled by configuration:
Invoking JoranConfigurator directly
Logback relies on a configuration library called Joran, part of logback-core. Logback’s default configuration mechanism invokes JoranConfigurator on the default configuration file it finds on the class path. If you wish to override logback’s default configuration mechanism for whatever reason, you can do so by invoking JoranConfigurator directly. The next application, MyApp3, invokes JoranConfigurator on a configuration file passed as a parameter.
Stopping logback-classic
In order to release the resources used by logback-classic, it is always a good idea to stop the logback context. Stopping the context will close all appenders attached to loggers defined by the context and stop any active threads in an orderly way. Please also read the section on «shutdown hooks» just below.
In web-applications the above code could be invoked from within the contextDestroyed method of ServletContextListener in order to stop logback-classic and release resources. Starting with version 1.1.10, the appropriate ServletContextListener is installed automatically for you (see just below).
Stopping logback-classic via a shutdown hook
Installing a JVM shutdown hook is a convenient way for shutting down logback and releasing associated resources.
Note that you may install a shutdown hook of your own making by setting the class attribute to correspond to your shutdown hook’s class name.
The default shutdown hook, namely DefaultShutdownHook, will stop the logback context after a specified delay (0 by default). Stopping the context will allow up to 30 seconds for any log file compression tasks running in the background to finish. In standalone Java applications, adding a directive to your configuration file is an easy way to ensure that any ongoing compression tasks are allowed to finish before JVM exit. In applications within a Web server, webShutdownHook will be installed automatically making directive quite redundant and unnecessary.
WebShutdownHook or stopping logback-classic in web-applications
You may disable the automatic the installation of LogbackServletContextListener by setting a named logbackDisableServletContainerInitializer in your web-application’s web.xml file. Here is the relevant snippet.
Note that logbackDisableServletContainerInitializer variable can also be set as a Java system property an OS environment variable. The most local setting has priority, i.e. web-app first, system property second and OS environment last.
Configuration file syntax
As you have seen thus far in the manual with plenty of examples still to follow, logback allows you to redefine logging behavior without needing to recompile your code. Indeed, you can easily configure logback so as to disable logging for certain parts of your application, or direct output to a UNIX Syslog daemon, to a database, to a log visualizer, or forward logging events to a remote logback server, which would log according to local server policy, for example by forwarding the log event to a second logback server.
The remainder of this section presents the syntax of configuration files.
As will be demonstrated over and over, the syntax of logback configuration files is extremely flexible. As such, it is not possible to specify the allowed syntax with a DTD file or an XML schema. Nevertheless, the very basic structure of the configuration file can be described as, element, containing zero or more elements, followed by zero or more elements, followed by at most one element. The following diagram illustrates this basic structure.
If you are unsure which case to use for a given tag name, just follow the camelCase convention which is almost always the correct convention.
Case sensitivity of tag names
Configuring loggers, or the element
At this point you should have at least some understanding of level inheritance and the basic selection rule. Otherwise, and unless you are an Egyptologist, logback configuration will be no more meaningful to you than are hieroglyphics.
A logger is configured using the element. A element takes exactly one mandatory name attribute, an optional level attribute, and an optional additivity attribute, admitting the values true or false. The value of the level attribute admitting one of the case-insensitive string values TRACE, DEBUG, INFO, WARN, ERROR, ALL or OFF. The special case-insensitive value INHERITED, or its synonym NULL, will force the level of the logger to be inherited from higher up in the hierarchy. This comes in handy if you set the level of a logger and later decide that it should inherit its level.
Note that unlike log4j, logback-classic does not close nor remove any previously referenced appenders when configuring a given logger.
Configuring the root logger, or the element
The element configures the root logger. It supports a single attribute, namely the level attribute. It does not allow any other attributes because the additivity flag does not apply to the root logger. Moreover, since the root logger is already named as «ROOT», it does not allow a name attribute either. The value of the level attribute can be one of the case-insensitive strings TRACE, DEBUG, INFO, WARN, ERROR, ALL or OFF. Note that the level of the root logger cannot be set to INHERITED or NULL.
Note that unlike log4j, logback-classic does not close nor remove any previously referenced appenders when configuring the root logger.
Example
Setting the level of a logger or root logger is as simple as declaring it and setting its level, as the next example illustrates. Suppose we are no longer interested in seeing any DEBUG messages from any component belonging to the «chapters.configuration» package. The following configuration file shows how to achieve that.
Example: Setting the level of a logger (logback-examples/src/main/resources/chapters/configuration/sample2.xml)
When the above configuration file is given as argument to the MyApp3 application, it will yield the following output:
Note that the message of level DEBUG generated by the «chapters.configuration.Foo» logger has been suppressed. See also the Foo class.
Example: Setting the level of multiple loggers (logback-examples/src/main/resources/chapters/configuration/sample3.xml)
Running MyApp3 with this configuration file will result in the following output on the console:
The table below list the loggers and their levels, after JoranConfigurator has configured logback with the sample3.xml configuration file.
| Logger name | Assigned Level | Effective Level |
|---|---|---|
| root | DEBUG | DEBUG |
| chapters.configuration | INFO | INFO |
| chapters.configuration.MyApp3 | null | INFO |
| chapters.configuration.Foo | DEBUG | DEBUG |
It follows that the two logging statements of level INFO in the MyApp3 class as well as the DEBUG messages in Foo.doIt() are all enabled. Note that the level of the root logger is always set to a non-null value, DEBUG by default.
Let us note that the basic-selection rule depends on the effective level of the logger being invoked, not the level of the logger where appenders are attached. Logback will first determine whether a logging statement is enabled or not, and if enabled, it will invoke the appenders found in the logger hierarchy, regardless of their level. The configuration file sample4.xml is a case in point:
Example: Logger level sample (logback-examples/src/main/resources/chapters/configuration/sample4.xml)
The following table lists the loggers and their levels after applying the sample4.xml configuration file.
| Logger name | Assigned Level | Effective Level |
|---|---|---|
| root | OFF | OFF |
| chapters.configuration | INFO | INFO |
| chapters.configuration.MyApp3 | null | INFO |
| chapters.configuration.Foo | null | INFO |
Configuring Appenders
Logging to multiple appenders is as easy as defining the various appenders and referencing them in a logger, as the next configuration file illustrates:
Example: Multiple loggers (logback-examples/src/main/resources/chapters/configuration/multiple.xml)
These configuration scripts define two appenders called FILE and STDOUT. The FILE appender logs to a file called myApp.log. The encoder for this appender is a PatternLayoutEncoder that outputs the date, level, thread name, logger name, file name and line number where the log request is located, the message and line separator character(s). The second appender called STDOUT outputs to the console. The encoder for this appender outputs only the message string followed by a line separator.
The appenders are attached to the root logger by referencing them by name within an appender-ref element. Note that each appender has its own encoder. Encoders are usually not designed to be shared by multiple appenders. The same is true for layouts. As such, logback configuration files do not provide any syntactical means for sharing encoders or layouts.
Appenders accumulate
By default, appenders are cumulative: a logger will log to the appenders attached to itself (if any) as well as all the appenders attached to its ancestors. Thus, attaching the same appender to multiple loggers will cause logging output to be duplicated.
Example: Duplicate appender (logback-examples/src/main/resources/chapters/configuration/duplicate.xml)
Running MyApp3 with duplicate.xml will yield the following output:
Notice the duplicated output. The appender named STDOUT is attached to two loggers, to root and to chapters.configuration. Since the root logger is the ancestor of all loggers and chapters.configuration is the parent of both chapters.configuration.MyApp3 and chapters.configuration.Foo, each logging request made with these two loggers will be output twice, once because STDOUT is attached to chapters.configuration and once because it is attached to root.
Appender additivity is not intended as a trap for new users. It is quite a convenient logback feature. For instance, you can configure logging such that log messages appear on the console (for all loggers in the system) while messages only from some specific set of loggers flow into a specific appender.
Example: Multiple appender (logback-examples/src/main/resources/chapters/configuration/restricted.xml)
In this example, the console appender will log all the messages (for all loggers in the system) whereas only logging requests originating from the chapters.configuration logger and its children will go into the myApp.log file.
Overriding the default cumulative behaviour
In case the default cumulative behavior turns out to be unsuitable for your needs, you can override it by setting the additivity flag to false. Thus, a branch in your logger tree may direct output to a set of appenders different from those of the rest of the tree.
Example: Additivity flag (logback-examples/src/main/resources/chapters/configuration/additivityFlag.xml)
This example, the appender named FILE is attached to the chapters.configuration.Foo logger. Moreover, the chapters.configuration.Foo logger has its additivity flag set to false such that its logging output will be sent to the appender named FILE but not to any appender attached higher in the hierarchy. Other loggers remain oblivious to the additivity setting of the chapters.configuration.Foo logger. Running the MyApp3 application with the additivityFlag.xml configuration file will output results on the console from the chapters.configuration.MyApp3 logger. However, output from the chapters.configuration.Foo logger will appear in the foo.log file and only in that file.
Setting the context name
As mentioned in an earlier chapter, every logger is attached to a logger context. By default, the logger context is called «default». However, you can set a different name with the help of the configuration directive. Note that once set, the logger context name cannot be changed. Setting the context name is a simple and straightforward method in order to distinguish between multiple applications logging to the same target.
Example: Set the context name and display it (logback-examples/src/main/resources/chapters/configuration/contextName.xml)
This last example illustrates naming of the logger context. Adding the contextName conversion word in layout’s pattern will output the said name.
Variable substitution
Note Earlier versions of this document used the term «property substitution» instead of the term «variable». Please consider both terms interchangeable although the latter term conveys a clearer meaning.
As in many scripting languages, logback configuration files support definition and substitution of variables. Variables have a scope (see below). Moreover, variables can be defined within the configuration file itself, in an external file, in an external resource or even computed and defined on the fly.
Variable substitution can occur at any point in a configuration file where a value can be specified.
Variable substitution can occur at any point in a configuration file where a value can be specified. The syntax of variable substitution is similar to that of Unix shells. The string between an opening $ <and closing > is interpreted as a reference to the value of the property. For property aName, the string «$
As they often come in handy, the HOSTNAME and CONTEXT_NAME variables are automatically defined and have context scope. Given that in some environments it may take some time to compute the hostname, its value is computed lazily (only when needed). Moreover, HOSTNAME can be set from within the configuration directly.
Defining variables
Variables can be defined one at a time in the configuration file itself or loaded wholesale from an external properties file or an external resource. For historical reasons, the XML element for defining variables is
although in logback 1.0.7 and later the element can be used interchangeably.
The next example shows a variable declared at the beginning of the configuration file. It is then used further down the file to specify the location of the output file.
Example: Simple Variable substitution (logback-examples/src/main/resources/chapters/configuration/variableSubstitution1.xml)
The next example shows the use of a System property to achieve the same result. The property is not declared in the configuration file, thus logback will look for it in the System properties. Java system properties can be set on the command line as shown next:
Example: System Variable substitution (logback-examples/src/main/resources/chapters/configuration/variableSubstitution2.xml)
When multiple variables are needed, it may be more convenient to create a separate file that will contain all the variables. Here is how one can do such a setup.
Example: Variable substitution using a separate file (logback-examples/src/main/resources/chapters/configuration/variableSubstitution3.xml)
This configuration file contains a reference to a file named variables1.properties. The variables contained in that file will be read and then defined within local scope. Here is what the variable.properties file might look like.
Example: Variable file (logback-examples/src/main/resources/chapters/configuration/variables1.properties)
You may also reference a resource on the class path instead of a file.
Scopes
A property can be defined for insertion in local scope, in context scope, or in system scope. Local scope is the default. Although it is possible to read variables from the OS environment, it is not possible to write into the OS environment.
local scope A property with local scope exists from the point of its definition in a configuration file until the end of interpretation/execution of said configuration file. As a corollary, each time a configuration file is parsed and executed, variables in local scope are defined anew.
context scope A property with context scope is inserted into the context and lasts as long as the context or until it is cleared. Once defined, a property in context scope is part of the context. As such, it is available in all logging events, including those sent to remote hosts via serialization.
system scope A property with system scope is inserted into the JVM’s system properties and lasts as long as the JVM or until it is cleared.
Properties are looked up in the the local scope first, in the context scope second, in the system properties scope third, and in the OS environment last.
During substitution, properties are looked up in the local scope first, in the context scope second, in the system properties scope third, and in the OS environment fourth and last.
The scope attribute of the
element, element or the element can be used to set the scope of a property. The scope attribute admits «local», «context» and «system» strings as possible values. If not specified, the scope is always assumed to be «local».
Example: A variable defined in «context» scope (logback-examples/src/main/resources/chapters/configuration/contextScopedVariable.xml)
In the above example, given that the nodeId property is defined in the context scope, it will be available in every logging event, even those sent to remote hosts via serialization.
Default values for variables
Under certain circumstances, it may be desirable for a variable to have a default value if it is not declared or its value is null. As in the Bash shell, default values can be specified using the «:-« operator. For example, assuming the variable named aName is not defined, «$
Nested variables
Variable nesting is fully supported. Both the name, default-value and value definition of a variable can reference other variables.
value nesting
The value definition of a variable can contain references to other variables. Suppose you wish to use variables to specify not only the destination directory but also the file name, and combine those two variables in a third variable called «destination». The properties file shown below gives an example.
Example: Nested variable references (logback-examples/src/main/resources/chapters/configuration/variables2.properties)
Note that in the properties file above, «destination» is composed from two other variables, namely «USER_HOME» and «fileName».
Example: Variable substitution using a separate file (logback-examples/src/main/resources/chapters/configuration/variableSubstitution4.xml)
name nesting
When referencing a variable, the variable name may contain a reference to another variable. For example, if the variable named «userid» is assigned the value «alice», then «$<$
default value nesting
The default value of a variable can reference a another variable. For example, assuming the variable ‘id’ is unassigned and the variable ‘userid’ is assigned the value «alice», then the expression «$
HOSTNAME property
As it often comes in handy, the HOSTNAME property is defined automatically during configuration with context scope.
CONTEXT_NAME property
As its name indicates, the CONTEXT_NAME property corresponds to the name of the current logging context.
Setting a timestamp
The timestamp element can define a property according to current date and time. The timestamp element is explained in a subsequent chapter.
Defining properties on the fly
Here is an example.
In the above example, shape, color and size are properties of «a.class.implementing.PropertyDefiner». As long as there is a setter for a given property in your implementation of the PropertyDefiner instance, logback will inject the appropriate values as specified in the configuration file.
| Implementation name | Description |
|---|---|
| CanonicalHostNamePropertyDefiner | Set the named variable to the canonical host name of the local host. Note that obtaining the canonical host name may take several seconds. |
| FileExistsPropertyDefiner | Set the named variable to «true» if the file specified by path property exists, to «false» otherwise. |
| ResourceExistsPropertyDefiner | Set the named variable to «true» if the resource specified by the user is available on the class path, to «false» otherwise. |
Conditional processing of configuration files
The general format for conditional statements is shown below.
Conditional processing is supported anywhere within the element. Nested if-then-else statements are also supported. However, XML syntax is awfully cumbersome and is ill suited as the foundation of a general purpose programming language. Consequently, too many conditionals will quickly render your configuration files incomprehensible to subsequent readers, including yourself.
Obtaining variables from JNDI
Under certain circumstances, you may want to make use of env-entries stored in JNDI. The configuration directive extracts an env-entry stored in JNDI and inserts the property in local scope with key specified by the as attribute. As all properties, it is possible to insert the new property into a different scope with the help of the scope attribute.
Example: Insert as properties env-entries obtained via JNDI (logback-examples/src/main/resources/chapters/configuration/insertFromJNDI.xml)
In this last example, the «java:comp/env/appName» env-entry is inserted as the appName property. Note that the directive sets the context name based on the value of the appName property inserted by the previous directive.
File inclusion
Joran supports including parts of a configuration file from another file. This is done by declaring a element, as shown below:
Example: File include (logback-examples/src/main/resources/chapters/configuration/containingConfig.xml)
The target file MUST have its elements nested inside an element. For example, a ConsoleAppender could be declared as:
Example: File include (logback-examples/src/main/resources/chapters/configuration/includedConfig.xml)
Again, please note the mandatory element.
The contents to include can be referenced as a file, as a resource, or as a URL.
As a resource:
To include a resource, i.e a file found on the class path, use the resource attribute.
As a URL:
To include the contents of a URL use the url attribute.
If it cannot find the file to be included, logback will complain by printing a status message. In case the included file is optional, you can suppress the warning message by setting optional attribute to true in the element.
Adding a context listener
Instances of the LoggerContextListener interface listen to events pertaining to the lifecycle of a logger context.
JMXConfigurator is one implementation of the LoggerContextListener interface. It is described in a subsequent chapter.
LevelChangePropagator
As of version 0.9.25, logback-classic ships with LevelChangePropagator, an implementation of LoggerContextListener which propagates changes made to the level of any logback-classic logger onto the java.util.logging framework. Such propagation eliminates the performance impact of disabled log statements. Instances of LogRecord will be sent to logback (via SLF4J) only for enabled log statements. This makes it reasonable for real-world applications to use the jul-to-slf4j bridge.
The contextListener element can be used to install LevelChangePropagator as shown next.







