【问题标题】:How to print Spring Boot log in both text and json format using logback?如何使用 logback 以文本和 json 格式打印 Spring Boot 日志?
【发布时间】:2021-03-11 14:20:53
【问题描述】:

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

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

【问题讨论】:

    标签: java spring-boot logging logback logstash-logback-encoder


    【解决方案1】:

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

    第一步:pom.xml中添加logstash-logback-encoder依赖。

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

    第二步: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>
    

    第 3 步: 现在您可以在类中的任何位置使用 log 语句。假设您在 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

    【讨论】:

      【解决方案2】:

      你可以在 logback.xml 中配置如下 sn-p 为 json 和 text 格式。

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

      只需更改此处的类,我将一个打印到 consoleAppender,另一个打印到一个文件,您也可以将两者都指向一个 consoleappender。

      【讨论】:

        猜你喜欢
        • 2019-08-24
        • 1970-01-01
        • 2021-08-26
        • 2015-05-20
        • 2022-10-05
        • 2019-04-03
        • 2021-10-16
        • 2023-03-20
        • 2021-11-18
        相关资源
        最近更新 更多