使用Spring Boot日志框架在已有的微服务代码中添加日志功能

本文涉及的产品
服务治理 MSE Sentinel/OpenSergo,Agent数量 不受限
云原生网关 MSE Higress,422元/月
注册配置 MSE Nacos/ZooKeeper,118元/月
简介: 我们需要在已有的微服务代码中添加日志功能,用于输出需要关注的内容,这是最平常的技术需求了。由于我们的微服务代码是基于SpringBoot开发的,那么问题就转换为如何在Spring Boot应用程序中输出相应的日志。

  引言:我们需要在已有的微服务代码中添加日志功能,用于输出需要关注的内容,这是最平常的技术需求了。由于我们的微服务代码是基于SpringBoot开发的,那么问题就转换为如何在Spring Boot应用程序中输出相应的日志。

  在传统Java应用程序中,我们一般会使用类似Log4j这样的日志框架来输出日志,而不是直接在代码中通过System.out.println()来输出日志。为什么要这么做呢?原因有两点。其一,我们希望日志能输出到文件中,而不是输出到应用程序的控制台中,这样更加容易收集和分析。其二,我们可以通过异步多线程的方式,将日志输出到文件中,这样既不会影响主线程,可以提高应用程序的吞吐率,也是一种节省性能开销的方法。直接将内容打印到控制台中,这种做法比较粗暴,不是业界所推荐的做法。
  这样一来,我们最终要解决的问题就非常清楚了,那就是如何在Spring Boot中添加日志框架。幸运的是,Spring Boot自带了一款名为Spring Boot Logging的插件(在Spring Boot中,称插件为Starter),它已经为我们提供了日志功能。

1 使用Spring Boot Logging插件

  Spring Boot使用Apache开源项目Commons Logging作为内部的日志框架,它是一个日志接口,在实际应用中,我们需要为该接口指定相应的日志实现。Spring Boot默认的日志实现是Java Util Logging,它是JDK自带的日志包,一般场景下很少会用到。此外,Spring Boot也提供了Log4J、Logback这类流行的日志实现,我们只需要添加简单的配置,就能开启对这些日志实现的支持。
  为了便于描述,我们将以上提到的“日志实现”统称为“日志框架”。
  大家可以通过以下网站,进一步学习这类日志框架。

  在Java应用程序中,日志一般分为以下5个级别。

  • ERROR:错误信息;
  • WARN:警告信息;
  • INFO:一般信息;
  • DEBUG:调试信息;
  • TRACE:跟踪信息。

  以上日志级别按照严重程度,从高往低排序,一般常用的三种日志级别是ERROR、INFO、DEBUG。Spring Boot Logging插件默认输出到INFO级别,也就是说,只包含ERROR、WARN、INFO,不包含DEBUG、TRACE。如果我们希望日志可以输出到DEBUG级别,则需在Spring Boot的application.properties文件中添加如下配置:

logging.level.root=DEBUG

  重新运行应用程序,我们就可在代码中看到DEBUG级别的日志了。
  以下是Spring Boot的应用程序代码片段,我们使用SLF4J类库输出日志,而不要使用具体的日志实现类库,比如Log4J。

package demo.msa;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
...

@RestController
@SpringBootApplication
public class HelloApplication {

  private static Logger logger =LoggerFactory.getLogger(HelloApplication.class);
    
  public static void main(String[] args) {
    SpringApplication.run(HelloApplication.class, args);
  }
  
  @GetMapping("/hello")
  public String hello() {
    logger.debug("log..."); // 输出DEBUG级别的日志
    return "hello";
  }
}

  运行以上Spring Boot应用程序,会发现控制台中输出了大量INFO级别的日志,这些日志是由Spring Boot框架输出的。因为我们调整日志输出到DEBUG级别,而INFO级别在DRBUG级别之上,所以INFO级别的日志也会输出,但TRACE级别的日志不会输出。
  当我们打开浏览器,发送http://localhost:8080/hello请求时,可在控制台中看到我们想要输出的DEBUG级别日志。
  如果我们不想关注Spring Boot框架的日志,则可将日志级别统一设置为ERROR,此时只会输出ERROR级别的日志。随后,再将Spring Boot应用程序指定的包(应用程序所对应的包)设置为DEBUG级别的日志,此时我们看到的就只是指定包中的日志了。

logging.level.root=ERROR
logging.level.demo.msa=DEBUG

  上面的logging.level.root表示所有包,logging.level.demo.msa表示应用程序的指定包(demo.msa是包名)。以上配置可以理解为,整个应用程序的日志输出到ERROR级别,除了demo.msa包中的日志输出到DEBUG级别。这是一种“先禁止所有,再允许个别”的配置方法,这种配置方法在很多技术中都应用过。
  默认情况下日志框架会将日志输出到控制台中,我们需要在application.properties文件中添加如下配置,才能将日志输出到文件中:

logging.file=${user.home}/logs/hello.log

  其中,${user.home}表示当前用户目录(该变量由Spring Boot框架在运行时传入),后面的/logs/hello.log是相对于该目录的路径。大家可根据实际情况,设置所需的日志文件路径,以上仅为示例。
  重新运行应用程序,就能看到日志输出到指定路径下的文件中了。
  目前我们虽然可以将日志输出到文件中,但控制台中仍然会输出同样的日志,这不是我们最终想要的效果。我们希望的是日志全部输出到文件中,控制台中不输出任何日志。也就是说,我们需要关闭控制台中的输出。通过以上的尝试,我们不难发现,仅通过修改Spring Boot的配置,貌似是无法做到的。
  下面我们不妨考虑集成经典的Log4J日志框架,看看能否实现我们的需求。

2 集成Log4J日志框架

  Spring Boot Logging默认集成了Logback,我们只需提供Logback的配置文件就能开启Logback日志功能,但我们现在想要尝试的是自己熟知的Log4J,而不是比较新潮的Logback。毫不犹豫,现在我们就来开启对Log4J的支持。通过学习Spring Boot的官方文档与示例代码,我们了解到,只需在pom.xml文件中添加如下Maven配置,就能在Spring Boot中集成Log4J。

<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter</artifactId>
  <exclusions>
    <exclusion>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-logging</artifactId>
    </exclusion>
  </exclusions>
</dependency>

<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-log4j2</artifactId>
</dependency>

  在第一段dependency配置中,我们排除掉spring-boot-starter-logging依赖是因为要去掉默认集成的Logback日志功能。在第二段dependency配置中,我们自行添加了spring-boot-starter- log4j2依赖,它是Spring Boot所提供的Log4J插件,此时使用的是Log4J的2.x版本。
  当完成了Maven依赖配置以后,我们接下来需要在源码中的resources目录下添加log4j2.xml文件,其内容如下:

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
  <appenders>
    <File name="file" fileName="${sys:user.home}/logs/hello.log">
      <PatternLayout pattern="%d{HH:mm:ss,SSS} %p %c (%L) - %m%n"/>
    </File>
  </appenders>
  <loggers>
    <root level="ERROR">
      <appender-ref ref="file"/>
    </root>
    <logger name="demo.msa" level="DEBUG"/>
  </loggers>
</configuration>

  log4j2.xml配置文件分为两大部分,即appenders与loggers。在appenders中,我们添加了一个File类型的appenders,表示日志以文件的方式进行输出,该文件路径基于根目录${sys:user.home},即当前用户目录(该变量由Log4J框架在运行时传入)。此外,还需指定PatternLayout为日志输出格式。在loggers中,我们先后添加了两段配置,第一段的root表示将所有包中的日志输出到ERROR级别,第二段的logger表示将指定包demo.msa中的日志输出到DEBUG级别。很明显,这段配置与之前在Spring Boot中配置的意义相同。
  通过以上配置,可将Log4J集成到Spring Boot应用中。
  重新运行应用程序,日志不再输出到控制台中,而是全部输出到指定路径下的文件中了。
  大家如果想了解更为详尽的Spring Boot日志特性,可参考它的官方技术文档。

  目前,虽然日志已经成功输出到文件中,但是我们的微服务是以Docker容器的方式来运行的,此时输出的日志文件仍然和应用程序在一个Docker容器中,我们得想办法将日志文件输出到Docker容器外。也就是说,需要将数据与程序相分离,以便后续更加方便地获取并分析日志内容。

3 将日志输出到Docker容器外

  最容易想到的办法就是,通过Docker数据卷的方式,将文件路径挂载到Docker容器上,这样日志文件就自然与Docker文件分离了,就像下面这样启动Docker容器。

docker run -v ~/logs:~/logs hello

  这样一来,我们可随时在宿主机上查看Docker容器内部的日志了。但是回过头想想,却不难发现,其实完全不需要将日志输出到文件中,因为即便将日志输出到控制台中,我们也能随时通过docker logs的方式来获取日志内容,将日志输出到文件似乎有些多余了,还占用了磁盘空间。
  那我们现在做的事情是否有意义呢?感兴趣的读者不妨到《架构探险:轻量级微服务架构(下册)》一书中探索详情~
  本文选自《架构探险:轻量级微服务架构(下册)》,点此链接可在博文视点官网查看此书。
                 图片描述
  想及时获得更多精彩文章,可在微信中搜索“博文视点”或者扫描下方二维码并关注。
                    图片描述

相关实践学习
日志服务之使用Nginx模式采集日志
本文介绍如何通过日志服务控制台创建Nginx模式的Logtail配置快速采集Nginx日志并进行多维度分析。
相关文章
|
21天前
|
Java UED Sentinel
微服务守护神:Spring Cloud Sentinel,让你的系统在流量洪峰中稳如磐石!
【8月更文挑战第29天】Spring Cloud Sentinel结合了阿里巴巴Sentinel的流控、降级、熔断和热点规则等特性,为微服务架构下的应用提供了一套完整的流量控制解决方案。它能够有效应对突发流量,保护服务稳定性,避免雪崩效应,确保系统在高并发下健康运行。通过简单的配置和注解即可实现高效流量控制,适用于高并发场景、依赖服务不稳定及资源保护等多种情况,显著提升系统健壮性和用户体验。
47 1
|
21天前
|
Cloud Native Java Nacos
微服务时代的新宠儿!Spring Cloud Nacos实战指南,带你玩转服务发现与配置管理,拥抱云原生潮流!
【8月更文挑战第29天】Spring Cloud Nacos作为微服务架构中的新兴之星,凭借其轻量、高效的特点,迅速成为服务发现、配置管理和治理的首选方案。Nacos(命名和配置服务)由阿里巴巴开源,为云原生应用提供了动态服务发现及配置管理等功能,简化了服务间的调用与依赖管理。本文将指导你通过五个步骤在Spring Boot项目中集成Nacos,实现服务注册、发现及配置动态管理,从而轻松搭建出高效的微服务环境。
88 0
|
21天前
|
Java UED 开发者
Spring Boot 降级功能的神秘面纱:Hystrix 与 Resilience4j 究竟藏着怎样的秘密?
【8月更文挑战第29天】在分布式系统中,服务稳定性至关重要。为应对故障,Spring Boot 提供了 Hystrix 和 Resilience4j 两种降级工具。Hystrix 作为 Netflix 的容错框架,通过隔离依赖、控制并发及降级机制增强系统稳定性;Resilience4j 则是一个轻量级库,提供丰富的降级策略。两者均可有效提升系统可靠性,具体选择取决于需求与场景。在面对服务故障时,合理运用这些工具能确保系统基本功能正常运作,优化用户体验。以上简介包括了两个工具的简单示例代码,帮助开发者更好地理解和应用。
39 0
|
9天前
|
运维 NoSQL Java
SpringBoot接入轻量级分布式日志框架GrayLog技术分享
在当今的软件开发环境中,日志管理扮演着至关重要的角色,尤其是在微服务架构下,分布式日志的统一收集、分析和展示成为了开发者和运维人员必须面对的问题。GrayLog作为一个轻量级的分布式日志框架,以其简洁、高效和易部署的特性,逐渐受到广大开发者的青睐。本文将详细介绍如何在SpringBoot项目中接入GrayLog,以实现日志的集中管理和分析。
44 1
|
13天前
|
缓存 Java 应用服务中间件
随着微服务架构的兴起,Spring Boot凭借其快速开发和易部署的特点,成为构建RESTful API的首选框架
【9月更文挑战第6天】随着微服务架构的兴起,Spring Boot凭借其快速开发和易部署的特点,成为构建RESTful API的首选框架。Nginx作为高性能的HTTP反向代理服务器,常用于前端负载均衡,提升应用的可用性和响应速度。本文详细介绍如何通过合理配置实现Spring Boot与Nginx的高效协同工作,包括负载均衡策略、静态资源缓存、数据压缩传输及Spring Boot内部优化(如线程池配置、缓存策略等)。通过这些方法,开发者可以显著提升系统的整体性能,打造高性能、高可用的Web应用。
42 2
|
15天前
|
NoSQL 前端开发 Java
使用 Spring Boot + Neo4j 实现知识图谱功能开发
在数据驱动的时代,知识图谱作为一种强大的信息组织方式,正逐渐在各个领域展现出其独特的价值。本文将围绕使用Spring Boot结合Neo4j图数据库来实现知识图谱功能开发的技术细节进行分享,帮助读者理解并掌握这一技术栈在实际项目中的应用。
71 4
|
20天前
|
机器学习/深度学习 文字识别 前端开发
基于 Spring Boot 3.3 + OCR 实现图片转文字功能
【8月更文挑战第30天】在当今数字化信息时代,图像中的文字信息越来越重要。无论是文档扫描、名片识别,还是车辆牌照识别,OCR(Optical Character Recognition,光学字符识别)技术都发挥着关键作用。本文将围绕如何使用Spring Boot 3.3结合OCR技术,实现图片转文字的功能,分享工作学习中的技术干货。
53 2
|
20天前
|
安全 Java 应用服务中间件
如何在 Spring Boot 3.3 中实现请求 IP 白名单拦截功能
【8月更文挑战第30天】在构建Web应用时,确保应用的安全性是至关重要的。其中,对访问者的IP地址进行限制是一种常见的安全措施,特别是通过实施IP白名单策略,可以只允许特定的IP地址或IP段访问应用,从而有效防止未授权的访问。在Spring Boot 3.3中,我们可以通过多种方式实现这一功能,下面将详细介绍几种实用的方法。
29 1
|
21天前
|
算法 Java UED
你的Spring Boot应用是否足够健壮?揭秘限流功能的实现秘诀
【8月更文挑战第29天】限流是保障服务稳定性的关键策略,通过限制单位时间内的请求数量防止服务过载。本文基于理论介绍,结合Spring Boot应用实例,展示了使用`@RateLimiter`注解和集成`Resilience4j`库实现限流的方法。无论采用哪种方式,都能有效控制请求速率,增强应用的健壮性和用户体验。通过这些示例,读者可以灵活选择适合自身需求的限流方案。
33 2
|
18天前
|
Java Spring XML
掌握面向切面编程的秘密武器:Spring AOP 让你的代码优雅转身,横切关注点再也不是难题!
【8月更文挑战第31天】面向切面编程(AOP)通过切面封装横切关注点,如日志记录、事务管理等,使业务逻辑更清晰。Spring AOP提供强大工具,无需在业务代码中硬编码这些功能。本文将深入探讨Spring AOP的概念、工作原理及实际应用,展示如何通过基于注解的配置创建切面,优化代码结构并提高可维护性。通过示例说明如何定义切面类、通知方法及其应用时机,实现方法调用前后的日志记录,展示AOP在分离关注点和添加新功能方面的优势。
30 0