目录

概述

我们在记录操作日志的时候,我们是直接基于System这种方式来记录的操作日志,那如果在项目开发中,我们记录日志全部采用System这种方式来记录日志,那有没有什么问题呢?接下来我们一起来分析一下。
首先大家都知道System是标准输出,就是往控制台当中来输出数据,如果我们基于这种方式来记录日志,那我们所记录的日志数据,它只能输出到控制台,是没有办法记录到日志文件或者记录到数据库中的,所以这是它的第一个问题,只能输出到控制台,一旦我将控制台的数据清空了,这个日志呢也就没有了
第二个问题,不便于项目的扩展,就比如这个数据,我不仅想输出到控制台,我还想记录到文件当中,那如果基于System这种方式是没办法实现的,所以不利于项目的扩展

在项目开发中,我们记录日志,我们强烈不推荐使用SYstem这种方式来记录,而是要使用专门的日志技术来记录日志。
什么是日志?
-
日志就好比生活中的日记,可以随时随地记录你生活中的点点滴滴。
-
程序中的日志,是用来记录应用程序的运行信息、状态信息、错误信息的。
为什么要在程序中记录日志呢?
首先第一点,通过这个日志可以方便我们进行数据的追踪。比如我们想知道这个功能接口在执行的过程中前端最终给我们传递的是什么样的请求参数,那传递过来请求参数后,我在调用service的时候,那service里面接收到了什么样的参数,以及最终业务逻辑执行完了,我给前端返回的是什么样的数据,那如果我们想追踪整个调用的过程,我们就可以将这些信息直接记录到日志当中,那最终我查看这份日志,我就能知道应用程序在运行的过程当中,这个数据的传递情况,这是它的第一个作用。
第二个作用是可以为我们的性能优化提供对应的数据支撑。在我们的项目中会有很多个业务功能,而部分业务功能可能执行效率比较低或者说执比较耗时,那我可能需要对这部分的功能进行优化,而优化之前,你首先得定位到执行比较耗时的功能,那怎么定位呢,我们就可以去记录对应的日志,我可以将每一个功能接口运行的日志直接输出出来,那在日志当中,我就可以去记录一下这个方法的运行耗时,那最终查看这份日志我就能知道哪些业务功能执行比较耗时,然后我在针对这部分业务功能再进行性能的优化,所以呢通过日志也可以为我们的性能优化提供对应的数据支撑。
然后第三个方面就是通过我们在日志当中所记录的这个错误信息就可以方便我们进行问题的排查,从而来解决对应的bug,解决对应的问题
最后一个方面,便于我们进行系统的监控,通过我们在日志当中所记录的程序的运行信息,状态信息,那我们就能够知道这个系统的运行情况如何,以及这个系统中的数据谁在什么时间点对这条数据进行了操作,以及执行的是什么样的操作,那这些我们都可以记录在日志当中,从而来监控整个系统。
当然这个日志的作用不仅仅局限于这四个方面,还有其他很多的作用...

日志框架
记录日志的技术比较多,这里主要介绍这么几个:
JUL : 是java.util.logging这个单词的简写,大家可以看到,这其实就是个包结构,,这是JavaSE平台提供的官方日志框架,也被称为JUL。配置相对简单,但不够灵活,性能较差,所以在现在的项目开发中,这个JUL用的很少,这个大家知道一下。
Log4j : 一个流行的日志框架,提供了灵活的配置选项,通过Log4j记录日志可以将记录的日志输出到控制台,也可以将记录的日志直接记录在日志文件里面,也可以将日志直接保存在数据库当中,都是可以的,它是支持多种输出目标,但是这个技术在近些年用的并不多,原因是因为有更优秀的日志技术出现。
Logback: 基于Log4j升级而来,Log4j的作者和Logback的作者其实是同一个人,Log4j的作者发现Log4j的性能有很大的优化空间,所以就在Log4j的基础上进行了升级,从而退出了新的Logback,在Logbakc它其实对Log4j的内核进行了重写,重写之后那性能得到了大幅度的提升,提供了更多的功能和配置选项,性能由于Log4j。
Slf4j : (Simple Logging Facade for Java)简单日志门面,提供了一套日志操作的标准接口及抽象类,允许应用程序使用不同的底层日志框架,大家可以理解为这个Slf4j其实就是定义了一套规范,它里面提供了一套标准的接口以及抽象类,它并不负责具体的日志技术的实现,底层的这些日志框架像Log4j,Logback就负责这一套规范的实现,所以Log4j和Logback就相当于是Slf4j这一套规范的具体实现,它会去实现里面所提供的这些标准的接口,所以最终干活的依然是Log4j或者是Logback。

而在我们项目记录日志,我们使用Logback这样的日志框架来进行记录
logback入门
1). 准备工作:引入logback的依赖(springboot中无需引入,在springboot中已经传递了此依赖)。Logback-classic这项依赖已经传递下来了,我们就不用再引入了。
XML
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.4.11</version>
</dependency>
2). 引入配置文件 logback.xml (资料中已经提供,拷贝进来,放在 src/main/resources 目录下; 或者直接AI生成)。这份配置文件相对比较固定,直接引入就可以了。
XML
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<!-- 控制台输出 -->
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度 %msg:日志消息,%n是换行符 -->
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50}-%msg%n</pattern>
</encoder>
</appender>
<!-- 日志输出级别 -->
<root level="ALL">
<appender-ref ref="STDOUT" />
</root>
</configuration>
3). 记录日志:定义日志记录对象Logger,记录日志
定义日志记录对象,通常来说,我们会在类中声明这个常量,就是Logger这个类型的,然后紧接着通过LoggerFactory这个工厂调用它里面的这个getLogger这个方法就可以获取到一个日志记录对象,而在调用这个方法的时候,里面需要传递当前类的这个字节码对象,用来标识那这个日志记录对象要记录的是哪个类当中的日志,而这句代码是固定写法,也就说只要大家需要去记录日志,你就可以在类中直接声明这么一个常量,然后就可以调用这个日志对象logger当中的方法来记录日志了

这个依赖已经传递下来了,我们就不用再引入了

找到课程资料,找到日志技术,找到Logback.xml,Ctrl C复制一下,

所有的配置文件,我们都需要放在resource这个目录下,所以直接放在resources这个根目录下就可以了,Ctrl V直接粘贴进来

定义日志记录对象logger
声明这么个常量,日志记录器叫Logger,起个名字叫log
XML
//定义日志记录对象
private static final Logger log = LoggerFactory.getLogger(LogTest.class);
Logger有很多,我们这里使用的是slf4j当中的接口,

LoggerFactory也有很多,我们依然采用slf4j当中提供的这个

再调用它里面的一个静态方法,叫getLogger,大家会发现有两个重载方法,第一个重载方法你可以指定一个日志记录器的名字,第二个你就直接传递一个字节码对象来标识我们要记录的是哪个类中的日志,这个地方我们直接传递当前类的字节码对象就可以了

logback配置文件
Logback日志框架的配置文件叫 logback.xml 。
该配置文件是对Logback日志框架输出的日志进行控制的,可以来配置输出的格式、位置及日志开关等。
常用的两种输出日志的位置:控制台、系统文件。
1). 如果需要输出日志到控制台。添加如下配置:
XML
<!-- 控制台输出 -->
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<!--格式化输出:%d 表示日期,%thread 表示线程名,%-5level表示级别从左显示5个字符宽度,%msg表示日志消息,%n表示换行符 -->
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50}-%msg%n</pattern>
</encoder>
</appender>
2). 如果需要输出日志到文件。添加如下配置:
XML
<!-- 按照每天生成日志文件 -->
<appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<!-- 日志文件输出的文件名, %i表示序号 -->
<FileNamePattern>D:/tlias-%d{yyyy-MM-dd}-%i.log</FileNamePattern>
<!-- 最多保留的历史日志文件数量 -->
<MaxHistory>30</MaxHistory>
<!-- 最大文件大小,超过这个大小会触发滚动到新文件,默认为 10MB -->
<maxFileSize>10MB</maxFileSize>
</rollingPolicy>
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<!--格式化输出:%d 表示日期,%thread 表示线程名,%-5level表示级别从左显示5个字符宽度,%msg表示日志消息,%n表示换行符 -->
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50}-%msg%n</pattern>
</encoder>
</appender>
3). 日志开关配置 (开启日志(ALL),取消日志(OFF))
XML
<!-- 日志输出级别 -->
<root level="ALL">
<!--输出到控制台-->
<appender-ref ref="STDOUT" />
<!--输出到文件-->
<appender-ref ref="FILE" />
</root>
logback日志级别
日志级别指的是日志信息的类型,日志都会分级别,常见的日志级别如下(优先级由低到高):
|-------|----------------------------------------|------------------|
| 日志级别 | 说明 | 记录方式 |
| trace | 追踪,记录程序运行轨迹 【使用很少】 | log.trace("...") |
| debug | 调试,记录程序调试过程中的信息,实际应用中一般将其视为最低级别 【使用较多】 | log.debug("...") |
| info | 记录一般信息,描述程序运行的关键事件,如:网络连接、io操作 【使用较多】 | log.info("...") |
| warn | 警告信息,记录潜在有害的情况 【使用较多】 | log.warn("...") |
| error | 错误信息 【使用较多】 | log.error("...") |
可以在配置文件logback.xml中,灵活的控制输出那些类型的日志。(大于等于配置的日志级别的日志才会输出)
XML
<!-- 日志输出级别 -->
<root level="info">
<!--输出到控制台-->
<appender-ref ref="STDOUT" />
<!--输出到文件-->
<appender-ref ref="FILE" />
</root>
@Slf4j
对于这部分的固定代码也有一种简化的方式

如果在项目中,我们使用了Lambok的话,那这时候这句代码你就不用写了,直接在类上加上一个注解就可以了,而这个注解就叫@Slf4j,大家注意,这是lombok提供的

所以在这块,直接上个注解就可以了
