Spring Boot 日志框架实践 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
hansonwang99
V2EX    推广

Spring Boot 日志框架实践

  •  
  •   hansonwang99 2018-03-29 09:01:53 +08:00 5086 次点击
    这是一个创建于 2763 天前的主题,其中的信息可能已经有所发展或是发生改变。

    CASIO G-SHOCK


    概述

    Java 应用中,日志一般分为以下 5 个级别:

    • ERROR 错误信息
    • WARN 警告信息
    • INFO 一般信息
    • DEBUG 调试信息
    • TRACE 跟踪信息

    Spring Boot 使用 Apache 的 Commons Logging 作为内部的日志框架,其仅仅是一个日志接口,在实际应用中需要为该接口来指定相应的日志实现。

    SpringBt 默认的日志实现是 Java Util Logging,是 JDK 自带的日志包,此外 SpringBt 当然也支持 Log4J、Logback 这类很流行的日志实现。

    统一将上面这些日志实现统称为日志框架

    下面我们来实践一下!


    使用 Spring Boot Logging 插件

    • 首先 application.properties 文件中加配置:
    logging.level.root=INFO 
    • 控制器部分代码如下:
    package com.hansonwang99.controller; import com.hansonwang99.K8sresctrlApplication; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @RestController @RequestMapping("/testlogging") public class LoggingTestController { private static Logger logger = LoggerFactory.getLogger(K8sresctrlApplication.class); @GetMapping("/hello") public String hello() { logger.info("test logging..."); return "hello"; } } 
    • 运行结果

    运行结果

    由于将日志等级设置为 INFO,因此包含 INFO 及以上级别的日志信息都会打印出来

    这里可以看出,很多大部分的 INFO 日志均来自于 SpringBt 框架本身,如果我们想屏蔽它们,可以将日志级别统一先全部设置为 ERROR,这样框架自身的 INFO 信息不会被打印。然后再将应用中特定的包设置为 DEBUG 级别的日志,这样就可以只看到所关心的包中的 DEBUG 及以上级别的日志了。

    • 控制特定包的日志级别

    application.yml 中改配置

    logging: level: root: error com.hansonwang99.controller: debug 

    很明显,将 root 日志级别设置为 ERROR,然后再将com.hansonwang99.controller包的日志级别设为 DEBUG,此即:即先禁止所有再允许个别的 设置方法

    • 控制器代码
    package com.hansonwang99.controller; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @RestController @RequestMapping("/testlogging") public class LoggingTestController { private Logger logger = LoggerFactory.getLogger(this.getClass()); @GetMapping("/hello") public String hello() { logger.info("test logging..."); return "hello"; } } 
    • 运行结果

    运行结果

    可见框架自身的 INFO 级别日志全部藏匿,而指定包中的日志按级别顺利地打印出来

    • 将日志输出到某个文件中
    logging: level: root: error com.hansonwang99.controller: debug file: ${user.home}/logs/hello.log 
    • 运行结果

    运行结果

    运行结果

    使用 Spring Boot Logging,我们发现虽然日志已输出到文件中,但控制台中依然会打印一份,发现用org.slf4j.Logger是无法解决这个问题的

    v 运行结果


    集成 Log4J 日志框架

    • pom.xml 中添加依赖
     <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> <exclusions> <exclusion> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-logging</artifactId> </exclusion> </exclusions> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-log4j2</artifactId> </dependency> 
    • 在 resources 目录下添加log4j2.xml文件,内容如下:
    <?xml version="1.0" encoding="UTF-8"?> <configuration> <appenders> <File name="file" fileName="${sys:user.home}/logs/hello2.log"> <PatternLayout pattern="%d{HH:mm:ss,SSS} %p %c (%L) - %m%n"/> </File> </appenders> <loggers> <root level="ERROR"> <appender-ref ref="file"/> </root> <logger name="com.hansonwang99.controller" level="DEBUG" /> </loggers> </configuration> 
    • 其他代码都保持不变

    运行程序发现控制台没有日志输出,而 hello2.log 文件中有内容,这符合我们的预期:

    运行结果

    运行结果

    运行结果

    而且日志格式和pattern="%d{HH:mm:ss,SSS} %p %c (%L) - %m%n"格式中定义的相匹配


    Log4J 更进一步实践

    • pom.xml 配置:
     <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> <exclusions> <exclusion> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-logging</artifactId> </exclusion> </exclusions> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-log4j2</artifactId> </dependency> 
    • log4j2.xml 配置
    <?xml version="1.0" encoding="UTF-8"?> <configuration status="warn"> <properties> <Property name="app_name">springboot-web</Property> <Property name="log_path">logs/${app_name}</Property> </properties> <appenders> <console name="Console" target="SYSTEM_OUT"> <PatternLayout pattern="[%d][%t][%p][%l] %m%n" /> </console> <RollingFile name="RollingFileInfo" fileName="${log_path}/info.log" filePattern="${log_path}/$${date:yyyy-MM}/info-%d{yyyy-MM-dd}-%i.log.gz"> <Filters> <ThresholdFilter level="INFO" /> <ThresholdFilter level="WARN" OnMatch="DENY" OnMismatch="NEUTRAL" /> </Filters> <PatternLayout pattern="[%d][%t][%p][%c:%L] %m%n" /> <Policies> <!-- 归档每天的文件 --> <TimeBasedTriggeringPolicy interval="1" modulate="true" /> <!-- 限制单个文件大小 --> <SizeBasedTriggeringPolicy size="2 MB" /> </Policies> <!-- 限制每天文件个数 --> <DefaultRolloverStrategy compressiOnLevel="0" max="10"/> </RollingFile> <RollingFile name="RollingFileWarn" fileName="${log_path}/warn.log" filePattern="${log_path}/$${date:yyyy-MM}/warn-%d{yyyy-MM-dd}-%i.log.gz"> <Filters> <ThresholdFilter level="WARN" /> <ThresholdFilter level="ERROR" OnMatch="DENY" OnMismatch="NEUTRAL" /> </Filters> <PatternLayout pattern="[%d][%t][%p][%c:%L] %m%n" /> <Policies> <!-- 归档每天的文件 --> <TimeBasedTriggeringPolicy interval="1" modulate="true" /> <!-- 限制单个文件大小 --> <SizeBasedTriggeringPolicy size="2 MB" /> </Policies> <!-- 限制每天文件个数 --> <DefaultRolloverStrategy compressiOnLevel="0" max="10"/> </RollingFile> <RollingFile name="RollingFileError" fileName="${log_path}/error.log" filePattern="${log_path}/$${date:yyyy-MM}/error-%d{yyyy-MM-dd}-%i.log.gz"> <ThresholdFilter level="ERROR" /> <PatternLayout pattern="[%d][%t][%p][%c:%L] %m%n" /> <Policies> <!-- 归档每天的文件 --> <TimeBasedTriggeringPolicy interval="1" modulate="true" /> <!-- 限制单个文件大小 --> <SizeBasedTriggeringPolicy size="2 MB" /> </Policies> <!-- 限制每天文件个数 --> <DefaultRolloverStrategy compressiOnLevel="0" max="10"/> </RollingFile> </appenders> <loggers> <root level="info"> <appender-ref ref="Console" /> <appender-ref ref="RollingFileInfo" /> <appender-ref ref="RollingFileWarn" /> <appender-ref ref="RollingFileError" /> </root> </loggers> </configuration> 
    • 控制器代码:
    package com.hansonwang99.controller; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @RestController @RequestMapping("/testlogging") public class LoggingTestController { private final Logger logger = LogManager.getLogger(this.getClass()); @GetMapping("/hello") public String hello() { for(int i=0;i<10_0000;i++){ logger.info("info execute index method"); logger.warn("warn execute index method"); logger.error("error execute index method"); } return "My First SpringBoot Application"; } } 
    • 运行结果

    运行结果

    运行结果

    运行结果

    日志会根据不同的级别存储在不同的文件,当日志文件大小超过 2M 以后会分多个文件压缩存储,生产环境的日志文件大小建议调整为 20-50MB。


    后记

    作者更多的 SpringBt 实践文章在此:

    作者更多的原创文章在此


    CodeSheep

    17 条回复    2018-07-11 18:52:46 +08:00
    mineqiqi
        1
    mineqiqi  
       2018-03-29 09:12:17 +08:00
    mark 看下,谢谢楼主
    FenGuWu
        2
    FenGuWu  
       2018-03-29 09:20:36 +08:00 via Android
    mark2
    guojxx
        3
    guojxx  
       2018-03-29 09:26:46 +08:00
    mark3
    mynameisny
        4
    mynameisny  
       2018-03-29 09:27:33 +08:00
    呃……那个表……那个 G Shock ……有链接嘛
    starmoon1994
        5
    starmoon1994  
       2018-03-29 09:55:39 +08:00
    兄弟这文章 csdn 上一搜一大堆啊
    xcc880
        6
    xcc880  
       2018-03-29 09:58:17 +08:00
    @mynameisny 角度刁钻
    danielmiao
        7
    danielmiao  
       2018-03-29 10:21:59 +08:00
    有这么复杂??
    Spring Boot 的默认日志是 SLF4j+Logback
    所以只需要配置 logback 就可以了
    * application.properties

    >logging.cOnfig=classpath:logback.xml

    * logback.xml

    ```xml
    <?xml version="1.0" encoding="UTF-8"?>
    <configuration debug="false">
    <property name="LOG_HOME" value="${log.dir:-logs}/"/>
    <property name="ENCODER_PATTERN"
    value="%d{yyyy-MM-dd HH:mm:ss.SSS} %-5level [%10.10thread] %logger{20} - %msg%n"/>
    <contextName>${APP_NAME}</contextName>

    <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
    <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
    <Pattern>${ENCODER_PATTERN}</Pattern>
    </encoder>
    </appender>

    <appender name="INFO" class="ch.qos.logback.core.rolling.RollingFileAppender">
    <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
    <fileNamePattern>${LOG_HOME}/info.%d{yyyy-MM-dd}.log</fileNamePattern>
    <maxHistory>30</maxHistory>
    </rollingPolicy>
    <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
    <pattern>${ENCODER_PATTERN}</pattern>
    </encoder>
    </appender>

    <root>
    <level value="INFO"/>
    <!--<appender-ref ref="STDOUT"/>-->
    <appender-ref ref="INFO"/>
    </root>
    </configuration>
    ```
    hansonwang99
        8
    hansonwang99  
    OP
       2018-03-29 10:26:43 +08:00
    @danielmiao 大佬勿喷,向大佬致敬,学习了
    nita22
        9
    nita22  
       2018-03-29 10:34:38 +08:00
    支持支持
    ixx
        10
    ixx  
       2018-03-29 10:38:51 +08:00
    默认可以在 application.yml 里配置 log 的级别及输出目录很方便,如果有特殊需求(比如按级别输出指定文件)可以加一个 logback.xml 但加了 logback.xml 后原 application.yml 的配置将失效
    wulaoban666
        11
    wulaoban666  
       2018-03-29 10:57:17 +08:00
    作为一名新人,表示看的有点吃力
    canbingzt
        12
    canbingzt  
       2018-03-29 11:21:09 +08:00
    Spring Boot 默认是 logback 组件,需要关闭控制台的话这样就可以
    application.properties

    logging.cOnfig=classpath:logback.xml

    logback.xml

    <?xml version="1.0" encoding="UTF-8"?>
    <configuration>
    <include resource="org/springframework/boot/logging/logback/base.xml"/>

    <property name="root.level.console" value="OFF"/>
    </configuration>
    Solarest
        13
    Solarest  
       2018-03-29 11:23:33 +08:00
    也想问一下各位大佬,这个 spring boot 项目如果通过 docker 部署 jar 包,那么我需要如何配置,才可以比较优雅的拿到.log 文件
    kunluanbudang
        14
    kunluanbudang  
       2018-03-29 12:42:36 +08:00 via Android
    MicroCatPad
        15
    MicroCatPad  
       2018-03-29 12:47:32 +08:00
    @Solarest 挂载目录
    z530151716
        16
    z530151716  
       2018-03-29 13:07:20 +08:00
    mark 一下
    jemygraw
        17
    jemygraw  
       2018-07-11 18:52:46 +08:00
    可以看看 https://github.com/qiniu/qiniu-logging-plugin ,spring boot 的日志直接上云。
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     961 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 27ms UTC 20:00 PVG 04:00 LAX 13:00 JFK 16:00
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86