当前位置: 首页 > news >正文

SpringBoot日志详解

一、简介

Spring Boot中的日志抽象确实是SLF4J(Simple Logging Facade for Java),它是一个面向Java的简单日志门面,旨在将各种现有的日志框架映射到基于统一抽象接口的通用API上。

通过使用SLF4J,应用程序可以将日志记录器与任何后端日志实现(如Log4j、Logback、Java Util Logging等)进行解耦。这使得在不更改应用程序代码的情况下,可以轻松地在不同的日志实现之间切换。

而Spring Boot中默认的日志实现是Logback,它是由同一作者创建的log4j框架的改进版。

Logback是一个功能强大、快速且易于配置的日志框架,它提供了多种日志输出渠道(包括控制台、文件、远程套接字、可插拔的多种数据库支持等),并支持过滤器、多线程等在内的一系列高级特性。

当然,你也可以在Spring Boot中使用各种不同的日志框架,比如Log4j2、SLF4j等,只需要在项目中引入对应的依赖,按照对应的配置方式即可。 

二、日志的抽象与实现

SpringBoot选用 SLF4j(日志抽象层)和logback(日志实现)

简化的日志调用关系图

三、配置文件

2.1 application.properties

在 application.properties 文件中,logging.config 属性用于指定 Logback 配置文件的位置。

Logback 是一个流行的 Java 日志框架,它提供了一种灵活的方式来记录应用程序日志。

如果您没有在 application.properties 文件中设置 logging.config 属性,则 Spring Boot 将使用默认的 Logback 配置。

默认情况下,Spring Boot 会在类路径下查找名为 logback-spring.xml 或 logback.xml 的文件,并使用找到的第一个文件作为 Logback 配置文件。如果找不到任何文件,则 Spring Boot 将使用 Logback 的默认配置。 

如果您没有在应用程序中显式地配置 Logback,则 Spring Boot 将使用 Logback 的默认配置。默认情况下,Logback 的默认配置将日志事件输出到控制台,并将日志级别设置为 INFO。

例如,如果您的 Logback 配置文件名为 logback-spring.xml,并且位于应用程序的根目录下,则您可以在 application.properties 文件中添加以下行

logging.config=classpath:logback-spring.xml 

注意:classpath前缀表示该文件位于应用程序的类路径下。

2.2 application.properties与logback-spring.xml的优先级

当在application.properties/application.yml和logback-spring.xml中都配置了同一属性时(比如logging.level.root),Spring Boot会优先读取application.properties/application.yml中的配置,而忽略logback-spring.xml中的配置。

这是因为在Spring Boot的日志系统中,logging属性优先级最高,即使你在 logback-spring.xml 中配置了某个属性,如果在 application.properties/application.yml 中发现了同名的属性,则会覆盖logback-spring.xml中的配置。

这也是Spring Boot日志配置中logging属性优先级高于logback-spring.xml中的原因。

因此,在实际应用中,如果您需要对日志输出级别、使用附加器等进行配置,推荐使用logback-spring.xml这样的日志配置文件,它可以实现更加灵活和细粒度的配置,而application.properties/application.yml中的配置主要用于简洁明了的全局配置。

2.3 自定义MDC

示例:

2023-06-07 10:21:02.971 INFO [,,,] 14676 --- [ main] c.e.s.SpringCloudSleuthDemoApplication : Started SpringCloudSleuthDemoApplication in 4.397 seconds (JVM running for 5.68)

这个日志格式中,[,,,]这一部分表示MDC(Mapped Diagnostic Context),它是一种记录应用程序信息的机制,在Logback框架和Spring Cloud Sleuth中都有应用。

MDC机制通常用于在系统运行时,记录一些信息,在日志输出时将这些信息一并输出,帮助我们在分析日志时能够更轻松地定位问题。例如,可以记录请求ID、用户IP、客户端信息等,然后在日志中输出这些信息,方便跟踪和排查。

在Spring Cloud Sleuth中,MDC中一般会包含Trace ID、Span ID,代表当前所在的请求链路信息,用于服务追踪和调用链路追踪。[,,,]这种空的中括号表示当前日志所在的上下文中没有设置MDC信息。

需要注意的是,MDC中记录的信息必须是线程私有的,不同线程之间不能共用MDC。若要在多线程环境下使用MDC,一般会配合使用ThreadLocal等线程安全的工具。

Logback支持自定义MDC信息。可以通过在代码中设置MDC,然后在日志输出时通过%X占位符输出MDC中的数据。比如:

MDC.put("requestId", "123456");
logger.info("This is a test log message with requestId={}", MDC.get("requestId"));

在上面的代码中,我们在MDC中添加了一个名为requestId的键值对,然后在日志记录时使用了%X占位符将requestId的值输出。

在Logback的配置文件中也可以指定每个appender是否包含MDC信息,举个例子

<appender name="console" class="ch.qos.logback.core.ConsoleAppender"><encoder><pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - [%X{requestId}] %msg%n</pattern></encoder>
</appender>

在上面的配置中,我们使用了%X{requestId}来输出MDC中名为requestId的键的值,将值输出到日志消息的括号中。

需要注意的是,在Logback中设置MDC信息可能会对性能造成影响,过多或过大的MDC数据可能会导致GC times过长等问题。为了避免这些问题,应该尽量精简MDC信息,只记录必要的信息。并且,MDC信息应该在不使用时及时清除。

在Spring Cloud Sleuth中,MDC默认记录如下

名称说明
appname记录跨度的应用程序的名称
spanId发生的特定操作的ID
traceId包含span的延迟图的ID
exportable是否将日志导出到Zipkin

2016-02-02 15:31:01.936  INFO [bar,46ab0d418373cbc9,46ab0d418373cbc9,false] 23030 --- [nio-8081-exec-4] ...

相关文章:

  • 传输大咖47 | 软件企业文件传输难题?这款FTP替代工具了解一下
  • python/爬虫技术/lxml工具介绍/XML和HTML解析
  • LVS-DR实战案例,实现四层负载均衡
  • TomCat乱码问题
  • EasyAR自定义相机RTSP视频流(CustomCamera)
  • 【UR #1】外星人(dp思维技巧)
  • Java项目: 基于SpringBoot+mybatis+maven+vue图书进销存管理系统分前后台(含源码+数据库+毕业论文)
  • Linux开机logo设置
  • Unity中分辨率适配
  • AMEYA360:村田电子更适合薄型设计应用场景的3.3V输入、12A输出的DCDC转换IC
  • 如何在 UniApp 中实现地图的视野自适应?
  • HarmonyOS---权限和http/Axios网络请求
  • 在视频上绘制区域:使用Vue和JavaScript实现交互式画布
  • SSH 远程连接到 Linux 服务器上的 SQLite
  • python AutoGen接入开源模型xLAM-7b-fc-r,测试function calling的功能
  • 分享一款快速APP功能测试工具
  • 【407天】跃迁之路——程序员高效学习方法论探索系列(实验阶段164-2018.03.19)...
  • 【Amaple教程】5. 插件
  • avalon2.2的VM生成过程
  • CSS魔法堂:Absolute Positioning就这个样
  • flask接收请求并推入栈
  • Java 多线程编程之:notify 和 wait 用法
  • socket.io+express实现聊天室的思考(三)
  • SpringBoot几种定时任务的实现方式
  • sublime配置文件
  • Vue2.x学习三:事件处理生命周期钩子
  • 当SetTimeout遇到了字符串
  • 前端学习笔记之观察者模式
  • 巧用 TypeScript (一)
  • 提升用户体验的利器——使用Vue-Occupy实现占位效果
  • 我与Jetbrains的这些年
  • ​【数据结构与算法】冒泡排序:简单易懂的排序算法解析
  • ###51单片机学习(2)-----如何通过C语言运用延时函数设计LED流水灯
  • #快捷键# 大学四年我常用的软件快捷键大全,教你成为电脑高手!!
  • (4)(4.6) Triducer
  • (每日一问)基础知识:堆与栈的区别
  • (十五)devops持续集成开发——jenkins流水线构建策略配置及触发器的使用
  • (转)VC++中ondraw在什么时候调用的
  • (转)大型网站的系统架构
  • (转)微软牛津计划介绍——屌爆了的自然数据处理解决方案(人脸/语音识别,计算机视觉与语言理解)...
  • (转载)(官方)UE4--图像编程----着色器开发
  • (转载)Linux 多线程条件变量同步
  • (最新)华为 2024 届秋招-硬件技术工程师-单板硬件开发—机试题—(共12套)(每套四十题)
  • .mkp勒索病毒解密方法|勒索病毒解决|勒索病毒恢复|数据库修复
  • .NET Core6.0 MVC+layui+SqlSugar 简单增删改查
  • .NET LINQ 通常分 Syntax Query 和Syntax Method
  • .NET Standard 的管理策略
  • .net 流——流的类型体系简单介绍
  • .NET框架
  • .net图片验证码生成、点击刷新及验证输入是否正确
  • /etc/sudoers (root权限管理)
  • @Transactional 详解
  • [ NOI 2001 ] 食物链
  • [ 手记 ] 关于tomcat开机启动设置问题
  • [C puzzle book] types