2.1 Eerste logger - log4j
Zoals u al weet, begon de geschiedenis van logboeken met System.err.println()
de uitvoer van een record naar de console. Het wordt nog steeds actief gebruikt voor foutopsporing, Intellij IDEA gebruikt het bijvoorbeeld om foutmeldingen op de console weer te geven. Maar deze optie heeft geen instellingen, dus laten we verder gaan.
De eerste en meest populaire logger heette Log4j
. Het was een goede en zeer aanpasbare oplossing. Vanwege verschillende omstandigheden is deze beslissing nooit in de JDK terechtgekomen, wat de hele gemeenschap enorm van streek maakte.
Deze logger kon niet alleen loggen, hij werd gemaakt door programmeurs voor programmeurs en stelde hen in staat problemen op te lossen die zich voortdurend voordeden in verband met logging.
Zoals u al weet, worden er uiteindelijk logboeken geschreven, zodat iemand ze leest en probeert te begrijpen wat er gebeurde tijdens de werking van het programma - wat en wanneer er fout ging zoals verwacht.
log4j
Hiervoor waren drie dingen :
- logboekregistratie van subpakketten;
- set bijlagen (resultaten);
- hot reload-instellingen.
Ten eerste zouden de instellingen log4j
zo geschreven kunnen worden dat inloggen in het ene pakket wel en in een ander pakket niet mogelijk is. Het was bijvoorbeeld mogelijk om inloggen in de com.codegym.server
, maar uit te schakelen in com.codegym.server.payment
. Hierdoor was het mogelijk om onnodige informatie snel uit het logboek te verwijderen.
Ten tweede log4j
maakte het het mogelijk om logresultaten naar meerdere logbestanden tegelijk te schrijven. En de uitvoer naar elk kan afzonderlijk worden geconfigureerd. In het ene bestand was het bijvoorbeeld mogelijk om alleen informatie over ernstige fouten te schrijven, in een ander - logs van een specifieke module, en in een derde - logs voor een bepaalde tijd.
Elk logbestand was dus afgestemd op een bepaald type verwacht probleem. Dit vereenvoudigt het leven van programmeurs die er niet van houden om handmatig door gigabyte logbestanden te bladeren.
En tot slot, ten derde, log4j
konden de loginstellingen direct worden gewijzigd terwijl het programma actief was, zonder het opnieuw op te starten. Dit was erg handig wanneer het nodig was om het werk van de logboeken te corrigeren om aanvullende informatie over een specifieke fout te vinden.
Belangrijk! Er zijn twee versies van het logboek log4j
: 1.2.x en 2.xx , die niet compatibel zijn met elkaar .
U kunt de logger aan het project koppelen met behulp van de 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 Eerste officiële logger - JUL: java.util.logging
Nadat de dierentuin van houthakkers in de Java-gemeenschap verscheen, JDK
besloten de ontwikkelaars om één standaard houthakkersmachine te maken die iedereen zou gebruiken. Zo verscheen de logger JUL
: pakket java.util.logging
.
Tijdens de ontwikkeling ervan hebben de makers van de logger echter niet als basis genomen log4j
, maar een variant van de logger van IBM, die de ontwikkeling ervan heeft beïnvloed. Het goede nieuws is dat de logger JUL
wordt meegeleverd JDK
, het slechte nieuws is dat er maar weinig mensen gebruik van maken.

De ontwikkelaars hebben niet alleen "een andere universele standaard"JUL
gemaakt , ze hebben er ook hun eigen loggingniveaus voor gemaakt, die verschilden van die welke destijds door populaire loggers werden geaccepteerd.
En dat was een groot probleem. Producten worden immers Java
vaak uit een groot aantal bibliotheken gehaald en elke bibliotheek had zijn eigen logger. Het was dus nodig om alle loggers in de applicatie te configureren.
Hoewel de logger zelf best goed is. Het maken van een logger is min of meer hetzelfde. Om dit te doen, moet u het volgende importeren:
java.util.logging.Logger log = java.util.logging.Logger.getLogger(LoggingJul.class.getName());
De klassenaam wordt speciaal doorgegeven om te weten waar de logging vandaan komt.
Pas met de release hebben de ontwikkelaars belangrijke problemen opgelost, waarna het JUL
echt handig in gebruik is. Daarvoor was het een soort tweederangs houthakker.
Deze logger ondersteunt ook lambda-expressies en luie evaluatie. Beginnend met Java 8
, kun je slagen Supplier<String>
. Dit helpt om een string alleen te lezen en te creëren op het moment dat het echt nodig is, en niet elke keer, zoals voorheen.
Methoden met een argument Supplier<String> msgSupplier
zien er als volgt uit:
public void info(Supplier msgSupplier) {
log(Level.INFO, msgSupplier);
}
2.3 Eerste loggerverpakking - JCL: jakarta commons logging
Lange tijd was er geen enkele standaard onder houthakkers, het JUL
had er een moeten worden, maar het was erger log4j
, dus er is nooit een enkele standaard verschenen. Maar er verscheen een hele dierentuin van houthakkers, die allemaal hetzelfde wilden worden.

Gewone Java-ontwikkelaars vonden het echter niet leuk dat bijna elke bibliotheek zijn eigen logger heeft en op de een of andere manier op een speciale manier moet worden geconfigureerd. Daarom besloot de gemeenschap om een speciale verpakking over andere houthakkers te maken - dit is hoeJCL: jakarta commons logging
En nogmaals, het project, dat was gemaakt om een leider te zijn, werd er geen. Je kunt geen winnaar creëren, je kunt alleen een winnaar worden. De functionaliteit JCL
was erg slecht en niemand wilde het gebruiken. De logger, ontworpen om alle loggers te vervangen, onderging hetzelfde lot omdat hij JUL
niet werd gebruikt.
Hoewel het is toegevoegd aan veel bibliotheken die zijn uitgegeven door de Apache-gemeenschap, is de dierentuin van houthakkers alleen maar gegroeid.
2.4 Eerste laatste logger - Logback
Maar dat is niet alles. De ontwikkelaar log4j
besloot dat hij de slimste was (nou ja, de meeste mensen gebruikten tenslotte zijn logger) en besloot een nieuwe, verbeterde logger te schrijven die de voordelen log4j
van andere loggers zou combineren.
De nieuwe logger werd gebeld Logback
. Het was deze logger die de toekomstige enkele logger moest worden die iedereen zou gebruiken. Het was gebaseerd op hetzelfde idee als in log4j
.
U kunt deze logger aan het project koppelen met behulp van de code:
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.2.6</version>
</dependency>
De verschillen zaten in Logback
:
- verbeterde prestatie;
- native ondersteuning toegevoegd
slf4j
; - uitgebreide filteroptie.
Een ander voordeel van deze logger was dat hij zeer goede standaardinstellingen had. En je moest de logger alleen configureren als je er iets in wilde veranderen. Ook was het instellingenbestand beter aangepast aan bedrijfssoftware - alle configuraties waren ingesteld als xml/
.
Het vereist standaard Logback
geen instellingen en registreert alle logboeken van het niveau DEBUG
en hoger. Als u ander gedrag nodig heeft, kan dit via xml
configuratie worden geconfigureerd:
<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 Nieuwste universele logger - SLF4J: Simple Logging Facade voor Java
Hoe lang kan het duren om de gulden middenweg te vinden...
In 2006 verliet een van de makers log4j
het project en besloot opnieuw te proberen een universele logger te maken. Maar deze keer was het geen nieuwe logger, maar een nieuwe universele standaard (wrapper) waardoor verschillende loggers met elkaar konden communiceren.
Deze logger heette slf4j — Simple Logging Facade for Java
, het was een wikkel om log4j
, JUL
, common-loggins и logback
. Deze logger loste een echt probleem op: het beheren van een dierentuin van loggers, dus iedereen begon het meteen te gebruiken.
We lossen heldhaftig de problemen op die we voor onszelf creëren. Zoals je kunt zien, heeft de voortgang het punt bereikt dat we een wikkel over de wikkel hebben gemaakt ...
De wrap zelf bestaat uit twee delen:
API
, dat wordt gebruikt in toepassingen;- Implementaties die als afzonderlijke afhankelijkheden voor elke logger worden toegevoegd.
U kunt de logger aan het project koppelen met behulp van de 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>
Het is voldoende om de juiste implementatie aan te sluiten en dat is alles: het hele project zal ermee werken.
2.6 Optimalisatie in slf4j
Slf4j
ondersteunt alle nieuwe functies, zoals tekenreeksopmaak voor logboekregistratie . Voordien was er zo'n probleem. Stel dat u een bericht naar het logboek wilt afdrukken:
log.debug("User " + user + " connected from " + request.getRemoteAddr());
Er is een probleem met deze code. Stel dat uw toepassing doorwerkt production
en niets naar het logboek schrijft DEBUG-messages
, maar de methode log.debug()
wordt nog steeds aangeroepen en wanneer deze wordt aangeroepen, worden ook de volgende methoden aangeroepen:
user.toString();
request.getRemoteAddr();
Het aanroepen van deze methoden vertraagt de toepassing. Hun aanroep is alleen nodig tijdens het debuggen, maar ze worden toch aangeroepen.
Logisch gezien moest dit probleem in de logging-bibliotheek zelf worden opgelost. En in de eerste versie van log4j kwam de oplossing:
if (log.isDebugEnabled()) {
log.debug("User " + user + " connected from " + request.getRemoteAddr());
}
In plaats van één regel voor het logboek, was het nu nodig om er drie te schrijven. Wat de leesbaarheid van de code drastisch verslechterde en de populariteit van log4j
.
De logger slf4j
wist de situatie iets te verbeteren door slim te loggen. Het zag er zo uit:
log.debug("User {} connected from {}", user, request.getRemoteAddr());
waar {}
geeft de invoeging aan van argumenten die in de methode worden doorgegeven. Dat wil zeggen, de eerste {}
komt overeen met gebruiker, de tweede {}
met request.getRemoteAddr()
.
Deze parameters worden alleen samengevoegd tot één bericht als het logboekniveau logboekregistratie toestaat. Niet perfect, maar beter dan alle andere opties.
Daarna SLF4J
begon het snel in populariteit te groeien, op dit moment is dit de beste oplossing.
Daarom zullen we overwegen om te loggen met behulp van het voorbeeld van een bundel slf4j-log4j12
.
GO TO FULL VERSION