如何配置OpenTelemetry在Jaeger中展示HTTP响应体?
解决Quarkus集成OpenTelemetry+Jaeger时查看HTTP响应体的问题
核心说明
Jaeger本身支持展示自定义Span属性,默认OpenTelemetry不会自动捕获HTTP响应体,需要通过自定义配置将响应体注入到Span中,即可在Jaeger中查看。
具体实现方案
1. 自定义响应拦截器捕获响应体
创建JAX-RS响应过滤器,拦截并记录响应体到当前OpenTelemetry Span:
import io.opentelemetry.api.trace.Span; import jakarta.ws.rs.container.ContainerRequestContext; import jakarta.ws.rs.container.ContainerResponseContext; import jakarta.ws.rs.container.ContainerResponseFilter; import jakarta.ws.rs.core.MediaType; import jakarta.ws.rs.ext.Provider; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.OutputStream; @Provider public class ResponseBodyTraceFilter implements ContainerResponseFilter { @Override public void filter(ContainerRequestContext requestContext, ContainerResponseContext responseContext) throws IOException { // 仅捕获JSON/文本类型响应,避免二进制数据占用过多存储 if (responseContext.getMediaType() != null && (responseContext.getMediaType().isCompatible(MediaType.APPLICATION_JSON_TYPE) || responseContext.getMediaType().isCompatible(MediaType.TEXT_PLAIN_TYPE))) { Span currentSpan = Span.current(); if (currentSpan != null && currentSpan.isRecording()) { // 复制响应体内容,同时保证原响应正常返回 OutputStream originalStream = responseContext.getEntityStream(); ByteArrayOutputStream baos = new ByteArrayOutputStream(); responseContext.setEntityStream(baos); try { originalStream.close(); baos.writeTo(originalStream); // 将响应体作为自定义属性添加到Span String responseBody = baos.toString(); currentSpan.setAttribute("http.response.body", responseBody); } finally { responseContext.setEntityStream(originalStream); } } } } }
2. 配置OpenTelemetry允许自定义属性
在application.properties中添加以下配置,确保自定义属性不会被过滤:
# 确保采样器开启(测试环境用always_on,生产按需调整) quarkus.opentelemetry.tracer.sampler=always_on # 允许自定义响应体属性被导出 quarkus.opentelemetry.tracer.attribute-filter.include=http.response.body
3. 在Jaeger中查看响应体
重启服务并触发请求后,打开Jaeger的Span详情页,在Tags区域就能找到http.response.body属性,查看对应的响应内容。
关键注意事项
- 限制捕获范围:只针对必要的媒体类型捕获响应体,避免大体积数据导致Jaeger存储压力过大。
- 敏感数据脱敏:如果响应包含敏感信息(如密码、令牌),需在添加到Span前做脱敏处理。
- 跨服务调用适配:对于微服务间的客户端调用(如RestClient),需要创建客户端拦截器,同样捕获下游服务的响应体注入Span。
内容的提问来源于stack exchange,提问作者Gilson
相关产品推荐
相关产品推荐

