![微服务从小白到专家: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=1739421368-yHUWT6R9X2avZqLejFg1lVjY1SBJhcS4-0-d9587ea60fb75f0ba6474ee9daabc29c)
如果需要配合Slf4j使用,还需引入log4j-slf4j-impl的依赖作为二者之间的桥梁,具体实现代码如下:
![](https://epubservercos.yuewen.com/91A00C/21440188001525406/epubprivate/OEBPS/Images/105-2.jpg?sign=1739421368-q26ZsGvrVHnK1umqisiItsBiHoFruzs4-0-1c98e58da3517eef932c7a62be4e6578)
其次,编辑Log4j2的配置文件,示例代码如下:
![](https://epubservercos.yuewen.com/91A00C/21440188001525406/epubprivate/OEBPS/Images/105-3.jpg?sign=1739421368-maVxebT989bmlNO68A0z2bFG7qXwCt5Y-0-846db57f6f40ea62d470e93539c6ecec)
然后,定义Logger对象。要在代码中使用Log4j2,需要先获得Logger对象,通常会定义一个类的静态变量以供所有方法使用,示例代码如下:
![](https://epubservercos.yuewen.com/91A00C/21440188001525406/epubprivate/OEBPS/Images/106-1.jpg?sign=1739421368-q0o7ahpK2YHPuVRxptaOTnygQQZgIiHq-0-285bfc65c659086f4d8a036339402c2b)
最后,按照业务所需使用logger输出各种日志即可,具体代码如下:
![](https://epubservercos.yuewen.com/91A00C/21440188001525406/epubprivate/OEBPS/Images/106-2.jpg?sign=1739421368-WkmMRTNJssXIpj55kMPIJhvXNvA0SvTM-0-9d9fb272ba40a6d034cae75049e8b2b4)
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=1739421368-qDOg4muZf2LiP5OX6Iml5RAeKeheEUMQ-0-7cb824e44dee073879c51dd9b0bbfe04)
Logback的配置文件中需要指定日志文件名称、日志记录的保存格式、日志的打印级别等,具体代码如下:
![](https://epubservercos.yuewen.com/91A00C/21440188001525406/epubprivate/OEBPS/Images/106-4.jpg?sign=1739421368-OR8CEXYpFDAbgKOZtBwV3BmACRXFMqTA-0-b29f5ec73abfa88ca354dd2fbb4da7f7)
![](https://epubservercos.yuewen.com/91A00C/21440188001525406/epubprivate/OEBPS/Images/107-1.jpg?sign=1739421368-ERhZUyv1KbTIYcmIVzW0NsJ1UjCFrr27-0-f6b9471f447e614502050a297812df08)
要在应用代码中使用Logback进行日志输出,需要先获得Logger实例,具体代码如下:
![](https://epubservercos.yuewen.com/91A00C/21440188001525406/epubprivate/OEBPS/Images/107-2.jpg?sign=1739421368-mcZpyVyfrFrZbfGArwI1hxOxOUdQpWNK-0-3e9e4d3df28e60834a78390514a89372)
再按照需要输出各种日志,具体代码如下:
![](https://epubservercos.yuewen.com/91A00C/21440188001525406/epubprivate/OEBPS/Images/107-3.jpg?sign=1739421368-y9ePCb4ipExNKcF5al1pa6NmhmGpCmHq-0-946a22a4990c6df88a670a9587947007)
随着各种互联网服务的广泛使用及用户的海量增加,系统性能也越来越成为各大公司系统的瓶颈。正是出于这种考量,同一个开发者才会先后开发出Log4J、Logback和Log4j2,以不断提高日志组件的性能,各大日志框架的性能指标也是架构师技术选型最重要的参考指标。图3-4是主流日志框架的性能对比。
![](https://epubservercos.yuewen.com/91A00C/21440188001525406/epubprivate/OEBPS/Images/107-4.jpg?sign=1739421368-6zgzoRcrwbdbuWjahygLNcutGn3B2Nz2-0-79c9776a17ebdfce622262742bfa6b32)
图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=1739421368-DRJjKK77uEgA68naLRRx7JbJjPUsx0fs-0-9d5ca99d7fff8f9b772c182a2b876d09)
图3-5 Slf4j绑定体系
因此,在系统中只要按照要求引入对应的Maven依赖,再实现框架的配置,即可在系统中使用该日志框架。Slf4j的Logger在代码中的定义方式如下:
![](https://epubservercos.yuewen.com/91A00C/21440188001525406/epubprivate/OEBPS/Images/108-2.jpg?sign=1739421368-kH5r794KSoq3czJLW4KnKkNLDJbLJSTd-0-f40b80eb3a878ad36f18f82bf2f3881a)
但此处的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=1739421368-olJMyXKTuBklBPWPIdErxOhKBRpixec2-0-6f1a8d9c35a7e292933982ffc3360806)
![](https://epubservercos.yuewen.com/91A00C/21440188001525406/epubprivate/OEBPS/Images/109-1.jpg?sign=1739421368-6iaYTFIYfScIjRrEuMchphov3Hyv3Evm-0-2099499c967f2cd3f4303b2e5910a3d8)
此外,lombok也提供了Log4j、Log4j2等日志框架的相应注释。