如何使用Spring Cloud Sleuth在日志中添加Principal用户名?
可以实现,通过自定义Spring Cloud Sleuth的baggage字段结合MDC(映射诊断上下文)即可完成日志添加Principal用户名的需求,具体操作步骤如下:
1. 配置Sleuth支持自定义baggage字段
在项目配置文件(以application.yml为例)中添加如下配置,声明principal为允许传递的baggage字段,且需要同步到MDC中:
spring: sleuth: baggage: # 声明允许跨服务传递的自定义baggage字段 remote-fields: principal # 声明需要同步到MDC的字段,日志框架可直接读取 correlation-fields: principal enabled: true
2. 注入Principal到Sleuth Baggage
编写MVC拦截器,在请求认证完成后将当前登录用户名存入Sleuth的baggage中:
import org.springframework.cloud.sleuth.BaggageInScope; import org.springframework.cloud.sleuth.Tracer; import org.springframework.security.core.Authentication; import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.web.servlet.HandlerInterceptor; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class PrincipalBaggageInterceptor implements HandlerInterceptor { private final Tracer tracer; private static final String PRINCIPAL_BAGGAGE_KEY = "principal"; public PrincipalBaggageInterceptor(Tracer tracer) { this.tracer = tracer; } @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { Authentication auth = SecurityContextHolder.getContext().getAuthentication(); // 仅认证通过的请求注入用户名 if (auth != null && auth.isAuthenticated() && !"anonymousUser".equals(auth.getPrincipal())) { BaggageInScope baggage = tracer.createBaggage(PRINCIPAL_BAGGAGE_KEY, auth.getName()); baggage.makeCurrent(); } return true; } }
将上述拦截器注册到Spring MVC上下文:
import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.config.annotation.InterceptorRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; @Configuration public class WebMvcConfig implements WebMvcConfigurer { private final Tracer tracer; public WebMvcConfig(Tracer tracer) { this.tracer = tracer; } @Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(new PrincipalBaggageInterceptor(tracer)) .addPathPatterns("/**"); } }
3. 修改日志输出格式
在日志框架配置中(以Logback为例),在日志pattern中添加%X{principal}占位符读取MDC中的用户名:
<property name="log.pattern" value="%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - [%X{spring.application.name},%X{traceId},%X{spanId},%X{principal},%X{export}] - %msg%n"/>
注意事项
- 上述配置适配Spring Cloud Sleuth 3.x版本,如果你使用2.x版本,需要将
spring.sleuth.baggage相关配置替换为spring.sleuth.propagation对应配置项即可。 - 跨服务调用场景下,只需保证链路内所有服务都配置了相同的
remote-fields,principal字段会跟随链路自动传递,无需额外开发。
内容的提问来源于stack exchange,提问作者alx
相关产品推荐
相关产品推荐

