Spring Boot logging

Logging is an important part of all applications and benefits not only us, the developers, but also the users and maintainers of the system. Spring Boot applications should collect relevant log data to help us diagnose and fix problems and measure business performance.

The Spring Boot framework is preconfigured with Logback as the default implementation in its "competent" approach to the Spring Framework. This article explores various ways to configure logging in Spring Boot.

 Sample code

This article is accompanied by a sample working code  on GitHub  .

Why journaling is important

Decisions about what and where to log are often strategic and are made with the assumption that an application might not function correctly in real-world environments. Logs play a key role in helping the application quickly recover from any such crashes and resume normal operation.

Making mistakes at integration points visible

The distributed nature of today's applications built using a microservice architecture introduces many work pieces. Thus, naturally, you can run into problems due to temporary failures in any of the infrastructure systems.

Exception logs recorded at integration points allow us to identify the root cause of an interruption and allow us to take appropriate action to recover with minimal impact on the end-user experience.

Diagnosis of functional errors in the production system

There may be customer complaints about the wrong transaction amount. To diagnose this, we need to drill down into our logs to find the sequence of operations from the request data when the API is called to the response data at the end of the processing API.

Event history analysis

.  , .

, , , .

, , , , .  CI / CD.

Spring Boot

Spring Boot - Logback .

, Spring Boot.  -,  start.spring.io .  :

@SpringBootApplication
public class SpringLoggerApplication {
    static final Logger log = 
        LoggerFactory.getLogger(SpringLoggerApplication.class);
  
    public static void main(String[] args) {
     log.info("Before Starting application");
     SpringApplication.run(SpringLoggerApplication.class, args);
     log.debug("Starting my application in debug with {} args", args.length);
     log.info("Starting my application with {} args.", args.length);  
    }
  }

Maven Gradle jar , :

13:21:45.673 [main] INFO io.pratik.springLogger.SpringLoggerApplication - Before Starting application

  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::        (v2.3.2.RELEASE)
.
.
.
... : Started SpringLoggerApplication in 3.054 seconds (JVM running for 3.726)
... : Starting my application 0

, Spring, .  .

Spring Boot     .

 application.propertiesapplication.yml), .

.  .

java -jar target/springLogger-0.0.1-SNAPSHOT.jar --trace

, , , .

, , Spring.  ,  log.level.<package-name>:

java \\
  -jar target/springLogger-0.0.1-SNAPSHOT.jar \\
  -Dlogging.level.org.springframework=ERROR \\
  -Dlogging.level.io.pratik=TRACE

 application.properties:

logging.level.org.springframework=ERROR 
logging.level.io.app=TRACE

,  logging.file.name logging.file.path  application.properties.  info.

# Output to a file named application.log. 
logging.file.name=application.log
# Output to a file named spring.log in path /Users
logging.file.path=/Users

,  logging.file.name .

, Spring 2.2 , .  2.3.2.RELEASE.

,  logging.pattern.file:

# Logging pattern for file
logging.pattern.file= %d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %msg%

, :

,

logging.file.max-size

10 Mb

logging.file.max-history

7

logging.file.total-size-cap

.  , .

logging.file.clean-history-on-start

, .

Spring .  , off  application.properties:

spring.main.banner-mode=off 

ANSI,  spring.output.ansi.enabled.  : , .

spring.output.ansi.enabled=ALWAYS

    spring.output.ansi.enabled DETECT.  , ANSI.

Logback  Spring Boot .  log4j java util, spring-boot-starter-loging  pom.xml:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
    <exclusions>
        <exclusion>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-logging</artifactId>
        </exclusion>
    </exclusions>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-log4j2</artifactId>
</dependency>

 logback-spring.xml

,  logback.xml logback-spring.xml XML . Spring  logback-spring.xmllogback-spring.groovy .

 appender  configuration.   encoder:

<configuration >
  <include
    resource="/org/springframework/boot/logging/logback/base.xml" />
  <appender name="STDOUT"
    class="ch.qos.logback.core.ConsoleAppender">
    <encoder>
      <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n
      </pattern>
    </encoder>
  </appender>
</configuration>

Logback

 debug  configuration  true, .

<configuration debug="true">

, Logback, :

...- About to instantiate appender of type [...ConsoleAppender]
...- About to instantiate appender of type [...RollingFileAppender]
..SizeAndTimeBasedRollingPolicy.. - setting totalSizeCap to 0 Bytes
..SizeAndTimeBasedRollingPolicy.. - ..limited to [10 MB] each.
..SizeAndTimeBasedRollingPolicy.. Will use gz compression
..SizeAndTimeBasedRollingPolicy..use the pattern /var/folders/
..RootLoggerAction - Setting level of ROOT logger to INFO

, , .

,  logback-spring.xml. ,   ​​   .

.  Spring Boot , .  , Logstash:

  <appender name="LOGSTASH"
    class="net.logstash.logback.appender.LogstashTcpSocketAppender">
    <destination>localhost:4560</destination>
    <encoder charset="UTF-8"
      class="net.logstash.logback.encoder.LogstashEncoder" />
  </appender>

 LogstashEncoder JSON  localhost:4560.  .

.  Spring - .        .

Lombok

, : Lombok, Slf4j :

@Service
@Slf4j
public class UserService {
  public String getUser(final String userID) {
    log.info("Service: Fetching user with id {}", userID);
  }
}

In this article, we have seen how to use logging in Spring Boot and how to configure it according to our requirements. But to take full advantage of the benefits, the framework's logging capabilities need to be complemented by robust and standardized logging practices across your development teams.

These techniques will also need to be implemented through a combination of peer review and automated code quality control tools. Taken together, this ensures that when production errors occur, we have as much information as possible to diagnose.

You can find all the source code used in the article on  Github  .




All Articles