-неизвестно

 -Поиск по дневнику

Поиск сообщений в ATUM

 -Подписка по e-mail

 

 -Постоянные читатели

 -Статистика

Статистика LiveInternet.ru: показано количество хитов и посетителей
Создан: 17.02.2006
Записей:
Комментариев:
Написано: 1139


...

Четверг, 21 Июня 2007 г. 14:01 + в цитатник



Как избавиться от привычки отлаживать все по средствам System.out.println();?




Log4j - это инструмент для журналирования. Он представляет собой набор API функций с помощью которых можно вставлять в свой код выражения, которые выводят отладочную информацию, сообщения об ошибках и т.д.

Конфигурировать этот вывод с помощью внешний конфигурационных файлов.

Открываем NetBeans IDE 5.5.
Создаем новый проект File->New Project (Ctrl + Shift + N)

Выбираем General->Java Application

Вводим имя пакета и имя Main class

У меня получилось так.

/*
* logInfo.java
*
* Created on 21 Июнь 2007 г., 12:00
*
* To change this template, choose Tools | Template Manager
* and open the template in the editor.
*/

package logger;

/**
*
* @author Atum
*/
public class logInfo {

/** Creates a new instance of logInfo */
public logInfo() {
}

/**
* @param args the command line arguments
*/
public static void main(String[] args) {
// TODO code application logic here
}

}


Нажимаем F11 (Build Main Project)

Скачиваем пакет log4j с сайта

logging.apache.org
на момент написания этого документа я скачал log4j-1.2.14.zip(во сложении)

распаковываем и ищем \logging-log4j-1.2.14\dist\lib\log4j-1.2.14.jar

копируем его в \dist\lib нашего проекта.

следующим шагом создаем для нашего проекта файл настроек в \src

(<Имя пакета>.properties Например log4j.properties)
Следующего содержания :

log4j.rootLogger=DEBUG,stdout

log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.target=System.out
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.conversionPattern=%d{ABSOLUTE} %5p %t %c{1}:%M:%L - %m%n

Он автоматически появится в \build\classes


Добавляем к исходному тексту следующие строки


/*
* logInfo.java
*
* Created on 21 Июнь 2007 г., 12:00
*
* To change this template, choose Tools | Template Manager
* and open the template in the editor.
*/
package logger;

// import log4j packages
import org.apache.log4j.Logger;

/**
*
* @author Atum
*/
public class logInfo {
private static final Logger log = Logger.getLogger(logInfo.class);
//общий случай - final Logger log = Logger.getLogger(текущий_класс.class);
/** Creates a new instance of logInfo */
public logInfo() {
}

/**
* @param args the command line arguments
*/
public static void main(String[] args) {
// TODO code application logic here
log.debug("Это DEBUG");
log.info("Это INFO");
log.warn("Это WARN");
log.error("Это ERROR");
log.fatal("Это FATAL");
}

}

Запускаем на исполнение (F6) и должны получить в консоли

compile:
run:
12:22:03,340 DEBUG main logInfo:main:39 - Это DEBUG
12:22:03,351 INFO main logInfo:main:40 - Это INFO
12:22:03,351 WARN main logInfo:main:41 - Это WARN
12:22:03,351 ERROR main logInfo:main:42 - Это ERROR
12:22:03,351 FATAL main logInfo:main:43 - Это FATAL
BUILD SUCCESSFUL (total time: 1 second)

Теперь разберемся во всем этом боле подробно:


Log4j имеет три базовые составляющие, три главных компонента :
1.logger (журналирующий элемент)
2.appender (элемент, определяющий куда нужно журналировать)
3.layout (представление в котором будет производится журналирование)


Logger берет на себя функцию журналирования какого-либо события в место назначения, определяемое элементом appender, в специально определенном формате, который задается элементом layout.
Logger можно представлять себе, как компонент некого приложения, который будет принимать и выполнять ваши запросы на запись каких-либо событий в регистрационный журнал, представленный файлом, базой данных, консолью и т.д. (определяется appender'ом). Каждый класс вашего приложения может иметь свой собственный logger или же быть привязанным к общему logger'у.
Log4j предусматривает корневой logger, от которого будут наследоваться все создаваемые вами объекты этого типа. Это значит, что если у вас не предусмотрен для каждого объекта свой logger, то вы всегда сможете воспользоваться корневым, с помощью метода Logger.getRootLogger(), однако так поступать не рекомендуется.
Log4j предусматривает пять уровней журналирования:

- DEBUG
- INFO
- WARN
- ERROR
- FATAL

Эти уровни определяют также порядок журналирования, которому следует log4j


Рассмотрим содержания файла log4j.properties

Первая строка

log4j.rootLogger=DEBUG,stdout


Настраивает logger по умолчанию, первый элементом идет уровень сообщений который нужно перехватывать (и все выше него), в данном случае это DEBUG, Если задать WARN то уровни info и debug в лог не пойдут, а warn, error и fatal будут в логе.

log4j.rootLogger = WARN,stdout


Следующие элемент это названия appender’а, настроек с помощью которых вести лог.

log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.target=System.out
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.conversionPattern=%d{ABSOLUTE} %5p %t %c{1}:%M:%L - %m%n

stdout – Это Его Имя (может быть любое , например out )
В этой строке:

log4j.appender.stdout=org.apache.log4j.ConsoleAppender

мы настраиваем appender с именем stdout, указывая что для него будет использоваться класс org.apache.log4j.ConsoleAppender,
это простой класс который выводит лог в консоль приложения. Далее строки, начинающиеся с log4j.appender.stdout. настраивают этот appender. Все что идет после указанного префикса должно совпадать со свойством класса, т.е. для target должен быть метод setTarget, для layout метод setLayout ну и т.д.
фактически log4j.appender.stdout.target=System.out
это тот же вывод System.out.println(); с использованием шаблона вывода

Для примера строку

log4j.appender.stdout.layout=org.apache.log4j.PatternLayout

Заменить на

log4j.appender.stdout.layout=org.apache.log4j.SimpleLayout

и этим ограничется – получим самый простой вывод

compile:
run:
DEBUG - Это DEBUG
INFO - Это INFO
WARN - Это WARN
ERROR - Это ERROR
FATAL - Это FATAL
BUILD SUCCESSFUL (total time: 0 seconds)

Шаблон (layout) вывода лога

log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.conversionPattern=%d{ABSOLUTE} %5p %t %c{1}:%M:%L - %m%n

что это означает
layout определяет как форматировать вывод в лог. В примере выше для этого используется класс org.apache.log4j.PatternLayout .
Данный форматтер принимает параметром conversionPattern, шаблон вывода лога :
%d{ABSOLUTE}
Выводит время. В скобках можно указать формат вывода, о нем подробней можно прочитать в хэлпе к стандартному классу SimpleDateFormat. И еще можно использовать именованные шаблоны, как в данном случае, это ISO8601 и ABSOLUTE. Последний означает формат HH:mm:ss,SSS.
%5p
Выводит уровень лога (ERROR, DEBUG, INFO и пр.), цифра 5 означает что всегда использовать 5 символов, остальное дополнится пробелами
%t
Выводит имя потока который вывел сообщение
%c{1}
Категория, в скобках указывается сколько уровней выдавать. Категорией в нашем случае будет имя класса с пакетом. Ну а вообще это строка, где уровни разделены точками. Т.к. у нас совпадает с полным именем класса, то верхний уровень будет являться именем класса
%M
Имя метода в котором произошёл вызов записи в лог
%L
Номер строки в которой произошёл вызов записи в лог
%m
Сообщение, которое передали в лог
%n
Перевод строки

Теперь видоизменим Наш Файл настроек
(log4j.properties) для вывода информации в файл

log4j.rootLogger= WARN,file

log4j.appender.file=org.apache.log4j.FileAppender
log4j.appender.file.file=logfile.log
log4j.appender.file.layout=org.apache.log4j.PatternLayout
log4j.appender.file.layout.conversionPattern=%d{ABSOLUTE} %5p %t %c{1}:%M:%L - %m%n

так же будем выводить всю информацию начиная с WARN
Запустив получим файл в нашей рабочей директории с именем logfile.log в нашей папке

Иноформация в консоли:

compile:
run:
BUILD SUCCESSFUL (total time: 2 seconds)

В файле:

13:03:55,532 WARN main logInfo:main:39 - Это WARN
13:03:55,542 ERROR main logInfo:main:40 - Это ERROR
13:03:55,542 FATAL main logInfo:main:41 - Это FATAL

Тем самым мы направили вывод сообщений в Файл

log4j.appender.file=org.apache.log4j.FileAppender


настроив

log4j.appender.file=org.apache.log4j.FileAppender

и указав его имя

log4j.appender.file.file=logfile.log

формат вывода остался прежним.


Таким образом установленный для элемента logger уровень (DEBUG,INFO,WARN,ERROR,FATAL) влияет на его функциональность. Дело в том, что запрос на занесение в журнал какого-либо события, с помощью определенного элемента appender, из нашего приложения будет выполнен лишь в том случае, если уровень журналируемого события (запроса) не ниже, чем уровень самого элемента logger, через который этот запрос был создан. Это означает, что все запросы, которые мы можем создавать в нашем приложении, могут быть только какого-то одного из этих пяти уровней. Это очень важное правило и, фактически, это является ядром функциональности log4j.


Введем в наш проект еще одни class

class Print {
//создаем logger
Logger log = Logger.getLogger(Print.class);

//ctor
Print(String st ) {

log.info("begin Print ");
System.out.println(st);
log.info("end Print ");

}

void PrintMessage() {
log.info("begin PrintMessage ");
System.out.println("Print ok");
log.info("end PrintMessage ");
}
}

И создадим экземпляр класса

public static void main(String[] args) {
// TODO code application logic here
log.debug("Это DEBUG");
log.info("Это INFO");
Print P = new Print("Logger");
log.warn("Это WARN");
P.PrintMessage();
log.error("Это ERROR");
log.fatal("Это FATAL");
}

Запустив получим

compile:
run:
Logger
Print ok
BUILD SUCCESSFUL (total time: 1 second)

В файле лога logfile.log – соответственно добавятся новые строки.
Перепишем файл настроек (log4j.properties) следующим образом



log4j.appender.file=org.apache.log4j.FileAppender
log4j.appender.file.file=logfile.log
log4j.appender.file.layout=org.apache.log4j.PatternLayout
log4j.appender.file.layout.conversionPattern=%d{ABSOLUTE} %5p %t %c{1}:%M:%L - %m%n

log4j.appender.fileclass=org.apache.log4j.FileAppender
log4j.appender.fileclass.file= logfile_print.log
log4j.appender.fileclass.layout=org.apache.log4j.PatternLayout
log4j.appender.fileclass.layout.conversionPattern=%d{ABSOLUTE} %5p %t %c{1}:%M:%L - %m%n


log4j.logger.logger.logInfo=DEBUG,file
log4j.logger.logger.Print=INFO,fileclass


уберем из него

#log4j.rootLogger=DEBUG

И добавим

log4j.logger.logger.logInfo=DEBUG,file
log4j.logger.logger.Print=INFO,fileclass

теперь информация по каждому классу будет писаться в отдельный лог файл
(logfile.log для class‘a logInfo и logfile_print.log для class‘a Print соответственно)
Принцип такой:

log4j.logger.<ИМЯ_ПАКЕТА>.<ИМЯ_КЛАССА>= <УРОВЕНЬ>, <ИМЯ_ЛОГГЕРА>

или:

log4j.logger.<ИМЯ_ПАКЕТА>= <УРОВЕНЬ>

таким вот образом мы индивидуально указывает для пакета, или класса, как писать лог, какой уровень минимальный и нужно ли писать в дополнительный аппендер (к примеру в дополнительынй файл).

помним что в Log4j используется иерархия logger-ов.
Корень генераторов сообщений находится в вершине иерархии. Он:

1. Всегда существует.
2. Нет необходимости давать ему имя.
При вызове статического метода из класса Logger.getRootLogger устанавливается корень генераторов сообщений - root. Все другие генераторы сообщений - наследуются и устанавливаются при вызове статического метода из класса Logger.getLogger. по умолчанию он установлен в log4j.rootLogger=DEBUG

Appender (накопитель сообщений), указывает куда будет выводится сообщение.

В настоящее время, накопители сообщений существуют для console, files, GUI components, remote socket servers, JMS , NT Event loggers , и Unix Syslog daemons на отдаленном сервере.
При этом возможно, что log работает асинхронно.
Несколько накопителей сообщений могут быть присоединены к генератору сообщений.


Вложение: 3589610_log4j1.rar

Метки:  

??????   обратиться по имени Четверг, 01 Марта 2012 г. 05:58 (ссылка)
Ответить С цитатой В цитатник    |    Не показывать комментарий
 

Добавить комментарий:
Текст комментария: смайлики

Проверка орфографии: (найти ошибки)

Прикрепить картинку:

 Переводить URL в ссылку
 Подписаться на комментарии
 Подписать картинку