Spring Boot 日志文件

本文涉及的产品
日志服务 SLS,月写入数据量 50GB 1个月
简介: Spring Boot 日志文件

引言



关于日志


我们日常在写代码的时候,出现了异常,都会在编译器的控制台上,找出问题。这些问题并不是我们盲猜的,而是控制台上有明显的日志打印,我们就可以根据日志打印发现问题、解决问题。所以说,日志是调试程序重要的一环。


此外,日志除了发现和定位问题外,它还有如下实用的功能:


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


基于上面的介绍,本篇博客着重介绍 Spring Boot 提供的日志框架。


一、Spring Boot 日志的格式说明



通常来说,如果我们的 Sping Boot 项目没有出现异常或错误信息,那么当我们运行启动类后,就会出现下面的日志信息:一个 Spring 图标,和一些基本都是 info 级别的日志信息。所以在一般情况下,我们就是通过这样的打印日志,来判定一个项目是否真正的编译无误了。


0252d220885b437a80c0619f0748c5b2.png


那么,这些日志信息是什么意思呢?请看下图:


6fdfab89c9cb4a098b80e8413e97e1a7.png


二、自定义打印日志



我们创建一个 Spring Boot 项目后,再创建一个 " UserController " 类,我们预期不给前端返回数据,只是最终能够在 IDEA 控制台显示日志。


@Controller
@ResponseBody
public class UserController {
    // 1. 先得到日志对象
    private final static Logger log =
            LoggerFactory.getLogger(UserController.class);
    @RequestMapping("/hello")
    public void hello() {
        // 2. 使用日志对象提供的打印方法进行日志打印
        log.trace("我是 trace");
        log.debug("我是 debug");
        log.info("我是 info");
        log.warn("我是 warn");
        log.error("我是 error");
    }
}


展示结果:


说明: 刚开始运行时,我们是看不到红色框框中的内容的,我们需要在前端输入 " hello " 这个 URL 后,才能看到下面的日志。这很好理解,因为日志打印的代码是我们自定义生成的,而且写在了 hello 方法内。 如下图所示:


22f6cbac7e5f488b958bf263b0d43409.png


然而,就算我们输入了 " URL ",我们最终发现只打印了三个自定义信息,但是,我们一开始在 hello 方法中,自定义的是五个日志信息,结果却少了两个信息。这就涉及到了【日志级别】的问题了,Spring Boot 框架默认的日志级别是 info,所以,只显示了 info、warn、error.这里不用担心,本篇博客后面会介绍到原因,请继续往下看。


解析代码


1. 先得到日志对象


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


对于上面这段代码,它是固定写法,但我们必须要知道,Logger 类、LoggerFactory 类,它们两是 Spring Boot 框架中 " slf4j " 这个包提供的。

关于 " slf4j ",我们在本篇博客的后面也会介绍到。


5932fadbb6f544daa3ece8168d4283fa.png


此外,使用 " getLogger " 这个方法的时候,我们要指定一个类对象,因为正是这个类对象告诉了 Spring Boot,之后的日志打印要精确到哪个类。


2. 使用日志对象提供的打印方法进行日志打印


下面的五个方法,也是 " slf4j " 这个包所提供的,五个方法实际上对应了五个日志级别,方法传入的参数,就是我们自定义的日志打印。这里需要明确,输出的日志和我们平时使用的 【 System.out.println(); 】不同,这里输出的日志包含在 Spring Boot 内置的框架中,也就是说,它是框架提供的功能。


log.trace("我是 trace");
log.debug("我是 debug");
log.info("我是 info");
log.warn("我是 warn");
log.error("我是 error");


三、日志级别



  1. trace:少许的日志 ( 级别最低 )
  2. debug:调试日志 ( 针对于开发人员调试的场景 )
  3. info:普通信息日志 ( Spring Boot 框架默认的级别 )
  4. warn:警告日志 ( 不影响使用,但仍需要注意问题 )
  5. error:错误日志 ( 级别较高 )
  6. fatal:致命 / 异常日志 ( 系统输出的日志,不能自定义打印 )


六种日志级别,由低到高,越往级别高的日志,接收到的信息越少。


比方说:

当你的日志级别设置为 info 的时候,你只能看到 info、warn、error、fatal.

当你的日志级别设置为 error 的时候,你只能看到 error、fatal.


这很好理解,假设你的项目出现了异常,那么它优先显示错误的日志,因为正常的数据信息与你无关,你也不会对正常的代码进行排查。


3f59fb7247bd46deb08f72c4a50ccb44.png


1. 通过配置文件设置日志级别


为 Spring Boot 项目设置日志级别,我们一般是将配置项放在配置文件中,下面是两种配置文件的配置格式。


983d0df1740a44ec9538b0c7a47a9d0f.png


2. 注意事项


(1) 我们既可以设置整个项目的日志级别 ( 全局配置 );也可以设置局部目录的日志级别。进行局部设置时,精确到某个类对应的目录即可,不需要精确到某个类。


(2) 刚刚上面所说的六种日志级别,都可以通过上图的格式进行配置。

(3) 假设我们配置如下代码:


# 全局配置日志
logging.level.root=warn


我们就可以看到输出日志,只有 warn 和 error,也就是我上面提到的,日志级别越高,接收到的信息就越少。


8f4ca5798013485895ceecd926560eb6.png


(4) 假设我们设置如下代码:


# 设置全局的日志级别
logging.level.root=info
# 设置局部目录的日志级别
logging.level.com.example.demo=warn


当我们同时设置了全局日志和局部日志,那么,指定的局部目录的优先级就会大于全局日志的优先级。


1f944ef605974ef496a1e8b3a3a5cb1b.png


四、日志持久化



日志持久化的意思就是将日志永久地保存到磁盘中。


为什么需要日志持久化呢?


答:我们平时利用 IDEA 随手写一个代码,再进行测试,是感知不到问题的,因为我们都是哪里出错了,再通过即时的日志信息来解决问题就可以了。所以说,IDEA 上的控制台程序只是临时的一份,一般来说,我们运行一次,就会出现一个新的日志信息。然而,在有些场景下,一个项目就需要将日志信息保存下来,以便于出现了问题,进行追溯。由于 Spring Boot 也是为我们后续的 Web 开发服务的,所以框架也实现了一个持久化存储的功能,它依然需要在配置文件中实现。


1. 日志持久化的两种方式


(1) 指定磁盘目录后,由框架自动生成一个文件,并把日志信息放入到此文件中。


logging.file.path=D:/Data


(2) 指定目录 + 文件名,框架会将日志信息放入自定义的文件中


logging.file.name=D:/Data/spring-boot.log


我们以第一种指定目录的方式为例,演示 " UserController " 类,最终发现,框架为我们生成了一个 " spring.log " 这样的文件,我们可以利用记事本的形式打开验证。


cbdb03e9d7b2474f846a57fc4b113adf.png


2. 注意事项


(1) 上面只演示了 properties 配置文件,实际上 yml 配置文件的思想是一样的,只是格式不同罢了。


但是经过我的测试发现,properties 配置文件的目录不能写成中文,否则日志文件就不会自动生成,但 yml 配置文件却可以配置成中文的。这可能是编码问题,也可能是 IDEA 版本问题。但是我认为,如果想避免此问题,还是将目录写成英文的好。实际上,很多场景下,目录和文件确实不宜写成中文。


(2) 框架为我们提供的日志持久化非常的人性化,我们不用担心,在日志文件中,后续的日志信息会将前面的日志信息覆盖。我们可以多运行几次启动类,结果都会发现,文件中的数据是以时间顺序保存着的,然而,文件始终就只有一份。


这让我想起了 Java 中的流对象的,它就可以实现将文本数据按照拼接字符串的方式,每一次生成的数据,就可以放在原先文件的最后方。而在这里,思想是一样的。


如下图所示:


ee09788ac739425ab8971739ea404bb8.png

(3) 也许你会担心如果一个大型项目的日志信息,多的有几个 G 怎么办?那个时候,光是找某个类的日志都会费好大的劲怎么办?


其实,这也不用担心。实际上,框架的底层为我们设计好了一个生成文件的最大内存不超过 10M. 万一超过 10M,就会以编号的方式,重新生成文件,放在同一个目录下。


以后在公司,公司或许有另类的规定,但在日常的学习中,自己做一个项目的话,即使你用到了日志持久化,一般情况下,10M 肯定也到不了。


b45c9440f7f647d7a90d5060eddd765e.png


五、利用 lombok 来做到更简单的日志输出



使用 lombok 这个依赖,添加 " @Slf4j " 注解,它可以替代我们之前的操作。


@Controller
@ResponseBody
@Slf4j // 替代了之前需要通过 LoggerFactory.getLogger 的操作
public class UserController2 {
    @RequestMapping("/hello2")
    public void hello2() {
        log.trace("我是 trace2");
        log.debug("我是 debug2");
        log.info("我是 info2");
        log.warn("我是 warn2");
        log.error("我是 error2");
    }
}


设置局部目录的日志级别为 " trace ",并访问 " hello2 " 这个 URL,查看输出结果:


d27cc106cd7a4c2595eda6e83458f862.png


1. lombok 的使用原理


请看下面的这幅图,它完美诠释了 lombok 的原理,左边是我们加上 " @Slf4j " 注解的代码,它是一个 " .java " 文件,右边代码就是左边 " .java " 文件经编译后,生成的一个 " .class " 文件。在 " .class " 文件中,我们可以清晰地看到,左边的注解已经被转换成了一个 " Logger " 对象了,这也是博客开篇,我们写的第一步。


d8ab8523e4cc4577b755fdb4c3e92cac.png


这样一来我们就明白了,lombok 其实是在 " .java " 文件进行编译的时候,在底层做了一些事情,所以,这就是我们写注解方便的原因。


948a8e337ddf450e849722b25616a885.png


2. 注意事项


上面的 " .class " 文件来源于 【 target 】目录下,当我们创建好一个项目时,它并不是自动生成的,而是当我们点击 main 方法运行时,IDEA 自动帮我们生成的。IDEA 其实就是照着我们平时写的 " .java " 文件,又生成了一个同名的 " .class " 文件,只是我们感知不到而已。


cde1cd52ff9b4406b070094d2ceaedbd.png


我们知道,一个 Java 程序,最终是在 JVM 运行的,但 JVM 实际上只认识 " .class " 文件。所以,如果我们拆解来看,我们平时写的代码,就是放在 " .java " 文件中的,然后再通过编译,变成了 " .class " 文件,最终才给 JVM 运行。


然而,IDEA 帮我们省去了编译的过程,或者说,我们平时根本感受不到编译,只顾着写代码了,但确实,IDEA 帮我们实现了 " 编译 + 运行 " 的整个过程。不过 IDEA 有一点好处,先抛开结果是否符合预期不谈,IDEA 可以在我们写代码的时候,就能够判定是否能正常编译,这是一个非常强大的功能。


此外," .class " 文件,实际上是一个字节码文件,也就是说,它的内容实际上就是以二进制的形式呈现的,只不过,IDEA 帮我做了一些处理,让程序员能够看懂代码。如果我们利用记事本打开 " .class " 文件,就会发现里面的内容是乱码。


3. lombok 提供的更多注解


① 基本注解:


注解 作用
@Getter 自动添加 getter 法
Setter 自动添加 setter 法
@ToString 自动添加 toString 法
@EqualsAndHashCode 自动添加 equals 和 hashCode 法
@NoArgsConstructor 自动添加无参的构造方法
@AllArgsConstructor 自动添加全属性构造方法,顺序按照属性的定义顺序
@NonNull 属性不能为 null
@RequiredArgsConstructor 添加必需属性的构造方法,final + @NonNull 的属性为必需


② 组合注解:


注解 作用
@Data @Getter + @Setter + @ToString + @EqualsAndHashCode + @RequiredArgsConstructor + @NoArgsConstructor


③ 日志注解:


注解 作用
@Slf4j 自动添加一个名为 log 的日志



4. 在 Spring Boot 项目中临时添加 lombok


如果我们的 Spring Boot 项目,在刚开始创建的时候,我们选中我们想要的依赖,那么,我们不用重新创建一个项目,只需要临时添加依赖即可。


第一步,搜索插件。


29469364ff9248e2b932081da7b1c72a.png


第二步,在 pom.xml 文件中,点击 Generate 生成。


337b217ed555470b87554f4a46515d79.png


第三步,选择我们需要添加的依赖。选好后,依赖就会从 maven 仓库引入。


3a3c450175b7420db0107dee5e113977.png


六、关于 Slf4j



" Slf4j " 是 lombok 这个依赖提供的包,不管是我们自己手动引入对象,还是通过注解的方式添加日志," Slf4j " 的核心就是下面这段代码。


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

所以,我们也可以说是 Spring Boot 内置了日志框架 " Slf4j " . 而 " Slf4j " 其实是遵循了门面模式,不管底层的实现代码怎么变," Slf4j " 提供的代码都是固定写法。


所以有时候,我们只需要会用上层的固定写法即可,底层实现的思想就算不理解,也能够将一个项目做的很好。 比方说:当前我们使用的就是 " Slf4j " 提供的一些方法,然而,它的日志实现是基于 " logback " 的。


这就好像," Slf4j " 是直播带货的," logback " 才是真正的生产厂家。


b0d6d8e8296f4cdbac3651c43ab9ad2b.png


这里的门面模式,它和我们正儿八经写的 JDBC 代码差不多,不管我们连接的是 MySQL 数据库,还是 Oracle 数据库,还是其他的数据库…我们开发人员在用的时候,只关注 JDBC 是怎么用的,至于其他的,底层已经为我们封装好了。


相关实践学习
日志服务之使用Nginx模式采集日志
本文介绍如何通过日志服务控制台创建Nginx模式的Logtail配置快速采集Nginx日志并进行多维度分析。
目录
打赏
0
0
0
0
1
分享
相关文章
springboot-多环境配置文件
本文介绍了如何创建开发和生产环境的配置文件,并在IDEA和Maven中进行配置。开发环境中,通过设置profile为`dev`来指定配置文件;生产环境中,使用Maven命令参数`-Pprod`打包并指定配置文件。公共配置可放在`application.yml`中统一管理。日志配置需确保`logback-spring.xml`中的profile正确,以保证日志正常输出。
springboot-多环境配置文件
微服务——SpringBoot使用归纳——Spring Boot使用slf4j进行日志记录—— logback.xml 配置文件解析
本文解析了 `logback.xml` 配置文件的详细内容,包括日志输出格式、存储路径、控制台输出及日志级别等关键配置。通过定义 `LOG_PATTERN` 和 `FILE_PATH`,设置日志格式与存储路径;利用 `<appender>` 节点配置控制台和文件输出,支持日志滚动策略(如文件大小限制和保存时长);最后通过 `<logger>` 和 `<root>` 定义日志级别与输出方式。此配置适用于精细化管理日志输出,满足不同场景需求。
103 1
微服务——SpringBoot使用归纳——Spring Boot使用slf4j进行日志记录——使用Logger在项目中打印日志
本文介绍了如何在项目中使用Logger打印日志。通过SLF4J和Logback,可设置不同日志级别(如DEBUG、INFO、WARN、ERROR)并支持占位符输出动态信息。示例代码展示了日志在控制器中的应用,说明了日志配置对问题排查的重要性。附课程源码下载链接供实践参考。
60 0
微服务——SpringBoot使用归纳——Spring Boot使用slf4j进行日志记录—— application.yml 中对日志的配置
在 Spring Boot 项目中,`application.yml` 文件用于配置日志。通过 `logging.config` 指定日志配置文件(如 `logback.xml`),实现日志详细设置。`logging.level` 可定义包的日志输出级别,例如将 `com.itcodai.course03.dao` 包设为 `trace` 级别,便于开发时查看 SQL 操作。日志级别从高到低为 ERROR、WARN、INFO、DEBUG,生产环境建议调整为较高级别以减少日志量。本课程采用 yml 格式,因其层次清晰,但需注意格式要求。
84 0
|
22天前
|
微服务——SpringBoot使用归纳——Spring Boot使用slf4j进行日志记录——slf4j 介绍
在软件开发中,`System.out.println()`常被用于打印信息,但大量使用会增加资源消耗。实际项目推荐使用slf4j结合logback输出日志,效率更高。Slf4j(Simple Logging Facade for Java)是一个日志门面,允许开发者通过统一方式记录日志,无需关心具体日志系统。它支持灵活切换日志实现(如log4j或logback),且具备简洁占位符和日志级别判断等优势。阿里巴巴《Java开发手册》强制要求使用slf4j,以保证日志处理方式的统一性和维护性。使用时只需通过`LoggerFactory`创建日志实例即可。
35 0
Springboot静态资源映射及文件映射
在Spring Boot项目中,为了解决前端访问后端存储的图片问题,起初尝试通过静态资源映射实现,但发现这种方式仅能访问打包时已存在的文件。对于动态上传的图片(如头像),需采用资源映射配置,将特定路径映射到服务器上的文件夹,确保新上传的图片能即时访问。例如,通过`addResourceHandler("/img/**").addResourceLocations("file:E:\\myProject\\forum_server\\")`配置,使前端可通过URL直接访问图片。
129 0
Springboot静态资源映射及文件映射
Java||Springboot读取本地目录的文件和文件结构,读取服务器文档目录数据供前端渲染的API实现
博客不应该只有代码和解决方案,重点应该在于给出解决方案的同时分享思维模式,只有思维才能可持续地解决问题,只有思维才是真正值得学习和分享的核心要素。如果这篇博客能给您带来一点帮助,麻烦您点个赞支持一下,还可以收藏起来以备不时之需,有疑问和错误欢迎在评论区指出~
Java||Springboot读取本地目录的文件和文件结构,读取服务器文档目录数据供前端渲染的API实现
docker运维查看指定应用log文件位置和名称
通过本文的方法,您可以更高效地管理和查看Docker容器中的日志文件,确保应用运行状态可控和可监测。
198 28
微服务——SpringBoot使用归纳——Spring Boot中的项目属性配置——指定项目配置文件
在实际项目中,开发环境和生产环境的配置往往不同。为简化配置切换,可通过创建 `application-dev.yml` 和 `application-pro.yml` 分别管理开发与生产环境配置,如设置不同端口(8001/8002)。在 `application.yml` 中使用 `spring.profiles.active` 指定加载的配置文件,实现环境快速切换。本节还介绍了通过配置类读取参数的方法,适用于微服务场景,提升代码可维护性。课程源码可从 [Gitee](https://gitee.com/eson15/springboot_study) 下载。
47 0
Spring Boot 两种部署到服务器的方式
本文介绍了Spring Boot项目的两种部署方式:jar包和war包。Jar包方式使用内置Tomcat,只需配置JDK 1.8及以上环境,通过`nohup java -jar`命令后台运行,并开放服务器端口即可访问。War包则需将项目打包后放入外部Tomcat的webapps目录,修改启动类继承`SpringBootServletInitializer`并调整pom.xml中的打包类型为war,最后启动Tomcat访问应用。两者各有优劣,jar包更简单便捷,而war包适合传统部署场景。需要注意的是,war包部署时,内置Tomcat的端口配置不会生效。
973 17
Spring Boot 两种部署到服务器的方式
AI助理

你好,我是AI助理

可以解答问题、推荐解决方案等