springboot下添加日志模块和设置日志文件输出

前言

日志的使用将通过SLF4J来使用,SLF4J(Simple Logging Facade for Java)是一个为Java应用提供简单日志记录的接口。它的主要目标是在不同的日志系统之间提供一个简单的抽象层,使得应用能够以一种灵活的方式切换日志实现,而不需要修改应用本身的代码。SLF4J不是一个具体的日志实现,而是一个桥接,它与其他具体的日志系统(如Log4J、Logback、Java Util Logging等)一起使用。在Spring框架中,SLF4J常常用于处理框架本身以及应用程序的日志记录。

使用

在pom文件添加以下依赖,使用logback,由于logback1.2.9以下存在漏洞,推荐使用新版本

    <dependency>
      <groupId>org.projectlombok</groupId>
      <artifactId>lombok</artifactId>
      <version>1.18.30</version>
      <optional>true</optional>
    </dependency>

    <dependency>
      <groupId>ch.qos.logback</groupId>
      <artifactId>logback-classic</artifactId>
      <version>1.4.14</version>
      <scope>test</scope>
    </dependency>

    <dependency>
      <groupId>ch.qos.logback</groupId>
      <artifactId>logback-core</artifactId>
      <version>1.4.14</version>
    </dependency>

在需要使用的类上面标注@Slf4j,即可使用log的相关方法,比如在全局异常类可以这样使用:

@Slf4j
@RestControllerAdvice
public class GlobalExceptionHandler {

    /********************************
     *  @function  : 自定义从捕捉
     *  @parameter : [e:CustomException | 自定义异常]
     *  @date      : 2023/12/5 11:47
     ********************************/
    @ExceptionHandler(value = CustomException.class)
    public AjaxResult customExceptionHandler(HttpServletRequest request, CustomException e) {
        log.error("业务异常,url:{}, 异常内容:{}" ,request.getRequestURI(), e);
        return new AjaxResult(e.getCode() , e.getMessage(), null);
    }

    /********************************
     *  @function  : 空指针异常捕捉
     *  @parameter : [e:Exception | 异常]
     *  @date      : 2023/12/5 11:47
     ********************************/
    @ExceptionHandler(value = Exception.class)
    public AjaxResult exceptionHandler(HttpServletRequest request, Exception e) {
        log.error("服务器内部异常异常,url:{}, 异常内容:{}" ,request.getRequestURI(), e);
        return new AjaxResult(500 , e.getMessage(), null);
    }

}

在try,catch中的使用,catch中不要使用e.printstacktrace,使用log代替:

try {
...
} catch {
  log.error{"..发送了异常,参数是{},异常信息{}",id,e};
}

阿里巴巴的日志规范

  1. 【强制】应用中不可直接使用日志系统(Log4j、Logback)中的API,而应依赖使用日志框架SLF4J中的API,使用门面模式的日志框架,有利于维护和各个类的日志处理方式统一。

    import org.slf4j.Logger;import org.slf4j.LoggerFactory;private static final Logger logger = LoggerFactory.getLogger(Abc.class);  
    
  2. 【强制】日志文件推荐至少保存15天,因为有些异常具备以“周”为频次发生的特点。

  3. 【强制】应用中的扩展日志(如打点、临时监控、访问日志等)命名方式:appName_logType_logName.log。logType:日志类型,推荐分类有stats/monitor/visit等;logName:日志描述。这种命名的好处:通过文件名就可知道日志文件属于什么应用,什么类型,什么目的,也有利于归类查找。

    正例:mppserver应用中单独监控时区转换异常,如:
    mppserver_monitor_timeZoneConvert.log
    

    说明:推荐对日志进行分类,如将错误日志和业务日志分开存放,便于开发人员查看,也便于通过日志对系统进行及时监控。

  4. 【强制】对trace/debug/info级别的日志输出,必须使用条件输出形式或者使用占位符的方式。

    说明:logger.debug(“Processing trade with id: “ + id + “ and symbol: “ + symbol); 如果日志级别是warn,上述日志不会打印,但是会执行字符串拼接操作,如果symbol是对象,会执行toString()方法,浪费了系统资源,执行了上述操作,最终日志却没有打印。
    

    正例:

    (条件)    
        if (logger.isDebugEnabled()) {      
            logger.debug("Processing trade with id: " + id + " and symbol: " + symbol);     
        }  
    

    正例:

    (占位符)
        logger.debug("Processing trade with id: {} and symbol : {} ", id, symbol);   
    
  5. 【强制】避免重复打印日志,浪费磁盘空间,务必在log4j.xml中设置additivity=false。

    正例:
    <logger name="com.taobao.dubbo.config" additivity="false">

  6. 【强制】异常信息应该包括两类信息:案发现场信息和异常堆栈信息。如果不处理,那么通过关键字throws往上抛出。

    正例:

    logger.error(各类参数或者对象toString + "_" + e.getMessage(), e);
    
  7. 【推荐】谨慎地记录日志。生产环境禁止输出debug日志;有选择地输出info日志;如果使用warn来记录刚上线时的业务行为信息,一定要注意日志输出量的问题,避免把服务器磁盘撑爆,并记得及时删除这些观察日志。
    说明:大量地输出无效日志,不利于系统性能提升,也不利于快速定位错误点。记录日志时请思考:这些日志真的有人看吗?看到这条日志你能做什么?能不能给问题排查带来好处?

  8. 【推荐】可以使用warn日志级别来记录用户输入参数错误的情况,避免用户投诉时,无所适从。如非必要,请不要在此场景打出error级别,避免频繁报警。

    说明:注意日志输出的级别,error级别只记录系统逻辑出错、异常或者重要的错误信息。

日志的配置文件

配置日志文件的持久化,示例如下:

<?xml version="1.0" encoding="UTF-8"?>
<!-- 日志级别从低到高分为TRACE < DEBUG < INFO < WARN < ERROR < FATAL,如果设置为WARN,则低于WARN的信息都不会输出 -->
<!-- scan:当此属性设置为true时,配置文档如果发生改变,将会被重新加载,默认值为true -->
<!-- scanPeriod:设置监测配置文档是否有修改的时间间隔,如果没有给出时间单位,默认单位是毫秒。
                 当scan为true时,此属性生效。默认的时间间隔为1分钟。 -->
<!-- debug:当此属性设置为true时,将打印出logback内部日志信息,实时查看logback运行状态。默认值为false。 -->
<configuration  scan="true" scanPeriod="10 seconds">
    <contextName>logback</contextName>

    <!-- name的值是变量的名称,value的值时变量定义的值。通过定义的值会被插入到logger上下文中。定义后,可以使“${}”来使用变量。 -->
    <property name="log.path" value="./log" />

    <!--0. 日志格式和颜色渲染 -->
    <!-- 彩色日志依赖的渲染类 -->
    <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(:){faint} %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}}"/>

    <!--1. 输出到控制台-->
    <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
        <!--此日志appender是为开发使用,只配置最底级别,控制台输出的日志级别是大于或等于此级别的日志信息-->
        <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
            <level>debug</level>
        </filter>
        <encoder>
            <Pattern>%d{yyyy-MM-dd HH:mm:ss.SSS}---[%thread] %-5level %logger{50} - %msg%n</Pattern>
            <!-- 设置字符集 -->
            <charset>UTF-8</charset>
        </encoder>
    </appender>

    <!--2. 输出到文档-->
    <!-- 2.1 level为 DEBUG 日志,时间滚动输出  -->
    <appender name="DEBUG_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <!--日志文档输出格式-->
        <encoder>
            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
            <charset>UTF-8</charset> <!-- 设置字符集 -->
        </encoder>
        <!-- 日志记录器的滚动策略,按日期,按大小记录 -->
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <!-- 日志归档 -->
            <fileNamePattern>${log.path}/debug/web-debug-%d{yyyy-MM-dd}.%i.log</fileNamePattern>
            <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
                <maxFileSize>10MB</maxFileSize>
            </timeBasedFileNamingAndTriggeringPolicy>
            <!--日志文档保留天数-->
            <maxHistory>15</maxHistory>
        </rollingPolicy>
        <!-- 此日志文档只记录debug级别的 -->
        <filter class="ch.qos.logback.classic.filter.LevelFilter">
            <level>debug</level>
            <onMatch>ACCEPT</onMatch>
            <onMismatch>DENY</onMismatch>
        </filter>
    </appender>

    <!-- 2.2 level为 INFO 日志,时间滚动输出  -->
    <appender name="INFO_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <!--日志文档输出格式-->
        <encoder>
            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
            <charset>UTF-8</charset>
        </encoder>
        <!-- 日志记录器的滚动策略,按日期,按大小记录 -->
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <!-- 每天日志归档路径以及格式 -->
            <fileNamePattern>${log.path}/info/web-info-%d{yyyy-MM-dd}.%i.log</fileNamePattern>
            <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
                <maxFileSize>10MB</maxFileSize>
            </timeBasedFileNamingAndTriggeringPolicy>
            <!--日志文档保留天数-->
            <maxHistory>15</maxHistory>
        </rollingPolicy>
        <!-- 此日志文档只记录info级别的 -->
        <filter class="ch.qos.logback.classic.filter.LevelFilter">
            <level>info</level>
            <onMatch>ACCEPT</onMatch>
            <onMismatch>DENY</onMismatch>
        </filter>
    </appender>

    <!-- 2.3 level为 WARN 日志,时间滚动输出  -->
    <appender name="WARN_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <!--日志文档输出格式-->
        <encoder>
            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
            <charset>UTF-8</charset> <!-- 此处设置字符集 -->
        </encoder>
        <!-- 日志记录器的滚动策略,按日期,按大小记录 -->
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <fileNamePattern>${log.path}/warn/web-warn-%d{yyyy-MM-dd}.%i.log</fileNamePattern>
            <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
                <maxFileSize>10MB</maxFileSize>
            </timeBasedFileNamingAndTriggeringPolicy>
            <!--日志文档保留天数-->
            <maxHistory>15</maxHistory>
        </rollingPolicy>
        <!-- 此日志文档只记录warn级别的 -->
        <filter class="ch.qos.logback.classic.filter.LevelFilter">
            <level>warn</level>
            <onMatch>ACCEPT</onMatch>
            <onMismatch>DENY</onMismatch>
        </filter>
    </appender>

    <!-- 2.4 level为 ERROR 日志,时间滚动输出  -->
    <appender name="ERROR_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <!--日志文档输出格式-->
        <encoder>
            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
            <charset>UTF-8</charset> <!-- 此处设置字符集 -->
        </encoder>
        <!-- 日志记录器的滚动策略,按日期,按大小记录 -->
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <fileNamePattern>${log.path}/error/web-error-%d{yyyy-MM-dd}.%i.log</fileNamePattern>
            <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
                <maxFileSize>10MB</maxFileSize>
            </timeBasedFileNamingAndTriggeringPolicy>
            <!--日志文档保留天数-->
            <maxHistory>15</maxHistory>
        </rollingPolicy>
        <!-- 此日志文档只记录ERROR级别的 -->
        <filter class="ch.qos.logback.classic.filter.LevelFilter">
            <level>ERROR</level>
            <onMatch>ACCEPT</onMatch>
            <onMismatch>DENY</onMismatch>
        </filter>
    </appender>


    <!--
        <logger>用来设置某一个包或者具体的某一个类的日志打印级别、
        以及指定<appender>。<logger>仅有一个name属性,
        一个可选的level和一个可选的addtivity属性。
        name:用来指定受此logger约束的某一个包或者具体的某一个类。
        level:用来设置打印级别,大小写无关:TRACE, DEBUG, INFO, WARN, ERROR, ALL 和 OFF,
              还有一个特俗值INHERITED或者同义词NULL,代表强制执行上级的级别。
              如果未设置此属性,那么当前logger将会继承上级的级别。
        addtivity:是否向上级logger传递打印信息。默认是true。
        <logger name="org.springframework.web" level="info"/>
        <logger name="org.springframework.scheduling.annotation.ScheduledAnnotationBeanPostProcessor" level="INFO"/>
    -->

    <!--
        使用mybatis的时候,sql语句是debug下才会打印,而这里我们只配置了info,所以想要查看sql语句的话,有以下两种操作:
        第一种把<root level="info">改成<root level="DEBUG">这样就会打印sql,不过这样日志那边会出现很多其他消息
        第二种就是单独给dao下目录配置debug模式,代码如下,这样配置sql语句会打印,其他还是正常info级别:
        【logging.level.org.mybatis=debug logging.level.dao=debug】
     -->

    <!--
        root节点是必选节点,用来指定最基础的日志输出级别,只有一个level属性
        level:用来设置打印级别,大小写无关:TRACE, DEBUG, INFO, WARN, ERROR, ALL 和 OFF,
        不能设置为INHERITED或者同义词NULL。默认是DEBUG
        可以包含零个或多个元素,标识这个appender将会添加到这个logger。
    -->

    <!-- 4. 最终的策略 -->
    <!-- 4.1 开发环境:打印控制台-->
    <!--    <springProfile name="dev">-->
    <!--        <logger name="com" level="debug"/>-->

    <!--    </springProfile>-->


    <root level="info">
        <appender-ref ref="CONSOLE" />
	    <appender-ref ref="DEBUG_FILE" />
        <appender-ref ref="INFO_FILE" />
        <appender-ref ref="WARN_FILE" />
        <appender-ref ref="ERROR_FILE" />
    </root>

    <!-- 4.2 生产环境:输出到文档
    <springProfile name="pro">
        <root level="info">
            <appender-ref ref="CONSOLE" />
            <appender-ref ref="DEBUG_FILE" />
            <appender-ref ref="INFO_FILE" />
            <appender-ref ref="ERROR_FILE" />
            <appender-ref ref="WARN_FILE" />
        </root>
    </springProfile> -->

</configuration>

其中,日志文件的大小和路径名称可以通过这块进行修改:

 <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <fileNamePattern>${log.path}/error/web-error-%d{yyyy-MM-dd}.%i.log</fileNamePattern>
            <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
                <maxFileSize>10MB</maxFileSize>
            </timeBasedFileNamingAndTriggeringPolicy>
            <!--日志文档保留天数-->
            <maxHistory>15</maxHistory>
        </rollingPolicy>

通过以上配置,产生的日志文件结构如下:

第一层是log文件夹:

image-20231211203208947

第二层是各个级别文件夹:

image-20231211203213475

第三层是每个日期的文件

image-20231211203221374

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: Spring Boot 框架的组成部分和功能模块主要包括以下几个方面: 1. Spring Boot Starter:Spring Boot Starter 是 Spring Boot 开发的核心模块之一,它提供了一系列的依赖包和配置,可以快速地构建 Spring Boot 应用程序。 2. Spring Boot Autoconfigure:Spring Boot Autoconfigure 可以自动地配置 Spring Boot 应用程序,它会根据应用程序的依赖和配置自动地配置应用程序的各个组件,并且让应用程序更加简单易用。 3. Spring Boot Actuator:Spring Boot Actuator 是 Spring Boot 提供的一个监控和管理组件,它可以帮助开发者监控应用程序的运行状态,并且提供了一系列的管理和监控接口,可以用于监控、管理和诊断应用程序。 4. Spring Boot CLI:Spring Boot CLI 是 Spring Boot 提供的一个命令行工具,可以用于快速创建、运行和调试 Spring Boot 应用程序。 5. Spring Boot Devtools:Spring Boot Devtools 是 Spring Boot 提供的一个开发工具,可以帮助开发者在开发过程中快速地修改、编译和测试应用程序。 6. Spring Boot Test:Spring Boot Test 是 Spring Boot 提供的一个测试框架,可以帮助开发者快速地编写和执行单元测试、集成测试和端到端测试等各种测试用例。 7. Spring Boot Web:Spring Boot Web 是 Spring Boot 提供的一个 Web 框架,可以帮助开发者快速地构建 Web 应用程序,并且提供了一系列的 Web 开发工具和组件,可以用于处理 HTTP 请求、响应和文件上传等各种 Web 开发任务。 ### 回答2: Spring Boot是一个用于简化Spring应用程序开发的框架。它由以下几个组成部分和功能模块组成: 1. 自动配置:Spring Boot利用了条件化配置的特性来消除繁琐的配置工作。通过自动配置,开发者可以使用默认的配置来快速启动应用程序,并根据需要进行自定义配置。 2. 起步依赖:Spring Boot提供了一系列预先配置好的依赖项,称为起步依赖。这些起步依赖可以根据需求引入和管理其他必需的依赖项,简化了项目构建和管理的过程。 3. 嵌入式服务器:Spring Boot内置了多个嵌入式Web服务器,如Tomcat、Jetty和Undertow。开发者可以选择其中之一来运行应用程序,而无需为部署和配置一个独立的服务器。 4. Actuator:Actuator是Spring Boot的一个重要模块,提供了监控和管理应用程序的功能。它可以通过HTTP接口或JMX来检查应用程序的运行状况、配置信息和性能指标,并进行管理和调整。 5. 数据访问:Spring Boot集成了多个常用的数据库访问框架,如Spring Data JPA、MyBatis和Hibernate。开发者可以使用这些框架来简化数据访问的过程。 6. 日志记录:Spring Boot默认使用Logback作为日志记录框架,同时也支持其他常用的日志记录框架,如Log4j和Slf4j。开发者可以根据需求进行配置和使用。 总之,Spring Boot的组成部分和功能模块提供了一系列开发和管理应用程序所需的工具和功能,简化了开发者的工作,并提高了生产力。 ### 回答3: Spring Boot是一个基于Spring框架的开发工具,它简化了Spring应用程序的配置和部署,并提供了丰富的功能模块Spring Boot的组成部分和功能模块主要包括以下几个方面: 1.自动配置(Auto-configuration):Spring Boot通过扫描classpath,根据应用程序的依赖关系来自动配置Spring应用程序。它自动配置了常用的功能模块,如数据库连接、事务管理、Web开发等,大大减少了配置的工作量。 2.启动器(Starters):Spring Boot提供了一系列的启动器,简化了Maven或Gradle的配置。它们包含了一组相关的依赖项,可以快速地添加所需的功能模块,例如添加spring-boot-starter-web就可以启用Web开发功能。 3.嵌入式Web服务器(Embedded Web Server):Spring Boot集成了多种嵌入式Web服务器,如Tomcat、Jetty和Undertow,开发人员不需要手动配置Web服务器,只需要编写Web应用程序代码即可。 4.健康检查(Health Check):Spring Boot提供了健康检查的功能,可以自动检测应用程序的运行状态,例如数据库的连接情况、缓存的可用性等,可以通过HTTP端点或者JMX进行访问和监控。 5.配置管理(Configuration Management):Spring Boot支持多种配置方式,可以通过属性文件、YAML文件、环境变量等方式进行配置,方便应用程序的部署和管理。 6.日志管理(Logging):Spring Boot集成了常用的日志框架,如Logback和Log4j,可以通过配置文件进行日志输出的管理和配置。 7.测试支持(Testing Support):Spring Boot提供了丰富的测试支持,可以进行单元测试、集成测试和端到端测试等,可以使用JUnit、Mockito等测试框架进行测试。 总的来说,Spring Boot提供了一套全面的功能模块,帮助开发人员快速构建和部署Spring应用程序,简化了开发流程,提高了开发效率。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值