如何通过 MDC 将从 JWT 获取的用户 ID 添加到后端日志?
Posted
技术标签:
【中文标题】如何通过 MDC 将从 JWT 获取的用户 ID 添加到后端日志?【英文标题】:How to add user id taken from JWT to the backend logs via MDC? 【发布时间】:2021-02-27 14:27:47 【问题描述】:我们有一个带有 REST 接口和 Web 客户端的 Spring Boot 应用程序。我们使用带有 OAuth 2.0 JWT 令牌的 spring-security 进行身份验证。我们使用 slf4j 和 sleuth 进行日志记录。我们想在日志中记录当前登录的用户 ID。从技术上讲,我们希望将用户 ID 添加到服务器应用程序的映射诊断上下文 (MDC)。
目标是将前端操作导致的服务器端错误链接到触发后端操作的用户。
目前,我们在客户端提取用户ID,并将ID作为HTTP头字段发送到服务器,在那里它被侦探从HTTP头中作为行李提取并添加到日志中,请参见以下spring.sleuth.baggage
配置。这是有效的。
spring.sleuth.baggage.remote-fields=user_id
spring.sleuth.baggage.tag-fields=user_id
spring.sleuth.baggage.correlation-fields=user_id
用户由user=%Xuser_id:-
登录,查看完整的日志模式:
logging:
level:
ROOT: WARN
pattern:
console: "[%d] [%t] %highlight(%-5p) %c10 - %cyan([trace=%XX-B3-TraceId:- span=%XX-B3-SpanId:- user=%Xuser_id:-]) %m%n"
但是,我们希望在服务器端直接从 JWT 令牌中提取用户 ID,而不是在客户端提取用户 id 并将其发送到后端。因为所有信息也可以直接在服务器端获得。
我查看了 spring-cloud-sleuth 文档如何在 Java 中设置行李字段,但我不知道该怎么做。
https://cloud.spring.io/spring-cloud-sleuth/reference/html/#java-configuration https://docs.spring.io/spring-cloud-sleuth/docs/current-SNAPSHOT/reference/html/project-features.html#features-brave-baggage https://docs.spring.io/spring-cloud-sleuth/docs/current-SNAPSHOT/reference/html/appendix.html#appendix我不知道要使用哪些类以及如何使用它们。我试过下面的代码。代码在 Spring 启动时不执行。因此,似乎缺少某些配置或代码完全错误。
package net.company.common.service;
import brave.baggage.BaggageField;
import brave.baggage.BaggagePropagation;
import brave.baggage.BaggagePropagationConfig;
import brave.baggage.BaggagePropagationCustomizer;
import brave.internal.baggage.BaggageContext;
import net.company.common.service.CommonServiceConfig;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
@Configuration
@ComponentScan
@Import(CommonServiceConfig.class)
public class ServiceConfig
@Bean
BaggagePropagationConfig.SingleBaggageField singleBaggageField()
BaggagePropagationConfig.SingleBaggageField field = BaggagePropagationConfig.SingleBaggageField.newBuilder(BaggageField.create("user_id")).build();
field.field().updateValue("user_12345"); // set only dummy value for debug
return field;
可以手动实现这样的 MDC,请参阅 https://www.baeldung.com/mdc-in-log4j-2-logback。但由于这很容易出错,我们希望避免它,例如上下文清理必须正确完成。
如何使用 sleuth/brave 将来自 JWT 的用户 ID 添加到 MDC 以进行服务器端日志记录?
【问题讨论】:
【参考方案1】:既然你正在使用
spring.sleuth.baggage.remote-fields=user_id
它对你有用,这就是如何创建和更新 Baggage Fields 的值。
BaggageField baggageField = BaggageField.create(baggageKey);
baggageField.updateValue(baggageValue);
请注意,以这种方式更新行李价值将显示在下一个跨度的日志中。如果您想更新同一跨度中的值,请查看此答案https://***.com/a/67373784/2224254
【讨论】:
【参考方案2】:我正在使用
spring boot version: 2.1.2.RELEASE
spring cloud version: Greenwich.RELEASE
您可以使用以下属性进行配置
spring.sleuth.propagation-keys=user_id
spring.sleuth.log.slf4j.whitelisted-mdc-keys=user_id
【讨论】:
以上是关于如何通过 MDC 将从 JWT 获取的用户 ID 添加到后端日志?的主要内容,如果未能解决你的问题,请参考以下文章