【JavaEE】Spring Boot 开发要点总结(3)
文章目录
- 【JavaEE】Spring Boot 开发要点总结(3)
- 1. 日志有什么作用
- 2. 日志格式
- 2.1 日志框架原理
- 3. 日志的打印
- 3.1 System.out.println
- 3.2 使用日志框架
- 3.3 日志级别
- 3.3.1 设置默认日志显示阈值
- 3.3.2 针对一个目录设置日志显示阈值
- 4. 日志持久化
- 4.1 设置日志保存路径
- 4.2 设置日志打印格式
- 4.3 设置日志文件名
- 4.4 面临的问题
- 5. lombok框架
- 5.1 节省重复简单代码的书写
- 5.2 快速读写日志文件
- 5.3 lombok实现原理
【JavaEE】Spring Boot 开发要点总结(3)
1. 日志有什么作用
写代码不是概率事件,bug的出现必然是有原因的,而日志的主要作用就是,排查和定位问题!
- 而日志的生成就是随着程序的进行和一步步生成的,不说全部过程都记录得清清楚楚,至少重要的点和环节或者一些异常情况都有记录
- 而通过日志的 “前后逻辑分析、类型级别、日志内容信息” ,就可以定位和排查了
- 就比如我们之前写普通 java 代码在控制台打印的信息和调试页面的信息差不多,都是让我们知道程序执行的过程怎么样~
除此之外,我们还能实现以下功能:
- 记录用户登录日志,方便分析用户是正常登录还是恶意破解用户
- 记录系统的操作日志,方便重要数据恢复和定位操作人
- 记录程序的执行时间,方便为以后优化程序提供数据支持
例如,启动项目的时候,控制台显示的就是,日志,标准的日志:
而且这些标准的日志,都是有固定格式的~
三个问题:
- Spring Boot 内置了日志框架,才能按照固定格式输出日志, 这些信息代表什么呢?
- 格式并不需要开发者去设计
- 默认情况下,项目输出的日志并非开发者自定义和打印的,Spring框架在运行时会自动打印一些日志, 如何自定义打印日志呢?
- 格式有了,内容和打印时机还是需要自定义的
- 日志默认是打印在控制台, 如何实现持久化呢?
- 控制台的,重新运行就会清空,日志得保存下来,才有意义,后续才能查阅
2. 日志格式
这就是日志框架提供的格式,提供的信息还是很全面的!
2.1 日志框架原理
Spring Boot之所以可以打印日志,是因为内置了两个日志框架:
-
slf4j
-
logback
为什么需要两个呢?
- slf4j 是开发者使用和调用的框架
- logback 最底层实现日志相关操作的框架
- 其实这里的思想跟 JQuery 和 JDBC 的思想差不多
- 多种浏览器统一满足JQuery,开发者统一地使用开发API,浏览器怎么识别代码展示出来的与开发者无关
- 多种数据库统一满足JDBC,开发者统一地使用开发API,底层怎么实现数据持久化与开发者无关
- 一种 低耦合高内聚 的分工
而这里,多种底层实现日志相关操作的框架统一支持slf4j,开发者统一地使用开发API,底层怎么实现日志相关操作的与开发者无关
- logback就是其中一种底层框架
后面设置日志级别,通过日志级别筛选 …等操作,底层由框架帮我们去实现,对于开发者,这些“坐享其成”的事太多了,我们要专心开发,不必可以他们的存在
3. 日志的打印
3.1 System.out.println
这是我们普通java程序的日志打印方式,效果平庸,信息很少:
运行后,浏览器访问:
查看控制台:
如果要打印时间:
效果:
其他的信息获取和组织起来就更加麻烦了~
- 而自己去加日志级别没有作用,你只是拼接了字符串罢了
- 这样就检索不了
并且对于后面第三个持久化的问题,sout的日志无法持久化保存
3.2 使用日志框架
程序能够启动并且能打印日志,就什么这个框架已经引入进来了,只需要以下操作:
- 获取日志工厂
- 生成一个日志制造器
一定要选择,slf4j框架的类
- 这里就涉及到了工厂模式,通过工厂类LoggerFactory去获取实例对象
- 能猜到,传过去的类对象,就是对应“包名+类名”的那一段信息
- 调用方法进行打印
访问一下试试:
可见,通过框架提供的API,就可以有效地设置日志级别,方法名对应的就是日志级别~
- 并且,日志格式跟系统日志一模一样~
但是,为什么我们打印了五条,却只显示三条呢?
- 这就是对日志级别的筛选操作
3.3 日志级别
- trace:微量、少许、痕迹,级别最低
- debug:调试日志级别
- info:普通日志级别
- warn:警告日志级别
- error:错误日志级别
- fatal:致命日志级别
- 只有系统崩溃时才会输出的日志级别,并没有fatal( )方法
- 级别最高
从上到下,日志级别递增!
而系统如何筛选日志的呢?
- 可见,我们啥也没设置的情况下,显示阈值是info,只显示跟info同级或者比info级别高的日志 => ≥info
- 这也是一种筛选~
而我们去筛选的话,就是根据这个原理,去设置默认显示阈值
3.3.1 设置默认日志显示阈值
效果:
- 看似没有启动成功,其实是因为trace和debug的日志太多了!
- 所以我们筛查的应该是≥info,≥warn,≥error的
效果:
- info不显示了
- 显示 ≥warn 的日志了~
日志级别的作用就是:过滤信息
- 将不需要的日志屏蔽掉
根据其他信息进行筛选排查的话,之后需要用到就去学~
3.3.2 针对一个目录设置日志显示阈值
要求:对于controller目录,显示阈值为info;对于model目录,显示阈值为error
- logging.level.[路径]
- 代表设置该路径下以及其子目录的日志显示阈值
- 其实设置默认日志显示阈值也是这个原理,代表设置root目录下的所有…
- 不过,越细致的优先级越高
效果:
4. 日志持久化
日志持久化,就是把日志保存到文件里,也就是保存到电脑磁盘里,后续在文件里去观看,可以通过文本编辑器进行一些查找查看~
配置项不懂的,可以去官方文档中解惑:Common Application Properties (spring.io)
- 以下内容只涉及部分,要想了解更多,阅读文档!
4.1 设置日志保存路径
不需要设置“要不要保存”的选项,因为设置了后还是需要给一个保存路径,还不如直接设置路径,就代表了两种含义
- 需要保存日志
- 保存日志的地址
- 保存到D盘的马库目录里:
控制台:
文件目录:
默认名为spring,类型为.log文件
并且目录不存在会自动创建
这个属性不能设置文件名
多按几下浏览器刷新:
以追加的方式更新:
4.2 设置日志打印格式
比如这个毫秒,我不喜欢,我要把他去掉:
效果:
日志文件里:
并不会更新之前的内容,而是往后去追加~
补充:
- 删除几条信息后按,Ctrl s
log文件修改后不能保存,只能另存为或者选择替换原本的文件
4.3 设置日志文件名
好像不符合预期猜想,key.log在哪:
原来在这儿~
所以path和name不能搭配~
- 这样生成的日志文件有两个~
而name对应的被认为是相对路径,就保存到项目目录里了
- 改为具体位置~
- perfect!
4.4 面临的问题
- 追加的方式去写到文件里的,那么一直这样下去,会不会文件太大,磁盘炸了?!
- 文件太大,查看不方便,打开特别慢
给文件设置极限大小
- 日志框架里是有默认的大小限制的
- 如果不进行配置,日志文件达到一定的大小,就会重新创建一个新文件,在原文件名加上后缀(比如时间),后续的日志追加到这个新文件里
当然,这些效果的实现,不止这一种做法,也还有更多的效果可以实现,可以去官方文档中阅读学习,之后遇到需要实现的效果,专门去查即可
5. lombok框架
Lombok虽然不是IDEA的“兄弟产品”,但是却能摆在一开始选择依赖的页面里:
说明这并不是等闲之辈,很多公司都在用
而它出现就是为了快速开发java项目的!
- 当然每个框架都是这样的
- 那么Lombok究竟好用在哪呢?
5.1 节省重复简单代码的书写
对于这些老朋友方法,我们再熟悉不过了,这些代码的特点就是,必要但是简单并且属性如果比较多,代码就会特别长
而Lombok框架提供的注解,很好的解决了这个问题:
- 注解帮助我们实现很多逻辑,甚至控制我们的操作显示,功能很强大
- 它不像一些API的类和方法参与到代码里,而是加在旁边,对我们进行强大的辅助,冥冥之中发挥强大的功能!
下载lombok插件和引入依赖:
其实在创建项目的时候就引入了,并且如果没有安装插件,也会自动帮你安装~
注解介绍:
属性越多,构造方法的个数呈阶乘倍数增加,所以全部都加上是不现实的,并且没多大必要,并不需要每个都存在~
如果你觉得不够简洁,还可以用 注解@Data,它等同于:
@Getter + @Setter + @ToString + @EqualsAndHashCode + @RequiredArgsConstructor + @NoArgsConstructor
等于这一整套~
当然,你自己写的代码,会覆盖原有的~
5.2 快速读写日志文件
同样的,用到注解
这样后,在类的内部就可以直接使用一个静态常量 log 了,代表的就是日志制造器
5.3 lombok实现原理
java程序执行的流程:
而Lombok就是在编码的时候,减轻了.java用户代码的负担:
我们没有书写对应的 log 以及Getter和Setter…,但是Lombok帮我们在.class里去添加了对应的字节码:
而那个小辣椒插件,是不可或缺的存在,因为没有它,我们在开发阶段,就会被系统判定没有对应的定义,以至于爆红,没有题词…
- 插件不等同于框架,插件的存在是在开发上和视觉上的提升
- 例如虽然class文件里有定义,但你现在的java代码上确实没有对应的定义,却可以使用,有题词,且不会爆红,这就是插件的帮助,将一些注解的含义“告诉”编译器,一些东西算他们定义过了~
- 插件的复杂实现,不是开发者需要注意的,“坐享其成即可” (>^ ω ^<)
文章到此结束!谢谢观看
可以叫我 小马,我可能写的不好或者有错误,但是一起加油鸭🦆!代码位置:spring_boot_demo2/src/main · 游离态/马拉圈2023年8月 - 码云 - 开源中国 (gitee.com)