![微服务从小白到专家: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=1739422929-SDwqKd4N20VqgMR5csb8VGGBYvOxOWDC-0-046c5caf9bd11a402a295f8b07e28f86)
如果需要配合Slf4j使用,还需引入log4j-slf4j-impl的依赖作为二者之间的桥梁,具体实现代码如下:
![](https://epubservercos.yuewen.com/91A00C/21440188001525406/epubprivate/OEBPS/Images/105-2.jpg?sign=1739422929-PFULjRG5hz4nOAoWhYY1Zmaws5BROzAK-0-e90c639f50b1ffde60f26a3945838d5a)
其次,编辑Log4j2的配置文件,示例代码如下:
![](https://epubservercos.yuewen.com/91A00C/21440188001525406/epubprivate/OEBPS/Images/105-3.jpg?sign=1739422929-AcxSUg1t2dn2r9585MIfAs8hnv8A6cXC-0-117dc83cfea73d0ec1cd97362ee488d7)
然后,定义Logger对象。要在代码中使用Log4j2,需要先获得Logger对象,通常会定义一个类的静态变量以供所有方法使用,示例代码如下:
![](https://epubservercos.yuewen.com/91A00C/21440188001525406/epubprivate/OEBPS/Images/106-1.jpg?sign=1739422929-lXyC9TziyLkgBAwvhl2bsYzwVe48XIDx-0-476fcefd2573fb6298f7188fa5ead511)
最后,按照业务所需使用logger输出各种日志即可,具体代码如下:
![](https://epubservercos.yuewen.com/91A00C/21440188001525406/epubprivate/OEBPS/Images/106-2.jpg?sign=1739422929-0etl6wgk5NZVnTMeQTT0wpxmZoJfSZmK-0-b3f220c362791a18ed09207c66552e4a)
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=1739422929-9vhED4VLVFO0q3En5ujMUQFmSi2NM6fg-0-7333b6c4390662e002006b9fc832d528)
Logback的配置文件中需要指定日志文件名称、日志记录的保存格式、日志的打印级别等,具体代码如下:
![](https://epubservercos.yuewen.com/91A00C/21440188001525406/epubprivate/OEBPS/Images/106-4.jpg?sign=1739422929-DLSudYGaIxbNVZ9WiUDu0rbjrXuBT76M-0-9a7377350785e893f4e898b606f85770)
![](https://epubservercos.yuewen.com/91A00C/21440188001525406/epubprivate/OEBPS/Images/107-1.jpg?sign=1739422929-gBV7hH4Gxf2crIaJNkj3uCSlhnKuDBit-0-ce9c3f0d2542b569564f46c1f168e078)
要在应用代码中使用Logback进行日志输出,需要先获得Logger实例,具体代码如下:
![](https://epubservercos.yuewen.com/91A00C/21440188001525406/epubprivate/OEBPS/Images/107-2.jpg?sign=1739422929-ZUglMEBJxBkNMTx0AfBxiucZC2ArkXqJ-0-4350def97b08f3ce92307aa2d54a2714)
再按照需要输出各种日志,具体代码如下:
![](https://epubservercos.yuewen.com/91A00C/21440188001525406/epubprivate/OEBPS/Images/107-3.jpg?sign=1739422929-6FlwQPcd2ACCEKwdHDsysPHoe7NoeMaP-0-fb0ba1c51250c8b0ca7267a056b5a262)
随着各种互联网服务的广泛使用及用户的海量增加,系统性能也越来越成为各大公司系统的瓶颈。正是出于这种考量,同一个开发者才会先后开发出Log4J、Logback和Log4j2,以不断提高日志组件的性能,各大日志框架的性能指标也是架构师技术选型最重要的参考指标。图3-4是主流日志框架的性能对比。
![](https://epubservercos.yuewen.com/91A00C/21440188001525406/epubprivate/OEBPS/Images/107-4.jpg?sign=1739422929-F9alCXDwCFn11C5kyTGob3rk2wZlmOQI-0-59eb811c8e4517091ad912985500fffe)
图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=1739422929-70bwpc59gyLiS0L7QCVQ5S15DL5ttbSX-0-37e141b753f4b9c58e5b46003d1a44f9)
图3-5 Slf4j绑定体系
因此,在系统中只要按照要求引入对应的Maven依赖,再实现框架的配置,即可在系统中使用该日志框架。Slf4j的Logger在代码中的定义方式如下:
![](https://epubservercos.yuewen.com/91A00C/21440188001525406/epubprivate/OEBPS/Images/108-2.jpg?sign=1739422929-kJ5k3coVnSmeguyzYqA6OrsJt65aBBaJ-0-50f4848f863520aa793e957a7267cdf4)
但此处的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=1739422929-DWQj8awi2Idvu48ixiJX3lLKhIkV5iPr-0-15187e0d82d2d33466f37ae0b42cd573)
![](https://epubservercos.yuewen.com/91A00C/21440188001525406/epubprivate/OEBPS/Images/109-1.jpg?sign=1739422929-kLeveyj8gq6yZ3WB64EfN6WWseIONBe6-0-8db21d37997c6cad7abcef2a65b8149b)
此外,lombok也提供了Log4j、Log4j2等日志框架的相应注释。