• SpringBoot 日志配置


    常见的框架日志有:log4j,log4j2,logback,common-logging(JCL),java-util-logging(JUL)和slf4j等。

    而日志框架主要分两类:

    • 日志门面(抽象)如:jboss-logging,slf4j,JCL
    • 日志实现(实现)如:log4j,log4j2,logback,JUL

    对于日志实现,JUL实现简陋,很多地方被开发者吐槽,所以排除;log4j和logback是同一个作者开发的,且logback是log4j的升级版,比log4j会更好点,排除log4j;log4j2不是log4j的升级版,因为太过于优秀,部分框架对其的支持有限,所以排除。

    所以日志实现选中logback。

    对于日志门面,jboss-logging很久未更新,而slf4j的作者就是log4j和logback的作者,所以选用slf4j和logback会比较合得来....

    所以日志门面选用slf4j。并且在springboot中也是使用的 slf4j + logback。

    简单使用

    首先导入slf4j的jar包和logback的jar包

    在开发的时候,日志记录方法的调用不应该直接调用日志的实现类,而是调用日志抽象层里面的方法。

    参考官方文档:https://www.slf4j.org/manual.html

    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    
    public class HelloWorld {
      public static void main(String[] args) {
        Logger logger = LoggerFactory.getLogger(HelloWorld.class);
        logger.info("Hello World");
      }
    }
    

    如何让系统中的所有的日志都统一到slf4j

    在系统中,自己使用了slf4j+logback,但是Spring默认的是commons-logging;如果集成Hibernate,他又自带了jboss-logging;如果集成mybatis,他又有自己的日志系统。

    想统一日志框架,都使用slf4j输出日志,可以参考slf4j官网 https://www.slf4j.org/legacy.html

    legacy

    slf4j提供了解决方案:

    1. 将系统中的其他日志框架排除出去(删除其他日志框架的jar包,如:commons-logging日志的jar包等);

    2. 然后使用中间包来替代原有的日志框架(如上图的jcl-over-slf4j.jar replaces commons-logging.jar,log4j-over-slf4j.jar replaces log4j.jar等);

    3. 导入slf4j其他日志包的实现;

      那些中间包实际上提供了原有包的功能,但是也对slf4j进行了实现。就像log4j-to-slf4j.jar下面的路径还是和log4j一样,但是里面的日志记录的功能使用的是slf4j:

      1566057101545

    Spring Boot的日志关系

    新建一个springboot项目,然后打开pom文件,查看依赖(右键>Diagrams>Show...)

    看到SpringBoot依赖spring-boot-starter

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter</artifactId>
        <version>2.1.7.RELEASE</version>
        <scope>compile</scope>
    </dependency>
    

    而spring-boot-starter依赖spring-boot-starter-logging,所以springboot使用它来做日志功能。

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-logging</artifactId>
        <version>2.1.7.RELEASE</version>
        <scope>compile</scope>
    </dependency>
    

    看一下spring-boot-starter-logging:

    所以springboot底层是使用slf4j+logback的方式进行日志记录的,并把其他日志替换成了slf4j;

    使用和配置

    1. 修改日志级别
    import org.junit.Test;
    import org.junit.runner.RunWith;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import org.springframework.boot.test.context.SpringBootTest;
    import org.springframework.test.context.junit4.SpringRunner;
    
    @RunWith(SpringRunner.class)
    @SpringBootTest
    public class SpringBoot03LoggingApplicationTests {
        Logger logger = LoggerFactory.getLogger(SpringBoot03LoggingApplicationTests.class);
        @Test
        public void contextLoads() {
            //日记级别:
            //从低到高:trace<debug<info<warn<error
            //可以调整输出的日志级别;日志就只在这个级别和之后的高级别生效
            logger.trace("这是trace日志");
            logger.debug("这是debug日志");  //调试日志
            //springboot默认的日志级别是info,所以运行时只会打印info级别和高于info级别的日志信息
            logger.info("这是info日志");  //
            logger.warn("这是warn日志");  //警告日志
            logger.error("这是error日志"); //错误日志
        }
    }
    
    

    所以打印是:

    但是可以通过properties等配置文件修改日志级别:

    logging.level.com.wangd = trace
    

    修改指定位置文件的日志级别后打印如下:

    1. 生成日志文件

      指定logging.file

    logging.level.com.wangd = trace
    
    # 不指定路径和文件的情况下,只在控制台打印日志信息
    # 若指定了logging.file,而无论是否指定logging.path,都只在指定文件中保存日志信息,而不会在路径中保存日志
    # 对于logging.path,若指定了目录,则会在这个目录中自动生成spring.log保存日志信息
    #logging.path=/spring/log
    logging.file=spring.log
    

    指定logging.path=/spring/log

    logging.level.com.wangd = trace
    
    # 不指定路径和文件的情况下,只在控制台打印日志信息
    # 若指定了logging.file,而无论是否指定logging.path,都只在指定文件中保存日志信息,而不会在路径中保存日志
    # 对于logging.path,若指定了目录,则会在当前磁盘的这个目录中自动生成spring.log保存日志信息
    logging.path=/spring/log
    #logging.file=spring.log
    

    1. 修改日志输出格式

      # 日志输出格式:
      # %d:日期时间
      # %thread:线程名
      # %-5level:级别从左显示5个字符宽度
      # %logger{50}:表示logger名字最长50个字符,否则按照句点切割
      # %msg:日志消息
      # %n:换行符
      
      # 在控制台输出日志的格式
      logging.pattern.console=%d{yyyy-MM-dd} [%thread] %-2level %logger{5} - %msg%n
      # 在日志文件中输出日志的格式
      logging.pattern.file=%d{yyyy-MM-dd} === [%thread] %-5level %logger{50} - %msg%n
      
    2. 使用@Slf4j注解

      在使用类名的时候,每个类都需要自己编写

      Logger mLogger = LoggerFactory.getLogger(XXX.class);
      

      会很不方便,所以可以通过一个注解(@Slf4j)来帮我们实现,该注解就可以帮我们自动创建一个 log对象。

      但是 如果使用 @Slf4j 注解 需要两点,

      1. 安装lombok插件,参考idea安装插件

      2. 添加 lombok的依赖

      <!--添加lombok依赖-->
      <dependency>
          <groupId>org.projectlombok</groupId>
          <artifactId>lombok</artifactId>
      </dependency>
      

      就可以使用@Slf4j注解了。

      @RunWith(SpringRunner.class)
      @SpringBootTest
      @Slf4j
      public class SpringBoot03LoggingApplicationTests {
          @Test
          public void contextLoads() {
              log.info("这是info日志");  //
              log.warn("这是warn日志");  //警告日志
              log.error("这是error日志"); //错误日志
          }
      }  
      
    3. 指定日志配置文件

    • logback.xml可以被日志框架直接识别;

    • logback-spring.xml无法被日志框架识别,但是可以由springboot识别,可以使用springboot的高级Profile功能。

      <!-- 如在logback-spring.xml中加入-->
      <springProfile name="dev">
       	 <!-- 可以指定某段配置只在某个环境下生效-->
       	 <pattern>%d{yyyy-MM-dd'T'HH:mm:ss.SSSXXX} %level [%thread] [%logger{100}.%method:%line] - %msg%n</pattern>
      </springProfile>,
      
      <!--然后修改properties配置文件的profile为dev-->
      spring.profiles.active=dev
      就可以在启动环境为dev时,日志打印的格式为对应配置的格式
      

    所以logback[-spring].xml,格式需要自己查询。

    另外logback.xml文件中配置了springProfile的话,运行会报错。

    <?xml version="1.0" encoding="utf-8" ?>
    <configuration>
    
        <appender name="consoleLog" class="ch.qos.logback.core.ConsoleAppender">
            <springProfile name="dev">
                <layout class="ch.qos.logback.classic.PatternLayout">
                    <pattern>%d -- %msg%n</pattern>
                </layout>
            </springProfile>
            <springProfile name="test">
                <layout class="ch.qos.logback.classic.PatternLayout">
                    <pattern>%d -----== %msg%n</pattern>
                </layout>
            </springProfile>
        </appender>
    
        <appender name="fileInfoLog" class="ch.qos.logback.core.rolling.RollingFileAppender">
            <filter class="ch.qos.logback.classic.filter.LevelFilter">
                <!--要拦截的日志级别-->
                <level>ERROR</level>
                <!--如果匹配,则禁止-->
                <onMatch>DENY</onMatch>
                <!--如果不匹配,则允许记录-->
                <onMismatch>ACCEPT</onMismatch>
            </filter>
            <encoder>
                <pattern>%d -- %msg%n</pattern>
            </encoder>
            <!--滚动策略-->
            <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
                <!--路径-->
                <fileNamePattern>d:/info-%d.log</fileNamePattern>
            </rollingPolicy>
        </appender>
    
        <appender name="fileErrorLog" class="ch.qos.logback.core.rolling.RollingFileAppender">
            <!--添加 范围 过滤-->
            <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
                <level>ERROR</level>
            </filter>
            <encoder>
                <pattern>%d -- %msg%n</pattern>
            </encoder>
            <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
                <fileNamePattern>d:/error-%d.log</fileNamePattern>
            </rollingPolicy>
        </appender>
    
        <root level="info">
            <appender-ref ref="consoleLog" />
            <appender-ref ref="fileInfoLog"/>
            <appender-ref ref="fileErrorLog"/>
        </root>
    </configuration>
    
  • 相关阅读:
    在SpringBoot中使用JWT
    异常解决:non-compatible bean definition of same name and class【com.xxx.xxx.XXX】
    mysql 字段名和关键字冲突
    约束(主键、非空、唯一性、外键、检查约束)
    唯一索引与非唯一索引区别(UNIQUE INDEX, NON-UNIQUE INDEX)
    数据库设计mysql字段不默认为NULL原因搜集
    mysql索引总结----mysql 索引类型以及创建
    互联网数据库架构设计思路
    干货满满!10分钟看懂Docker和K8S
    PowerDesigner 使用教程(很具体,很实用)
  • 原文地址:https://www.cnblogs.com/wangd1/p/13646119.html
Copyright © 2020-2023  润新知