![微服务从小白到专家:Spring Cloud和Kubernetes实战](https://wfqqreader-1252317822.image.myqcloud.com/cover/981/41202981/b_41202981.jpg)
3.3 Spring Boot管理日志
3.3.1 日志框架
从系统设计者的角度评估系统,任何系统都应该被监控,否则该系统将会被定性为失控。因为一旦缺少了系统运行状况的日志,开发团队和运维团队都将无法搜索、统计和分析系统,并依此做出相关决策。
如果缺少必要的日志信息,那么当出现线上问题时,开发团队也无法判断该问题的严重性。例如电商网站客户打电话投诉无法下单,此时第一线的监控团队,必须知道系统是否有任何异常状况。虽然理论上说监控团队应该比用户更早收到系统警报,但监控系统难免会有所遗漏,此时监控团队迫切需要知道是系统的哪个部分出现了问题。
在现代的系统问题诊断过程中,第一步是查询系统的各种日志,这些日志可能来自操作系统、中间件或者应用本身。对排查问题最有帮助的是应用日志,应用日志由开发人员在应用程序中进行配置,选用哪种日志框架及如何输出日志,将会对系统性能和可维护性产生巨大的影响。
作为开发者,特别是初学者,常常会怀疑日志框架的作用,如要需要日志,直接执行System.out.print即可,为何需要日志框架?答案很简单,如果只是写HelloWorld程序或者简单的demo程序,System.out.print就已经足够用。如果系统被部署到生产环境,并尽可能地为客户提供无间断服务,那么无论作为运维团队还是开发团队,都无法直接查看系统日志。除默认的控制台日志外,系统日志还需要按照不同格式输出到不同的存储目的地,而且这些日志需要被检索、被聚合、被备份,等等。这正是日志框架的功能所在。
本节将展示几种能与Spring Boot集成的主流日志框架,并逐一分析它们各自的优缺点。
目前Java生态中主流的日志框架(排除JDK自带的Logger)是Log4j2和Logback。另外一款开源软件Slf4j并不是一种新的日志框架,而是日志框架的一种门面模式实现(Facade),它以接口的形式出现,并以此方式将具体的日志实现从代码中屏蔽。利用这个方法,项目在更换日志的实现框架时就会相对容易些。此外,lombok还提供了Slf4j的注释,更进一步简化了相关代码。
在一个项目中如果要使用日志框架,至少需要以下三部分:
• 日志框架的依赖项(通过Maven或Gradle引入)。
• 框架对应的配置文件。
• 遵循框架规范在代码中插入日志代码。
如果需要将日志写入文件,那么某些平台需要提前建立目录并设置正确的权限。
3.3.2 Log4J2
事实上,Log4j2是Log4j的升级版,提供了更丰富的功能和更好的性能,而且从架构的角度将其API和实现划分为两个独立的jar包。因此,开发者既可以使用默认实现(log4j-core jar包),也可以根据自身需求做定制化开发。
首先,引入Log4j2相关的依赖,实现代码如下:
![](https://epubservercos.yuewen.com/91A00C/21440188001525406/epubprivate/OEBPS/Images/105-1.jpg?sign=1739287170-nZGOpAYCo0GYbrylBVB1y8bVq6N7jx4v-0-4b0146701833529a8777696637f57e9d)
如果需要配合Slf4j使用,还需引入log4j-slf4j-impl的依赖作为二者之间的桥梁,具体实现代码如下:
![](https://epubservercos.yuewen.com/91A00C/21440188001525406/epubprivate/OEBPS/Images/105-2.jpg?sign=1739287170-pQcTo6bQ811O8PKZNTl3tICmQY32V0uo-0-201f2dde70686fab737e9442f4c78abc)
其次,编辑Log4j2的配置文件,示例代码如下:
![](https://epubservercos.yuewen.com/91A00C/21440188001525406/epubprivate/OEBPS/Images/105-3.jpg?sign=1739287170-2Wp8ruVbcc4TsKcErBF0uplRWeDr8zDW-0-e3c2259438b0ad2ca69b26da6a3f913f)
然后,定义Logger对象。要在代码中使用Log4j2,需要先获得Logger对象,通常会定义一个类的静态变量以供所有方法使用,示例代码如下:
![](https://epubservercos.yuewen.com/91A00C/21440188001525406/epubprivate/OEBPS/Images/106-1.jpg?sign=1739287170-koJTJfmA2zpo6GsMqOhfOQcTXzlpD8ZY-0-9211141d0e5e7cf8e7f7f1f8e61aeb2f)
最后,按照业务所需使用logger输出各种日志即可,具体代码如下:
![](https://epubservercos.yuewen.com/91A00C/21440188001525406/epubprivate/OEBPS/Images/106-2.jpg?sign=1739287170-IynybbWOsPTvkoVhAy2sNlkWZzlEJjoJ-0-7eafbd9ac0aab4e4e06b61b9bb724467)
3.3.3 Logback
Logback最初的设计目的是用作Log4j的替代者,其主要卖点是与Log4j相同的日志体系结构,但性能却比Log4j(不是Log4j2)高很多。
Logback由三部分组成:第一部分是Logback-core,它提供整个日志框架的核心功能;第二部分是Logback-classic,它在core的基础之上扩展了更多功能,例如与Slf4j的集成;第三部分是logback-access,它主要用于在Servlet容器中记录HTTP的访问日志。
由于Logback-classic是依赖于Logback-core的,所以在引入依赖时,只需要引入Logback-classic即可,具体代码如下:
![](https://epubservercos.yuewen.com/91A00C/21440188001525406/epubprivate/OEBPS/Images/106-3.jpg?sign=1739287170-hyrrAJokqSk4cAqQcXsk3fBrxeIxTLDc-0-c61ee05c7b063b56b44663cdde117c24)
Logback的配置文件中需要指定日志文件名称、日志记录的保存格式、日志的打印级别等,具体代码如下:
![](https://epubservercos.yuewen.com/91A00C/21440188001525406/epubprivate/OEBPS/Images/106-4.jpg?sign=1739287170-rsLKC3Lvc0dxqS2yLG4UewVadV47rR6o-0-0914e7b09666d57269eea6df8bafa642)
![](https://epubservercos.yuewen.com/91A00C/21440188001525406/epubprivate/OEBPS/Images/107-1.jpg?sign=1739287170-kEmHNW0udMIkY4GPNfD76u9THjQbWLjM-0-d7ef9aae0070ee2f0b3e28315824e8cc)
要在应用代码中使用Logback进行日志输出,需要先获得Logger实例,具体代码如下:
![](https://epubservercos.yuewen.com/91A00C/21440188001525406/epubprivate/OEBPS/Images/107-2.jpg?sign=1739287170-PGTN8Ijs2FQ45G1Wifb7kvnAQufdvsOs-0-7ab2f051b1f4080c9d6f24f0a35d5989)
再按照需要输出各种日志,具体代码如下:
![](https://epubservercos.yuewen.com/91A00C/21440188001525406/epubprivate/OEBPS/Images/107-3.jpg?sign=1739287170-uUccIhF5DE4LqKNByELnFzkdzn6wQC5h-0-a38acc98a6904742b34b8d1325a71cb6)
随着各种互联网服务的广泛使用及用户的海量增加,系统性能也越来越成为各大公司系统的瓶颈。正是出于这种考量,同一个开发者才会先后开发出Log4J、Logback和Log4j2,以不断提高日志组件的性能,各大日志框架的性能指标也是架构师技术选型最重要的参考指标。图3-4是主流日志框架的性能对比。
![](https://epubservercos.yuewen.com/91A00C/21440188001525406/epubprivate/OEBPS/Images/107-4.jpg?sign=1739287170-Bmo7zbPthxinV25PsqBk8aiEFSsuYxMp-0-96a188a2bd9b88dc9fa8b26b3dfad4aa)
图3-4 主流日志框架的性能对比
3.3.4 Slf4j
Slf4j是Simple Logging Facade for Java的缩写,顾名思义,它为各种Java日志框架提供了统一门面接口,进而为应用提供了自由切换日志框架的能力。
Slf4j的工作原理简单明了:在API层面,所有的类都被设计进slf4j-api.jar,因此在系统启动的时候,Slf4j会自动寻找当前系统绑定的日志框架,其绑定体系如图3-5所示。
![](https://epubservercos.yuewen.com/91A00C/21440188001525406/epubprivate/OEBPS/Images/108-1.jpg?sign=1739287170-hOFZvlv7hURc8qiA6gcVxWCAUrQLAhiq-0-fbe68391116b54495ef75136fcd1a51e)
图3-5 Slf4j绑定体系
因此,在系统中只要按照要求引入对应的Maven依赖,再实现框架的配置,即可在系统中使用该日志框架。Slf4j的Logger在代码中的定义方式如下:
![](https://epubservercos.yuewen.com/91A00C/21440188001525406/epubprivate/OEBPS/Images/108-2.jpg?sign=1739287170-oVzXbAt8NFHfV7Ro2BZzPDTnHbWt2JDB-0-3d92f1675412b606a3527a29e0217257)
但此处的Logger是Slf4j提供的Logger类,不是Spring Boot日志框架的Logger。
lombok为简化所有Logger的取得方式提供了相应的注释,将@Slf4j置于要使用Slf4j的类前面,在代码中直接引用log实例(log实例是lombok生成的内置对象)即可,示例代码如下:
![](https://epubservercos.yuewen.com/91A00C/21440188001525406/epubprivate/OEBPS/Images/108-3.jpg?sign=1739287170-dWpVf693v2tFY7xP6c5Bv5A5NYLeTF4F-0-645be341e109a4382e4b8602b30b0064)
![](https://epubservercos.yuewen.com/91A00C/21440188001525406/epubprivate/OEBPS/Images/109-1.jpg?sign=1739287170-WdK9Nz1TnNubXqsdYlP2z3Ia7nKvaqcn-0-44ae3642498354441c1d0b89c0a904c7)
此外,lombok也提供了Log4j、Log4j2等日志框架的相应注释。