英文:
How to trace requests in normal Spring micro service app (non Spring boot)?
问题
如何在普通的Spring微服务应用程序(非Spring Boot)中跟踪请求?
我知道Spring Boot提供了Sleuth,但我想在非Spring Boot应用程序中进行类似的操作,这是一个普通的Spring应用程序。当请求通过不同的微服务时,我们想要对它们进行跟踪。
英文:
How to trace requests in normal Spring micro service app (non Spring boot) ?
I know Spring boot give Sleuth but I wanted to do the similar for non Spring boot app, its a normal Spring app. When request passes through the different micro-service, we want to trace them.
答案1
得分: 1
-
You need to configure the Spring app to use a logback.xml file for logging.
-
Create an interceptor that would set additional MDC contexts as Sleuth does.
-
You need to pass the same additional MDC contexts to other services in HTTP headers.
Log back Configuration
<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>
Interceptor that sets the MDC context for tracing.
@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();
}
}
If you want to measure execution time, then add a profiler for the same. Read more about the same at the example at Profiling Spring Boot, it talks specifically about Spring Boot, but you can use the same approach in a Spring app as well.
If you're using RestTemplate, then you can set these headers.
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);
In this simple example, TRACE_ID
and SPAN_ID
headers have been set.
英文:
- You need to configure the Spring app to use a logback.xml file for logging.
- Create an interceptor that would set additional MDC contexts as Sleuth does
- You need to pass the same additional MDC contexts to other services in HTTP headers.
Log back Configuration
<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>
Interceptor that sets the MDC context for tracing.
@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();
}
}
If you want to measure execution time then add a profiler for the same. Read more about the same at the example at Profiling Spring Boot, it says specific about Spring boot but you can use the same approach in Spring app as well.
If you're using RestTemplate then you can set these headers.
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);
In this simple example, TRACE_ID
and SPAN_ID
headers have been set.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论