Spring Boot 2 Actuator请求响应体追踪:HttpTraceFilter配置疑问
解决Spring Boot 2中HttpTraceFilter自定义追踪属性的问题
我完全理解你的困扰——Spring Boot 2的HttpTraceFilter和早期版本的处理逻辑差异不小,它默认依赖HttpTracer接口封装请求响应的追踪细节,直接通过请求属性设置追踪属性确实需要针对性的自定义处理。
下面给你两种实用的解决方案,你可以根据自己的业务场景选择:
方案一:重写HttpTraceFilter的trace方法,按需添加自定义属性
你可以在自定义的RequestTraceFilter中重写trace方法,在创建HttpTrace实例的流程里,从请求属性中提取需要的信息,追加到追踪的属性集合中。
完整代码示例如下:
import org.springframework.boot.actuate.trace.http.HttpTrace; import org.springframework.boot.actuate.trace.http.HttpTraceFilter; import org.springframework.boot.actuate.trace.http.HttpTracer; import org.springframework.stereotype.Component; import javax.servlet.FilterChain; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.util.HashMap; import java.util.Map; @Component public class RequestTraceFilter extends HttpTraceFilter { public RequestTraceFilter(HttpTracer tracer) { super(tracer); } @Override protected void trace(HttpServletRequest request, HttpServletResponse response, FilterChain chain, Throwable error) throws IOException, ServletException { // 从请求属性中获取自定义数据,这里假设你要获取的属性名为"custom_trace_attr" String customAttr = (String) request.getAttribute("custom_trace_attr"); // 调用父类逻辑完成基础追踪,拿到初始的HttpTrace实例 HttpTrace trace = getTracer().receiveRequest(request); try { chain.doFilter(request, response); } finally { // 给trace添加自定义属性(注意HttpTrace是不可变类,需创建新实例) Map<String, Object> updatedAttrs = new HashMap<>(trace.getAttributes()); updatedAttrs.put("customAttribute", customAttr); HttpTrace updatedTrace = new HttpTrace( trace.getTimestamp(), trace.getPrincipal(), trace.getSession(), trace.getRequest(), trace.getResponse(), trace.getTimeTaken(), updatedAttrs ); // 用更新后的trace完成响应阶段的追踪 getTracer().sendResponse(updatedTrace, response, error); } } }
方案二:自定义HttpTracer实现,全局统一处理追踪属性
如果你希望所有HTTP请求的追踪数据都自动包含请求中的特定属性,可以自定义HttpTracer的实现,替换掉Spring Boot默认的InMemoryHttpTracer(或你正在使用的其他实现)。
示例代码如下:
import org.springframework.boot.actuate.trace.http.DefaultHttpTrace; import org.springframework.boot.actuate.trace.http.HttpTrace; import org.springframework.boot.actuate.trace.http.HttpTraceRepository; import org.springframework.boot.actuate.trace.http.HttpTracer; import org.springframework.stereotype.Component; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.util.HashMap; import java.util.Map; @Component public class CustomHttpTracer implements HttpTracer { private final HttpTraceRepository repository; public CustomHttpTracer(HttpTraceRepository repository) { this.repository = repository; } @Override public HttpTrace receiveRequest(HttpServletRequest request) { HttpTrace baseTrace = DefaultHttpTrace.create(request); // 从请求属性提取自定义属性 String customAttr = (String) request.getAttribute("custom_trace_attr"); Map<String, Object> updatedAttrs = new HashMap<>(baseTrace.getAttributes()); updatedAttrs.put("customAttribute", customAttr); // 返回包含自定义属性的新Trace实例 return new DefaultHttpTrace( baseTrace.getTimestamp(), baseTrace.getPrincipal(), baseTrace.getSession(), baseTrace.getRequest(), baseTrace.getResponse(), baseTrace.getTimeTaken(), updatedAttrs ); } @Override public void sendResponse(HttpTrace trace, HttpServletResponse response, Throwable error) { // 更新响应信息并保存到追踪仓库 DefaultHttpTrace finalTrace = DefaultHttpTrace.update(trace).response(response).error(error).build(); this.repository.add(finalTrace); } }
之后你的自定义过滤器只需注入这个CustomHttpTracer即可:
@Component public class RequestTraceFilter extends HttpTraceFilter { public RequestTraceFilter(CustomHttpTracer tracer) { super(tracer); } }
关键注意点
- Spring Boot 2中的
HttpTrace是不可变类,无法直接修改已有实例的属性,必须创建新的实例来承载自定义属性。 - 你可以根据实际需求调整请求属性的提取逻辑,比如获取多个属性、不同类型的属性等。
- 如果使用Actuator的
/actuator/httptrace端点,自定义的属性会自动出现在返回的追踪数据中。
内容的提问来源于stack exchange,提问作者kiara
相关产品推荐
相关产品推荐

