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.

log4jHiervoor waren drie dingen :

  • logboekregistratie van subpakketten;
  • set bijlagen (resultaten);
  • hot reload-instellingen.

Ten eerste zouden de instellingen log4jzo 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 log4jmaakte 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, log4jkonden 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, JDKbesloten 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 JULwordt meegeleverd JDK, het slechte nieuws is dat er maar weinig mensen gebruik van maken.

JULI

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 Javavaak 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 JULecht 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> msgSupplierzien 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 JULhad 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.

JCL

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 JCLwas erg slecht en niemand wilde het gebruiken. De logger, ontworpen om alle loggers te vervangen, onderging hetzelfde lot omdat hij JULniet 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 log4jbesloot 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 log4jvan 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 Logbackgeen instellingen en registreert alle logboeken van het niveau DEBUGen hoger. Als u ander gedrag nodig heeft, kan dit via xmlconfiguratie 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 log4jhet 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 and 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

Slf4jondersteunt 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 productionen 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 slf4jwist 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 SLF4Jbegon 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.