![]() |
Модераторы: LSD, AntonSaburov |
![]() ![]() ![]() |
|
LSD |
|
||||||||||||||||||||||||
![]() Leprechaun Software Developer ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 15718 Регистрация: 24.3.2004 Где: Dublin Репутация: 210 Всего: 538 |
Предположим вы пишете, или уже написали и отлаживаете, свое приложение. Пока приложение маленькое вам вполне хватет возможностей System.out.println(), но по мере увеличения и усложнения приложения его возможностей уже нехватает. В частности что нельзя (или затруднительно) сделать с помощью System.out.println():
1) управление логгированием: отключить логгирование одних сообщений, и включить логгирование других 2) запись логов в файл, БД и т.п. 3) вывод дополнительной информации о сообщении: время события, место события, контекст 4) форматирование вывода для решения всех этих проблем и были созданы системы логгирования. Две наиболее популярные это Log4j от Apache и Java Logging API входящее в состав JDK 1.4 и старше. Надо еще упомянуть про Commons Logging, которая тоже часто используется. Commons Logging не является системой логгирования как таковой, это просто надстройка которая предоставляет единый интерфейс к системам логгирования (Log4j и Java Logging API). Из этих двух систем я предпочитаю Log4j, т.к. это готовая система логгирования, а Java Logging API для своего использования требует "доработки напильником". Итак приступаем. Идем на сайт Log4j и скачиваем последнюю версию (на момент написания статьи последняя стабильная версия 1.2), распаковываем и подключаем log4j-X.X.XX.jar к проекту. Создаем новый класс и пишем:
запускаем и получаем:
Итак, что же тут произошло. Базовым классом через которое и будет идти все логгирование является org.apache.log4j.Logger. Для получения логгера используется статический метод getLogger() куда в качестве параметра надо передать имя этого логгера. Также есть перегруженный метод куда можно передать класс, и он вернет логгер с именем этого класса (в примере это ru.vingrad.log.Test). Каждый логгер имеет уникальное имя, и вызов getLogger() с одним и тем же именем вернет один и тот же логгер. Логгер синхронизирован и его можно свободно использовать в многопоточной среде. Для именования логгеров принято использовать правила именования пакаджей Java. Для логгеров существует иерархия аналогичная иерархии пакаджей, т.е. для ru.vingrad.log.Test родительским будет логгер ru.vingrad.log, для ru.vingrad.log - ru.vingrad и т.д. Плюс существует корневой логгер, являющийся родительским для всех остальных, получит его можно: Logger.getRootLogger(). Важным фактом является то, что логгер если логгер не сконфигурирован индивидуально, то он будет использовать настройки своего родительского логгера. Т.е. мы можем сконфигурировать только корневой логгер, а все логгеры будут использовать его настройки. Так же логгер использует аппендеры родительского логгера (об аппендерах далее), это можно отключается свойством additivity. Логгер может писать сообщения разных уровней (org.apache.log4j.Level), уровень очень важное понятие для управления логгированием. Уровни упорядочены по старшинству (в порядке убывания): FATAL, ERROR, WARN, INFO, DEBUG, TRACE. Уровни FATAL, ERROR, WARN предназначенны для сообщений об ошибках, разной степени серьезности, INFO информационные сообщения, DEBUG - отладочные, TRACE - очень подробная отладочная информация. Когда мы конфигурируем систему логгирования мы указываем сообщения какого уровня надо писать в лог. В лог будут писаться сообщения этого уровня и выше, т.е если мы настроили систему на уровень INFO то будут писаться сообщения с уровнями FATAL, ERROR, WARN, INFO. Плюс еще есть спец уровни ALL и OFF, которые предназначены для включения/выключения записи всех сообщений. Следующая важная составляющая системы логгирования это - аппендер (org.apache.log4j.Appender). Аппендер это класс который занимается непосредственно записью сообщений. org.apache.log4j.Appender это интерфейс, но у него есть реализации для записи сообщений в консоль, файл, БД, e-mail и т.д. Так же у аппендера можно установить фильтры (org.apache.log4j.spi.Filter) для фильтрации сообщений. И форматер сообщений (org.apache.log4j.Layout) для форматирования выводимых сообщений. А теперь со всей этой фигней на борту мы попробуем взлететь. Как же происходит запись логов? 1. Вызываем logger.info("Hello world!") 2. Происходит проверка уровня логгирования для данного логгера, если данному логгеру не был явно задан уровень, то тогда проверка осуществляется для его родителей. Если уровень логгера выше уровня сообщения, то оно отбрасывается и запись его не происходит. В нашем случае корневой аппендер сконфигурирован на уровешь DEBUG а у сообщения уровень INFO, т.е. уровень логгера ниже уровня сообщения и оно проходит проверку. 3. Далее сообщение передается аппендерам установленным для данного логгера (если есть). 4. Если свойство additivity установлено в true (по умолчанию оно установлено), то сообщение так же передается родительским логгерам. 5. Аппендер получив сообщение проверяет его установленными фильтрами (если есть). Если сообщение прошло фильтры оно форматируется и записывается в лог. Это все конечно хорошо, но как же конфигурировать логгеры, не кодом же в main() добавлять аппендеры и логгеры? Для конфигурирования Log4j используются файлы конфигурации log4j.xml и log4j.properties, можно загружать конфигурацию вручную, но проще положить один из этих файлов в CLASSPATH и тогда при запуске Log4j сам загрузит из него конфигурацию. Какой из конфигов использовать дело вкуса, мне больше нравится xml, да и возможностей у него побольше, так что расскажу как конфигурировать с его помощью. Итак создаем в папке с исходниками файл log4j.xml и пишем в него:
(файл log4j.dtd можно найти внутри log4j.jar) Для начала добавим аппендеры. Консоль:
CONSOLE-DEBUG имя аппендера, по этому имени мы будем его упоминать в этом конфиге. org.apache.log4j.ConsoleAppender - имя класса аппендера <param name="target" value="System.out"/> - устанавливаем параметр аппендера который определяет куда писать лог <layout - форматер, подробнее о формате шаблона можно почитать в Java doc по классу форматера (org.apache.log4j.PatternLayout) <filter - фильтр сообщений, в данные аппендер будут писаться все сообщения уровней INFO, DEBUG и TRACE Аналогично конфигурируем аппендер для ошибок:
разница в том, ошибки будут писаться в System.err. Конфигурируем запись в файл
тут все аналогично, параметр file задает имя файла. Теперь сконфигурируем логгеры. Предположим что мы используем Hibernate и хотим видеть только сообщения об ошибках и писать их только в консоль но не файл.
но в то же самое время, мы хотим видеть отладочные сообщения в org.hibernate.SQL (где пишутся выполняемые Hibernate SQL запросы).
Для всех остальных категорий включаем уровень DEBUG и запись в консоль и файл
В итоге мы получаем следующий файл:
Теперь самое время протестировать, что получилось.
на выходе получим:
Автор благодарит алфавит за любезно предоставленные буквы ![]() -------------------- Disclaimer: this post contains explicit depictions of personal opinion. So, if it sounds sarcastic, don't take it seriously. If it sounds dangerous, do not try this at home or at all. And if it offends you, just don't read it. |
||||||||||||||||||||||||
|
|||||||||||||||||||||||||
Hidrag |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 877 Регистрация: 9.4.2005 Где: JDK Репутация: 3 Всего: 25 |
А вот пример как прописать настройки лоджера в коде:
-------------------- ![]() |
|||
|
||||
The_M |
|
|||
Новичок Профиль Группа: Участник Сообщений: 1 Регистрация: 5.12.2007 Репутация: нет Всего: нет |
А может ктото подсказать как в файле настроек log4j сделать так чтоб эти настройки брались из другого файлика?
например чтобы при смене уровня логирования не нада было бы изменять log4j.xml для этого можно просто проимпортить в log4j.xml нужный файлик и все? может у когото уже есть примерчик ![]() |
|||
|
||||
LSD |
|
|||
![]() Leprechaun Software Developer ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 15718 Регистрация: 24.3.2004 Где: Dublin Репутация: 210 Всего: 538 |
Импортировать вроде бы нельзя, но можно определить переменную окружения log4j.configuration в которой и указать путь к файлу с настройками (путь может быть относительным). Если имя файла заканчивается на .xml, то он будет парситься как XML, иначе как properties.
-------------------- Disclaimer: this post contains explicit depictions of personal opinion. So, if it sounds sarcastic, don't take it seriously. If it sounds dangerous, do not try this at home or at all. And if it offends you, just don't read it. |
|||
|
||||
Fedrus |
|
|||
Шустрый ![]() Профиль Группа: Участник Сообщений: 130 Регистрация: 20.9.2007 Репутация: нет Всего: нет |
1: Решил по полной использовать Log4j и почему-то сразу нашел эту статью))
Спасибо за статью.(перешел на xml конфигурацию) 2: The_M А если не секрет тебе это зачем? --------------------
Если вы идете через ад, идите не останавливаясь. |
|||
|
||||
![]() ![]() ![]() |
Правила форума "Java" | |
|
Если Вам помогли, и атмосфера форума Вам понравилась, то заходите к нам чаще! С уважением, LSD, AntonSaburov, powerOn, tux, javastic. |
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей) | |
0 Пользователей: | |
« Предыдущая тема | Java: Общие вопросы | Следующая тема » |
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |