微服务从小白到专家:Spring Cloud和Kubernetes实战
上QQ阅读APP看本书,新人免费读10天
设备和账号都新为新人

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相关的依赖,实现代码如下:

如果需要配合Slf4j使用,还需引入log4j-slf4j-impl的依赖作为二者之间的桥梁,具体实现代码如下:

其次,编辑Log4j2的配置文件,示例代码如下:

然后,定义Logger对象。要在代码中使用Log4j2,需要先获得Logger对象,通常会定义一个类的静态变量以供所有方法使用,示例代码如下:

最后,按照业务所需使用logger输出各种日志即可,具体代码如下:

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即可,具体代码如下:

Logback的配置文件中需要指定日志文件名称、日志记录的保存格式、日志的打印级别等,具体代码如下:

要在应用代码中使用Logback进行日志输出,需要先获得Logger实例,具体代码如下:

再按照需要输出各种日志,具体代码如下:

随着各种互联网服务的广泛使用及用户的海量增加,系统性能也越来越成为各大公司系统的瓶颈。正是出于这种考量,同一个开发者才会先后开发出Log4J、Logback和Log4j2,以不断提高日志组件的性能,各大日志框架的性能指标也是架构师技术选型最重要的参考指标。图3-4是主流日志框架的性能对比。

图3-4 主流日志框架的性能对比

3.3.4 Slf4j

Slf4j是Simple Logging Facade for Java的缩写,顾名思义,它为各种Java日志框架提供了统一门面接口,进而为应用提供了自由切换日志框架的能力。

Slf4j的工作原理简单明了:在API层面,所有的类都被设计进slf4j-api.jar,因此在系统启动的时候,Slf4j会自动寻找当前系统绑定的日志框架,其绑定体系如图3-5所示。

图3-5 Slf4j绑定体系

因此,在系统中只要按照要求引入对应的Maven依赖,再实现框架的配置,即可在系统中使用该日志框架。Slf4j的Logger在代码中的定义方式如下:

但此处的Logger是Slf4j提供的Logger类,不是Spring Boot日志框架的Logger。

lombok为简化所有Logger的取得方式提供了相应的注释,将@Slf4j置于要使用Slf4j的类前面,在代码中直接引用log实例(log实例是lombok生成的内置对象)即可,示例代码如下:

此外,lombok也提供了Log4j、Log4j2等日志框架的相应注释。