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


    前言

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

    使用

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

        <dependency>
          <groupId>org.projectlombokgroupId>
          <artifactId>lombokartifactId>
          <version>1.18.30version>
          <optional>trueoptional>
        dependency>
    
        <dependency>
          <groupId>ch.qos.logbackgroupId>
          <artifactId>logback-classicartifactId>
          <version>1.2.9version>
        dependency>
    
       <dependency>
         <groupId>ch.qos.logbackgroupId>
         <artifactId>logback-coreartifactId>
         <version>1.2.9version>
       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。

      正例:

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

      正例:

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

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

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

    日志的配置文件

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

    
    
    
    
    
    <configuration  scan="true" scanPeriod="10 seconds">
        <contextName>logbackcontextName>
    
        
        <property name="log.path" value="./log" />
    
        
        
        <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}}"/>
    
        
        <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
            
            <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
                <level>debuglevel>
            filter>
            <encoder>
                <Pattern>%d{yyyy-MM-dd HH:mm:ss.SSS}---[%thread] %-5level %logger{50} - %msg%nPattern>
                
                <charset>UTF-8charset>
            encoder>
        appender>
    
        
        
        <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%npattern>
                <charset>UTF-8charset> 
            encoder>
            
            <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
                
                <fileNamePattern>${log.path}/debug/web-debug-%d{yyyy-MM-dd}.%i.logfileNamePattern>
                <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
                    <maxFileSize>10MBmaxFileSize>
                timeBasedFileNamingAndTriggeringPolicy>
                
                <maxHistory>15maxHistory>
            rollingPolicy>
            
            <filter class="ch.qos.logback.classic.filter.LevelFilter">
                <level>debuglevel>
                <onMatch>ACCEPTonMatch>
                <onMismatch>DENYonMismatch>
            filter>
        appender>
    
        
        <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%npattern>
                <charset>UTF-8charset>
            encoder>
            
            <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
                
                <fileNamePattern>${log.path}/info/web-info-%d{yyyy-MM-dd}.%i.logfileNamePattern>
                <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
                    <maxFileSize>10MBmaxFileSize>
                timeBasedFileNamingAndTriggeringPolicy>
                
                <maxHistory>15maxHistory>
            rollingPolicy>
            
            <filter class="ch.qos.logback.classic.filter.LevelFilter">
                <level>infolevel>
                <onMatch>ACCEPTonMatch>
                <onMismatch>DENYonMismatch>
            filter>
        appender>
    
        
        <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%npattern>
                <charset>UTF-8charset> 
            encoder>
            
            <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
                <fileNamePattern>${log.path}/warn/web-warn-%d{yyyy-MM-dd}.%i.logfileNamePattern>
                <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
                    <maxFileSize>10MBmaxFileSize>
                timeBasedFileNamingAndTriggeringPolicy>
                
                <maxHistory>15maxHistory>
            rollingPolicy>
            
            <filter class="ch.qos.logback.classic.filter.LevelFilter">
                <level>warnlevel>
                <onMatch>ACCEPTonMatch>
                <onMismatch>DENYonMismatch>
            filter>
        appender>
    
        
        <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%npattern>
                <charset>UTF-8charset> 
            encoder>
            
            <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
                <fileNamePattern>${log.path}/error/web-error-%d{yyyy-MM-dd}.%i.logfileNamePattern>
                <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
                    <maxFileSize>10MBmaxFileSize>
                timeBasedFileNamingAndTriggeringPolicy>
                
                <maxHistory>15maxHistory>
            rollingPolicy>
            
            <filter class="ch.qos.logback.classic.filter.LevelFilter">
                <level>ERRORlevel>
                <onMatch>ACCEPTonMatch>
                <onMismatch>DENYonMismatch>
            filter>
        appender>
    
    
        
    
        
    
        
    
        
        
        
        
    
        
    
    
        <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>
    
        
    
    configuration>
    

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

     <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
                <fileNamePattern>${log.path}/error/web-error-%d{yyyy-MM-dd}.%i.logfileNamePattern>
                <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
                    <maxFileSize>10MBmaxFileSize>
                timeBasedFileNamingAndTriggeringPolicy>
                
                <maxHistory>15maxHistory>
            rollingPolicy>
    

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

    第一层是log文件夹:

    image-20231211203208947

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

    image-20231211203213475

    第三层是每个日期的文件

    image-20231211203221374

  • 相关阅读:
    x264 参考帧管理原理:b_ref_reorder 数组变量
    Unity API学习之消息机制理论与应用
    C++基础算法离散化及区间合并篇
    走访名校名企,助力生涯规划
    双11好物分享:网络机顶盒哪个好?博主分享电视机顶盒排行榜
    再谈字符串
    Java项目SpringMVC拦截器+Redis优化登录功能
    每日一题:请解释什么是闭包(Closure)?并举一个实际的例子来说明。(前端初级)
    《工程伦理与学术道德》之《工程师的职业伦理》
    FastReport.Net 2022.2.17 Crack
  • 原文地址:https://www.cnblogs.com/Johnyzh/p/17895498.html