2.1 Első logger - log4j
Mint már tudja, a naplók története System.err.println()
a rekord kimenetével kezdődött a konzolon. Még mindig aktívan használják hibakeresésre, például az Intellij IDEA használja a hibaüzenetek megjelenítésére a konzolon. Ennek az opciónak azonban nincsenek beállításai, úgyhogy menjünk tovább.
Az első és legnépszerűbb favágó a neve Log4j
. Jó és nagyon testreszabható megoldás volt. Különböző körülmények miatt ez a döntés soha nem került be a JDK-ba, ami nagyon felzaklatta az egész közösséget.
Ez a naplózó nem csak naplózni tudott, hanem programozók hozták létre a programozók számára, és lehetővé tette a naplózással kapcsolatban folyamatosan felmerülő problémák megoldását.
Mint már tudod, a naplók a végén úgy készülnek, hogy valaki elolvassa őket, és megpróbálja megérteni, mi történt a program működése során – mi és mikor hibásodott meg a várakozásoknak megfelelően.
log4j
Ehhez három dolog volt :
- alcsomag naplózása;
- mellékletek halmaza (eredmények);
- hot reload beállítások.
Először is, a beállításokat log4j
úgy lehet megírni, hogy az egyik csomagban engedélyezzék a bejelentkezést, a másikban pedig letiltsák azt. Például engedélyezni lehetett a bejelentkezést com.codegym.server
, de letiltani a -ban com.codegym.server.payment
. Ez lehetővé tette a szükségtelen információk gyors eltávolítását a naplóból.
Másodszor, log4j
lehetővé tette a naplózási eredmények írását több naplófájlba egyszerre. És mindegyik kimenete külön-külön konfigurálható. Például az egyik fájlban csak a súlyos hibákról szóló információkat lehetett írni, a másikban - egy adott modul naplóit, a harmadikban - egy bizonyos ideig.
Így minden naplófájl egy adott típusú várt probléma szerint lett hangolva. Ez nagyban leegyszerűsíti azoknak a programozóknak az életét, akik nem szeretik a gigabájtos naplófájlokat manuálisan átnézni.
És végül, harmadszor, log4j
lehetővé tette a naplóbeállítások közvetlen módosítását a program futása közben, újraindítás nélkül. Ez nagyon hasznos volt, amikor ki kellett javítani a naplók munkáját, hogy további információkat találjanak egy adott hibáról.
Fontos! A naplónak két változata létezik log4j
: az 1.2.x és a 2.xx , amelyek nem kompatibilisek egymással .
A loggert a következő kóddal kapcsolhatja a projekthez:
<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 Első hivatalos naplózó – JUL: java.util.logging
Miután a naplózók állatkertje megjelent a Java közösségben, a fejlesztők JDK
úgy döntöttek, hogy készítenek egy szabványos loggert, amelyet mindenki használni fog. Így jelent meg a logger JUL
: csomag java.util.logging
.
log4j
A naplózó készítői azonban a fejlesztés során nem , hanem az IBM logger egy változatát vették alapul , ami befolyásolta a fejlesztését. A jó hír az, hogy a logger is JUL
benne van JDK
, a rossz hír az, hogy kevesen használják.
A fejlesztők nemcsak „egy másik univerzális szabványt”JUL
készítettek , hanem saját naplózási szinteket is készítettek hozzá, amelyek eltértek az akkori népszerű favágók által elfogadottaktól.
És ez nagy probléma volt. Hiszen a termékeket Java
gyakran nagyszámú könyvtárból gyűjtik össze, és minden ilyen könyvtárnak saját naplózója volt. Ezért be kellett állítani az összes naplózót, amely az alkalmazásban található.
Bár maga a logger egész jó. A logger létrehozása többé-kevésbé ugyanaz. Ehhez importálnia kell:
java.util.logging.Logger log = java.util.logging.Logger.getLogger(LoggingJul.class.getName());
Az osztálynév speciálisan azért van átadva, hogy megtudja, honnan származik a naplózás.
Csak a kiadással oldották meg a fejlesztők a fontos problémákat, amelyek után JUL
valóban kényelmes a használata. Előtte valami másodrangú favágó volt.
Ez a naplózó támogatja a lambda kifejezéseket és a lusta kiértékelést is. Kezdve Java 8
, átadhatod Supplier<String>
. Ez segít abban, hogy egy karakterláncot csak akkor olvasson és hozzon létre, amikor valóban szükség van rá, és nem minden alkalommal, mint korábban.
Az argumentumot tartalmazó módszerek Supplier<String> msgSupplier
így néznek ki:
public void info(Supplier msgSupplier) {
log(Level.INFO, msgSupplier);
}
2.3 Első naplózó wrapper - JCL: Jakarta commons naplózás
Sokáig nem volt egységes szabvány a fakitermelők között, azzá JUL
kellett volna válnia, de ez rosszabb volt log4j
, így egyetlen szabvány sem jelent meg. De megjelent egy egész állatkert favágó, amelyek mindegyike azonos akar lenni.
A hétköznapi Java fejlesztőknek azonban nem tetszett, hogy szinte minden könyvtárnak saját naplózója van, és valahogy különleges módon kell konfigurálni. Ezért a közösség úgy döntött, hogy létrehoz egy speciális burkolóanyagot a többi favágó fölé – ez így vanJCL: jakarta commons logging
És ismét a projekt, amelyet vezetőnek hoztak létre, nem lett az. Nem lehet győztest teremteni, csak győztes lehetsz. A funkcionalitás JCL
nagyon gyenge volt, és senki sem akarta használni. Az összes fakitermelőt helyettesítő fakitermelő ugyanarra a sorsra jutott, mivel JUL
nem használták.
Bár számos, az Apache közösség által kiadott könyvtárhoz hozzáadták, a favágók állatkertje csak nőtt.
2.4 Első utolsó naplózó - Visszajelentkezés
De ez még nem minden. A fejlesztő log4j
úgy döntött, hogy ő a legokosabb (elvégre a legtöbben az ő naplózóját használták), és úgy döntött, ír egy új, továbbfejlesztett naplózót, amely egyesíti log4j
más naplózók előnyeit.
Az új favágót Logback
. Ennek a naplózónak kellett volna a jövőbeni egyetlen naplózóvá válnia, amelyet mindenki használni fog. Ugyanaz az ötlet volt, mint a log4j
.
Ezt a naplózót a következő kóddal kapcsolhatja a projekthez:
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.2.6</version>
</dependency>
A különbségek a következők voltak Logback
:
- jobb teljesítmény;
- hozzáadott natív támogatás
slf4j
; - kiterjesztett szűrési lehetőség.
A logger másik előnye az volt, hogy nagyon jó alapértelmezett beállításokkal rendelkezik. A naplózót pedig csak akkor kellett beállítani, ha valamit változtatni akart bennük. Ezenkívül a beállítási fájl jobban igazodott a vállalati szoftverekhez - minden konfigurációja a következőre volt beállítva xml/
.
Alapértelmezés szerint Logback
nem igényel semmilyen beállítást, és rögzíti az összes naplót a szinttől DEBUG
és magasabb szinttől. Ha más viselkedésre van szüksége, a konfiguráción keresztül konfigurálható 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 A legújabb univerzális naplózó - SLF4J: Egyszerű naplózási homlokzat Java számára
Mennyi idő alatt lehet megtalálni az arany középutat...
2006-ban az egyik alkotó log4j
kilépett a projektből, és úgy döntött, hogy újra megpróbálja létrehozni egy univerzális naplózót. De ezúttal nem egy új naplózó volt, hanem egy új univerzális szabvány (wrapper), amely lehetővé tette a különböző naplózók együttműködését.
Ezt a favágót úgy hívták slf4j — Simple Logging Facade for Java
, hogy egy burkoló volt log4j
, JUL
, common-loggins and logback
. Ez a favágó egy valós problémát oldott meg - egy favágó állatkert irányítása, így mindenki azonnal használni kezdte.
Hősiesen oldjuk meg a magunknak teremtett problémákat. Amint látja, a fejlődés elérte azt a pontot, hogy létrehoztunk egy burkolatot a burkolólap felett...
Maga a borítás két részből áll:
API
, amelyet alkalmazásokban használnak;- Az egyes naplózókhoz külön függőségekként hozzáadott megvalósítások.
A loggert a következő kóddal kapcsolhatja a projekthez:
<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>
Elég a megfelelő megvalósítást összekapcsolni, és kész: az egész projekt működni fog vele.
2.6 Optimalizálás az slf4j-ben
Slf4j
támogatja az összes új funkciót, például a karakterlánc formázását a naplózáshoz . Előtte volt egy ilyen probléma. Tegyük fel, hogy üzenetet szeretne nyomtatni a naplóba:
log.debug("User " + user + " connected from " + request.getRemoteAddr());
Probléma van ezzel a kóddal. Tegyük fel, hogy az alkalmazás működik production
, és nem ír semmit a naplóba DEBUG-messages
, azonban a metódus log.debug()
továbbra is meghívásra kerül, és amikor meghívják, a következő metódusok is meghívásra kerülnek:
user.toString();
request.getRemoteAddr();
E módszerek meghívása lelassítja az alkalmazást. A hívásukra csak hibakereséskor van szükség, de mindenképp hívják őket.
Logikai szempontból ezt a problémát magában a naplózó könyvtárban kellett megoldani. És a log4j első verziójában megjelent a megoldás:
if (log.isDebugEnabled()) {
log.debug("User " + user + " connected from " + request.getRemoteAddr());
}
A naplónak egy sor helyett most hármat kellett írni. Ez drámaian rontotta a kód olvashatóságát, és csökkentette a népszerűségét log4j
.
A favágó slf4j
némileg javítani tudott a helyzeten azáltal, hogy intelligens naplózást kínált. Így nézett ki:
log.debug("User {} connected from {}", user, request.getRemoteAddr());
ahol {}
a metódusban átadott argumentumok beszúrását jelöli. Vagyis az első a {}
felhasználónak, a második a {}
felhasználónak felel meg request.getRemoteAddr()
.
Ezek a paraméterek csak akkor kerülnek egyetlen üzenetbe, ha a naplózási szint lehetővé teszi a naplózást. Nem tökéletes, de jobb, mint az összes többi lehetőség.
Ezt követően SLF4J
gyorsan növekedni kezdett a népszerűsége, jelenleg ez a legjobb megoldás.
Ezért fontolóra vesszük a naplózást egy köteg példáján keresztül slf4j-log4j12
.