System.out.println vs Loggers

1. Varför loggare?

När du skriver ett program eller utvecklar en företagsproduktionsapplikation verkar det vara det enklaste och enklaste alternativet att använda System.out.println . Det finns inga extra bibliotek som ska läggas till i klassvägen och inga ytterligare konfigurationer ska göras.

Men att använda System.out.println har flera nackdelar som påverkar dess användbarhet i många situationer. I den här handledningen kommer vi att diskutera varför och när vi vill använda en Logger över vanlig gammal System.out och System.err . Vi visar också några snabba exempel med Log4J2-loggningsramen.

2. Inställning

Innan vi börjar, låt oss titta på de Maven-beroenden och konfigurationer som krävs.

2.1. Maven Beroenden

Låt oss börja med att lägga till Log4J2-beroendet till vår pom.xml :

 org.apache.logging.log4j log4j-api 2.12.1   org.apache.logging.log4j log4j-core 2.12.1 

Vi hittar de senaste versionerna av log4j-api och log4j-core på Maven Central.

2.2. Log4J2-konfiguration

Användningen av System.out kräver ingen ytterligare konfiguration. För att använda Log4J2 behöver vi dock en log4j.xml- konfigurationsfil:

Nästan alla loggerramar kräver en viss konfigurationsnivå, antingen programmatiskt eller via en extern konfigurationsfil, till exempel XML-filen som visas här.

3. Separera loggutmatning

3.1. System.out och System.err

När vi distribuerar vår applikation till en server som Tomcat använder servern sin egen logger. Om vi ​​använder System.out hamnar loggarna i catalina.out . Det är mycket lättare att felsöka vår applikation om loggar läggs i en separat fil. Med Log4j2 måste vi inkludera en filappender i konfigurationen för att spara applikationsloggar i en separat fil.

Med System.out.println finns det ingen kontroll eller filtrering av vilka loggar som ska skrivas ut. Det enda möjliga sättet att separera loggarna är att använda System.out.println för informationsloggar och System.err.println för felloggar :

System.out.println("This is an informational message"); System.err.println("This is an error message");

3.2. Log4J2 loggningsnivåer

I felsöknings- eller utvecklingsmiljöer vill vi se all information som applikationen skriver ut. Men i en live-företagsapplikation betyder fler loggar en ökning av latens. Logger-ramar som Log4J2 ger flera loggnivåkontroller:

  • DÖDLIG
  • FEL
  • VARNA
  • INFO
  • DEBUG
  • SPÅR
  • ALLT

Med hjälp av dessa nivåer kan vi enkelt filtrera när och var vi ska skriva ut vilken information :

logger.trace("Trace log message"); logger.debug("Debug log message"); logger.info("Info log message"); logger.error("Error log message"); logger.warn("Warn log message"); logger.fatal("Fatal log message");

Vi kan också konfigurera nivåerna för varje källkodspaket individuellt. Mer information om konfiguration av loggnivå finns i vår Java-loggningsartikel.

4. Skriva loggar till filer

4.1. Omdirigera System.out och System.err

Det är möjligt att dirigera System.out.println till en fil med metoden System.setOut () :

PrintStream outStream = new PrintStream(new File("outFile.txt")); System.setOut(outStream); System.out.println("This is a baeldung article");

Och i fallet System.err :

PrintStream errStream = new PrintStream(new File("errFile.txt")); System.setErr(errStream); System.err.println("This is a baeldung article error");

När vi omdirigerar utdata till en fil med System.out eller System.err kan vi inte styra filstorleken , vilket innebär att filen fortsätter att växa under hela programmets körning.

När filstorleken växer kan det vara svårt att öppna eller analysera dessa större loggar.

4.2. Logga in på filer med Log4J2

Log4J2 tillhandahåller en mekanism för att systematiskt skriva loggar i filer och även rulla filerna baserat på vissa policyer. Till exempel kan vi konfigurera filerna som ska rullas ut baserat på ett datum / tidsmönster :

Eller så kan vi rulla filerna baserat på storlek när de når en viss tröskel :

...   %d{yyyy-MM-dd HH:mm:ss} %p %m%n      

5. Logga in på externa system

Som vi har sett i föregående avsnitt tillåter loggerramar att skriva loggarna till en fil. På samma sätt ger de också appenders att skicka loggar till andra system och applikationer . Detta gör det möjligt att skicka loggar till en Kafka Stream eller en Elasticsearch-databas med hjälp av Log4J appenders istället för att använda System.out.println.

Se vår Log4j-appenderartikel för mer information om hur man använder sådana appenders.

6. Anpassa loggutmatning

Med hjälp av Loggers kan vi anpassa vilken information som ska skrivas ut tillsammans med det faktiska meddelandet. Informationen som vi kan skriva ut inkluderar paketnamn, loggnivå, radnummer, tidsstämpel, metodnamn etc.

While this would be possible with System.out.println, it would require a lot of manual work, while logging frameworks provide this functionality out of the box. With loggers, we can simply define a pattern in the logger configuration:

If we consider Log4J2 for our logger framework, there are several patterns that we can choose from or customize. Refer to the official Log4J2 documentation to learn more about them.

7. Conclusion

This article explains various reasons why to use a logger framework and why not to rely only on System.out.println for our application logs. While it is justifiable to use System.out.println for small test programs, we'd prefer not to use it as our main source of logging for an enterprise production application.

As always, the code examples in the article are available over on GitHub.