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

简介: 我们需要在已有的微服务代码中添加日志功能,用于输出需要关注的内容,这是最平常的技术需求了。由于我们的微服务代码是基于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的方式来获取日志内容,将日志输出到文件似乎有些多余了,还占用了磁盘空间。
  那我们现在做的事情是否有意义呢?感兴趣的读者不妨到《架构探险:轻量级微服务架构(下册)》一书中探索详情~
  本文选自《架构探险:轻量级微服务架构(下册)》,点此链接可在博文视点官网查看此书。
                 图片描述
  想及时获得更多精彩文章,可在微信中搜索“博文视点”或者扫描下方二维码并关注。
                    图片描述

相关实践学习
通过日志服务实现云资源OSS的安全审计
本实验介绍如何通过日志服务实现云资源OSS的安全审计。
相关文章
|
5月前
|
安全 Java Ruby
我尝试了所有后端框架 — — 这就是为什么只有 Spring Boot 幸存下来
作者回顾后端开发历程,指出多数框架在生产环境中难堪重负。相比之下,Spring Boot凭借内置安全、稳定扩展、完善生态和企业级支持,成为构建高可用系统的首选,真正经受住了时间与规模的考验。
418 2
|
4月前
|
安全 前端开发 Java
《深入理解Spring》:现代Java开发的核心框架
Spring自2003年诞生以来,已成为Java企业级开发的基石,凭借IoC、AOP、声明式编程等核心特性,极大简化了开发复杂度。本系列将深入解析Spring框架核心原理及Spring Boot、Cloud、Security等生态组件,助力开发者构建高效、可扩展的应用体系。(238字)
|
6月前
|
XML JSON Java
Spring框架中常见注解的使用规则与最佳实践
本文介绍了Spring框架中常见注解的使用规则与最佳实践,重点对比了URL参数与表单参数的区别,并详细说明了@RequestParam、@PathVariable、@RequestBody等注解的应用场景。同时通过表格和案例分析,帮助开发者正确选择参数绑定方式,避免常见误区,提升代码的可读性与安全性。
|
4月前
|
消息中间件 缓存 Java
Spring框架优化:提高Java应用的性能与适应性
以上方法均旨在综合考虑Java Spring 应该程序设计原则, 数据库交互, 编码实践和系统架构布局等多角度因素, 旨在达到高效稳定运转目标同时也易于未来扩展.
289 8
|
4月前
|
XML Java 应用服务中间件
【SpringBoot(一)】Spring的认知、容器功能讲解与自动装配原理的入门,带你熟悉Springboot中基本的注解使用
SpringBoot专栏开篇第一章,讲述认识SpringBoot、Bean容器功能的讲解、自动装配原理的入门,还有其他常用的Springboot注解!如果想要了解SpringBoot,那么就进来看看吧!
565 2
|
5月前
|
Prometheus 监控 Java
日志收集和Spring 微服务监控的最佳实践
在微服务架构中,日志记录与监控对系统稳定性、问题排查和性能优化至关重要。本文介绍了在 Spring 微服务中实现高效日志记录与监控的最佳实践,涵盖日志级别选择、结构化日志、集中记录、服务ID跟踪、上下文信息添加、日志轮转,以及使用 Spring Boot Actuator、Micrometer、Prometheus、Grafana、ELK 堆栈等工具进行监控与可视化。通过这些方法,可提升系统的可观测性与运维效率。
552 1
日志收集和Spring 微服务监控的最佳实践
|
5月前
|
监控 Kubernetes Cloud Native
Spring Batch 批处理框架技术详解与实践指南
本文档全面介绍 Spring Batch 批处理框架的核心架构、关键组件和实际应用场景。作为 Spring 生态系统中专门处理大规模数据批处理的框架,Spring Batch 为企业级批处理作业提供了可靠的解决方案。本文将深入探讨其作业流程、组件模型、错误处理机制、性能优化策略以及与现代云原生环境的集成方式,帮助开发者构建高效、稳定的批处理系统。
627 1
|
6月前
|
Cloud Native Java API
Java Spring框架技术栈选和最新版本及发展史详解(截至2025年8月)-优雅草卓伊凡
Java Spring框架技术栈选和最新版本及发展史详解(截至2025年8月)-优雅草卓伊凡
1259 0
|
7月前
|
Java Spring 容器
SpringBoot自动配置的原理是什么?
Spring Boot自动配置核心在于@EnableAutoConfiguration注解,它通过@Import导入配置选择器,加载META-INF/spring.factories中定义的自动配置类。这些类根据@Conditional系列注解判断是否生效。但Spring Boot 3.0后已弃用spring.factories,改用新格式的.imports文件进行配置。
1186 0
|
8月前
|
人工智能 Java 测试技术
Spring Boot 集成 JUnit 单元测试
本文介绍了在Spring Boot中使用JUnit 5进行单元测试的常用方法与技巧,包括添加依赖、编写测试类、使用@SpringBootTest参数、自动装配测试模块(如JSON、MVC、WebFlux、JDBC等),以及@MockBean和@SpyBean的应用。内容实用,适合Java开发者参考学习。
960 0