• Spring Boot日志配置logback


    目录

    一、logback介绍

    1.logback定义

    2.logback启动加载文件

    3.pom依赖 

    3.日志级别

    二、配置文件详解

    1.configuration

    2.property

    3.springProperty

    4.logger

    5.root

    6.appender

    7.AsyncAppender

    三.Spring Boot配置

    完整logback-spring.xml配置文件


    一、logback介绍

    1.logback定义

    Logback是由log4j创始人设计的另一个开源日志组件,官方网站: http://logback.qos.ch

    logback的结构主要由三个模块组成:

    1. logback-core:其它两个模块的基础模块。
    2. logback-classic:它是log4j的一个改良版本,同时它完整实现了slf4j API使你可以很方便地更换成其它日志系统如log4j或JDK14 Logging。
    3. logback-access:访问模块与Servlet容器集成提供通过Http来访问日志的功能。

    SLF4J 是一个用于日志系统的简单Facade,允许最终用户在部署其应用时使用其所希望的日志系统。大概意思是指你只需要按统一的方式写记录日志的代码,而无需关心日志是通过哪个日志系统,以什么风格输出的,因为它们取决于部署项目时绑定的日志系统。

    SLF4J最常用的日志实现框架是:log4j、logback。一般有slf4j+log4j、slf4j+log4j2、slf4j+logback三种日志组合。

    本文选取logback做具体介绍

    2.logback启动加载文件

    在工程resources目录下建立logback.xml

    1. logback首先会试着查找logback.groovy文件;
    2. 当没有找到时,继续试着查找logback-test.xml文件;
    3. 当没有找到时,继续试着查找logback.xml文件;
    4. 如果仍然没有找到,则使用默认配置(打印到控制台)。

    注:Spring Boot官方推荐优先使用带有-spring的文件名作为你的日志配置(如使用logback-spring.xml,而不是logback.xml),命名为logback-spring.xml的日志配置文件

    3.pom依赖 

    1. <dependency>
    2. <groupId>ch.qos.logbackgroupId>
    3. <artifactId>logback-classicartifactId>
    4. <version>1.2.3version>
    5. dependency>

    注:在实际开发中我们不需要直接添加该依赖,spring-boot-starter其中包含了spring-boot-starter-logging,该依赖内容就是 Spring Boot 默认的日志框架就是logback。而spring-boot-starter-web包含了spring-boot-starter,可通过引入spring-boot-starter-web后的项目JAR依赖关系很快得出这个结论。

    3.日志级别

    日志级别用来控制日志信息的输出,从高到低分为共分为七个等级:

    1. off 最高等级,用于关闭所有日志记录。
    2. fatal 指出每个严重的错误事件将会导致应用程序的退出。
    3. error 指出虽然发生错误事件,但仍然不影响系统的继续运行。
    4. warm 表明会出现潜在的错误情形。
    5. info 一般和在粗粒度级别上,强调应用程序的运行全程。
    6. debug 一般用于细粒度级别上,对调试应用程序非常有帮助。
    7. all 最低等级,用于打开所有日志记录。

    Log4j建议只使用四个级别,优先级从高到低分别是 ERROR、WARN、INFO、DEBUG,优先级高的将被打印出来。(logback通用),通过定义级别,可以作为应用程序中相应级别的日志信息的开关。

    二、配置文件详解

    1.configuration

    1. scan:当此属性设置为true时,配置文件如果发生改变,将会被重新加载,默认值为true。
    2. scanPeriod:设置监测配置文件是否有修改的时间间隔,如果没有给出时间单位,默认单位是毫秒。当scan为true时,此属性生效。默认的时间间隔为1分钟。
    3. debug:当此属性设置为true时,将打印出logback内部日志信息,实时查看logback运行状态。默认值为false。
    1. <configuration scan="true" scanPeriod="60 seconds" debug="false">
    2. configuration>

    2.property

    property有两个属性name和value:name变量的名称,value变量的值。

    1. <property name="appName" value="demoServer">property>
    2. <property name="logLevel" value="INFO">property>
    3. <property name="logPath" value="/data/project/logs">property>
    4. <property name="maxHistory" value="60"/>
    5. <property name="queueSize" value="512">property>
    6. <property name="logPattern" value="[ %-5level] [%date{yyyy-MM-dd HH:mm:ss.SSS}] %logger{36} [%line] [%thread]- %msg%n">property>

    3.springProperty

    springProperty要配合配置文件来用。

    1. <springProperty scope="context" name="spring.application.name" source="spring.application.name"/>
    2. <springProperty scope="context" name="spring.profiles.active" source="spring.profiles.active"/>

    也就是在配置文件中有对应配置。 

    spring:
      application:
        name: demoServer
      profiles:
        active: dev

    4.logger

    logger节点,可选节点,作用是指明具体的包或类的日志输出级别,以及要使用的(可以把理解为一个日志模板)。

    1. name:必写属性,指定具体包或类,被指定的包或类中的日志输出将遵从该logger规定配置。
    2. level:非必写属性,指定日志输出级别,该级别将覆盖root配置的输出级别。
    3. addtivity:非必写属性,是否向上级loger传递打印信息,默认是true。
    4. appender-ref:引用的appender,引用后将实现appender中定义的行为。一个logger可以有多个引用,互不影响。
    1. <logger name="com.github.demo" level value="INFO" >
    2. <appender-ref ref="ASYNC_LOG_INFO" />
    3. <appender-ref ref="STDOUT" />
    4. logger>

     不过一般需要特殊检测的基础服务实际使用中additivity常常设置为false。如下:

    1. <logger name="com.alibaba.nacos.client" level="${log.level.nacos}" additivity="false">
    2. <appender-ref ref="ASYNC_THIRD_PARTY_APPENDER"/>
    3. logger>
    4. <logger name="com.alibaba.nacos.client.config" level="${log.level.nacos}" additivity="false">
    5. <appender-ref ref="ASYNC_THIRD_PARTY_APPENDER"/>
    6. logger>
    7. <logger name="com.alibaba.nacos.client.naming" level="${log.level.nacos}" additivity="false">
    8. <appender-ref ref="ASYNC_THIRD_PARTY_APPENDER"/>
    9. logger>

    5.root

    root节点,必选节点,用来指定最基础的日志输出级别并指定,可以理解为根logger。

    1. <root level="${logLevel}">
    2. <appender-ref ref="STDOUT"/>
    3. <appender-ref ref="ASYNC_LOG_DEBUG"/>
    4. <appender-ref ref="ASYNC_LOG_INFO"/>
    5. <appender-ref ref="ASYNC_LOG_WARN"/>
    6. <appender-ref ref="ASYNC_LOG_ERROR"/>
    7. root>

    6.appender

    appender节点是非常关键的一个节点,它有两个必要属性name和class,name指定appender名称,class指定appender的全限定名。

    另一个属性encoder:负责两件事,一是把日志信息转换成字节数组,二是把字节数组写入到输出流。

    appender有三种类型:

    1. ConsoleAppender(控制台日志)。
    2. FileAppender(文件日志)。
    3. RollingFileAppender(滚动文件日志)。

    最常用的滚动策略,根据时间再根据文件大小来滚动生成文件

    1. <appender name="FILE_INFO" class="ch.qos.logback.core.rolling.RollingFileAppender">
    2. <file>${logPath}/info/${appName}_info.logfile>
    3. <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
    4. <fileNamePattern>${logPath}/info/${appName}_info-%d{yyyy-MM-dd}.%i.log.gzfileNamePattern>
    5. <maxFileSize>128MBmaxFileSize>
    6. <maxHistory>${maxHistory}maxHistory>
    7. <totalSizeCap>10GBtotalSizeCap>
    8. rollingPolicy>
    9. <encoder>
    10. <pattern>${logPattern}pattern>
    11. <charset>utf-8charset>
    12. encoder>
    13. <filter class="ch.qos.logback.classic.filter.LevelFilter">
    14. <level>INFOlevel>
    15. <onMatch>ACCEPTonMatch>
    16. <onMismatch>DENYonMismatch>
    17. filter>
    18. appender>

    把日志输出到控制台

    1. <property name="logPattern" value="[ %-5level] [%date{yyyy-MM-dd HH:mm:ss.SSS}] %logger{36} [%line] [%thread]- %msg%n">property>
    2. <jmxConfigurator/>
    3. <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
    4. <encoder>
    5. <charset>UTF-8charset>
    6. <pattern>${logPattern}pattern>
    7. encoder>
    8. appender>

    pattern定义了日志的输出格式解析:

    1. %date:表示日期
    2. %thread:表示线程名
    3. %-5level:表示级别从左显示 5 个字符宽度
    4. %logger{36}:表示 Logger 名字最长 36 个字符
    5. %msg:表示日志消息
    6. %n:换行符

    7.AsyncAppender

    1. <appender name="ASYNC_LOG_INFO" class="ch.qos.logback.classic.AsyncAppender">
    2. <discardingThreshold>0discardingThreshold>
    3. <queueSize>${queueSize}queueSize>
    4. <neverBlock>trueneverBlock>
    5. <appender-ref ref="FILE_INFO"/>
    6. appender>
    1. queueSize:控制阻塞队列大小,使用的ArrayBlockingQueue阻塞队列,默认容量256:内存中最多保存256条日志
    2. discardingThreshold:丢弃日志的阈值,为防止队列满后发生阻塞。默认队列剩余容量 < 队列长度的20%,就会丢弃TRACE、DEBUG和INFO级日志
    3. neverBlock:控制队列满时,加入的数据是否直接丢弃,不会阻塞等待,默认是false
      1. 队列满时:offer不阻塞,而put会阻塞
      2. neverBlock为true时,使用offer

    注意:

    queueSize 过大
    可能导致OOM
    queueSize 较小
    默认值256就已经算很小了,且discardingThreshold设置为大于0(或为默认值),队列剩余容量少于discardingThreshold的配置就会丢弃<=INFO日志。这里的坑点有两个:
    因为discardingThreshold,所以设置queueSize时容易踩坑。
    neverBlock 默认false
    意味总可能会出现阻塞。

    1.  若discardingThreshold = 0,那么队列满时再有日志写入就会阻塞。
    2. 若discardingThreshold != 0,也只丢弃≤INFO级日志,出现大量错误日志时,还是会阻塞。

    queueSize、discardingThreshold和neverBlock三参密不可分,务必按业务需求设置:

    1. 若优先绝对性能,设置neverBlock = true,永不阻塞。
    2. 若优先绝不丢数据,设置discardingThreshold = 0,即使≤INFO级日志也不会丢。但最好把queueSize设置大一点,毕竟默认的queueSize显然太小,太容易阻塞。
    3. 若兼顾,可丢弃不重要日志,把queueSize设置大点,再设置合理的discardingThreshold

    三.Spring Boot配置

    Spring Boot项目的配置文件。

    logging:
      file:
        path: '@logging.file.path@'
        name: ${logging.file.path}/${spring.application.name}/root.log
      config: classpath:logback-spring.xml

    spring-boot-starter-web默认引入logback

    1. <dependency>
    2. <groupId>org.springframework.bootgroupId>
    3. <artifactId>spring-boot-starter-webartifactId>
    4. dependency>

    完整logback-spring.xml配置文件

    1. "1.0" encoding="UTF-8"?>
    2. <configuration scan="true" scanPeriod="60 seconds" debug="false">
    3. <property name="appName" value="demoServer">property>
    4. <property name="logLevel" value="INFO">property>
    5. <property name="logPath" value="/data/project/logs">property>
    6. <property name="maxHistory" value="60"/>
    7. <property name="queueSize" value="512">property>
    8. <property name="logPattern" value="[ %-5level] [%date{yyyy-MM-dd HH:mm:ss.SSS}] %logger{36} [%line] [%thread]- %msg%n">property>
    9. <jmxConfigurator/>
    10. <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
    11. <encoder>
    12. <charset>UTF-8charset>
    13. <pattern>${logPattern}pattern>
    14. encoder>
    15. appender>
    16. <appender name="FILE_DEBUG" class="ch.qos.logback.core.rolling.RollingFileAppender">
    17. <file>${logPath}/debug/${appName}_debug.logfile>
    18. <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
    19. <fileNamePattern>${logPath}/debug/${appName}_debug-%d{yyyy-MM-dd}.%i.log.gzfileNamePattern>
    20. <maxFileSize>128MBmaxFileSize>
    21. <maxHistory>${maxHistory}maxHistory>
    22. <totalSizeCap>10GBtotalSizeCap>
    23. rollingPolicy>
    24. <encoder>
    25. <pattern>${logPattern}pattern>
    26. <charset>utf-8charset>
    27. encoder>
    28. <filter class="ch.qos.logback.classic.filter.LevelFilter">
    29. <level>DEBUGlevel>
    30. <onMatch>ACCEPTonMatch>
    31. <onMismatch>DENYonMismatch>
    32. filter>
    33. appender>
    34. <appender name="FILE_INFO" class="ch.qos.logback.core.rolling.RollingFileAppender">
    35. <file>${logPath}/info/${appName}_info.logfile>
    36. <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
    37. <fileNamePattern>${logPath}/info/${appName}_info-%d{yyyy-MM-dd}.%i.log.gzfileNamePattern>
    38. <maxFileSize>128MBmaxFileSize>
    39. <maxHistory>${maxHistory}maxHistory>
    40. <totalSizeCap>10GBtotalSizeCap>
    41. rollingPolicy>
    42. <encoder>
    43. <pattern>${logPattern}pattern>
    44. <charset>utf-8charset>
    45. encoder>
    46. <filter class="ch.qos.logback.classic.filter.LevelFilter">
    47. <level>INFOlevel>
    48. <onMatch>ACCEPTonMatch>
    49. <onMismatch>DENYonMismatch>
    50. filter>
    51. appender>
    52. <appender name="FILE_WARN" class="ch.qos.logback.core.rolling.RollingFileAppender">
    53. <file>${logPath}/warn/${appName}_warn.logfile>
    54. <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
    55. <fileNamePattern>${logPath}/warn/${appName}_warn-%d{yyyy-MM-dd}.%i.log.gzfileNamePattern>
    56. <maxFileSize>128MBmaxFileSize>
    57. <maxHistory>${maxHistory}maxHistory>
    58. <totalSizeCap>10GBtotalSizeCap>
    59. rollingPolicy>
    60. <encoder>
    61. <pattern>${logPattern}pattern>
    62. <charset>utf-8charset>
    63. encoder>
    64. <filter class="ch.qos.logback.classic.filter.LevelFilter">
    65. <level>WARNlevel>
    66. <onMatch>ACCEPTonMatch>
    67. <onMismatch>DENYonMismatch>
    68. filter>
    69. appender>
    70. <appender name="FILE_ERROR" class="ch.qos.logback.core.rolling.RollingFileAppender">
    71. <file>${logPath}/error/${appName}_error.logfile>
    72. <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
    73. <fileNamePattern>${logPath}/error/${appName}_error-%d{yyyy-MM-dd}.%i.log.gzfileNamePattern>
    74. <maxFileSize>128MBmaxFileSize>
    75. <maxHistory>${maxHistory}maxHistory>
    76. <totalSizeCap>10GBtotalSizeCap>
    77. rollingPolicy>
    78. <encoder>
    79. <pattern>${logPattern}pattern>
    80. <charset>utf-8charset>
    81. encoder>
    82. <filter class="ch.qos.logback.classic.filter.LevelFilter">
    83. <level>ERRORlevel>
    84. <onMatch>ACCEPTonMatch>
    85. <onMismatch>DENYonMismatch>
    86. filter>
    87. appender>
    88. <appender name="ASYNC_LOG_DEBUG" class="ch.qos.logback.classic.AsyncAppender">
    89. <discardingThreshold>0discardingThreshold>
    90. <queueSize>${queueSize}queueSize>
    91. <neverBlock>trueneverBlock>
    92. <appender-ref ref="FILE_DEBUG"/>
    93. appender>
    94. <appender name="ASYNC_LOG_INFO" class="ch.qos.logback.classic.AsyncAppender">
    95. <discardingThreshold>0discardingThreshold>
    96. <queueSize>${queueSize}queueSize>
    97. <neverBlock>trueneverBlock>
    98. <appender-ref ref="FILE_INFO"/>
    99. appender>
    100. <appender name="ASYNC_LOG_WARN" class="ch.qos.logback.classic.AsyncAppender">
    101. <discardingThreshold>0discardingThreshold>
    102. <queueSize>${queueSize}queueSize>
    103. <neverBlock>trueneverBlock>
    104. <appender-ref ref="FILE_WARN"/>
    105. appender>
    106. <appender name="ASYNC_LOG_ERROR" class="ch.qos.logback.classic.AsyncAppender">
    107. <discardingThreshold>0discardingThreshold>
    108. <queueSize>${queueSize}queueSize>
    109. <neverBlock>trueneverBlock>
    110. <appender-ref ref="FILE_ERROR"/>
    111. appender>
    112. <logger name="com.github.demo" level value="DEBUG" additivity="false">
    113. <appender-ref ref="STDOUT" />
    114. logger>
    115. <root level="${logLevel}">
    116. <appender-ref ref="ASYNC_LOG_DEBUG"/>
    117. <appender-ref ref="ASYNC_LOG_INFO"/>
    118. <appender-ref ref="ASYNC_LOG_WARN"/>
    119. <appender-ref ref="ASYNC_LOG_ERROR"/>
    120. root>
    121. configuration>
  • 相关阅读:
    微服务框架 SpringCloud微服务架构 20 RestClient 操作索引库 20.2 hotel 数据结构分析
    GPT-1, GPT-2, GPT-3, InstructGPT / ChatGPT and GPT-4 总结
    三、W5100S/W5500+RP2040树莓派Pico<TCP Client数据回环测试>
    为什么用IP访问网站也要使用SSL证书
    Redis的缓存更新策略和缓存问题
    代码随想录算法训练营Day58 | 单调栈(1/3) LeetCode 739. 每日温度 496.下一个更大元素 I
    SpringBoot 项目,三种方式实现打印 sql 日志
    解析java数值类型数据混合运算
    XML 应用程序
    vite脚手架框架使用
  • 原文地址:https://blog.csdn.net/star20100906/article/details/127864862