SpringBoot项目从0到1配置logback日志打印

大家好!我是sum墨,一个一线的底层码农,平时喜欢研究和思考一些技术相关的问题并整理成文,限于本人水平,如果文章和代码有表述不当之处,还请不吝赐教。

以下是正文!

一、写文背景

我们在写后端项目的时候,日志打印是必需的。支持SpringBoot项目的日志框架一般有log4j、logback,这二者各有优劣,这里就不展开对比了。我们项目中常用的是logback框架,该框架主要是一个logback-spring.xml配置文件起作用。每次起新的项目我都是从老项目中copy一份出来,这份配置文件内容很详细,几百行左右,我一般都是修改一下应用名、日志输出路径,新项目就可以用了。这份老文件是之前的一个师兄留下的,我使用的时候也没深入去思考过各个配置的作用,这段时间刚好比较空闲,打算从0开始写出一个自己能看懂的logback-spring.xml

二、准备篇

首先,我准备了一个空的SpringBoot项目,版本为2.7.13。项目结构图如下:

SpringBoot项目从0到1配置logback日志打印_第1张图片

初始的pom.xml配置文件内容如下:



    4.0.0
    
        org.springframework.boot
        spring-boot-starter-parent
        2.7.13
         
    
    com.example
    logback
    0.0.1-SNAPSHOT
    logback
    Demo project for Spring Boot
    
        1.8
    
    
        
        
            org.springframework.boot
            spring-boot-starter-web
        
    

    
        
            
                org.springframework.boot
                spring-boot-maven-plugin
            
        
    

启动日志输出如下:

其次,引入logback核心组件,因为SpringBoot自带logback组件,所以我们在引入的时候不需要指定logback的版本号。



  ch.qos.logback
  logback-core

最后,我们在resources目录下新建一个空的logback-spring.xml文件,代码如下:



   

这样我们在启动的时候,打印只有一个banner 

三、基础篇

1、输出日志到控制台(console)

刚才我们看到如果logback-spring.xml的配置为空的话,那么只会输出一个banner,其他的日志都不会被打印,所以我们第一步就是要把日志打印到控制台上来。

第一步、配置控制台的appender(logback中appender是负责写日志的组件)



    
    
        
            
            %d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] ${PID:- } %logger{36} %-5level - %msg%n
            utf8
        
    

第二步、设置打印到控制台的日志的级别



    
    
        
            
            %d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] ${PID:- } %logger{36} %-5level - %msg%n
            utf8
        
    

    
    
        
    

这时控制台已经有日志输出了,输出格式如下

第三步、加入logback默认的一些配置

上面自定义的输出格式有点丑,logback给我们提供了一些默认的配置和格式,只需要使用include标签引入即可。
代码如下:



    
    

    
    
        
            
            ${CONSOLE_LOG_PATTERN}
            utf8
        
    

    
    
        
    

这时我们再启动,发现样式就好看多了

2、将日志输出到文件,如application.log文件

刚才的日志是打印到控制台的,我们一旦把ide关闭就看不到了,所以我们需要把日志输出到一个文件中,以便将日志留存下来。

第一步、定义应用名称,区分应用



    
    

   
   

  
    
        
            
            ${CONSOLE_LOG_PATTERN}
            utf8
        
    

    
    
        
    

第二步、定义日志文件的输出路径



    
    

    
    
    
    
    
    
    
        
            
            ${CONSOLE_LOG_PATTERN}
            utf8
        
    

    
    
        
    

第三步、定义日志文件名称和路径



    
    

    
    
    
    
    
    
    
    
    
        
            
            ${CONSOLE_LOG_PATTERN}
            utf8
        
    

    
    
        
    

第四步、将日志滚动输出到application.log文件中



    
    

    
    
    
    
    
    

    
    
        
        ${LOG_FILE}
        
            
            ${CONSOLE_LOG_PATTERN}
            utf8
        
    

    
    
        
            
            ${CONSOLE_LOG_PATTERN}
            utf8
        
    

    
    
        
        
    

第五步、设置 RollingPolicy 属性,用于配置文件大小限制,保留天数、文件名格式


    
    
   
   
    
    
    
    
    

  
    
        
        ${LOG_FILE}
        
            
            ${CONSOLE_LOG_PATTERN}
            utf8
        
        
        
            
            ${LOG_FILE}.%d{yyyy-MM-dd}.%i.log
            
            7
            
            50MB
            
            500MB
        
    
    

  
    
        
            
            ${CONSOLE_LOG_PATTERN}
            utf8
        
    
  
   
    
        
        
    

第六步、追加日志到APPLICATION中


    
    
    
  
    
    
    
    
    

   
    
        
        ${LOG_FILE}
        
            
            ${CONSOLE_LOG_PATTERN}
            utf8
        
        
        
            
            ${LOG_FILE}.%d{yyyy-MM-dd}.%i.log
            
            7
            
            50MB
            
            500MB
        
    
    
 
  
    
        
            
            ${CONSOLE_LOG_PATTERN}
            utf8
        
    
   
   
    
        
        
        
        
    

配置好之后,启动项目,找到user.home会发现有一个logback-test的文件,里面有一个application.log文件,如下图

温馨提示:如何找到user.home

在Windows上,可以通过打开Windows资源管理器,然后在地址栏中键入%userprofile%来找到user.home。

在Mac上,可以通过打开终端应用程序,然后输入echo $HOME命令来找到user.home。

在Linux上,可以通过打开终端应用程序,然后输入echo $HOME命令来找到user.home。

  

3、日志分级,将INFO、WARN、ERROR日志分别打印

其实INFO的日志已经在打印在控制台中了,这里我们需要单独把WARN、ERROR拎出来打印,主要是为了方便后续排查bug使用。

第一步、定义WARN、ERROR日志文件路径


    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
        
        ${LOG_FILE}
        
            
            ${CONSOLE_LOG_PATTERN}
            utf8
        
        
        
            
            ${LOG_FILE}.%d{yyyy-MM-dd}.%i.log
            
            7
            
            50MB
            
            500MB
        
    
    
    
        
            
            ${CONSOLE_LOG_PATTERN}
            utf8
        
    
    
    
        
        
        
        
    

第二步、将WARN、ERROR日志摘取出并输出到指定文件中 


    
    
    
    
    
    
    
    
    
    
    
    

    
    
        
        ${LOG_FILE}
        
            
            ${CONSOLE_LOG_PATTERN}
            utf8
        
        
        
            
            ${LOG_FILE}.%d{yyyy-MM-dd}.%i.log
            
            7
            
            50MB
            
            500MB
        
    

    
    
        ${WARN_LOG_FILE}
        
            
            ${CONSOLE_LOG_PATTERN}
            utf8
        
        
        
            
            ${LOG_PATH}/warn.%d{yyyy-MM-dd}.%i.log
            
            7
            
            50MB
            
            500MB
        
        
        
            WARN
        
    

    
    
        ${ERROR_LOG_FILE}
        
            
            ${CONSOLE_LOG_PATTERN}
            utf8
        
        
        
            
            ${LOG_PATH}/error.%d{yyyy-MM-dd}.%i.log
            
            7
            
            50MB
            
            500MB
        
        
        
            ERROR
        
    

    
    
        
            
            ${CONSOLE_LOG_PATTERN}
            utf8
        
    
    
    
        
        
        
        
    

第三步、将WARN、ERROR日志加到控制台打印,并输出到指定文件中 


    
    
    
    
    
    
    
    
    
    
    
    

    
    
        
        ${LOG_FILE}
        
            
            ${CONSOLE_LOG_PATTERN}
            utf8
        
        
        
            
            ${LOG_FILE}.%d{yyyy-MM-dd}.%i.log
            
            7
            
            50MB
            
            500MB
        
    

    
    
        ${WARN_LOG_FILE}
        
            
            ${CONSOLE_LOG_PATTERN}
            utf8
        
        
        
            
            ${LOG_PATH}/warn.%d{yyyy-MM-dd}.%i.log
            
            7
            
            50MB
            
            500MB
        
        
        
            WARN
        
    

    
    
        ${ERROR_LOG_FILE}
        
            
            ${CONSOLE_LOG_PATTERN}
            utf8
        
        
        
            
            ${LOG_PATH}/error.%d{yyyy-MM-dd}.%i.log
            
            7
            
            50MB
            
            500MB
        
        
        
            ERROR
        
    

    
    
        
            
            ${CONSOLE_LOG_PATTERN}
            utf8
        
    

    
    
        
        
        
        
        
        
        
        
    

在启动之前,我分别加了一条WARN、ERROR日志,启动时自动打印,如下

 同时在logback-test目录下也生成了warn.log和error.log文件。

四、进阶篇

1、打印指定目录下的日志

现在我们调整项目结构如下:

SpringBoot项目从0到1配置logback日志打印_第2张图片

我想把service中的日志单独打印出来,输出到service.log中,步骤如下

第一步、定义指定目录日志文件输出路径 


    
    
    
    
    
    
    
    
    
    
    
    
    
    

    
    
        
        ${LOG_FILE}
        
            
            ${CONSOLE_LOG_PATTERN}
            utf8
        
        
        
            
            ${LOG_FILE}.%d{yyyy-MM-dd}.%i.log
            
            7
            
            50MB
            
            500MB
        
    

    
    
        ${WARN_LOG_FILE}
        
            
            ${CONSOLE_LOG_PATTERN}
            utf8
        
        
        
            
            ${LOG_PATH}/warn.%d{yyyy-MM-dd}.%i.log
            
            7
            
            50MB
            
            500MB
        
        
        
            WARN
        
    

    
    
        ${ERROR_LOG_FILE}
        
            
            ${CONSOLE_LOG_PATTERN}
            utf8
        
        
        
            
            ${LOG_PATH}/error.%d{yyyy-MM-dd}.%i.log
            
            7
            
            50MB
            
            500MB
        
        
        
            ERROR
        
    

    
    
        
            
            ${CONSOLE_LOG_PATTERN}
            utf8
        
    

    
    
        
        
        
        
        
        
        
        
    

第二步、定义指定目录日志的appender


    
    
    
    
    
    
    
    
    
    
    
    
    
    

    
    
        
        ${LOG_FILE}
        
            
            ${CONSOLE_LOG_PATTERN}
            utf8
        
        
        
            
            ${LOG_FILE}.%d{yyyy-MM-dd}.%i.log
            
            7
            
            50MB
            
            500MB
        
    

    
    
        ${WARN_LOG_FILE}
        
            
            ${CONSOLE_LOG_PATTERN}
            utf8
        
        
        
            
            ${LOG_PATH}/warn.%d{yyyy-MM-dd}.%i.log
            
            7
            
            50MB
            
            500MB
        
        
        
            WARN
        
    

    
    
        ${ERROR_LOG_FILE}
        
            
            ${CONSOLE_LOG_PATTERN}
            utf8
        
        
        
            
            ${LOG_PATH}/error.%d{yyyy-MM-dd}.%i.log
            
            7
            
            50MB
            
            500MB
        
        
        
            ERROR
        
    

    
    
        
            
            ${CONSOLE_LOG_PATTERN}
            utf8
        
    

    
    
        ${SERVICE_LOG_FILE}
        
            
            ${CONSOLE_LOG_PATTERN}
            utf8
        
        
        
            
            ${LOG_PATH}/service.%d{yyyy-MM-dd}.%i.log
            
            7
            
            50MB
            
            500MB
        
    

    
    
        
        
        
        
        
        
        
        
    

第三步、追加日志到service的appender中

这里我们不能直接将SERVICE加到root标签下,要使用另外一个标签logger,该标签继承了root,是子logger。该标签有一个additivity属性,若是additivity设为true,则子logger不止会在自己的appender里输出,还会在root的logger的appender里输出;若是additivity设为false,则子logger只会在自己的appender里输出,不会在root的logger的appender里输出


    
    
    
    
    
    
    
    
    
    
    
    
    
    

    
    
        
        ${LOG_FILE}
        
            
            ${CONSOLE_LOG_PATTERN}
            utf8
        
        
        
            
            ${LOG_FILE}.%d{yyyy-MM-dd}.%i.log
            
            7
            
            50MB
            
            500MB
        
    

    
    
        ${WARN_LOG_FILE}
        
            
            ${CONSOLE_LOG_PATTERN}
            utf8
        
        
        
            
            ${LOG_PATH}/warn.%d{yyyy-MM-dd}.%i.log
            
            7
            
            50MB
            
            500MB
        
        
        
            WARN
        
    

    
    
        ${ERROR_LOG_FILE}
        
            
            ${CONSOLE_LOG_PATTERN}
            utf8
        
        
        
            
            ${LOG_PATH}/error.%d{yyyy-MM-dd}.%i.log
            
            7
            
            50MB
            
            500MB
        
        
        
            ERROR
        
    

    
    
        
            
            ${CONSOLE_LOG_PATTERN}
            utf8
        
    

    
    
        ${SERVICE_LOG_FILE}
        
            
            ${CONSOLE_LOG_PATTERN}
            utf8
        
        
        
            
            ${LOG_PATH}/service.%d{yyyy-MM-dd}.%i.log
            
            7
            
            50MB
            
            500MB
        
    

    
    
    
        
    

    
    
        
        
        
        
        
        
        
        
    

启动只有又会多一个service.log,如下

SpringBoot项目从0到1配置logback日志打印_第3张图片

2、切面日志打印

可能有些同学不知道这个是啥,这里我举个场景,就好理解了。

假设现在的项目结构如下,增加了一个HttpAspect切面类,作用是监控controller中每个方法的入参、出参、接口耗时等信息,这个功能相信大家都做过。

SpringBoot项目从0到1配置logback日志打印_第4张图片

HttpAspect代码如下

@Retention(RetentionPolicy.SOURCE)
@Target(ElementType.TYPE)
public @interface Slf4j {
    /** @return The category of the constructed Logger. By default, it will use the type where the annotation is placed. */
    String topic() default "";
}

相信细心的同学已经发现问题了,controller目录下的类里面是没有打印的,log都在config目录下的HttpAspect中,显然指定打印目录为controller是不行的。

那如果指定目录为config呢?如果这个目录下只有一个HttpAspect类是可以的,但如果该目录下还有其他配置类,那这个办法就不太好用了。

这时我们就需要通过指定类的方式进行打印。

那怎么指定类进行打印呢?我们常用的@Slf4j注解里面有一个属性topic

@Retention(RetentionPolicy.SOURCE)
@Target(ElementType.TYPE)
public @interface Slf4j {
    /** @return The category of the constructed Logger. By default, it will use the type where the annotation is placed. */
    String topic() default "";
}

定义方式也很简单,如下

SpringBoot项目从0到1配置logback日志打印_第5张图片

这个topic定义之后,和logger中的name属性对上之后,那么这个logger就只会打印这个类的日志!!!

第一步、指定类定义topic

package com.example.logback.config;

import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;

@Slf4j(topic = "http-log")
@Aspect
@Component
public class HttpAspect {

    @Pointcut("execution(* com.example.logback.controller..*.*(..))")
    public void pointCut() {

    }

    @Around(value = "pointCut()")
    public Object doAround(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {

        // 获取目标参数
        String serviceUniqueName = proceedingJoinPoint.getSignature().getDeclaringTypeName();
        String methodName = proceedingJoinPoint.getSignature().getName();
        long start = System.currentTimeMillis();
        Object proceed = proceedingJoinPoint.proceed();
        log.info("@Http:{}.{},耗时:{}ms", serviceUniqueName, methodName,
            System.currentTimeMillis() - start);
        return proceed;
    }
}

第二步、定义指定类topic的日志文件输出路径 


    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    

    
    
        
        ${LOG_FILE}
        
            
            ${CONSOLE_LOG_PATTERN}
            utf8
        
        
        
            
            ${LOG_FILE}.%d{yyyy-MM-dd}.%i.log
            
            7
            
            50MB
            
            500MB
        
    

    
    
        ${WARN_LOG_FILE}
        
            
            ${CONSOLE_LOG_PATTERN}
            utf8
        
        
        
            
            ${LOG_PATH}/warn.%d{yyyy-MM-dd}.%i.log
            
            7
            
            50MB
            
            500MB
        
        
        
            WARN
        
    

    
    
        ${ERROR_LOG_FILE}
        
            
            ${CONSOLE_LOG_PATTERN}
            utf8
        
        
        
            
            ${LOG_PATH}/error.%d{yyyy-MM-dd}.%i.log
            
            7
            
            50MB
            
            500MB
        
        
        
            ERROR
        
    

    
    
        
            
            ${CONSOLE_LOG_PATTERN}
            utf8
        
    

    
    
        ${SERVICE_LOG_FILE}
        
            
            ${CONSOLE_LOG_PATTERN}
            utf8
        
        
        
            
            ${LOG_PATH}/service.%d{yyyy-MM-dd}.%i.log
            
            7
            
            50MB
            
            500MB
        
    

    
    
        ${HTTP_PACKAGE_LOG_FILE}
        
            
            ${CONSOLE_LOG_PATTERN}
            utf8
        
        
        
            
            ${LOG_PATH}/http-package.%d{yyyy-MM-dd}.%i.log
            
            7
            
            50MB
            
            500MB
        
    

    
    
    
        
    

    
    
    
        
    

    
    
        
        
        
        
        
        
        
        
    
 

第三步、定义指定类topic的appender


    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    

    
    
        
        ${LOG_FILE}
        
            
            ${CONSOLE_LOG_PATTERN}
            utf8
        
        
        
            
            ${LOG_FILE}.%d{yyyy-MM-dd}.%i.log
            
            7
            
            50MB
            
            500MB
        
    

    
    
        ${WARN_LOG_FILE}
        
            
            ${CONSOLE_LOG_PATTERN}
            utf8
        
        
        
            
            ${LOG_PATH}/warn.%d{yyyy-MM-dd}.%i.log
            
            7
            
            50MB
            
            500MB
        
        
        
            WARN
        
    

    
    
        ${ERROR_LOG_FILE}
        
            
            ${CONSOLE_LOG_PATTERN}
            utf8
        
        
        
            
            ${LOG_PATH}/error.%d{yyyy-MM-dd}.%i.log
            
            7
            
            50MB
            
            500MB
        
        
        
            ERROR
        
    

    
    
        
            
            ${CONSOLE_LOG_PATTERN}
            utf8
        
    

    
    
        ${SERVICE_LOG_FILE}
        
            
            ${CONSOLE_LOG_PATTERN}
            utf8
        
        
        
            
            ${LOG_PATH}/service.%d{yyyy-MM-dd}.%i.log
            
            7
            
            50MB
            
            500MB
        
    

    
    
        ${HTTP_PACKAGE_LOG_FILE}
        
            
            ${CONSOLE_LOG_PATTERN}
            utf8
        
        
        
            
            ${LOG_PATH}/http-package.%d{yyyy-MM-dd}.%i.log
            
            7
            
            50MB
            
            500MB
        
    

    
    
        ${HTTP_TOPIC_LOG_FILE}
        
            
            ${CONSOLE_LOG_PATTERN}
            utf8
        
        
        
            
            ${LOG_PATH}/http-topic.%d{yyyy-MM-dd}.%i.log
            
            7
            
            50MB
            
            500MB
        
    

    
    
    
        
    

    
    
    
        
    

    
    
        
        
        
        
        
        
        
        
    

第四步、追加日志到指定类topic的appender中


    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    

    
    
        
        ${LOG_FILE}
        
            
            ${CONSOLE_LOG_PATTERN}
            utf8
        
        
        
            
            ${LOG_FILE}.%d{yyyy-MM-dd}.%i.log
            
            7
            
            50MB
            
            500MB
        
    

    
    
        ${WARN_LOG_FILE}
        
            
            ${CONSOLE_LOG_PATTERN}
            utf8
        
        
        
            
            ${LOG_PATH}/warn.%d{yyyy-MM-dd}.%i.log
            
            7
            
            50MB
            
            500MB
        
        
        
            WARN
        
    

    
    
        ${ERROR_LOG_FILE}
        
            
            ${CONSOLE_LOG_PATTERN}
            utf8
        
        
        
            
            ${LOG_PATH}/error.%d{yyyy-MM-dd}.%i.log
            
            7
            
            50MB
            
            500MB
        
        
        
            ERROR
        
    

    
    
        
            
            ${CONSOLE_LOG_PATTERN}
            utf8
        
    

    
    
        ${SERVICE_LOG_FILE}
        
            
            ${CONSOLE_LOG_PATTERN}
            utf8
        
        
        
            
            ${LOG_PATH}/service.%d{yyyy-MM-dd}.%i.log
            
            7
            
            50MB
            
            500MB
        
    

    
    
        ${HTTP_PACKAGE_LOG_FILE}
        
            
            ${CONSOLE_LOG_PATTERN}
            utf8
        
        
        
            
            ${LOG_PATH}/http-package.%d{yyyy-MM-dd}.%i.log
            
            7
            
            50MB
            
            500MB
        
    

    
    
        ${HTTP_TOPIC_LOG_FILE}
        
            
            ${CONSOLE_LOG_PATTERN}
            utf8
        
        
        
            
            ${LOG_PATH}/http-topic.%d{yyyy-MM-dd}.%i.log
            
            7
            
            50MB
            
            500MB
        
    

    
    
    
        
    

    
    
    
        
    

    
    
    
        
    


    
    
        
        
        
        
        
        
        
        
    

 日志目录中多了一个文件,http-topic,如下

SpringBoot项目从0到1配置logback日志打印_第6张图片

五、写在最后

这篇文章篇幅比较长,主要是配置文件贴的比较多,我本来是想每一步只贴关键代码的,但成文之后看起来有点费劲,所以每一步都贴了全量的配置。xml文件我觉得是比较难阅读的一种文档,里面的标签又多又乱,没有顺序可言。如果不是从第一个标签开始看,根本不知道标签之间的依赖关系,为了方便大家阅读,我在博客园也发布一篇,SpringBoot项目从0到1配置logback日志打印

 

 

你可能感兴趣的:(java,开发语言)