精华内容
下载资源
问答
  • 0.为什么依赖日志,少依赖调试? 开发过程中,无论写RPC接口,还是正常的业务代码,之前我的习惯代码跑通后,进入断点调试模式,用不同的入参条件跟代码,模拟正常和非常情况,检查是否有隐藏的bug,这种做法...
    0.为什么多依赖日志,少依赖调试?
           开发过程中,无论是写RPC接口,还是正常的业务代码,之前我的习惯是代码跑通后,进入断点调试模式,用不同的入参条件跟代码,模拟正常和非常情况,检查是否有隐藏的bug,这种做法也确实奏效,能够及时地发现一些编码时没有考虑周全的校验、以及逻辑上的一些疏忽。但是往往随着测试一步步升级,从测试2环境切到测试3,从测试3切到预生产,debug已经不能为我所用了,往往这个时候代码报出一些奇怪错误的时候,就很难下手快速定位问题,当然系统上线之后出现紧急的bug,如果提前日志没有做好“埋点”,对于开发,那简直就是“灾难的时刻”。所以,作为一名业务组的开发人员,尤其是写复杂业务接口的时候,请特别重视“日志”,这个东西很像买保险,不能给你带来什么能预见的好处,但是能在你最困难的时候,帮你一把。


    1.日志分类
           日志分类,本文中不要理解为究竟是“Log4J”还是“SL4J”等这个层次的分类(小编公司用的是SL4J,基于这个层次的对比,网上很多),我要说的分类,是最终打出来的日志,从功能以及使用习惯角度上的分类,暂且分为如下四类:
          (1)系统致命错误日志
          (2)系统可控错误日志
          (3)用户操作日志
          (4)系统运行日志
           有开发经验的朋友很容易明白这4类日志的区别,对于日常开发,“4.系统运行日志”我们无需关注,这块收集会有架构同事在运维平台做处理,“3.用户操作日志”除非做行为分析等大数据搜集分析,无需过多关注,对于复杂业务来讲,必要处埋点,日志级别可为Error或Info,由日志收集系统规则制定,但是对于“1.系统致命错误日志”以及“2.系统可控错误日志”,作为一名后台开发就必须要着重注意了,这2中错误是必要收集的,级别最好定位Error,到线上之后将会非常方便排查问题、发现隐患。


    2.使用习惯
          1.养成看日志的习惯,从我在神州的一位同事身上我养成了每天看日志的习惯,尤其是重大上线之后,非常便于排除隐患。
          2.代码开发测试完成之后不要急着提交,先跑一遍看看日志是否看得懂。因为日志都是打出来供大家一起看的,觉得可以了,再提交代码。

          3.对于“系统致命错误日志”以及“系统可控错误日志”,在try catch的时候,logger的写法,最好这样写:

    private Logger logger = LoggerFactory.getLogger(ProductBackwardNewRemoteService.class);
    
    try{
    	//todo business
    }catch (BusinessException e){
    	result.setStatus(-1);
    	result.setMsg("XXXXXXXXX" + e);
    	return result;
    	//这一层的日志,由上层throws的地方来打
    }catch (Exception e){
    	logger.error("XXXXXXX",e);
    	result.setStatus(-1);
    	result.setMsg("XXXXXXXXX" + e);
    	return result;
    }

           如上, 对于catch住的异常,在logger打印的时候,最好,不要用e.getMessage(),直接用e,或者e.getStackTrace,也不知道为什么,如图:

      

           对于RunTime异常,使用e.getMessage()经常打印出来的信息是Null。(有知道的,可以分享给我哦~)

          4.对于能够避免的异常,就不要抓啦,举个例子 :

    Integer serviceFeeTermRepayNum = (calcParamDTO.getServiceFeeTermRepayNum() !=null && calcParamDTO.getServiceFeeTermRepayNum() != 0) ?
                    calcParamDTO.getServiceFeeTermRepayNum(): 1;
    Double ServiceFeeAmt = calcParamDTO.getServiceFeeAmt() !=null ? calcParamDTO.getServiceFeeAmt():0D;
    //每期还款金额 = 服务费金额 / 还款期数
    Double serviceFeeTermRepayAmt = AmtCalcBaseUtil.get2Double(ServiceFeeAmt / serviceFeeTermRepayNum);
           这里可能会抛出“计算异常”,但是能够避免,就用三元表达式避免就ok了,可以让程序继续执行就Ok了。

           5.在异常处理模块中提供适量的错误原因信息。比如,如果封装了RPC的结果类型Result,定义公共错误Code码:

    public class RemoteCommConstant {
    	/**
    	 * 远程服务成功
    	 */
    	public final static int REMOTE_SUCCES_STATUS = 0;
    	/**
    	 * 远程服务失败
    	 */
    	public final static int REMOTE_ERROR_STATUS = -1;
    	public enum RemoteCommonResult {
    		SUCCESS("成功",0),
    		ERROR_IN_SERVER("服务器内部错误", -500),
    		PARAMETER_EMPTY("参数值不能为空", -400),
    		UN_LOGIN("未登录,当前请求需登陆后访问", -910),
    		LOGIN_ERROR("登录异常,请稍候重试", -912),
    		CALL_OFTEN("请求频繁", -920),
    		REMOTE_INSTAN_EXCEPTION("获取远程服务对象实例化异常", -921),
    		REMOTE_ILLEGALACCESS__EXCEPTION("非法访问异常", -922),
            //and so on ……
    		
    		 RemoteCommonResult(String name, int value) {
    				this.name = name;
    				this.value = value;
    		 }
    
    		private String name;
    		private int value;
    		
    		public String getName() {
    			return name;
    		}
    		public void setName(String name) {
    			this.name = name;
    		}
    		public int getValue() {
    			return value;
    		}
    		public void setValue(int value) {
    			this.value = value;
    		}
    		public int getIndex() {
    			return value;
    		}	
    	}	
    }
          6.将try/catch区段置于循环之外。
          7.不要将异常用于程序流程控制条件。
          8.线上系统日志,最好打印出机器ip或者名称,如果线上某系统部署在6台不同的机器上,比如下图:


          此时,如果想要深入去查找问题,通过打印出来的机器名称,直接xshell到那台机器,通过时间找到上下文立刻查看问题。至于怎么sl4j配置日志打印机器名称或ip,在nginx上有配置,location下添加add_header,添加机器名称,从而让返回头里面返回是哪个机器处理的。
           9.复杂业务地方,比如RPC接口入参、调用别人RPC接口处,我一般都会打上logger,非常方便复现问题。
           10.Logger和RPC测试工具/单元测试结合使用,基本上==Degub本地代码效果,做到程序上线了,只要有参数,依然可以分析出数据整套流程在哪里出错。


    3.日志平台
         上面主要是说如何自己通过xshell连接linux服务器,到日志路径下查看定位,如果公司有成熟的日志收集系统,那一定要利用起来,那我公司举例:

        (1)自助运维平台


            找线上问题的第一步,就是先去看“自助运维平台",能够定位到异常的,就直接凭着他发现问题进行修改了,如果不能详细地发现问题,这个时候,就该使用下面介绍的”XXX“或者自己去特定的机子上扒日志了。

          (2)“XXX”系统

         如图,红色圈圈代表在这分钟内发生了异常,点进去之后:


          便可以查看完整的异常调用链,这样排错的工作效率不高就怪了。
       
          总之,养成定时看日志的习惯,养成打好日志的习惯,就像是定时收邮件,多依赖日志,多借助工具,节省出排错的时间,放到更有意义的事情上去吧!



    展开全文
  • 文章目录一、写在前面二、什么是slf4j2.1 什么是slf4j2.2 slf4j、logback...springboot的默认日志依赖为slf4j。 本文的特点会举很多通俗易懂的例子,让大家通过例子来学习使用slf4j。 二、什么是slf4j 2.1 什么是slf4

    一、写在前面

    首先,推荐一篇优秀的介绍slf4j的优秀文章 https://juejin.im/post/5c7e2445f265da2de71370f2

    springboot的默认日志依赖为slf4j+logback,本文也是主要讲slf4j+logback

    本文的特点是会举很多通俗易懂的例子,让大家通过例子来学习使用slf4j。

    二、什么是slf4j

    2.1 什么是slf4j

    刚刚接触slf4j,对这个名词的全称惊到了,Simple Logging Facade for Java,简称SLF4J。翻译为 简单的日志Facade对于java,就是说明这个日志依赖是为java而生的。

    2.2 slf4j、logback和log4j的关系

    相信很多人听说过slf4j,log4j,logback,JDK Logging等跟日志框架有关的词语,所以这里也简单介绍下他们之间的关系。

    首先slf4j可以理解为规则的制定者,是一个抽象层,定义了日志相关的接口。

    log4j,logback,JDK Logging都是slf4j的实现层,只是出处不同,当然使用起来也就各有千秋,这里放一张网上的图更明了的解释了他们之间的关系:
    在这里插入图片描述
    可以看到logback是直接实现的slf4j,而其他的中间还有一个适配层,至于原因也很简单,因为logback和slf4j的作者是一个人。

    2.3 在springboot中使用slf4j+logback日志框架

    在Spring boot使用是非常方便的,不需要我们有什么额外的配置,因为Spring boot默认支持的就是slf4j+logback的日志框架,想要灵活的定制日志策略,只需要我们在src/main/resources下添加配置文件即可,只是默认情况下配置文件的命名需要符合以下规则:

    logback.xml
    logback-spring.xml
    

    在这里插入图片描述
    其中logback-spring.xml是官方推荐的,并且只有使用这种命名规则,才可以配置不同环境使用不同的日志策略这一功能。

    三、直接面对案例,建议各位同学跟我一起练

    随便建一个springboot项目,以下6个案例每个案例一个配置哦

    3.1、通过springboot的默认配置,对log进行自定义输出

    注: Springboot默认日志格式
    时间日期 -> 日志级别 -> 线程ID -> 分隔符 -> 线程名 -> Logger名(通常对应的是类名) -> 日志内容

    1 输出到程序的同一个目录下 log/log-can.log
    2 自定义日志格式
    3 日志水平的level=info
    4 日志大小为10m
    
    logging.file=log/log-can.log
    logging.level.root=info
    
    logging.file.max-size=20MB
    
    logging.pattern.console=%boldRed(%d{yyyy-MM-dd HH:mm:ss}) | %highlight(%-5level) | %boldYellow(%thread) | %boldGreen(%logger) | %boldCyan(%msg%n)
    logging.pattern.file=%d{yyyy/MM/dd-HH:mm} [%thread] %-5level %logger- %msg%n
    

    在这里插入图片描述

    3.2、根据不同的日志等级打印不同的颜色

    创建一个 logback-spring.xml,放置到src/main/resources下,不需要另外配置

    <!-- Logback configuration. See http://logback.qos.ch/manual/index.html -->
    <configuration scan="true" scanPeriod="10 seconds">
        <!--设置重要-->
        <property name="CONSOLE_LOG_PATTERN"
                  value="%highlight(%date{yyyy-MM-dd HH:mm:ss}) | %highlight(%-5level) | %highlight(%thread) | %highlight(%logger) | %msg%n"/>
    
        <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
            <encoder charset="UTF-8">
                <pattern>${CONSOLE_LOG_PATTERN}</pattern>
            </encoder>
        </appender>
    
    
        <root level="INFO">
            <appender-ref ref="CONSOLE"/>
        </root>
    </configuration>
    

    在这里插入图片描述

    3.3、日志持久化到本地

    创建一个 logback-spring.xml,放置到src/main/resources下,不需要另外配置

    <?xml version="1.0" encoding="UTF-8"?>
    <configuration  scan="true" scanPeriod="60 seconds" debug="false">
    
        <contextName>logback</contextName>
    
        <property name="log.path" value="log" />
    
        <!--输出到控制台-->
        <appender name="console" class="ch.qos.logback.core.ConsoleAppender">
            <encoder>
                <pattern>%highlight(%date{yyyy-MM-dd HH:mm:ss}) | %highlight(%-5level) | %highlight(%thread) | %highlight(%logger) | %msg%n</pattern>
            </encoder>
        </appender>
    
        <!--输出到文件-->
        <appender name="file" class="ch.qos.logback.core.FileAppender">
            <file>${log.path}/log-can.log</file>
            <append>true</append>
            <encoder>
                <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
            </encoder>
        </appender>
    
        <root level="info">
            <appender-ref ref="console" />
            <appender-ref ref="file" />
        </root>
    
    </configuration>
    

    3.4 异步日志持久化到本地

    创建一个 logback-spring.xml,放置到src/main/resources下,不需要另外配置

    <?xml version="1.0" encoding="UTF-8"?>
    <configuration  scan="true" scanPeriod="60 seconds" debug="false">
    
        <contextName>logback</contextName>
    
        <property name="log.path" value="log" />
    
        <!--输出到控制台-->
        <appender name="console" class="ch.qos.logback.core.ConsoleAppender">
            <encoder>
                <pattern>%highlight(%date{yyyy-MM-dd HH:mm:ss}) | %highlight(%-5level) | %highlight(%thread) | %highlight(%logger) | %msg%n</pattern>
            </encoder>
        </appender>
    
        <!--输出到文件-->
        <appender name="file" class="ch.qos.logback.core.FileAppender">
            <file>${log.path}/log-can.log</file>
            <append>true</append>
            <encoder>
                <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
            </encoder>
        </appender>
    
        <!-- 异步写入日志 -->
        <appender name ="ASYNC" class= "ch.qos.logback.classic.AsyncAppender">
            <!-- 不丢失日志.默认的,如果队列的80%已满,则会丢弃TRACT、DEBUG、INFO级别的日志 -->
            <discardingThreshold >0</discardingThreshold>
            <!-- 更改默认的队列的深度,该值会影响性能.默认值为256 -->
            <queueSize>512</queueSize>
            <!-- 添加附加的appender,最多只能添加一个 -->
            <appender-ref ref ="file"/>
        </appender>
    
        <root level="info">
            <appender-ref ref="console" />
            <appender-ref ref="ASYNC" />
        </root>
    
    </configuration>
    

    3.5 异步日志持久化到本地,按时间滚动产生日志文件

    创建一个 logback-spring.xml,放置到src/main/resources下,不需要另外配置

    <?xml version="1.0" encoding="UTF-8"?>
    <configuration  scan="true" scanPeriod="60 seconds" debug="false">
    
        <contextName>logback</contextName>
    
        <property name="log.path" value="log" />
    
        <!--输出到控制台-->
        <appender name="console" class="ch.qos.logback.core.ConsoleAppender">
            <encoder>
                <pattern>%highlight(%date{yyyy-MM-dd HH:mm:ss}) | %highlight(%-5level) | %highlight(%thread) | %highlight(%logger) | %msg%n</pattern>
            </encoder>
        </appender>
    
        <!--  按时间滚动产生日志文件 -->
        <appender name="ROL-FILE-LOG" class="ch.qos.logback.core.rolling.RollingFileAppender">
            <!--滚动策略,按照时间滚动 TimeBasedRollingPolicy-->
            <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
                <fileNamePattern>${log.path}/log-can.%d{yyyy-MM-dd}.log</fileNamePattern>
                <!-- 只保留近七天的日志 -->
                <maxHistory>7</maxHistory>
                <!-- 用来指定日志文件的上限大小,那么到了这个值,就会删除旧的日志 -->
                <totalSizeCap>1GB</totalSizeCap>
            </rollingPolicy>
    
            <encoder>
                <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
            </encoder>
        </appender>
    
        <!-- 异步写入日志 -->
        <appender name ="ASYNC" class= "ch.qos.logback.classic.AsyncAppender">
            <!-- 不丢失日志.默认的,如果队列的80%已满,则会丢弃TRACT、DEBUG、INFO级别的日志 -->
            <discardingThreshold >0</discardingThreshold>
            <!-- 更改默认的队列的深度,该值会影响性能.默认值为256 -->
            <queueSize>512</queueSize>
            <!-- 添加附加的appender,最多只能添加一个 -->
            <appender-ref ref ="ROL-FILE-LOG"/>
        </appender>
    
        <root level="info">
            <appender-ref ref="console" />
            <appender-ref ref="ASYNC" />
        </root>
    
    </configuration>
    

    3.6 异步日志持久化到本地,按时间和文件大小滚动产生日志文件

    并且会随着spring.profiles.active=dev的变化,dev时打印到控制台,prod时数据持久化到本地

    创建一个 logback-spring.xml,放置到src/main/resources下,不需要另外配置

    <?xml version="1.0" encoding="UTF-8"?>
    <configuration  scan="true" scanPeriod="60 seconds" debug="false">
    
        <contextName>logback</contextName>
    
        <property name="log.path" value="log" />
    
        <!--输出到控制台-->
        <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
            <encoder>
                <pattern>%highlight(%date{yyyy-MM-dd HH:mm:ss}) | %highlight(%-5level) | %highlight(%thread) | %highlight(%logger) | %msg%n</pattern>
            </encoder>
        </appender>
    
        <!-- 按时间和文件大小滚动产生日志文件 -->
        <appender name="ROL-SIZE-FILE-LOG" class="ch.qos.logback.core.rolling.RollingFileAppender">
            <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
                <fileNamePattern>${log.path}/log-can.%d{yyyy-MM-dd}.%i.log</fileNamePattern>
                <!-- 单个文件的最大内存 -->
                <maxFileSize>100MB</maxFileSize>
                <!-- 只保留近七天的日志 -->
                <maxHistory>7</maxHistory>
                <!-- 用来指定日志文件的上限大小,那么到了这个值,就会删除旧的日志 -->
                <totalSizeCap>1GB</totalSizeCap>
            </rollingPolicy>
    
            <encoder>
                <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
            </encoder>
    
            <!-- 只处理INFO级别以及之上的日志 -->
            <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
                <level>INFO</level>
            </filter>
        </appender>
    
        <!-- 异步写入日志 -->
        <appender name ="ASYNC" class= "ch.qos.logback.classic.AsyncAppender">
            <!-- 不丢失日志.默认的,如果队列的80%已满,则会丢弃TRACT、DEBUG、INFO级别的日志 -->
            <discardingThreshold >0</discardingThreshold>
            <!-- 更改默认的队列的深度,该值会影响性能.默认值为256 -->
            <queueSize>512</queueSize>
            <!-- 添加附加的appender,最多只能添加一个 -->
            <appender-ref ref ="ROL-SIZE-FILE-LOG"/>
        </appender>
    
        <!-- 指定开发环境基础的日志输出级别为DEBUG,并且绑定了名为STDOUT的appender,表示将日志信息输出到控制台 -->
        <springProfile  name="dev">
            <root level="DEBUG">
                <appender-ref ref="STDOUT" />
            </root>
        </springProfile>
    
        <!-- 指定生产环境基础的日志输出级别为INFO,并且绑定了名为ASYNC的appender,表示将日志信息异步输出到文件 -->
        <springProfile  name="prod">
            <root level="INFO">
                <appender-ref ref="ASYNC" />
            </root>
        </springProfile>
    
    </configuration>
    

    在这里插入图片描述

    四、logback-spring.xml说明

    使用slf4j+logback在application.yml可以不进行任何配置,直接在src/main/resources添加logback-spring.xml

    在这里插入图片描述

    4.1 < configuration >:根节点,有三个属性

    1. scan:当配置文件发生修改时,是否重新加载该配置文件,两个可选值true or false,默认为true。
    2. scanPeriod:检测配置文件是否修改的时间周期,当没有给出时间单位时默认单位为毫秒,默认值为一分钟,需要注意的是这个属性只有在scan属性值为true时才生效。
    3. debug:是否打印loback内部日志信息,两个可选值true or false,默认为false。

    4.2 < appender >:定义日志策略的节点

    < appender >:定义日志策略的节点,一个日志策略对应一个,一个配置文件中可以有零个或者多该节点,但一个配置文件如果没有定义至少一个,虽然程序不会报错,但就不会有任何的日志信息输出,也失去了意义,该节点有两个必要的属性:

    1. name:指定该节点的名称,方便之后的引用。
    2. class:指定该节点的全限定名,所谓的全限定名就是定义该节点为哪种类型的日志策略
    • 我们需要将日志输出到控制台,就需要指定class的值为:ch.qos.logback.core.ConsoleAppender
    • 需要将日志输出到文件,则class的值为: ch.qos.logback.core.FileAppender等

    4.3 < logger >:用来设置某个包或者类的日志打印级别

    < logger >:用来设置某个包或者类的日志打印级别,并且可以引用绑定日志策略,有三个属性:

    1. name:用来指定受此约束的包或者类。
    2. level:可选属性,用来指定日志的输出级别,如果不设置,那么当前会继承上级的级别。
    3. additivity:是否向上级传递输出信息,两个可选值true or false,默认为true。

    在该节点内可以添加子节点,该节点有一个必填的属性ref,值为我们定义的节点的name属性的值。

    4.4 < root >:根< logger >一个特殊的< logger >

    < root >:根< logger >一个特殊的< logger >,即默认name属性为root的< logger >,因为是根< logger >,所以不存在向上传递一说,故没有additivity属性,所以该节点只有一个level属性。

    介绍了根节点的三个主要的子节点,下面再介绍两个不那么重要但可以了解的子节点:

    4.5 < contextName >:设置上下文名称

    < contextName >:设置上下文名称,每个都关联到上下文,默认上下文名称为default,但可以使用设置成其他名字,用于区分不同应用程序的记录,一旦设置,不能修改,可以通过 %contextName 来打印日志上下文名称,一般来说我们不用这个属性,可有可无。

    4.6 < property >:用来定义变量的节点

    < property >:用来定义变量的节点,定义变量后,可以使${}来使用变量,两个属性,当定义了多个< appender >的时候还是很有用的:

    1. name:变量名
    2. value:变量值
    展开全文
  • 要想快速的解决已上2个问题,就依赖日志了。日志是开发为了跟踪用户行为和代码异常而打的记录。当一个请求到来时,我们一般会登记以下几种日志:1、AccessLog:用户访问日志。一般会记录请求URL、请求参数、用户ID...

    2d689fcf10d3e812b4d44d36d4c854c5.png

    ​在讲日志之前先看2个问题:

    1、当用户在使用某个功能报错时,开发该如何排查问题?2、当出现某个接口返回数据很慢时,该如何优化?

    要想快速的解决已上2个问题,就依赖于日志了。

    日志是开发为了跟踪用户行为和代码异常而打的记录。

    当一个请求到来时,我们一般会登记以下几种日志:

    1、AccessLog:用户访问日志。一般会记录请求URL、请求参数、用户ID、行为发生时间、接口返回值等几个关键指标。

    2、Exception:代码异常。代码异常一般会记录报错信息、报错发生的代码是哪一行、报错发生时间等指标。代码异常日志是最重要也是经常要看的日志,根据报错可以快速定位到发生错误的原因,快速地修复问题。

    3、SqlLog:数据库查询日志。一般会记录SQL查询语句、数据库名表名、查询耗时等指标。

    4、第三方服务日志:调用第三方服务日志。如果后台调用了第三方服务,比如接入了公司内的统一登录服务,当调用该登录服务时,就记录这些行为。

    5、CronLog:定时任务日志。如果后台有定时任务,比如每天凌晨同步某个数据库到另一个仓库,则可以记录下该任务是否成功、成功耗时等。

    上面说的都是后台产生的日志,那么前端有没有错误日志呢?当然是有的,但是前端日志比后台就简单纯粹多了。前端一般只要记录发生错误的日志,上报到日志平台就可以了。

    如果没有用户向你投诉某个功能报错了,开发如何在用户发现错误之前避免这些错误?这时就需要给异常添加监控告警了。

    监控告警一般监控以下这些指标:

    1、流量异常:指的是pv相比于以前,猛然升高。可能存在有人在恶意刷页面

    2、服务崩溃:服务因为某种异常,导致的服务停止,不能正常访问。3、代码异常:代码发生错误。4、数据库查询过慢:可能因为查询人数过多、数据量过大、查询语句有问题导致的查询耗时过长。5、服务占用CPU/内存过高:可能因为访问人数过多或者代码有bug导致的内存泄漏/CPU占用高。

    更多产品经理需要学的技术知识,可关注公众号:产品的技术小课

    展开全文
  • 日志框架老生常谈,什么是日志;我们平时用System.out.println("xxxxxx")将一下比较关键的数据在控制台;后来接触了日志框架比较常用的就是Log4J了;一般常用的框架有:longback,log4j,log4j2,slf4j 等日志门面 ...
    • 日志框架

        老生常谈,什么是日志;我们平时用System.out.println("xxxxxx")将一下比较关键的数据在控制台;后来接触了日志框架比较常用的就是Log4J了;

    一般常用的框架有:
    longback,log4j,log4j2,slf4j 等

    日志门面  (日志的抽象层)日志实现
    JCL(Jakarta  Commons Logging)SLF4j(Simple  Logging Facade for Java)    jboss-loggingLog4j  JUL(java.util.logging)  Log4j2  Logback

    左边选一个门面(抽象层)、右边来选一个实现;

    日志门面:SLF4J;

    日志实现:Logback;

    SpringBoot选用的是SLF4J和logback

    2、SLF4j使用

    1、系统中使用SLF4j

    我们开发的时候一般都是调用日志抽象里面的方法,而不直接调用日志的实现类,这样可扩展性更强

    211d6a99d9ea8132cca8d241b0fd6576.png

    我们看看这张图,我们知道了SLF4J是接口,他有很多实现类,这次我们的项目用的是logback,如果我们想换成log4j怎么呢?我们可以到通过一个中间的适配器来适配log4j

    2、如何统一日志框架

    我们知道每种框架都有自己的日志系统,如果一个系统里面包含了SLF4J+logback,Spring(commons-logging),Hibernate(jboss-logging),Mybatis·····等等。如何统一日志记录,让所有的日志都统一使用slf4j进行输出?

    f09c8244954faa12f7d1d3e0cabd8305.png

    我们来看看这张图,一个应用面向了很多日志框架,如果我们直接去掉这些依赖包的话,系统肯定会报错的,因为Spring本来底层会调用这些框架的API等。那怎么解决?从图中可以看出采取了偷梁换柱的做法;用另一个jar包代替了本来的jar包。比如:logging;代替后和slf4j完美契合,就可以使用。总结:
    1.先将以前的剔除2.用中间包替换原有的日志框架
    3.导入slf4j其他的实现

    3、SpringBoot日志

    说了这么多,我们来看看SprinBoot的日志实现
    导入场景

          org.springframework.boot
    spring-boot-starter-logging

    我们可以看看依赖关系图

    55c8e5df85ad1ba1c2b695277ce0da80.png

    1425a708185fb9dca48407e31a177da1.png

    分析:
    1.我们可以看到SpringBoot底层使用slf4j+logback的方式进行日志记录
    2.其他日志会转换成slf4j
    3.可以从依赖中看到明显的替换包

    86949b59408121ad728f45ab8298e144.png


    4.要引用其他框架的时候记得剔除
    Spring框架用的是commons-logging;

                org.springframework
    spring-core
    commons-loggingcommons-logging

    SpringBoot能自动适配所有的日志,而且底层使用slf4j+logback的方式记录日志,引入其他框架的时候,只需要把这个框架依赖的日志框架排除掉即可

    1、默认配置

    SpringBoot默认帮我们配置好了日志;

    public class SpringBootLong4jApplicationTests {

        private Logger logger = LoggerFactory.getLogger(SpringBootLong4jApplicationTests.class);
    @Test
    public void contextLoads() {
    //日志的级别;
    //由低到高 trace //可以调整输出的日志级别;日志就只会在这个级别以以后的高级别生效
    logger.trace("这是trace日志...");
    logger.debug("这是debug日志...");
    //SpringBoot默认给我们使用的是info级别的,没有指定级别的就用SpringBoot默认规定的级别;root级别
    logger.info("这是info日志...");
    logger.warn("这是warn日志...");
    logger.error("这是error日志...");
    }

    }

    4aaf52447029fdace591c549ba5c7600.png

    i    日志输出格式:

            %d表示日期时间,
    %thread表示线程名,
    %-5level:级别从左显示5个字符宽度
    %logger{50} 表示logger名字最长50个字符,否则按照句点分割。
    %msg:日志消息,
    %n是换行符
    -->
    %d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n

    SpringBoot修改日志的默认配置

    logging.level.com.atguigu=trace



    #logging.path=
    # 不指定路径在当前项目下生成springboot.log日志
    # 可以指定完整的路径;
    #logging.file=G:/springboot.log

    # 在当前磁盘的根路径下创建spring文件夹和里面的log文件夹;使用 spring.log 作为默认文件
    logging.path=/spring/log

    # 在控制台输出的日志的格式
    logging.pattern.console=%d{yyyy-MM-dd} [%thread] %-5level %logger{50} - %msg%n
    # 指定文件中日志输出的格式
    logging.pattern.file=%d{yyyy-MM-dd} === [%thread] === %-5level === %logger{50} ==== %msg%n

    63c3ddf77e41e7880311cb0181173e64.png

    0d90fe507e36d35202577528ebbbce3c.png

    1f054b1c88c969ed1d3f525a1d0ddad1.png

    logging.filelogging.pathExampleDescription
    (none)(none)只在控制台输出
    指定文件名(none)my.log输出日志到my.log文件
    (none)指定目录/var/log输出到指定目录的 spring.log 文件中

    2、指定配置

    给类路径下放上每个日志框架自己的配置文件即可;SpringBoot就不使用他默认配置的了

    Logging SystemCustomization
    Logbacklogback-spring.xml, logback-spring.groovy, logback.xml or logback.groovy
    Log4j2log4j2-spring.xml or log4j2.xml
    JDK (Java Util Logging)logging.properties

    logback.xml:直接就被日志框架识别了;

    logback-spring.xml:日志框架就不直接加载日志的配置项,由SpringBoot解析日志配置,可以使用SpringBoot的高级Profile功能
    使用形式:

        
    可以指定某段配置只在某个环境下生效

    name="stdout" class="ch.qos.logback.core.ConsoleAppender">
            
    %d{yyyy-MM-dd HH:mm:ss.SSS} ----> [%thread] ---> %-5level %logger{50} - %msg%n%d{yyyy-MM-dd HH:mm:ss.SSS} ==== [%thread] ==== %-5level %logger{50} - %msg%n

    直接运行就是非开发环境

    42958fd15a5fb10dd7b4deca0589fb60.png

    切换到开发环境

    864f13d22aab3f9561d084b17a710f81.png


    或者
    在配置那里填写 --spring.profiles.active=dev

    结果:

    f988ee3fa5555ad9a1468bf6cd86c92c.png

    e5ac16d0a3c4fd0260be7bbdbe52d478.png

    出处:

    作者:AS_lan
    链接:https://www.jianshu.com/p/33135f3418f0

    展开全文
  • Mysql的日志模块尤为重要,平日的crash-safe和主从都依赖我们的日志模块。Mysql有两个日志模块:redolog 和 binlog咱们先看一下redolog。redolog中文来讲就是重做日志,它有什么用呢?如果每次你的更新或者插入都...
  • MySQL的崩溃恢复crash_safe能力依赖于Redo Log事务日志。当MySQL更改数据的时候,它的设计思想先对内存中的数据进行修改,并且写Redo Log,即更改数据,总是遵循WAL日志先行机制。那为啥redo日志是两阶段提交呢? ...
  • 一、日志简介1.1 日志是什么(WHAT)日志:记录程序的运行轨迹,方便查找关键信息,也方便快速定位解决问题。通常,Java程序员在开发项目时都是依赖Eclipse/IDEA等集成开发工具的Debug 调试功能来跟踪解决Bug,但项目...
  • Mysql的日志模块尤为重要,平日的crash-safe和主从都依赖我们的日志模块。Mysql有两个日志模块:redolog 和 binlog咱们先看一下redolog。redolog中文来讲就是重做日志,它有什么用呢?如果每次你的更新或者插入都...
  • 日志

    2020-09-08 08:47:24
    日志是什么日志主要的作用是记录程序运行的过程,通过日志方便观察程序的运行状况和运行过程,便于分析程序的执行过程,JDK自带一个日志,但是效果不太好,速度较慢,要写的代码较多 常见的日志工具 jdk-...
  • 原文地址:点击打开链接在这篇文章里,我想详细谈下为什么你要避免事务日志(Transaction Log)上的自动增长操作(Auto Growth operations)。很多运行的数据库服务器,对于事务日志,用的都默认的日志文件大小和...
  • 在这篇文章里,我想详细谈下为什么你要避免事务日志(Transaction Log)上的自动增长操作(Auto Growth operations)。很多运行的数据库服务器,对于事务日志,用的都默认的日志文件大小和自动增长设置。人们有时...
  • 想必大家或多或少都对我们使用的日志api有所疑惑,为什么网上有那么多日志框架可以选择,但是我们平时打印日志的时候用的却基本都log.info("xxx")这种形式,为什么在我们的pom.xml中要配置那么多的日志依赖,...
  • Mysql的日志模块尤为重要,平日的crash-safe和主从都依赖我们的日志模块。Mysql有两个日志模块:redolog 和 binlog咱们先看一下redolog。redolog中文来讲就是重做日志,它有什么用呢?如果每次你的更新或者插入都...
  • 在这篇文章里,我想详细谈下为什么你要避免事务日志(Transaction Log)上的自动增长操作(Auto Growth operations)。很多运行的数据库服务器,对于事务日志,用的都默认的日志文件大小和自动增长设置。人们有时...
  • 【.NET】为什么要记录日志?

    千次阅读 热门讨论 2015-01-11 16:43:24
    我本在log4net之上又进行了封装,为的不必依赖于log4net.大家都知道日志框架有很多,我们不一定非要依附于log4net.针对接口编程还是要一直记得这事滴!    先补充一点,单独写一个配置文件后如何读取的问题.  ...
  • Maven依赖

    2016-06-14 14:43:43
    在 Maven 依赖机制的帮助下自动下载所有必需的依赖库,并保持版本升级。 案例分析 让我们看一个案例研究,以了解它如何工作的。假设你想使用 Log4j 作为项目的日志。这里你要做什么? 1.在...
  • Spring -- 日志

    2016-12-01 19:41:50
    日志日志对于Spring是一个非常重要的依赖,因为: ...Spring中强制的日志依赖是JCL (Jakata Commons Logging API),JCL的对象 log 在Spring中是可见的。最好所有版本都使用同一个日志库,这样迁移时就比较方便,
  • quave:logs一个Meteor软件包,它允许您从客户端和服务器将日志发送到loggly。 为什么 每个应用程序都需要日志,我们利用Meteor方法还可以从客户端发送日志。 我们没有在客户端中加载大量的依赖关系,而是使用...
  • Mybatis日志管理

    2019-08-23 11:19:17
    1.什么是日志 日志文件记录系统操作事件的记录文件,日志保存历史数据,诊断问题及理解系统活动的重要依据 2.Java中的日志实现 在java中日志分为两部分,"日志门面"和"日志实现" 3.案例参考 ...
  • 作者:GeekerLouwww.jianshu.com/p/546e9aace657一、日志简介1.1 日志是什么(WHAT)日志:记录程序的运行轨迹,方便查找关键信息,也方便快速定位解决问题。通常,Java程序员在开发项目时都是依赖Eclipse/IDEA等集成...
  • 一、日志简介1.1 日志是什么(WHAT)日志:记录程序的运行轨迹,方便查找关键信息,也方便快速定位解决问题。通常,Java程序员在开发项目时都是依赖Eclipse/IDEA等集成开发工具的Debug 调试功能来跟踪解决Bug,但项目...
  • Java日志框架

    2019-11-25 20:33:27
    绑定很好理解, 桥接什么用的呢? 比如说你的应用slf4j+log4j2, 但你引入的一个依赖包没有使用slf4j, 使用的log4j. 怎么搞? 难道你项目又得搞两套配置了? 这个时候你就应该排除依赖包的log...
  • Composer依赖管理工具

    2018-12-13 17:20:17
    1.最简单的一句话概括composer什么的(简介):  Composer PHP 的一个依赖管理工具。它允许你申明项目所依赖的代码库,它会在你的项目中为你安装他们。 2.composer怎么干的(依赖管理):  a) 你有一...
  • 伤感日志:但我的结局是不幸福的 — 伤感日志:但我的结局是不幸福的  曾经幻想过多少个自己.... 极强的依赖性,爱做梦,活在浪漫的完美主义中,完全...或者更多是不知道自己想要的是什么.每当半夜总是睡不着了.那

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 813
精华内容 325
关键字:

日志依赖是什么