首页 > 解决方案 > 如何使用 logback 以文本和 json 格式打印 Spring Boot 日志?

问题描述

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

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

标签: javaspring-bootlogginglogbacklogstash-logback-encoder

解决方案


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

Step1:在logstash-logback-encoder.pom.xml

<dependency>
    <groupId>net.logstash.logback</groupId>
    <artifactId>logstash-logback-encoder</artifactId>
    <version>6.4</version>
</dependency>

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

<?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>

第三步:现在你可以在类的任何地方使用日志语句。假设您在 Spring Boot 的主类中使用。

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 ----------");
    }
}

这将在目录中创建两个日志文件logs

  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


推荐阅读