Accesso a Spring Boot

1. Panoramica

In questo breve tutorial, esploreremo le principali opzioni di registrazione disponibili in Spring Boot.

Informazioni più approfondite su Logback sono disponibili in A Guide to Logback, mentre Log4j2 è introdotto in Intro to Log4j2 - Appenders, Layouts and Filters.

2. Configurazione iniziale

Creiamo prima un modulo Spring Boot. Il modo consigliato per farlo è usare Spring Initializr, che trattiamo nel nostro Tutorial Spring Boot.

Ora creiamo il nostro unico file di classe, LoggingController :

@RestController public class LoggingController { Logger logger = LoggerFactory.getLogger(LoggingController.class); @RequestMapping("/") public String index() { logger.trace("A TRACE Message"); logger.debug("A DEBUG Message"); logger.info("An INFO Message"); logger.warn("A WARN Message"); logger.error("An ERROR Message"); return "Howdy! Check out the Logs to see the output..."; } } 

Una volta caricata l'applicazione web, saremo in grado di attivare quelle linee di registrazione semplicemente visitando // localhost: 8080 / .

3. Registrazione configurazione zero

Spring Boot è un framework molto utile. Ci permette di dimenticare la maggior parte delle impostazioni di configurazione, molte delle quali si auto-sintonizza presuntamente.

Nel caso della registrazione, l'unica dipendenza obbligatoria è Apache Commons Logging.

Dobbiamo importarlo solo quando si utilizza Spring 4.x (Spring Boot 1.x) poiché è fornito dal modulo spring-jcl di Spring Framework in Spring 5 (Spring Boot 2.x).

Non dovremmo preoccuparci di importare spring-jcl se stiamo usando Spring Boot Starter (che quasi sempre lo siamo). Questo perché ogni starter, come il nostro spring-boot-starter-web , dipende dalla registrazione di spring-boot-starter, che già tira in spring-jcl per noi.

3.1. Logback predefinito

Quando si utilizzano gli avviatori, Logback viene utilizzato per la registrazione per impostazione predefinita.

Spring Boot lo preconfigura con modelli e colori ANSI per rendere l'output standard più leggibile.

Eseguiamo ora l'applicazione e visitiamo la pagina // localhost: 8080 / e vediamo cosa succede nella console:

Come possiamo vedere, il livello di registrazione predefinito del Logger è preimpostato su INFO, il che significa che i messaggi TRACE e DEBUG non sono visibili.

Per attivarli senza modificare la configurazione, possiamo passare gli argomenti –debug o –trace sulla riga di comando :

java -jar target/spring-boot-logging-0.0.1-SNAPSHOT.jar --trace 

3.2. Livelli di registro

Spring Boot ci dà anche accesso a un'impostazione del livello di registro più dettagliata tramite variabili di ambiente. Ci sono diversi modi in cui possiamo farlo.

Innanzitutto, possiamo impostare il nostro livello di registrazione nelle nostre Opzioni VM:

-Dlogging.level.org.springframework=TRACE -Dlogging.level.com.baeldung=TRACE

In alternativa, se stiamo usando Maven, possiamo definire le nostre impostazioni di log tramite la riga di comando :

mvn spring-boot:run -Dspring-boot.run.arguments=--logging.level.org.springframework=TRACE,--logging.level.com.baeldung=TRACE

Quando si lavora con Gradle, possiamo passare le impostazioni del registro tramite la riga di comando. Ciò richiederà l'impostazione dell'attività bootRun .

Fatto ciò, eseguiamo l'applicazione:

./gradlew bootRun -Pargs=--logging.level.org.springframework=TRACE,--logging.level.com.baeldung=TRACE

Se vogliamo modificare il livello di dettaglio in modo permanente, possiamo farlo nel file application.properties come descritto qui:

logging.level.root=WARN logging.level.com.baeldung=TRACE 

Infine, possiamo modificare il livello di registrazione in modo permanente utilizzando il nostro file di configurazione del framework di registrazione.

Abbiamo detto che Spring Boot Starter utilizza Logback per impostazione predefinita. Vediamo come definire un frammento di un file di configurazione Logback in cui impostiamo il livello per due pacchetti separati:

Ricorda che se il livello di log per un pacchetto viene definito più volte utilizzando le diverse opzioni sopra menzionate, ma con livelli di log differenti, verrà utilizzato il livello più basso.

Quindi, se impostiamo i livelli di registrazione utilizzando Logback, Spring Boot e le variabili di ambiente contemporaneamente, il livello di registrazione sarà TRACE , poiché è il più basso tra i livelli richiesti.

4. Logback Configuration Logging

Anche se la configurazione predefinita è utile (ad esempio, per iniziare in tempo zero durante POC o esperimenti rapidi), molto probabilmente non è sufficiente per le nostre esigenze quotidiane.

Vediamo come includere una configurazione Logback con un colore e un modello di registrazione diversi, con specifiche separate per console e output di file e con una politica di rotazione decente per evitare di generare file di log enormi.

Innanzitutto, dovremmo trovare una soluzione che consenta di gestire le nostre impostazioni di registrazione da sole invece di inquinare application.properties, che è comunemente usato per molte altre impostazioni dell'applicazione.

Quando un file nel classpath ha uno dei seguenti nomi, Spring Boot lo caricherà automaticamente sulla configurazione predefinita:

  • logback-spring.xml
  • logback.xml
  • logback-spring.groovy
  • logback.groovy

Spring recommends using the -spring variant over the plain ones whenever possible, as described here.

Let's write a simple logback-spring.xml:

      %black(%d{ISO8601}) %highlight(%-5level) [%blue(%t)] %yellow(%C{1.}): %msg%n%throwable     ${LOGS}/spring-boot-logger.log  %d %p %C{1.} [%t] %m%n    ${LOGS}/archived/spring-boot-logger-%d{yyyy-MM-dd}.%i.log   10MB               

And when we run the application, here's the output:

As we can see, it now logs TRACE and DEBUG messages, and the overall console pattern is both textually and chromatically different than before.

It also now logs on a file in a /logs folder created under the current path and archives it through a rolling policy.

5. Log4j2 Configuration Logging

While Apache Commons Logging is at the core, and Logback is the reference implementation provided, all the routings to the other logging libraries are already included to make it easy to switch to them.

In order to use any logging library other than Logback, though, we need to exclude it from our dependencies.

For every starter like this one (it's the only one in our example, but we could have many of them):

 org.springframework.boot spring-boot-starter-web  

we need to turn it into a skinny version, and (only once) add our alternative library, here through a starter itself:

 org.springframework.boot spring-boot-starter-web   org.springframework.boot spring-boot-starter-logging     org.springframework.boot spring-boot-starter-log4j2  

At this point, we need to place in the classpath a file named one of the following:

  • log4j2-spring.xml
  • log4j2.xml

We'll print through Log4j2 (over SLF4J) without further modifications.

Let's write a simple log4j2-spring.xml:

        %d %p %C{1.} [%t] %m%n                    

And when we run the application, here's the output:

As we can see, the output is quite different from the Logback one — a proof that we're fully using Log4j2 now.

In addition to the XML configuration, Log4j2 allows us to use also a YAML or JSON configuration, described here.

6. Log4j2 Without SLF4J

We can also use Log4j2 natively, without passing through SLF4J.

In order to do that, we simply use the native classes:

import org.apache.logging.log4j.Logger; import org.apache.logging.log4j.LogManager; // [...] Logger logger = LogManager.getLogger(LoggingController.class); 

We don't need to perform any other modification to the standard Log4j2 Spring Boot configuration.

We can now exploit the brand-new features of Log4j2 without getting stuck with the old SLF4J interface. But we're also tied to this implementation, and we'll need to rewrite our code when switching to another logging framework.

7. Logging With Lombok

In the examples we've seen so far, we've had to declare an instance of a logger from our logging framework.

This boilerplate code can be annoying. We can avoid it using various annotations introduced by Lombok.

We'll first need to add the Lombok dependency in our build script to work with it:

 org.projectlombok lombok 1.18.4 provided 

7.1. @Slf4j and @CommonsLog

SLF4J and Apache Commons Logging APIs allow us the flexibility to change our logging framework with no impact on our code.

And we can use Lombok's @Slf4j and @CommonsLog annotations to add the right logger instance into our class: org.slf4j.Logger for SLF4J and org.apache.commons.logging.Log for Apache Commons Logging.

To see these annotations in action, let's create a class similar to LoggingController but without a logger instance. We name it as LombokLoggingController and annotate it with @Slf4j:

@RestController @Slf4j public class LombokLoggingController { @RequestMapping("/lombok") public String index() { log.trace("A TRACE Message"); log.debug("A DEBUG Message"); log.info("An INFO Message"); log.warn("A WARN Message"); log.error("An ERROR Message"); return "Howdy! Check out the Logs to see the output..."; } }

Note that we've adjusted the snippet just a bit, using log as our logger instance. This is because adding the annotation @Slf4j automatically adds a field named log.

With Zero-Configuration Logging, the application will use underlying logging implementation Logback for logging. Similarly, Log4j2 implementation is used for logging with Log4j2-Configuration Logging.

We get the same behavior when we replace the annotation @Slf4j with @CommonsLog.

7.2. @Log4j2

We can use the annotation @Log4j2 to use Log4j2 directly. So, we make a simple change to LombokLoggingController to use @Log4j2 instead of @Slf4j or @CommonsLog:

@RestController @Log4j2 public class LombokLoggingController { @RequestMapping("/lombok") public String index() { log.trace("A TRACE Message"); log.debug("A DEBUG Message"); log.info("An INFO Message"); log.warn("A WARN Message"); log.error("An ERROR Message"); return "Howdy! Check out the Logs to see the output..."; } } 

Other than logging, there are other annotations from Lombok that help in keeping our code clean and tidy. More information about them is available in Introduction to Project Lombok, and we also have a tutorial on Setting Up Lombok With Eclipse and IntelliJ.

8. Beware of Java Util Logging

Spring Boot also supports JDK logging, through the logging.properties configuration file.

There are cases when it's not a good idea to use it, though. From the documentation:

There are known classloading issues with Java Util Logging that cause problems when running from an ‘executable jar'. We recommend that you avoid it when running from an ‘executable jar' if at all possible.

It's also a good practice when using Spring 4 to manually exclude commons-logging in pom.xml, to avoid potential clashes between the logging libraries. Spring 5 instead handles it automatically, so we don't need to do anything when using Spring Boot 2.

9. JANSI on Windows

While Unix-based operating systems such as Linux and Mac OS X support ANSI color codes by default, on a Windows console, everything will be sadly monochromatic.

Windows can obtain ANSI colors through a library called JANSI.

We should pay attention to the possible class loading drawbacks, though.

We must import and explicitly activate it in the configuration as follows:

Logback:

  true  [%thread] %highlight(%-5level) %cyan(%logger{15}) - %msg %n     

Log4j2:

ANSI escape sequences are supported natively on many platforms but are not by default on Windows. To enable ANSI support, add the Jansi jar to our application and set property log4j.skipJansi to false. This allows Log4j to use Jansi to add ANSI escape codes when writing to the console.

Note: Prior to Log4j 2.10, Jansi was enabled by default. The fact that Jansi requires native code means that Jansi can only be loaded by a single class loader. For web applications, this means the Jansi jar has to be in the web container's classpath. To avoid causing problems for web applications, Log4j no longer automatically tries to load Jansi without explicit configuration from Log4j 2.10 onward.

It's also worth noting:

  • The layout documentation page contains useful Log4j2 JANSI informations in the highlight{pattern}{style} section.
  • While JANSI can color the output, Spring Boot's Banner (native or customized through the banner.txt file) will stay monochromatic.

10. Conclusion

Abbiamo visto i modi principali per interfacciarsi con i principali framework di registrazione all'interno di un progetto Spring Boot.

Abbiamo anche esplorato i principali vantaggi e le insidie ​​di ciascuna soluzione.

Come sempre, il codice sorgente completo è disponibile su GitHub.