如何使用 logback 以文本格式和 json 格式打印 Spring 引导日志?

How to print Spring Boot log in both text and json format using logback?

对于日志记录,我们使用 Logback。目前我们正在使用 Splunk 查看 Spring 引导日志。根据项目要求,我们需要转向 Kibana。首先,我们应该以 JSON 格式登录,以便 Kibana 可以轻松处理它。目前我们没有用 Kibana 替换 Splunk,但是当与 Kibana 集成成功后,我们可以逐渐在所有项目中替换 Splunk。

因此,根据要求,我们需要现有日志,即文本日志,但出于研发目的,我们还需要 JSON 日志。

您可以在 logback.xml 中为 json 和文本格式配置如下片段。

    <appender name="json" class="ch.qos.logback.core.ConsoleAppender">
    <layout class="ch.qos.logback.contrib.json.classic.JsonLayout">
        <jsonFormatter
            class="ch.qos.logback.contrib.jackson.JacksonJsonFormatter">
            <prettyPrint>true</prettyPrint>
        </jsonFormatter>
        <timestampFormat>yyyy-MM-dd' 'HH:mm:ss.SSS</timestampFormat>
    </layout>
</appender>




<appender name="FILE" class="ch.qos.logback.core.FileAppender">
        <file>logfile.log</file>
        <append>true</append>
        <encoder>
            <pattern>%-4relative [%thread] %-5level %logger{35} - %msg %n</pattern>
        </encoder>
    </appender>

只需更改 class 这里我将一个打印到 consoleAppender,另一个打印到一个文件,您也可以将两者都指向 consoleappender。

这个很简单。您只需要在 pom.xml 文件中添加 logstash-logback-encoder 依赖项并在 logback.xml 文件中编写一些配置。请按照以下步骤来满足您的要求。

Step1:pom.xml.

中添加logstash-logback-encoder依赖
<dependency>
    <groupId>net.logstash.logback</groupId>
    <artifactId>logstash-logback-encoder</artifactId>
    <version>6.4</version>
</dependency>

第 2 步:src/main/resources/ 中创建 logback.xml 文件并复制粘贴以下内容。

<?xml version="1.0" encoding="UTF-8"?>
<configuration debug="false">
  <include resource="org/springframework/boot/logging/logback/defaults.xml" />
  <include resource="org/springframework/boot/logging/logback/console-appender.xml" />
  <property name="LOG_PATH" value="logs" />
  <property name="CONSOLE_LOG_PATTERN" value="[%-5level] %d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %X{id} %c{1} - %msg%n" />
  <property name="FILE_LOG_PATTERN" value="[%-5level] %d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %X{id} %c{1} - %msg%n" />

  <appender name="CONSOLE_APPENDER" class="ch.qos.logback.core.ConsoleAppender">
    <encoder>
      <pattern>${CONSOLE_LOG_PATTERN}</pattern>
      <charset>utf8</charset>
    </encoder>
  </appender>

  <appender name="ROLLING_TEXT_FILE_APPENDER" class="ch.qos.logback.core.rolling.RollingFileAppender">
    <file>${LOG_PATH}/application-text.log</file>
    <encoder>
      <Pattern>${FILE_LOG_PATTERN}</Pattern>
    </encoder>
    <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
      <fileNamePattern>${LOG_PATH}/application-text.%d{yyyy-MM-dd}.%i.gz
      </fileNamePattern>
      <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
        <maxFileSize>100MB</maxFileSize>
      </timeBasedFileNamingAndTriggeringPolicy>
      <maxHistory>10</maxHistory>
    </rollingPolicy>
  </appender>
  
  <appender name="ROLLING_JSON_FILE_APPENDER" class="ch.qos.logback.core.rolling.RollingFileAppender">
    <file>${LOG_PATH}/application-json.log</file>
    <encoder class="net.logstash.logback.encoder.LogstashEncoder" />
    <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
      <fileNamePattern>${LOG_PATH}/application-json.%d{yyyy-MM-dd}.%i.gz
      </fileNamePattern>
      <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
        <maxFileSize>100MB</maxFileSize>
      </timeBasedFileNamingAndTriggeringPolicy>
      <maxHistory>10</maxHistory>
    </rollingPolicy>
  </appender>

  <root level="INFO">
    <appender-ref ref="CONSOLE_APPENDER" />
    <appender-ref ref="ROLLING_TEXT_FILE_APPENDER" />
    <appender-ref ref="ROLLING_JSON_FILE_APPENDER" />
  </root>
</configuration>

Step3:现在你可以在class的任何地方使用日志语句了。假设您在 Spring Boot.

的主要 class 中使用
import org.slf4j.MDC;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import com.altafjava.constant.AppConstant;
import lombok.extern.slf4j.Slf4j;

@Slf4j
@SpringBootApplication
public class JsonLogApplication {

    public static void main(String[] args) {
        SpringApplication.run(JsonLogApplication.class, args);
        MDC.put("id", AppConstant.PROJECT_NAME_PREFIX + "_" + AppConstant.MARKET_CODE + "_" + AppConstant.PARAM_TYPE);
        log.info("---------- Spring Application started successfully ----------");
        log.debug("This is a debug message.");
        log.info("This is an info message.");
        log.warn("This is a warn message.");
        log.error("This is an error message.");
        log.info("---------- Spring Application ended successfully ----------");
    }
}

This will create two log files inside the logs directory.

  1. application-text.log 看起来像这样
[INFO ] 2020-09-11 22:36:13.627 [main] DEMO_IND_PARAM c.a.JsonLogApplication - ---------- Spring Application started successfully ----------
[INFO ] 2020-09-11 22:36:13.630 [main] DEMO_IND_PARAM c.a.JsonLogApplication - This is an info message.
[WARN ] 2020-09-11 22:36:13.630 [main] DEMO_IND_PARAM c.a.JsonLogApplication - This is a warn message.
[ERROR] 2020-09-11 22:36:13.631 [main] DEMO_IND_PARAM c.a.JsonLogApplication - This is an error message.
[INFO ] 2020-09-11 22:36:13.631 [main] DEMO_IND_PARAM c.a.JsonLogApplication - ---------- Spring Application ended successfully ----------
  1. application-json.log 看起来像这样
{"@timestamp":"2020-09-11T22:36:13.627+05:30","@version":"1","message":"---------- Spring Application started successfully ----------","logger_name":"com.altafjava.JsonLogApplication","thread_name":"main","level":"INFO","level_value":20000,"id":"DEMO_IND_PARAM"}
{"@timestamp":"2020-09-11T22:36:13.630+05:30","@version":"1","message":"This is an info message.","logger_name":"com.altafjava.JsonLogApplication","thread_name":"main","level":"INFO","level_value":20000,"id":"DEMO_IND_PARAM"}
{"@timestamp":"2020-09-11T22:36:13.630+05:30","@version":"1","message":"This is a warn message.","logger_name":"com.altafjava.JsonLogApplication","thread_name":"main","level":"WARN","level_value":30000,"id":"DEMO_IND_PARAM"}
{"@timestamp":"2020-09-11T22:36:13.631+05:30","@version":"1","message":"This is an error message.","logger_name":"com.altafjava.JsonLogApplication","thread_name":"main","level":"ERROR","level_value":40000,"id":"DEMO_IND_PARAM"}
{"@timestamp":"2020-09-11T22:36:13.631+05:30","@version":"1","message":"---------- Spring Application ended successfully ----------","logger_name":"com.altafjava.JsonLogApplication","thread_name":"main","level":"INFO","level_value":20000,"id":"DEMO_IND_PARAM"}

注意:这里的@Slf4j是一个Lombok注解。这意味着无需创建 LoggerFactory 即可直接使用日志方法。因此,您需要在 IDE 中安装 Lombok 并在 pom.xml

中添加依赖项

如需演示工程,请访问https://github.com/altafjava/json-log