An overview of the

In Java applications, logs fall into the following five levels:

  • ERROR ERROR information
  • WARN Warning Information
  • INFO General information
  • DEBUG Debugging information
  • TRACE TRACE information

Spring Boot uses Apache Commons Logging as the internal Logging framework, which is only a Logging interface. In practical applications, the corresponding Logging implementation needs to be specified for this interface.

The default Logging implementation of SpringBt is Java Util Logging, which comes with the JDK. SpringBt also supports popular Logging implementations such as Log4J and Logback.

These logging implementations are collectively referred to as logging frameworks

Let’s put it into practice!

Note: This article was published on My public account CodeSheep. You can subscribe by holding down or scanning the heart below ↓ ↓ ↓


Use the Spring Boot Logging plug-in

  • First add a configuration to the application.properties file:
logging.level.root=INFO
Copy the code
  • Part of the controller code is as follows:
package com.hansonwang99.controller;

import com.hansonwang99.K8sresctrlApplication;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/testlogging")
public class LoggingTestController {
    private static Logger logger = LoggerFactory.getLogger(K8sresctrlApplication.class);
    @GetMapping("/hello")
    public String hello() {
        logger.info("test logging...");
        return "hello"; }}Copy the code
  • The results

Because the log level is set to INFO, logs of INFO and higher levels are displayed

As you can see, most of the INFO logs come from the SpringBt framework itself. If we want to mask them, we can set the log level to ERROR so that the framework’s INFO will not be printed. You can then set specific packages in your application to DEBUG level logs so that you can only see DEBUG and above logs in the packages you are interested in.

  • Controls the logging level of a particular package

Change the configuration in application.yml

logging:
  level:
    root: error
    com.hansonwang99.controller: debug
Copy the code

It is clear that the root log level is set to ERROR, and then he will com. Hansonwang99. Controller packages of the log level to DEBUG, for this is: the first banned all again allows individual to set method

  • Controller code
package com.hansonwang99.controller;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/testlogging")
public class LoggingTestController {
    private Logger logger = LoggerFactory.getLogger(this.getClass());
    @GetMapping("/hello")
    public String hello() {
        logger.info("test logging...");
        return "hello"; }}Copy the code
  • The results

You can see that the framework’s own info-level logs are all hidden, while the logs in the specified package print out smoothly by level

  • Output logs to a file
logging:
  level:
    root: error
    com.hansonwang99.controller: debug
  file: ${user.home}/logs/hello.log
Copy the code
  • The results

Using Spring Boot Logging, we found that although the log was exported to a file, a copy was still printed in the console. Org.slf4j.logger was not able to solve this problem


Integrate Log4J logging framework

  • Add dependencies to 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>
Copy the code
  • Add it in the Resources directorylog4j2.xmlFile, as follows:
<? xml version="1.0" encoding="UTF-8"? > <configuration> <appenders> <File name="file" fileName="${sys:user.home}/logs/hello2.log">
            <PatternLayout pattern="%d{HH:mm:ss,SSS} %p %c (%L) - %m%n"/>
        </File>
    </appenders>

    <loggers>

        <root level="ERROR">
            <appender-ref ref="file"/>
        </root>
        <logger name="com.hansonwang99.controller" level="DEBUG" />
    </loggers>

</configuration>
Copy the code
  • Everything else remains the same

Running the program found no log output from the console and something in the hello2.log file, which is what we expected:

The log format matches that defined in pattern=”%d{HH:mm:ss,SSS} %p % C (%L) – %m%n”


Log4J takes this a step further

  • Pom. XML configuration:
		<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>
Copy the code
  • Log4j2. XML configuration
<? xml version="1.0" encoding="UTF-8"? > <configuration status="warn">
    <properties>

        <Property name="app_name">springboot-web</Property>
        <Property name="log_path">logs/${app_name}</Property>

    </properties>
    <appenders>
        <console name="Console" target="SYSTEM_OUT">
            <PatternLayout pattern="[%d][%t][%p][%l] %m%n" />
        </console>

        <RollingFile name="RollingFileInfo" fileName="${log_path}/info.log"
                     filePattern="${log_path}/ $${date:yyyy-MM}/info-%d{yyyy-MM-dd}-%i.log.gz">
            <Filters>
                <ThresholdFilter level="INFO" />
                <ThresholdFilter level="WARN" onMatch="DENY"
                                 onMismatch="NEUTRAL" />
            </Filters>
            <PatternLayout pattern="[%d][%t][%p][%c:%L] %m%n"/> <Policies> <! - archive file every day -- -- > < TimeBasedTriggeringPolicy interval ="1" modulate="true"/ > <! - a single file size limit - > < SizeBasedTriggeringPolicy size ="2 MB"/> </Policies> <! -- Limit number of files per day --> <DefaultRolloverStrategy compressionLevel="0" max="10"/>
        </RollingFile>

        <RollingFile name="RollingFileWarn" fileName="${log_path}/warn.log"
                     filePattern="${log_path}/ $${date:yyyy-MM}/warn-%d{yyyy-MM-dd}-%i.log.gz">
            <Filters>
                <ThresholdFilter level="WARN" />
                <ThresholdFilter level="ERROR" onMatch="DENY"
                                 onMismatch="NEUTRAL" />
            </Filters>
            <PatternLayout pattern="[%d][%t][%p][%c:%L] %m%n"/> <Policies> <! - archive file every day -- -- > < TimeBasedTriggeringPolicy interval ="1" modulate="true"/ > <! - a single file size limit - > < SizeBasedTriggeringPolicy size ="2 MB"/> </Policies> <! -- Limit number of files per day --> <DefaultRolloverStrategy compressionLevel="0" max="10"/>
        </RollingFile>

        <RollingFile name="RollingFileError" fileName="${log_path}/error.log"
                     filePattern="${log_path}/ $${date:yyyy-MM}/error-%d{yyyy-MM-dd}-%i.log.gz">
            <ThresholdFilter level="ERROR" />
            <PatternLayout pattern="[%d][%t][%p][%c:%L] %m%n"/> <Policies> <! - archive file every day -- -- > < TimeBasedTriggeringPolicy interval ="1" modulate="true"/ > <! - a single file size limit - > < SizeBasedTriggeringPolicy size ="2 MB"/> </Policies> <! -- Limit number of files per day --> <DefaultRolloverStrategy compressionLevel="0" max="10"/>
        </RollingFile>

    </appenders>

    <loggers>


        <root level="info">
            <appender-ref ref="Console" />
            <appender-ref ref="RollingFileInfo" />
            <appender-ref ref="RollingFileWarn" />
            <appender-ref ref="RollingFileError" />
        </root>

    </loggers>

</configuration>
Copy the code
  • Controller code:
package com.hansonwang99.controller;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/testlogging")
public class LoggingTestController {
    private final Logger logger = LogManager.getLogger(this.getClass());
    @GetMapping("/hello")
    public String hello() {
        for(int i=0; i<10_0000; i++){ logger.info("info execute index method");
            logger.warn("warn execute index method");
            logger.error("error execute index method");
        }
        return "My First SpringBoot Application"; }}Copy the code
  • The results

Logs are stored in different files based on different levels. When the size of a log file exceeds 2 MB, it is compressed and stored in multiple files. You are advised to set the size of a log file to 20-50MB in the production environment.


Afterword.

  • The author’s more original articles are here, welcome to watch

  • My Personal Blog

The author has more SpringBt practice articles here:

  • Spring Boot application monitoring actual combat
  • The SpringBoot application is deployed in an external Tomcat container
  • ElasticSearch in SpringBt practice
  • A preliminary study on Kotlin+SpringBoot joint programming
  • Spring Boot Logging framework practices
  • SpringBoot elegant coding: Lombok plus

If you are interested, take some time to read some of the author’s articles on containerization and microservitization:

  • Use K8S technology stack to create personal private cloud serial articles
  • Nginx server configuration from a detailed configuration list
  • Docker container visual monitoring center was built
  • Use ELK to build Docker containerized application log center
  • RPC framework practice: Apache Thrift
  • RPC framework practice: Google gRPC
  • Establishment of microservice call chain tracking center
  • Docker containers communicate across hosts
  • Preliminary study on Docker Swarm cluster
  • Several guidelines for writing dockerFiles efficiently