Spring MDC事务日志


在本文中,我们将了解如何配置 Spring 应用程序以使用MDC(映射诊断上下文)进行事务日志记录。
@Transactional这项技术将帮助我们在服务方法发出的所有日志条目中注入持久性上下文信息以及关联的数据库事务标识符。

MDC 用于应用程序记录ThreadLocalJava 线程的上下文。
简而言之,MDC 允许我们注册绑定到给定线程的键/值集,并且可以在打印给定日志消息时由日志框架引用。
要使用 MDC,日志框架需要引用日志消息模式中设置的 MDC 键/值的键,如以下示例所示:

<appender name="console" class="ch.qos.logback.core.ConsoleAppender">
    <filter class=
"ch.qos.logback.classic.filter.ThresholdFilter">
        <level>TRACE</level>
    </filter>
    <encoder>
        <Pattern>%-5p [%t]:%X{txId} %c{1} - %m%n</Pattern>
        <charset>UTF-8</charset>
    </encoder>
</appender>

一旦我们txId通过 Logback 消息模式引用了 MDC 变量,在运行以下代码片段时:

try(MDC.MDCCloseable mdc = MDC
    .putCloseable(
        "txId",
        String.format(
           
" Persistence Context Id: [%d], DB Transaction Id: [%s]",
            123456,
            7890
        )
    )
) {
    LOGGER.info(
"Fetch Post by title");
}

Logback 将打印以下消息:
     
2022-12-21 14:51:38,823 INFO [main]: Persistence Context Id: [123456], DB Transaction Id: [7890] c.v.b.h.s.t.m.SpringMdcTest - Update Post entity

这很好,但是我们需要自动化如何将持久性上下文标识符和实际数据库事务 ID 绑定到txIdMDC 变量。

因此,为了实现我们的目标,我们需要拦截以下 JPA 操作:

  • 当 JPA Persistence Context 打开时,我们需要分配一个 Persistence Context 标识符
  • 语句执行后,我们检查关系数据库是否分配了事务标识符
  • JPA 事务结束后,我们移除事务标识符
  • 在 JPA 持久性上下文关闭后,我们txId从 MDC 日志上下文中删除变量

幸运的是,Spring 和 Hibernate 都是高度可定制的,因此我们可以拦截所有这些操作并应用 MDC 转换日志记录。

...详细点击标题