SpringBoot 日志设置

目录

      • 日志概述
      • springboot的日志实现
      • logback的日志格式
      • logback常用配置
      • 记录日志
        • 使用commons-logging
        • 使用slf4j(推荐)
      • 日志规范

 

日志概述

日志的作用

  • 便于分析程序执行过程
  • 方便调试
  • 可以将业务数据存储到文件、数据库、es,便于统计分析

 

常见的日志组件

  • 日志门面|接口层:提供日志接口 | api,常见的 slf4j、apache的commons-logging
  • 日志实现:提供具体实现,常见的 log4j、log4j2、logback、jdk自带的jul

日志组件对性能有一定影响,尤其是需要大量使用日志的项目,应该注意日志组件的选择。

日志之所以采用门面模式,是为了在项目中使用统一的日志api,方便以后切换。比如项目统一使用commons-logging的日志接口来记录日志,使用log4j作具体实现,后续可以直接切换为log4j2等其它日志实现组件,无需修改记录日志的相关java代码。
 

ssm老项目常用 commons-logging+log4j。

slf4j支持占位符,性能更高,springboot默认使用 slf4j+logback,通常也是使用 slf4j+logback。

 

springboot的日志实现

springboot默认集成了spring-boot-starter-logging,采用slf4j+logback作日志

<dependency>
    <groupId>org.springframework.bootgroupId>
    <artifactId>spring-boot-starter-loggingartifactId>
dependency>

 

这个依赖包含了

  • slf4j-api:slf4j的日志接口
  • logback-classic:logback对slf4j的实现
  • jul-to-slf4j:将jul转slf4j,已经包含了slf4j、logback的依赖
  • log4j-to-slf4j:将log4j转slf4j,已经包含了log4j、slf4j、logback的依赖

可以看出,spring-boot-starter-logging可以将其它日志类型转换为slf4j,如果要统一第三方jar依赖中的日志,exclusion移除第三方依赖自带的日志组件即可,spring-boot-starter-logging会自动适配为slf4j。

 

logback的日志格式

logback的日志级别

TRACE < DEBUG < INFO(默认) < WARN < ERROR < FATAL

 
logback日志默认格式

2020-05-24 16:51:38.323  INFO 25168 --- [           main] com.chy.visit.VisitApplication           : No active profile set, falling back to default profiles: default

日期时间   日志级别   pid   线程名(main是主线程)  哪个类输出的日志(包名.类名)  信息

pid即进程id,记录当前java进程的pid

 

logback常用配置

resources下新建 logback.xml 或 logback-spring.xml ,springboot应用启动时会自动加载这个文件,官方推荐使用logback-spring.xml,因为可以自动应用一些spring的配置。
 

彩色日志+区分环境+逐日输出+springboot admin实时查看日志+常用输出级别


<configuration debug="false">

    
    <property name="SERVER-NAME" value="user-server"/>

    
    <springProfile name="dev">
        <property name="LOG_HOME" value="C:/Users/chy/Desktop/日志"/>
    springProfile>
    <springProfile name="test">
        <property name="LOG_HOME" value="/app/微服务/${SERVER-NAME}"/>
    springProfile>
    <springProfile name="prod">
        <property name="LOG_HOME" value="/var/logs/${SERVER-NAME}"/>
    springProfile>

    
    <conversionRule conversionWord="clr" converterClass="org.springframework.boot.logging.logback.ColorConverter"/>
    <conversionRule conversionWord="wex"
                    converterClass="org.springframework.boot.logging.logback.WhitespaceThrowableProxyConverter"/>
    <conversionRule conversionWord="wEx"
                    converterClass="org.springframework.boot.logging.logback.ExtendedWhitespaceThrowableProxyConverter"/>

    
    <property name="CONSOLE_LOG_PATTERN"
              value="${CONSOLE_LOG_PATTERN:-%clr(%d{yyyy-MM-dd HH:mm:ss.SSS}){faint} %clr(${LOG_LEVEL_PATTERN:-%5p}) %clr(${PID:-}){magenta} %clr(---){faint} %clr([%15.15t]){faint} %clr(%-40.40logger{39}){cyan} %clr(LN:%L  ){faint} %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}}"/>

    
    <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
            
            <pattern>${CONSOLE_LOG_PATTERN}pattern>
            <charset>utf8charset>
        encoder>
    appender>

    
    <appender name="DAY_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            
            <FileNamePattern>${LOG_HOME}/${SERVER-NAME}-%d{yyyy-MM-dd}.logFileNamePattern>
            
            <MaxHistory>30MaxHistory>
        rollingPolicy>
        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
            
            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%npattern>
            
        encoder>
        
        <triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
            <MaxFileSize>500MBMaxFileSize>
        triggeringPolicy>
    appender>

    
    <appender name="FILE" class="ch.qos.logback.core.FileAppender">
        <file>${LOG_HOME}/${SERVER-NAME}-all.logfile>
        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
            
            
            <pattern>${CONSOLE_LOG_PATTERN}pattern>
        encoder>
    appender>

    
    <root level="INFO">
        <appender-ref ref="STDOUT"/>
        <appender-ref ref="DAY_FILE"/>
        <appender-ref ref="FILE"/>
    root>

    
    <logger name="com.apache.ibatis" level="WARN" />
    <logger name="java.sql.Connection" level="WARN" />
    <logger name="java.sql.Statement" level="WARN" />
    <logger name="java.sql.PreparedStatement" level="WARN" />
    <logger name="java.sql.ResultSet" level="DEBUG" />
    <logger name="com.alibaba.druid.pool.DruidPooledResultSet" level="ERROR" />

    <logger name="org.apache.shiro" level="WARN" />
    <logger name="springfox.documentation" level="WARN" />

configuration>
  • 彩色日志在springboot admin中、使用tail -f查看都是正常的,但使用记事本之类的纯文本阅读器打开是乱码,使用时要注意。尽量不要使用彩色日志这种花里花哨的东西,拉低性能。
  • 可以把之类的配置放在中,只在指定的环境中起作用

 

记录日志

使用commons-logging
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

public class Xxx {

    private static Log log = LogFactory.getLog(this.getClass());

    public void xxx(){
        log.info("xxx");
    }

}

 

使用slf4j(推荐)
  • 可以使用 LoggerFactory 手动创建日志对象,也可以使用 lombok 的注解自动创建log对象,默认对象名 log;
  • 输出多个值时,尽量不要用 + 号拼接字符串,使用占位符代替,性能更高;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class Xxx {

    private static Logger logger = LoggerFactory.getLogger(this.getClass());

    public void xxx(){
        String username="xxx", tel="xxx", address="xxx";
        log.info("username:{},tel:{},address:{}",username,tel,address);
    }

}

 

可以用 topic 属性设置日志主题,缺省时默认为所在类的全限定类名

// 17:37:09.322 [main] INFO com.chy.mall.service.UserServiceImpl - 日志信息
@Slf4j

// 17:34:08.554 [main] INFO Xxx服务 - xxx日志信息
// 17:34:08.554 [main] INFO Xxx定时任务 - xxx日志信息
@Slf4j(topic = "Xxx服务")
@Slf4j(topic = "Xxx定时任务")

 

日志规范

1、接口、rpc调用、重要的service方法,务必打印出方法入参、返回值

2、写代码时务必要在关键、重要之处务必打印日志,考虑出现bug时,打印的日志是否方便排查、定位问题

3、复杂类型尽量转换为 json 格式打印,json格式更通用,便于 copy 到 postman 测试、修复数据等

//用户信息user=User(userId=1, username=chy, tel=1888xxxx, orderList=null)
log.info("用户信息user={}", user);

//用户信息user={"tel":"1888xxxx","userId":1,"username":"chy"}
log.info("用户信息user={}", JSON.toJSONString(user));

你可能感兴趣的:(SpringBoot,springboot,日志,logback,slf4j,springboot日志)