如何在普通 Spring 微服务应用(非 Spring boot)中跟踪请求? 我知道 Spring boot 提供了 Sleuth,但我想对非 Spring boot 应用程序执行类似的操作,它是一个普通的 Spring 应用程序。当请求通过不同的微服务时,我们想要跟踪它们。
最佳答案
- 您需要配置 Spring 应用程序以使用 logback.xml 文件进行日志记录。
- 创建一个拦截器,像 Sleuth 一样设置额外的 MDC 上下文
- 您需要将相同的附加 MDC 上下文传递给 HTTP header 中的其他服务。
登录配置
<configuration>
<appender class="ch.qos.logback.core.ConsoleAppender" name="STDOUT">
<encoder>
<pattern>[%date{dd-MM-yyyy HH:mm:ss.SSS}] [%thread] %-5level %X{traceId:-} %X{spanId:-} ${PID:-} %logger{36} - %msg%n</pattern>
</encoder>
</appender>
<appender class="ch.qos.logback.core.rolling.RollingFileAppender" name="FILE">
<encoder>
<pattern>[%date{dd-MM-yyyy HH:mm:ss.SSS}] [%thread] %-5level %X{traceId:-} %X{spanId:-} ${PID:-} %logger{36} - %msg%n</pattern>
</encoder>
<file>log/app.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>log/app.%d{yyyy-MM-dd-HH}.log</fileNamePattern>
<maxHistory>30</maxHistory>
<totalSizeCap>200MB</totalSizeCap>
</rollingPolicy>
</appender>
<logger level="INFO" name="root">
<appender-ref ref="STDOUT"/>
</logger>
</configuration>
设置 MDC 上下文以进行跟踪的拦截器。
@Slf4j
public class LoggerInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws Exception {
String traceId = request.getHeader("TRACE_ID");
String spanId = request.getHeader("SPAN_ID");
if (traceId == null) {
traceId = UUID.randomUUID().toString();
}
// You can generate new spanId or use the same one
if (spanId == null) {
spanId = UUID.randomUUID().toString();
}
MDC.put("TRACE_ID", traceId);
MDC.put("traceId", traceId);
MDC.put("SPAN_ID", spanId);
MDC.put("spanId", spanId);
log.info("[preHandle] HTTP: {}, URL: {} ", request.getMethod(), request.getRequestURI());
return true;
}
@Override
public void postHandle(
HttpServletRequest request,
HttpServletResponse response,
Object handler,
ModelAndView modelAndView)
throws Exception {
log.info("[postHandle] HTTP: {}, URL: {} ", request.getMethod(), request.getRequestURI());
MDC.clear();
}
}
如果您想测量执行时间,请为其添加分析器。在 Profiling Spring Boot 的示例中了解更多相关信息,它具体说明了 Spring boot,但您也可以在 Spring 应用程序中使用相同的方法。
如果您使用 RestTemplate,则可以设置这些 header 。
HttpHeaders headers = new HttpHeaders();
headers.set("TRACE_ID", MDC.get("TRACE_ID"));
headers.set("SPAN_ID", MDC.get("SPAN_ID"));
HttpEntity entity = new HttpEntity(headers);
RestTemplate restTemplate = new RestTemplate();
SimpleClientHttpRequestFactory rf =
(SimpleClientHttpRequestFactory) restTemplate.getRequestFactory();
rf.setReadTimeout(2 * Constants.ONE_MILLI_INT);
rf.setConnectTimeout(2 * Constants.ONE_MILLI_INT);
ResponseEntity<String> response =
restTemplate.exchange(url, HttpMethod.GET, entity, String.class);
在这个简单的示例中,已设置 TRACE_ID
和 SPAN_ID
header 。
关于java - 如何跟踪普通 Spring 微服务应用程序(非 Spring boot)中的请求?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62083662/