"О, ето те! Помниш ли, че днес имаме още един урок?"

„Не, просто те търсих. Почти…“

„Отлично, тогава да започваме. Днес искам да ви разкажа за дърводобива.“

„Дневникът е списък на събитията, които са се случor. Почти като корабен дневник or дневник. Или Twitter – може би можете да се свържете по-добре с това. Не е изненадващо, че регистраторът е обект, който използвате за регистриране.“

„В програмирането е обичайно да се регистрира почти всичко. А в Java регистрираме всичко и дори малко повече.“

„Факт е, че Java програмите много често са големи сървърни applications без UI, конзола и т.н. Те обработват хиляди потребителски заявки едновременно и често има различни грешки. Особено когато различни нишки започнат да си пречат.“

„Всъщност единственият начин за търсене на рядко възпроизводими грешки и грешки при тези обстоятелства е да регистрирате всичко, което се случва във всяка нишка.“

„Най-често дневникът съдържа информация за аргументите на метода, всяHowви уловени грешки и много междинна информация.“

„Колкото по-пълен е дневникът, толкова по-лесно е да се възпроизведе последователност от събития и да се проследят причините за неуспехи or грешки.“

„Понякога регистрационните файлове достигат няколко гигаbyteа на ден. Това е нормално.“

„Няколко гигаbyteа? O_o“

"Да. Най-често лог файловете се архивират автоматично, с указание за съответната дата."

"Уау!"

"Ъ-ъъ. Първоначално Java нямаше собствен логер. В резултат на това бяха написани няколко независими регистратори. Най-често срещаният от тях беше log4j."

„Няколко години по-късно Java получи собствен логер, но функционалността му беше далеч по-ниска и не беше широко използван.“

„Факт е, че Java има официален регистратор, но цялата общност от Java програмисти предпочита да използва други регистратори.

„По-късно бяха написани още няколко регистратора на базата на log4j.“

„Тогава специалният универсален регистратор slf4j, който сега се използва широко, беше написан за всички тях. Той е много подобен на log4j, така че ще го използвам като пример, когато обяснявам регистриране.“

„Целият процес на регистриране се състои от три части.“

" Първо , съберете информация."

Второ , филтрирайте събраната информация.“

" Трето , запишете избраната информация."

"Нека започнем със събирането. Ето типичен пример за клас, който регистрира:"

Клас с дърводобив
class Manager
{
 private static final Logger logger = LoggerFactory.getLogger(Manager.class);

 public boolean processTask(Task task)
 {
  logger.debug("processTask id = " + task.getId());
  try
  {
   task.start();
   task.progress();
   task.compleate();
   return true;
  }
  catch(Exception e)
  {
   logger.error("Unknown error", e);
   return false;
  }
 }
}

"Обърнете внимание на думите, подчертани в червено."

" Ред 3  – Създайте обекта за регистриране . Такъв статичен обект се създава в почти всеки клас! Е, с изключение на класовете, които не правят нищо друго освен да съхраняват данни."

" LoggerFactory е специален клас за създаване на регистратори, а getLogger е един от статичните му методи. Текущият обект обикновено се предава, но са възможни различни опции."

" Ред 7 – Информацията за извикването на метода се записва в регистратора. Обърнете внимание, че това е първият ред на метода. Веднага щом методът бъде извикан, ние незабавно записваме информация в журнала."

„Ние наричаме метода за отстраняване на грешки, което означава, че важността на информацията е ниво DEBUG. Това се използва за филтриране. Ще ви разкажа за това след няколко minutesи.“

" Ред 17 – Хващаме изключение и... незабавно го записваме в дневника! Точно това трябва да се направи."

„Този ​​път извикваме метода за грешка, който веднага показва, че информацията е на ниво ГРЕШКА“

Дървосекач - 1

„Засега всичко изглежда ясно. Е, доколкото може да стане ясно по средата на нашия разговор.“

„Чудесно, тогава да преминем към филтриране на съобщения.“

„Обикновено всяко съобщение в регистрационния файл има собствено ниво на важност, което можете да използвате, за да отхвърлите някои от съобщенията. Ето нивата на важност, които споменах:“

Ниво на важност Описание
ВСИЧКО Всички съобщения
СЛЕДИ Прецизни съобщения за отстраняване на грешки
ОТСТРАНЯВАНЕ НА ГРЕШКИ Важни съобщения за отстраняване на грешки
ИНФО Информационни съобщения
ПРЕДУПРЕЖДЕНИЕ Предупреждения
ГРЕШКА Грешки
ФАТАЛНО Фатални грешки
ИЗКЛ Няма съобщения

Тези нива се използват и при филтриране на съобщения.

Да предположим, че зададете нивото на регистриране на WARN. Тогава всички съобщения, които са по-малко важни от WARN, ще бъдат отхвърлени: TRACE, DEBUG, INFO.

Ако зададете нивото на филтриране на FATAL, тогава дори съобщенията за ГРЕШКА ще бъдат отхвърлени.

„Има още две нива на важност, използвани при филтриране: ИЗКЛЮЧЕНО, което отхвърля всички съобщения; и ВСИЧКИ, което показва всички съобщения (нищо не се отхвърля).“

„Как и къде да настроя филтриране?“

— Ще ви кажа без повече приказки.

"Обикновено настройките на log4j logger са посочени във file log4j.properties."

Можете да посочите множество обекти за добавяне в този файл. В тези обекти се записват данни. Има източници на данни и има добавки - обекти, които имат противоположни цели. Обекти, в които данните се вливат като вода.

"Ето няколко примера:"

Влизане в конзолата
# Root logger option
log4j.rootLogger = INFO, stdout

# Direct log messages to 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{yyyy-MM-dd HH:mm:ss}

Редове 1 и 4 – Това са коментари

Ред 2 – Посочваме желаното ниво на регистриране. Всички по-малко важни нива (DEBUG, TRACE) ще бъдат отхвърлени.

На същото място добавяме запетая и след това посочваме името на обекта (който сами измисляме), в който ще бъде записан дневникът. Редове 5-9 съдържат неговите настройки.

Ред 5 – Указваме типа на appender ( ConsoleAppender ).

Ред 6 – Посочваме точно къде пишем ( System.out. ).

Ред 7 – Задаваме класа, който ще управлява моделите за преобразуване (PatternLayout).

Ред 8 – Задаваме модела за преобразуване, който ще се използва за писане. В примера по-горе това са датата и часът.

„И ето How изглежда записът във файл:“

Регистриране във файл
# Root logger option
log4j.rootLogger = INFO, file

# Direct log messages to a log file
log4j.appender.file = org.apache.log4j.RollingFileAppender
log4j.appender.file.File = C:\\loging.log
log4j.appender.file.MaxFileSize = 1MB
log4j.appender.file.MaxBackupIndex = 1
log4j.appender.file.layout = org.apache.log4j.PatternLayout
log4j.appender.file.layout.ConversionPattern = %-5p %c{1}:%L - %m%n

„Ред 2 задава нивото на филтриране на съобщенията и името на обекта за добавяне (мивка).“

„Ред 5 – Указваме типа на приложението за добавяне на файлове ( RollingFileAppender ).“

„Ред 6 – Указваме името на file, в който ще се записва регистрационният файл.“

"Ред 7 – Ние определяме максималния размер на регистрационния файл. Когато това ограничение за размер бъде надвишено, се създава нов файл."

„Ред 8 – Указваме броя на старите регистрационни файлове, които да се съхраняват.“

„Редове 9-10 – Задайте модела за преобразуване.“

"Не знам Howво се случва тук, но мога да предположа. Това е окуражаващо."

„Това е страхотно. След това ето пример How да напишете журнал във файл и конзолата:“

Влизане в конзолата и файл
# Root logger option
log4j.rootLogger = INFO, file, stdout

# Direct log messages to a log file
log4j.appender.file = org.apache.log4j.RollingFileAppender
log4j.appender.file.File = C:\\loging.log
log4j.appender.file.MaxFileSize = 1MB
log4j.appender.file.MaxBackupIndex = 1
log4j.appender.file.layout = org.apache.log4j.PatternLayout
log4j.appender.file.layout.ConversionPattern = %-5p %c{1}:%L - %m%n

# Direct log messages to 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{yyyy-MM-dd HH:mm:ss}

„А, значи можеш да направиш това? Това е страхотно!“

„Да. Можете да декларирате толкова applications, колкото искате, и да персонализирате всеки от тях.“

Освен това всеки appender може да има много гъвкави настройки за филтриране на съобщения. Не само можем да присвоим индивидуално ниво на филтриране на съобщенията на всяко допълнение, но можем също така да филтрираме съобщенията по пакет! Ето защо трябва да посочите клас, когато създавате логер (говоря за LoggerFactory.getLogger ).

"Например:"

Влизане в конзолата и файл
# Root logger option
log4j.rootLogger = INFO, file, stdout

# Direct log messages to a log file
log4j.appender.file = org.apache.log4j.RollingFileAppender
log4j.appender.file.threshold = DEBUG
log4j.appender.file.File = C:\\loging.log
log4j.appender.file.MaxFileSize = 1MB
log4j.appender.file.MaxBackupIndex = 1
log4j.appender.file.layout=org.apache.log4j.PatternLayout
log4j.appender.file.layout.ConversionPattern = %-5p %c{1}:%L - %m%n

# Direct log messages to stdout
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.threshold = ERROR
log4j.appender.stdout.Target = System.out
log4j.appender.stdout.layout = org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern = %d{yyyy-MM-dd HH:mm:ss}

log4j.logger.org.springframework = ERROR
log4j.logger.org.hibernate = ERROR
log4j.logger.com.codegym = DEBUG
log4j.logger.org.apache.cxf = ERROR

„Редове 6 и 15 – Ние задаваме наше собствено ниво на филтриране за всеки appender.“

"Редове 20-23 – Указваме името на пакета и нивото на филтриране за неговите съобщения. Log4j.logger е префикс: името на пакета е маркирано в оранжево."

„Наистина? Можете дори това. Е, готино!“

„Между другото, нито log4j, нито slf4j са включени в JDK. Ще трябва да ги изтеглите отделно. Можете да го направите тук . Но има и друг начин:“

" Стъпка 1. Добавете импортирания към класа:"

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

" Стъпка 2. Поставете курсора върху тези редове и натиснете Alt+Enter в IntelliJ IDEA"

" Стъпка 3. Изберете елемента от менюто „Файлов буркан в мрежата“.

" Стъпка 4. Изберете 'slf4j-log4j13.jar'"

" Стъпка 5. Посочете къде да изтеглите библиотеката (jar)"

" Стъпка 6. Използвайте класовете, от които се нуждаете."

„Уау! Какъв ден беше това. Толкова много ново и толкова много страхотно!“

„Ето още една добра статия за регистриране: https://docs.oracle.com/javase/10/core/java-logging-overview.htm#JSCOR-GUID-48004124-2C00-49F7-A640-0C0DDA271DBC

„Добре, това е достатъчно. Отиди да се отпуснеш, програмист.“