• SpringBoot项目中使用Logback输出json格式日志


    前言

    定义日志为json格式,方便ELK的接入和查询。

    Maven依赖

    依赖的版本,查询下面的链接:
    https://mvnrepository.com/artifact/net.logstash.logback/logstash-logback-encoder

    例如:

    <dependency>
        <groupId>net.logstash.logbackgroupId>
        <artifactId>logstash-logback-encoderartifactId>
        <version>7.0.1version>
    dependency>
    
    • 1
    • 2
    • 3
    • 4
    • 5

    logback-spring.xml文件

    在项目的resources目录下,添加文件 logback-spring.xml
    注:文件名不允许是 logback.xml ,否则会报错:
    no applicable action for [springProfile], current ElementPath is [[configuration][springProfile]]

    使用LoggingEventCompositeJsonEncoder json格式的编码器。

    文件内容参考:

    
    <configuration>
        <jmxConfigurator/>
    
        <springProperty scope="context" name="module_name" source="spring.application.name"/>
        
        <springProperty scope="context" name="version" source="app.version"/>
        <springProperty scope="context" name="env" source="app.env"/>
    
    	
        <define name="hostname" class="com.xx.property.HostNamePropertyDefiner"/>
    
        <timestamp key="log_date" datePattern="yyyy-MM-dd"/>
    
        
        <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
            <encoder charset="UTF-8" class="net.logstash.logback.encoder.LoggingEventCompositeJsonEncoder">
                <providers>
                    <pattern>
                        <pattern>
                            {
                            "timestamp": "%date{\"yyyy-MM-dd'T'HH:mm:ss,SSSXXX\", UTC}",
                            "app": "${module_name}",
                            "version": "${version}",
                            "env": "${env}",
                            "host": "${hostname}",
                            
                            "level": "%level",
                            
                            "pid": "${PID:-}",
                            "thread": "%thread",
                            "class": "%logger",
                            "method": "%method",
                            "line": "%line",
                            
                            "message": "%message",
                            
                            "statck_trace":"%xEx"
                            }
                        pattern>
                    pattern>
                providers>
            encoder>
        appender>
    
        <appender name="logfile" class="ch.qos.logback.core.rolling.RollingFileAppender">
            <file>/app/log/${module_name}.logfile>
            <append>trueappend>
            <encoder charset="UTF-8" class="net.logstash.logback.encoder.LoggingEventCompositeJsonEncoder">
                <providers>
                    <pattern>
                        <pattern>
                            {
                            "timestamp": "%date{\"yyyy-MM-dd'T'HH:mm:ss,SSSXXX\", UTC}",
                            "app": "${module_name}",
                            "version": "${version}",
                            "env": "${env}",
                            "host": "${hostname}",
                            
                            "level": "%level",
                            
                            "pid": "${PID:-}",
                            "thread": "%thread",
                            "class": "%logger",
                            "method": "%method",
                            "line": "%line",
                            
                            "message": "%message",
                            
                            "statck_trace":"%xEx"
                            }
                        pattern>
                    pattern>
                providers>
            encoder>
            <prudent>falseprudent>
            <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
                <fileNamePattern>/app/log/${module_name}-%d{yyyy-MM-dd}.log.gzfileNamePattern>
                <maxHistory>7maxHistory>
            rollingPolicy>
        appender>
    
        <logger name="com.xx" level="debug"/>
    
        
        <root level="info">
            <appender-ref ref="STDOUT"/>
            <appender-ref ref="logfile"/>
        root>
    
    configuration>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91

    参考链接:

    https://logback.qos.ch/manual/index.html
    https://logback.qos.ch/manual/layouts.html

    如果Logback未获取到property,将会显示成:...IS_UNDEFINED

    相关问题

    appender里的 fileNamePattern与 file 的关系

    没有设置file属性:当天(分钟/时/月)的日志输出到fileNamePattern指向的日志。

    设置file属性:当天(分钟/时/月)的日志输出到file指向的日志,第二天凌晨日志输出到fileNamePattern指向的日志。

    logback如何从apollo配置中心读取变量

    app:
      id: xxx
      version: 1.0.0
      env: dev
      
    apollo:
      bootstrap:
        enabled: true
        # 将Apollo配置加载提到初始化日志系统之前
        eagerLoad:
          enabled: true
        autoUpdateInjectedSpringProperties: true
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    注意:

    将Apollo配置加载提到初始化日志系统之前(1.2.0+):
    从1.2.0版本开始,如果希望把日志相关的配置(如logging.level.root=info或logback-spring.xml中的参数)也放在Apollo管理,那么可以额外配置apollo.bootstrap.eagerLoad.enabled=true来使Apollo的加载顺序放到日志系统加载之前

    Apollo官方链接

    获取主机名

    方法1:自定义

    import ch.qos.logback.core.PropertyDefinerBase;
    
    import java.net.InetAddress;
    import java.net.UnknownHostException;
    
    /**
     * 将主机名添加到日志中
     *
     */
    public class HostNamePropertyDefiner extends PropertyDefinerBase {
    
        @Override
        public String getPropertyValue() {
            try {
                return InetAddress.getLocalHost().getHostName();
            } catch (UnknownHostException e) {
                e.printStackTrace();
            }
            return null;
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    方法2:高版本的logback jar包中提供了 CanonicalHostNamePropertyDefiner

    https://logback.qos.ch/apidocs/ch/qos/logback/core/property/CanonicalHostNamePropertyDefiner.html

    使Logback以“%date”格式在日期和时间之间包括“ T”,以严格遵守ISO 8601

    默认情况下,Logback编码器使用类似于ISO
    8601标准的日期格式。但是它在日期和时间部分之间的中间缺少“
    T”。该标记使解析更加容易,并且是标准所必需的(除非私有方另行同意)。

    时区

    为了更完全符合ISO 8601标准,并且为了获得更有用的日志记录,您应该包括一个时区。

    编辑(Michael-O,2014-06-15):事实 并非 如此,时区是绝对可选的。

    要包含时区,请向传递第二个参数(请参阅doc)%date。传递时区的专有名称。避免使用三个或四个字母的时区代码,例如“
    EST”,因为它们既不是唯一的也不是标准化的。例如,通过Australia/Perth。通常,对于日志记录,我们需要UTC(GMT)时间,这意味着没有任何偏移。在这种情况下,请通过UTC。

    您可以在日志中将时区偏移量显示为日期和时间的小时数和分钟数。附加一个X以将时区偏移显示为日期时间值的一部分。

    例如:

    %date{"yyyy-MM-dd'T'HH:mm:ss,SSSXXX", UTC}
    
    • 1

    输出:

    2021-04-16T09:59:24,009Z
    
    • 1
  • 相关阅读:
    ffmpeg 中av_rescale_rnd 的含义
    得帆云iPaaS白皮书|WMS集成,打造高效规范的仓储管理业务生态
    怎样在PDF上直接编辑文字?这几种编辑方法需要掌握
    利用 Pytorch 加载词向量库文件
    bamboo is currently exporting
    技术分享 | 接口自动化测试如何进行认证?
    MybatisPlus【SpringBoot】 5 条件构造器和常用接口 5.1 wrapper 介绍 & 5.2 QueryWrapper
    github push 报错的问题记录
    力扣刷题-数组-双指针法总结-移除元素
    Springboot整合WebSocket实现浏览器和服务器交互
  • 原文地址:https://blog.csdn.net/u014163312/article/details/126713959