SpringBoot日志全方位超详细手把手教程,零基础可学习 日志如何配置及SLF4J的使用......

🧸欢迎来到dream_ready的博客,📜相信您对这篇博客也感兴趣o (ˉ▽ˉ;)

📜SpringIOC和DI的代码实现,Spring如何存取对象?@Controller、@Service、@Repository、@Component、@Configuration、@Bean DI详解-CSDN博客

目录

1、什么是日志?

2、为什么要学习日志?

3、日志的用途

3.1、定位和发现问题

3.2、系统监控

3.3、数据采集

3.4、日志审计

[4、日志使用 ------ 要打印什么样的日志才符合要求?](#4、日志使用 —— 要打印什么样的日志才符合要求?)

5、使用日志对象打印日志

5.1、在程序中得到日志对象

5.2、使用日志对象打印日志

6、日志框架介绍及门面模式讲解

6.1、门面模式(外观模式)

门面模式的定义

门面模式的实现

门面模式的优点:

7、SLF4J框架介绍及使用

7.1、SLF4J框架介绍

7.2、使用注解打印日志

8、日志格式的说明

9、日志级别

9.1、什么是日志级别及其作用

9.2、日志级别的分类

9.3、日志级别的顺序

9.4、日志级别的使用(打印)

9.5、配置日志级别(以yml举例)

10、日志持久化

11、日志文件分割

11、配置日志格式


1、什么是日志?

日志是系统或应用程序生成的记录事件和活动的文件或信息

⽇志对我们来说并不陌⽣, 从JavaSE部分, 我们就在使⽤ System.out.print 来打印⽇志了

如下图,控制台输出的这些就是日志

2、为什么要学习日志?

我们可以通过打印⽇志来发现和定位问题, 或者根据⽇志来分析程序的运⾏过程.在Spring的学习中, 也经常根据控制台的日志来分析和定位问题

随着项⽬的复杂度提升, 我们对⽇志的打印也有了更⾼的需求, ⽽不仅仅是定位排查问题

⽐如需要记录⼀些⽤⼾的操作记录(⼀些审计公司会要求), 也可能需要使⽤⽇志来记录⽤⼾的⼀些喜好, 把⽇志持久化, 后续进⾏数据分析等. 但是 System.out.print 不能很好的满⾜我们的需求, 我们就 需要使⽤⼀些专门日志框架(专业的事情交给专业的⼈去做)

3、日志的用途

3.1、定位和发现问题

比如从下面日志中我们就可以得到相关信息:

3.2、系统监控

监控现在⼏乎是⼀个成熟系统的标配, 我们可以通过⽇志记录这个系统的运⾏状态, 每⼀个⽅法的响应时间, 响应状态等, 对数据进⾏分析, 设置不同的规则, 超过阈值时进⾏报警. ⽐如统计⽇志中关键字的数量,并在关键字数量达到⼀定条件时报警,这也是⽇志的常⻅需求之⼀

3.3、数据采集

数据采集是一个比较大的范围,采集的数据可以作用在很多方面,比如数据统计,推荐排序等

数据统计:统计页面的浏览量(PV),访客量(UV),点击量等,根据这些数据进行数据分析,优化公司运行策略

推荐排序:目前推荐排序应用在各个领域,我们经常接触的各行各业很多也都涉及推荐排序,比如购物,广告,新闻等领域。数据采集是推荐排序工作中必须做的一环,系统通过日志记录用户的浏览历史,停留时长等,算法人员通过分析这些数据,训练模型,给用户做推荐

下图中的数据源, 其中⼀部分就来⾃于⽇志记录的数据.

3.4、日志审计

随着互联网的发展,众多企业的关键业务越来越多的运行于网络之上,网络安全越来越受到大家的关注,系统安全也成为了项目中的一个重要环节,安全审计也是系统中非常重要的部分。国家的政策法规、行业标准等都明确地对日志审计提出了要求,通过系统日志分析,可以判断一些非法攻击、非法调用,以及系统处理过程中的安全隐患

⽐如, ⼤家平时都在做运营系统, 其中运营⼈员在通过界⾯处理⼀些数据的时候, 如果没有清楚的⽇志 操作记录, ⼀条数据被删除或者修改, 你是⽆法找到是谁操作的,但是如果你做了相应的记录,该数 据被谁删除或者修改就会⼀⽬了然.

还有⼀些内部的违规和信息泄漏(⽐如客⼾信息被卖掉)现象出现后, 如果未记录留存⽇志, 为事后调查 提供依据, 则事后很难追查(⼀些公司查看客⼾的信息都会被记录⽇志, 如果频繁查询也会报警)

4、日志使用 ------ 要打印什么样的日志才符合要求?

接下来的5和7标题中分别介绍了两种打印日志的方式,本质是相同的,只是用法不同,企业中更常用的是7标题中的方法

Spring Boot 项⽬在启动的时候默认就有⽇志输出,如下图所⽰:

它打印的⽇志和 System.out.print 有什么不同呢?我们为什么不使用System.out.print打印日志呢?

观察日志输出

可以看到, 我们通过 System.out.print 打印的⽇志, ⽐ SpringBoot 打印的⽇志缺少了很多信息

凭借 System.out.print 打印的⽇志,我们很难完成之前提到过的日志相关作用,而Spring Boot启动时的日志就可以称之为优秀的日志,能满足我们实现各种功能

5、使用日志对象打印日志

打印⽇志的步骤:

  • 在程序中得到⽇志对象.
  • 使⽤⽇志对象输出要打印的内容

5.1、在程序中得到日志对象

在程序中获取⽇志对象需要使⽤⽇志⼯⼚ LoggerFactory,如下代码所⽰:

java 复制代码
private static Logger logger = LoggerFactory.getLogger(LoggerController.class);

括号内部(此处的LoggerController.class)是LoggerFactory.getLogger 需要传递的⼀个参数,标记这个日志的名称,这样可以更清晰地知道是哪个类输出的日志。当有问题时,可以更方便直观地定位到问题类

注意:Logger对象是属于org.slf4j包下的,不要导入错包

5.2、使用日志对象打印日志

⽇志对象的打印⽅法有很多种,我们可以先使⽤ info() ⽅法来输出⽇志,如下代码所⽰:

java 复制代码
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class LoggerController {
    private static Logger logger = LoggerFactory.getLogger(LoggerController.class);

    @RequestMapping("/logger")
    public String logger(){
        logger.info("--------------要输出⽇志的内容----------------");
        return "打印⽇志";
    }
}

这种其实已经很方便了,但在企业中,这种用法仍然不是主流,因为存在着专业的日志框架,使用日志框架比使用日志对象更加方便快捷!

6、日志框架介绍及门面模式讲解

目前企业中最常用的日志框架是 SLF4J

SLF4J不同于其他⽇志框架, 它不是⼀个真正的⽇志实现, ⽽是⼀个抽象层, 对⽇志框架制定的⼀种规范, 标准, 接⼝. 所有SLF4J并不能独⽴使⽤, 需要和具体的⽇志框架配合使⽤,具体实现是log4j/2,JUL,logback等

其实SLF4J框架就是门面模式思想的一种典型体现

6.1、门面模式(外观模式)

SLF4J是⻔⾯模式的典型应⽤(但不仅仅使⽤了⻔⾯模式)

门面模式的定义

⻔⾯模式(Facade Pattern)⼜称为外观模式, 提供了⼀个统⼀的接⼝, ⽤来访问⼦系统中的⼀群接⼝. 其主要特征是定义了⼀个⾼层接⼝, 让⼦系统更容易使⽤

⻔⾯模式主要包含2种⻆⾊:

外观⻆⾊(Facade): 也称⻔⾯⻆⾊,系统对外的统⼀接⼝.

⼦系统⻆⾊(SubSystem): 可以同时有⼀个或多个 SubSystem. 每个 SubSytem 都不是⼀个单独的类, ⽽是⼀个类的集合. SubSystem 并不知道 Facade 的存在, 对于 SubSystem ⽽⾔, Facade 只是另⼀个 客⼾端⽽已(即 Facade 对 SubSystem 透明)

门面模式的实现

场景:回家开灯

没有使用门面模式: 回家时,我们进入各个房间,依次打开各个房间的灯

使用门面模式:回家时,打开门口的总开门,总开关一开,家里所有灯都会被打开

使用代码如下:

先定义个灯的接口

以下分别是三个房间灯的类:

如果不使用门面模式,我想打开所有的灯的话:

使用门面模式:

我们定义一个门面角色,此处就是所有灯的总开关:

然后我们操作者只需打开总开关即可:

而且使用了门面模式后,我们是不需要关注它底层是调用了哪个子接口,采用哪种方式实现的,比如我现在要对餐厅灯进行升级:

可以发现,我们的Main方法不需要做出任何的改变,这就是门面模式的优点之一:

门面模式的优点:

  • 减少了系统的相互依赖. 实现了客⼾端与⼦系统的耦合关系, 这使得⼦系统的变化不会影响到调⽤它 的客⼾端;
  • 提⾼了灵活性, 简化了客⼾端对⼦系统的使⽤难度, 客⼾端⽆需关⼼⼦系统的具体实现⽅式, ⽽只需 要和⻔⾯对象交互即可.
  • 提⾼了安全性. 可以灵活设定访问权限, 不在⻔⾯对象中开通⽅法, 就⽆法访问

7、SLF4J框架介绍及使用

7.1、SLF4J框架介绍

SLF4J就是其他日志框架的门面。SLF4J可以理解为是提供日志服务的统一API接口,并不涉及到具体的日志逻辑实现

那我们为什么要引入日志门面呢,直接使用底层实现的接口/方法不就行了么,比如log4j、logback等?

常⻅的⽇志框架有log4J, logback等. 如果⼀个项⽬已经使⽤了log4j,⽽你依赖的另⼀个类库,假如是Apache Active MQ,它依赖于另外⼀个⽇志框架logback, 那么你就需要把logback也加载进去

存在问题:

  1. 不同⽇志框架的API接⼝和配置⽂件不同, 如果多个⽇志框架共存, 那么不得不维护多套配置⽂件(这个配置⽂件是指⽤⼾⾃定义的配置⽂件).
  2. 如果要更换⽇志框架, 应⽤程序将不得不修改代码, 并且修改过程中可能会存在⼀些代码冲突.
  3. 如果引⼊的第三⽅框架, 使⽤了多套, 那就不得不维护多套配置

引入日志门面

引⼊⻔⾯⽇志框架之后, 应⽤程序和⽇志框架(框架的具体实现)之间有了统⼀的API接⼝(⻔⾯⽇志框架 实现), 此时应⽤程序只需要维护⼀套⽇志⽂件配置, 且当底层实现框架改变时, 也不需要更改应⽤程序代码

SLF4J 就是这个⽇志⻔⾯.

总的来说,SLF4J使你的代码独⽴于任意⼀个特定的⽇志API,这是⼀个对于开发API的开发者很好的思想

7.2、使用注解打印日志

每次都使⽤ LoggerFactory.getLogger(xxx.class) 很繁琐, 且每个类都添加⼀遍, lombok给我们提供了 ⼀种更简单的⽅式.

  1. 添加 lombok 框架⽀持

  2. 使⽤ @slf4j 注解输出⽇志

java 复制代码
<dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
    <optional>true</optional>
</dependency>

在对应类上加上注解 @Slf4j ,它会自动创建该类的日志对象,并将其命名为 log

java 复制代码
@Slf4j     // 使用该注解后Spring会自动帮我们生成日志对象 ------ log
@RestController
public class LoggerController {


    @PostConstruct
    public void print(){
        System.out.println("打印日志");
        log.info("=================我是日志框架打印的日志================");
        log.info("=======我是日志框架打印的日志===================");
        log.error("我是error日志");
        log.warn("我是warn日志");
        log.info("我是info日志");
        log.debug("我是debug日志");
        log.trace("我是trace日志");
    }
}

我们找到该类的字节码文件

可以看到,这个框架只是帮我们创建了该类的日志对象,更方便了些,其实使用上和之前的使用日志对象打印日志操作是一样的

8、日志格式的说明

打印的日志分别代表什么呢?

9、日志级别

9.1、什么是日志级别及其作用

⽇志级别代表着⽇志信息对应问题的严重性, 为了更快的筛选符合⽬标的⽇志信息.

试想⼀下这样的场景,假设你是⼀家 2 万⼈公司的⽼板, 如果每个员⼯的⽇常⼯作和琐碎的信息都要反 馈给你, 那你⼀定⽆暇顾及. 于是就有了组织架构,⽽组织架构就会分级,有很多的级别设置,如下图所⽰:

有了组织架构之后,就可以逐级别汇报消息了, 例如:组员汇报给组⻓, 组⻓汇报给研发⼀组, 研发⼀组 汇报给 Java 研发, 等等依次进⾏汇报.

⽇志级别⼤概是同样的道理,有了⽇志级别之后就可以过滤⾃⼰想看到的信息了, ⽐如只关注error级别 的, 就可以根据级别过滤出来error级别的⽇志信息, 节约开发者的信息筛选时间

9.2、日志级别的分类

⽇志的级别从⾼到低依次为: FATAL、ERROR、WARN、INFO、DEBUG、TRACE

  • FATAL: 致命信息,表⽰需要⽴即被处理的系统级错误.
  • ERROR: 错误信息, 级别较⾼的错误⽇志信息, 但仍然不影响系统的继续运⾏.
  • WARN: 警告信息, 不影响使⽤, 但需要注意的问题
  • INFO: 普通信息, ⽤于记录应⽤程序正常运⾏时的⼀些信息, 例如系统启动完成、请求处理完成等.
  • DEBUG: 调试信息, 需要调试时候的关键信息打印.
  • TRACE: 追踪信息, ⽐DEBUG更细粒度的信息事件(除⾮有特殊⽤意,否则请使⽤DEBUG级别替代)

⽇志级别通常和测试⼈员的Bug级别没有关系.

⽇志级别是开发⼈员设置的, ⽤来给开发⼈员看的. ⽇志级别的正确设置, 也与开发⼈员的⼯作经验有关. 如果开发⼈员把error级别的⽇志设置成了info, 就很有可能会影响开发⼈员对项⽬运⾏情况的判断. 出现error级别的⽇志信息较多时, 可能也没有任何问题. 测试的bug级别更多是依据现象和影响范围来判断

9.3、日志级别的顺序

级别越高,收到的消息越少

这个很好理解,若天天出现trace日志,天天都出现这种系统级错误,非常严重,那这个公司的相关人员马上就没法干下去了

9.4、日志级别的使用(打印)

日志只会打印大于或等于日志输出级别的日志

日志级别是开发人员自己设置的,开发人员根据自己的理解来判断该信息的重要程度

类似公司管理, 通常由领导来判断什么样的事情需要汇报, 什么样的事情不需要汇报

针对这些级别, Logger 对象分别提供了对应的⽅法, 来输出⽇志

java 复制代码
@Slf4j     // 使用该注解后Spring会自动帮我们生成日志对象 ------ log
@RestController
public class LoggerController {


    @PostConstruct
    public void print(){
        System.out.println("打印日志");
        log.info("=================我是日志框架打印的日志================");
        log.info("=======我是日志框架打印的日志===================");
        log.error("我是error日志");
        log.warn("我是warn日志");
        log.info("我是info日志");
        log.debug("我是debug日志");
        log.trace("我是trace日志");
    }
}

观察打印的日志结果

结果发现, 只打印了info, warn和error级别的⽇志

这与⽇志级别的配置有关, ⽇志的输出级别默认是 info级别, 所以只会打印⼤于等于此级别的⽇志, 也就是info, warn和error.

不过输出的日志级别是可以设置的

9.5、配置日志级别(以yml举例)

⽇志级别配置只需要在配置⽂件中设置logging.level配置项即可,如下所⽰:

配置文件皆以yml举例,properties操作类似,只是格式不同

logging:

level:

root: info

root后即为要设置的日志级别,下面我们将其设置为debug

重新运行程序:

需要一提的是,SpringBoot本身输出的日志可以和其他日志分别设置输出级别(了解即可,不常用)

10、日志持久化

以上的⽇志都是输出在控制台上的, 然⽽在线上环境中, 我们需要把⽇志保存下来, 以便出现问题之后追溯问题. 把⽇志保存下来就叫持久化.

日志保存在文件和数据库中都可以将日志持久化,保存在文件中用的较多,我们讲解的也是这种方式

日志持久化有两种方式

1、配置日志文件的路径和文件名 (可以设置路径和文件名)

2、配置日志文件的保存路径 (只可以设置路径,不可以设置文件名,不过可以依靠其他方法来设置文件名)

配置日志文件的路径和文件名

logging:

file:

name: logger/ioc.log

name后⾯可以跟绝对路径或者相对路径

如果没有加路径,默认是放在当前项目下

配置日志文件的保存路径

logging:

file:

path: logger1

这种⽅式只能设置⽇志的路径, ⽂件名为固定的spring.log

运⾏程序, 该路径下多出⼀个⽇志⽂件: spring.log

注意:

logging.file.name 和 logging.file.path 两个都配置的情况下, 只⽣效其⼀, 以 logging.file.name 为准

11、日志文件分割

如果我们的⽇志都放在⼀个⽂件中, 随着项⽬的运⾏, ⽇志⽂件会越来越⼤, 需要对⽇志⽂件进⾏分割

当然, ⽇志框架也帮我们考虑到了这⼀点, 所以如果不进⾏配置, 就⾛⾃动配置

默认⽇志⽂件超过10M就进⾏分割

logging:

logback:

rollingpolicy:

max-file-size: 1KB

file-name-pattern: ${LOG_FILE}.%d{yyyy-MM-dd}.%i

  • 推荐搭配日志持久化方式中的设置文件路径和命名一起使用,命名不会被采纳,会按着分割的配置中的文件名来(不搭配的话文件路径不知道会跑哪里去,你可以自己试试(狗头))
  • 也推荐搭配设置日志输出级别一起使用,否则有可能运行半天没生成文件,因为没有日志可输入到文件中
  1. ⽇志⽂件超过1KB就分割(设置1KB是为了更好展⽰. 企业开发通常设置为200M, 500M等, 此处没 有明确标准)

  2. 分割后的⽇志⽂件名为: ⽇志名.⽇期.索引

项⽬运⾏, 多打印⼀些⽇志, ⽇志分割结果:

11、配置日志格式

更多说明, 参考:https://logback.qos.ch/manual/layouts.html#conversionWord

⽬前⽇志打印的格式是默认的

打印⽇志的格式, 也是⽀持配置的. ⽀持控制台和⽇志⽂件分别设置

配置项说明:

1、%clr(表达式){颜⾊} 设置输⼊⽇志的颜⾊

⽀持颜⾊有以下⼏种:

• blue

• cyan

• faint

• green

• magenta

• red

• yellow

2、%d{${LOG_DATEFORMAT_PATTERN:-yyyy-MM-ddTHH:mm:ss.SSSXXX}} ⽇期和时间--精确到毫秒

%d{}

⽇期 ${LOG_DATEFORMAT_PATTERN:-yyyy-MM-dd'T'HH:mm:ss.SSSXXX} ⾮空表达式, 获取 系统属性 LOG_DATEFORMAT_PATTERN , 若属性 LOG_DATEFORMAT_PATTERN 不存在,则使 ⽤ -yyyy-MM-dd HH:mm:ss.SSSXXX 格式, 系统属性可以

System.getProperty("LOG_DATEFORMAT_PATTERN") 获取

3、%5p 显⽰⽇志级别ERROR,MARN,INFO,DEBUG,TRACE.

4、%t 线程名. %c 类的全限定名. %M method. %L 为⾏号. %thread 线程名称. %m 或者 %msg 显⽰输出消息. %n 换⾏符

5、%5 若字符⻓度⼩于5,则右边⽤空格填充. %-5 若字符⻓度⼩于5,则左边⽤空格填充. %.15 若 字符⻓度超过15,截去多余字符. %15.15 若字符⻓度⼩于5,则右边⽤空格填充. 若字符⻓度超 过15,截去多余字符

演示:

通常情况下,咱们就使用默认的日志格式打印即可

🧸欢迎您于百忙之中阅读这篇博客,📜希望这篇博客给您带来了一些帮助,祝您生活愉快!

相关推荐
这周也會开心3 分钟前
云服务器安装JDK、Tomcat、MySQL
java·服务器·tomcat
hrrrrb1 小时前
【Spring Security】Spring Security 概念
java·数据库·spring
小信丶1 小时前
Spring 中解决 “Could not autowire. There is more than one bean of type“ 错误
java·spring
sdgsdgdsgc1 小时前
Next.js企业级应用开发:SSR、ISR与性能监控方案
开发语言·前端·javascript
周杰伦_Jay2 小时前
【Java虚拟机(JVM)全面解析】从原理到面试实战、JVM故障处理、类加载、内存区域、垃圾回收
java·jvm
摇滚侠3 小时前
Spring Boot 3零基础教程,IOC容器中组件的注册,笔记08
spring boot·笔记·后端
rit84324995 小时前
基于MATLAB的模糊图像复原
开发语言·matlab
fie88895 小时前
基于MATLAB的声呐图像特征提取与显示
开发语言·人工智能
程序员小凯5 小时前
Spring Boot测试框架详解
java·spring boot·后端
豐儀麟阁贵6 小时前
基本数据类型
java·算法