2.1 Първи регистратор - log4j

Както вече знаете, историята на регистрационните файлове започва с System.err.println()извеждането на запис към конзолата. Все още се използва активно за отстраняване на грешки, например Intellij IDEA го използва за показване на съобщения за грешка на конзолата. Но тази опция няма ниHowви настройки, така че нека продължим.

Първият и най-популярен дърводобив се наричаше Log4j. Беше добро решение с възможност за персонализиране. Поради различни обстоятелства това решение така и не влезе в JDK, което силно разстрои цялата общност.

Този логер не само можеше да регистрира, той беше създаден от програмисти за програмисти и им позволяваше да решават проблеми, които постоянно възникват във връзка с регистрирането.

Както вече знаете, логовете се записват накрая, така че някой да ги прочете и да се опита да разбере Howво се е случило по време на работата на програмата - Howво и кога се е объркало според очакванията.

Имаше log4jтри неща за това:

  • регистриране на подпакети;
  • набор от добавки (резултати);
  • настройки за горещо презареждане.

Първо, настройките log4jмогат да бъдат написани по такъв начин, че да активират влизането в един пакет и да го деактивират в друг. Например, беше възможно да се активира влизането в com.codegym.server, но да се деактивира в com.codegym.server.payment. Това направи възможно бързото премахване на ненужната информация от дневника.

Второ, log4jтой позволява запис на резултатите от регистриране в няколко регистрационни file наведнъж. И изходът към всеки може да бъде конфигуриран индивидуално. Например в един файл беше възможно да се записва само информация за сериозни грешки, в друг - логове от определен модул, а в трети - логове за определено време.

По този начин всеки лог файл беше настроен за определен тип очакван проблем. Това значително опростява живота на програмистите, които не обичат да преглеждат ръчно гигаbyteови лог файлове.

И накрая, трето, log4jпозволява промяна на настройките на дневника директно, докато програмата работи, без да я рестартира. Това беше много удобно, когато беше необходимо да се коригира работата на регистрационните файлове, за да се намери допълнителна информация за конкретна грешка.

важно! Има две версии на дневника log4j: 1.2.x и 2.xx , които са несъвместими една с друга .

Можете да свържете регистратора към проекта, като използвате codeа:

<dependencies>
  <dependency>
    <groupId>org.apache.logging.log4j</groupId>
    <artifactId>log4j-api</artifactId>
    <version>2.17.2</version>
  </dependency>

  <dependency>
    <groupId>org.apache.logging.log4j</groupId>
    <artifactId>log4j-core</artifactId>
    <version>2.17.2</version>
  </dependency>
</dependencies>

2.2 Първи официален регистратор - JUL: java.util.logging

След като зоологическата градина на регистраторите се появи в Java общността, разработчиците JDKрешиха да направят един standardн регистратор, който всеки да използва. Ето How се появи регистраторът JUL: пакет java.util.logging.

Въпреки това, по време на разработката си, създателите на регистратора взеха за основа не log4j, а вариант на регистратора от IBM, който повлия на неговото развитие. Добрата новина е, че регистраторът JULе включен JDK, лошата новина е, че малко хора го използват.

ЮЛ

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

И това беше голям проблем. В края на краищата продуктите Javaчесто се събират от голям брой библиотеки и всяка такава библиотека има свой собствен регистратор. Така че беше необходимо да се конфигурират всички регистратори, които са в приложението.

Въпреки че самият логер е доста добър. Създаването на логер е горе-долу същото. За да направите това, трябва да импортирате:


java.util.logging.Logger log = java.util.logging.Logger.getLogger(LoggingJul.class.getName());

Името на класа се предава специално, за да се знае откъде идва записването.

Само с пускането разработчиците решиха важни проблеми, след което JULе наистина удобно за използване. Преди това беше няHowъв второкласен дърводобив.

Този регистратор също поддържа ламбда изрази и мързелива оценка. Започвайки с Java 8, можете да преминете Supplier<String>. Това помага да се чете и създава низ само в момента, когато наистина е необходим, а не всеки път, Howто беше преди.

Методите с аргумент Supplier<String> msgSupplierизглеждат така:

public void info(Supplier msgSupplier) {
   log(Level.INFO, msgSupplier);
}

2.3 Първа обвивка на регистратор - JCL: регистриране на общините на Джакарта

Дълго време нямаше единен стандарт сред дървосекачите, JULтрябваше да стане такъв, но беше по-лошо log4j, така че единен стандарт никога не се появи. Но се появи цял зоопарк от дървосекачи, всеки от които искаше да стане същият.

JCL

Обикновените разработчици на Java обаче не харесаха, че почти всяка библиотека има свой собствен регистратор и трябва да бъде конфигуриран по няHowъв специален начин. Затова общността реши да създаде специална обвивка над другите регистратори - ето HowJCL: jakarta commons logging

И отново проектът, който беше създаден да бъде лидер, не стана такъв. Не можете да създадете победител, можете само да станете победител. Функционалността JCLбеше много слаба и никой не искаше да я използва. Логерът, предназначен да замени всички регистратори, срещна същата съдба, тъй като JULне беше използван.

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

2.4 Първи последен регистратор - Регистриране

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

Новият регистратор беше извикан Logback. Именно този регистратор трябваше да стане бъдещият единичен регистратор, който всеки ще използва. Тя се основава на същата идея като в log4j.

Можете да свържете този регистратор към проекта, като използвате codeа:

<dependency>
    <groupId>ch.qos.logback</groupId>
    <artifactId>logback-classic</artifactId>
    <version>1.2.6</version>
</dependency>

Разликите бяха в Logback:

  • подобрена производителност;
  • добавена нативна поддръжка slf4j;
  • разширена опция за филтриране.

Друго предимство на този регистратор беше, че имаше много добри настройки по подразбиране. И трябваше да конфигурирате регистратора само ако искате да промените нещо в тях. Освен това файлът с настройки беше по-добре адаптиран към корпоративния софтуер - всички негови конфигурации бяха зададени като xml/.

По подразбиране Logbackне изисква ниHowви настройки и записва всички регистрационни файлове от ниво DEBUGи по-високо. Ако имате нужда от различно поведение, то може да бъде конфигурирано чрез xmlконфигурация:

<configuration>
    <appender name="FILE" class="ch.qos.logback.core.FileAppender">
        <file>app.log</file>
        <encoder>
            <pattern>%d{HH:mm:ss,SSS} %-5p [%c] - %m%n</pattern>
        </encoder>
    </appender>
    <logger name="org.hibernate.SQL" level="DEBUG" />
    <logger name="org.hibernate.type.descriptor.sql" level="TRACE" />
    <root level="info">
        <appender-ref ref="FILE" />
    </root>
</configuration>

2.5 Най-новият универсален регистратор - SLF4J: Проста фасада за регистриране за Java

Колко време може да отнеме да намерим златната среда...

През 2006 г. един от създателите log4jнапусна проекта и реши да опита отново да създаде универсален регистратор. Но този път не беше нов регистратор, а нов универсален стандарт (обвивка), който позволява на различни регистратори да взаимодействат заедно.

Този регистратор се наричаше slf4j — Simple Logging Facade for Java, беше обвивка около log4j, JUL, common-loggins and logback. Този дървосекач реши истински проблем - управлението на зоопарк от дървосекачи, така че всички веднага започнаха да го използват.

Ние героично решаваме проблемите, които сами си създаваме. Както можете да видите, напредъкът достигна точката, че създадохме обвивка върху обвивката ...

Самата обвивка се състои от две части:

  • API, който се използва в applications;
  • Реализации, които се добавят като отделни зависимости за всеки регистратор.

Можете да свържете регистратора към проекта, като използвате codeа:

<dependency>
    <groupId>org.apache.logging.log4j</groupId>
    <artifactId>log4j-api</artifactId>
    <version>2.17.2</version>
</dependency>
<dependency>
    <groupId>org.apache.logging.log4j</groupId>
    <artifactId>log4j-core</artifactId>
    <version>2.17.2</version>
</dependency>
<dependency>
    <groupId>org.apache.logging.log4j</groupId>
    <artifactId>log4j-slf4j-impl</artifactId>
    <version>2.17.2</version>
</dependency>

Достатъчно е да свържете правилното изпълнение и това е всичко: целият проект ще работи с него.

2.6 Оптимизация в slf4j

Slf4jподдържа всички нови функции като форматиране на низове за регистриране . Преди това имаше такъв проблем. Да приемем, че искате да отпечатате съобщение в дневника:

log.debug("User " + user + " connected from " + request.getRemoteAddr());

Има проблем с този code. Да предположим, че приложението ви работи productionи не записва нищо в журнала DEBUG-messages, но методът log.debug()все още ще бъде извикан и когато бъде извикан, ще бъдат извикани и следните методи:

  • user.toString();
  • request.getRemoteAddr();

Извикването на тези методи забавя приложението. Тяхното извикване е необходимо само по време на отстраняване на грешки, но те се извикват така or иначе.

От гледна точка на логиката, този проблем трябваше да бъде решен в самата библиотека за регистриране. И в първата version на log4j се появи решението:

if (log.isDebugEnabled()) {
    log.debug("User " + user + " connected from " + request.getRemoteAddr());
}

Вместо един ред за дневника, сега беше необходимо да се напишат три. Което драстично влоши четливостта на codeа и намали популярността на log4j.

Логерът slf4jуспя леко да подобри ситуацията, като предложи интелигентно регистриране. Изглеждаше така:

log.debug("User {} connected from {}", user, request.getRemoteAddr());

където {}обозначават вмъкването на аргументи, които се предават в метода. Тоест първият {}съответства на user, вторият {}на request.getRemoteAddr().

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

След това SLF4Jзапочна да расте бързо в популярност, в момента това е най-доброто решение.

Затова ще разгледаме регистрирането, използвайки примера на пакет slf4j-log4j12.