详解 Spring Boot 项目中的日志文件

时间:2022-12-05 08:02:02

目录

1. 日志的作用

2. 自定义日志打印

2.1 日志的基本格式

2.2 得到日志对象

2.3 使用日志对象提供的方法, 打印自定义的日志内容

2.4 日志框架的说明

3. 日志的持久化 

3.1 配置日志文件的文件名

3.2 配置日志文件的保存路径

 3.3 持久化日志的特性

4. 日志的级别

4.1 日志级别的作用

4.2 日志级别的分类

4.3 设置日志级别

5.更加简单的打印日志

5.1  添加 lombok 依赖

5.2 使用 @SLF4J 注解实现更简单的打印日志

5.3 lombok 原理分析


1. 日志的作用

日志最基本的作用就是发现和定位问题, 我们平时在写程序的时候, 没有达到预期效果时, 我们都会打开控制台去查看错误原因, 这就是最基本的体现.

当然日志还有其他的作用:

1. 记录用户登录日志,方便分析用户是正常登录还是恶意破解用户.
2. 记录系统的操作日志,方便数据恢复和定位操作人.
3. 记录程序的执行时间,方便为以后优化程序提供数据支持.

2. 自定义日志打印

2.1 日志的基本格式

详解 Spring Boot 项目中的日志文件

自定义日志打印的基本步骤:

  1. 得到日志对象
  2. 使用日志对象提供的方法, 打印自定义的日志内容

【代码示例】

2.2 得到日志对象

private static Logger log = LoggerFactory.getLogger(TestController.class);

1.  Logger 对象和 LoggerFactory 都是来自与 org.slf4j 包下的.

2. TestController.class 表示只能当前日志的出处, 来自于哪个类, 对应上述格式中的执行类名.

2.3 使用日志对象提供的方法, 打印自定义的日志内容

详解 Spring Boot 项目中的日志文件 

当然, 我们使用 System.out.println() 也能输出日志, 但是它不能代替日志, 因为这样打印日志存在问题:

1. 这样打印的日志只有日志内容, 没有日志的其他信息, 例如: 日志的打印时间, 打印的日志是来自于哪个类.

2.不能实现不同环境下的行为控制.

详解 Spring Boot 项目中的日志文件

 

2.4 日志框架的说明

详解 Spring Boot 项目中的日志文件

【解析】日志的框架其实也类似前后端分离, 日志门面相当于前端, 日志实现相当于后端.

为什么一个简简单单的日志也分 "前后端" ?

>>最早其实是不分的, 最早可能就是调用一个 log4j 就实现了, 后来因为代码通用性等问题, log4j 爆出一些漏洞了, 亦或是 log4j 太老了, 没人更新了, 于是就换用了 logback 日志, 但是在换用 logback 的时候, 之前调用日志代码的部分都得去改, 这就是一个致命的问题.

>>我们的 JDBC 也是如此, 在最早没有 JDBC 的时候, 每一家数据库的厂商和 API 都是不一样的, 所以这样就导致了我的数据库代码没有移植性可言, 为了解决这个问题, 才引入了 JDBC , 给这些数据库厂商上面又封了一层, 对于用户来说, 你不用关注你操作的到底是谁, 你只需要遵守 JDBC 的写法, 你只需要在配置里声明你要连接的数据库即可. 这样就可以解决数据库的差异化了.  (JVM -- Java 代码的一处编译到处运行亦是如此)

>> 所以此处的日志门面就是将底下的日志实现又封装了一层, 给用户去调用, 用户始终操作的是 SLF4J, 然后 SLF4J 会帮咱们去适配底层的实现. (Spring Boot 默认的日志实现是 logback)

3. 日志的持久化 

为什么要将日志持久化?

如果不将日志持久化, 我们就只能在控制台上看日志, 控制台一关, 我们的日志就没了. 并且生产环境随时可能会出现问题, 不可能让运维人员 24 小时的盯着控制台去看, 这不现实.

日志的持久化有两种方式:

  • 配置日志文件的文件名.
  • 配置日志文件的保存路径.

3.1 配置日志文件的文件名

# 配置日志的保存名称
logging:
  file:
    name: mylog.log

启动程序, 访问 url, 我们的项目中就会多出一个 mylog.log 的文件, 如果你的项目中没有出现你命名的日志文件, 并且代码都是正确的情况下, 那可能就是 IDEA 缓存的问题, 你就可以打开你项目的文件夹, 找到底下的 target ,将其删除, 然后再运行一次程序, 访问 url 就能看见了.

详解 Spring Boot 项目中的日志文件

 打开 mylog 文件可以看到和在控制台看到一样的日志信息:

详解 Spring Boot 项目中的日志文件

3.2 配置日志文件的保存路径

# 配置日志的保存路径
logging:
  file:
    path: D:\aa\

 和上述操作一样, 最终会在指定路径下得到一个 spring.log 的文件.

详解 Spring Boot 项目中的日志文件

 3.3 持久化日志的特性

上述两种持久化日志的方式, 都会存在两种顾虑: 

1. 如果程序运多次, 我的本地日志文件, 是产生覆盖的效果, 还是追加的效果? 如果是覆盖, 那岂不是也有丢失日志的风险?

2. 如果是追加日志, 那么随着程序的多次运行, 日志越来越大, 光查看日志就很不方便了,  它是怎么解决的?

首先, 持久化日志的两种方式的特性都是有日志追加效果

详解 Spring Boot 项目中的日志文件

对于日志越来越大不方便查看的问题, 它也是有相应的应对策略的: 当日志比较大的时候, 会自动分割成多个文件 (默认是 20 MB, 可设置系统参数)

4. 日志的级别

4.1 日志级别的作用

  • 日志级别的作用就是用来筛选日志的, 默认日志级别是 info, 那么对于普通日志和调试日志就可以忽略了, 可以加快开发的效率.
  • 日志级别可以控制不同情况下, 一个程序对日志信息的需求, 例如开发环境上需要很详细的信息, 可能需要看到 info 甚至 dubug 以下的信息, 而生产环境上为了安全和性能就会输出尽可能少的日志信息, 这时候就可以通过日志级别来控制了.

4.2 日志级别的分类

日志有 6 个级别, 级别从低到高如下图所示:

详解 Spring Boot 项目中的日志文件

trace:  微量, 少许的意思, 级别最低.

debug:需要调试时候的关键信息打印.
info:普通的打印信息 (默认日志级别).
warn:警告,不影响使用,但需要注意的问题.
error:错误信息,级别较高的错误日志信息.
fatal:致命的,因为代码异常导致程序退出执行的事件.(不能在程序中调用它, 但是它存在)

 这 6 个级别的设置, 越往下, 输出的日志就越少. 例如我们设置了 warn 级别, 那么我们就只能收到 warn, error, fatal 级别的日志了.

【代码示例】

@RestController
public class TestController {

    private static Logger log = LoggerFactory.getLogger(TestController.class);

    @RequestMapping("/log")
    public String printLog() {
        log.trace("i am trace.");
        log.debug("i am debug.");
        log.info("i am info.");
        log.warn("i am warn.");
        log.error("i am error.");
        return "Hello Spring Boot~";
    }
}

详解 Spring Boot 项目中的日志文件

 从执行结果来看, 当我们不设置日志级别的shihou,默认是 info, 于是控制台只打印了 warn, error 级别的日志.  (fatal 级别的日志是不能通过方法打印出来的, 它没有这个方法, 只有在代码异常导致程序退出执行时才会有

4.3 设置日志级别

基本格式:

logging:
  level:
    root: debug  # 全局日志级别

此时云运行之前的代码:

详解 Spring Boot 项目中的日志文件

设置成 debug 后, Spring 很多的系统日志就都打印出来了, 不方便查找我们所需要的日志, 这时候我们还可以更精细化的设置日志级别.

logging:
  level:
    root: warn  # 设置系统日志级别
    com:
      example:
        demo: debug  # 具体到设置文件夹的日志级别

详解 Spring Boot 项目中的日志文件

我们可以看到打印的日志信息少了很多, 只会打印我们所控制的日志级别范围内的日志信息了.

5.更加简单的打印日志

经过前面的讲解, 我们已经知道了打印日志需要两个步骤:  1. 得到日志对象;  2. 调用日志对象的方法, 打印日志.

>> 于是就会存在这样一件事情, 我们每个类中似乎都要去做第一步: 得到日志对象, 相对来说还是有点麻烦的, 那么我们可以使用 lombok 来做到更加简单的实现.

【具体步骤】

  1. 添加 lombok 依赖
  2. 使用 @SLF4J 注解替代第一步 - 得到日志对象.

5.1  添加 lombok 依赖

方式一: 

  • 下载 EditStarters 插件
  • 在 pom.xml 中右键选择 Generate -> Edit Starters 然后进行选择 lombok 依赖.

方式二: (IDEA 2021 3.2+)

  • 在 pom.xml 中右击选择 Generate -> Dependency, 然后输入 lombok 进行查找, 选择相关依赖.

5.2 使用 @SLF4J 注解实现更简单的打印日志

【代码示例】

@RestController
@Slf4j   // @SLF4J 注解代替原始步骤的第一步
public class UserController {
    @RequestMapping("/user")
    public String hello() {
        log.info("i am info.");  // 内置的 log 对象
        return "Hello Spring Boot~";
    }
}

注意: 当我们使用 @SLF4J 注解时, 它会为我们提供一个 log 对象, 我们只能拿这个对象去调用打印日志的方法, 这是 lombok 的规定, 我们要遵守!! 

>>> 为什么使用一个 @SLF4J 注解就能实现下面这条语句呢 ?

详解 Spring Boot 项目中的日志文件

这就要去分析底层源码了>>>

5.3 lombok 原理分析

1. 打开项目文件夹所在路径, 找到以下路径下的 UserController.class 文件: 

.\target\classes\com\example\demo

然后拖入到 IDEA 中观察代码: 

详解 Spring Boot 项目中的日志文件

可以发现生成的最终源码还是按照以前的方式来打印日志的, 所以 lombok 只是帮我们做了这些复杂的事情.

运行原理图: 

详解 Spring Boot 项目中的日志文件


本篇文章就到这里了, 谢谢观看!!