**后台:**SpringBoot 3.1.0 -内嵌tomcat
样本:https://github.com/PerryZhao/spring-filter-error-lost-log-correlation-demo/tree/main
//在过滤器中抛出异常
public class MyFilter extends GenericFilterBean {
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
// ...
throw new IllegalArgumentException("IllegalArgumentException");
}
}
//自定义ErrorController
public class MyErrorController extends AbstractErrorController {
@RequestMapping
public ResponseEntity<Map<String, Object>> handler(HttpServletRequest request) {
// ...
Object ex = request.getAttribute(RequestDispatcher.ERROR_EXCEPTION);
throw new MyErrorControllerException("requestInfo", (Throwable) ex, status);
}
}
//自定义ExceptionHandler
@ExceptionHandler(Throwable.class)
public ResponseEntity<MessageSourceResult> handler(Throwable ex, HttpServletRequest request, HttpServletResponse response) {
Observation observation = (Observation) request.getAttribute(ServerHttpObservationFilter.class.getName() + ".observation");
if (null != observation) {
** // If I want to get the traceId here, what should I do? Is the following code correct?
**
try (Observation.Scope scope = observation.openScope()) {
response.setHeader("X-B3-TraceId", tracer.currentTraceContext().context().traceId());
log.warn("Missing log correlation...");
// ...
}
}
}
ServerHttpObservationFilter在finally块中调用了observation.stop()
// org.springframework.web.filter.ServerHttpObservationFilter
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
Observation observation = createOrFetchObservation(request, response);
try (Observation.Scope scope = observation.openScope()) {
filterChain.doFilter(request, response);
} catch (Exception ex) {
observation.error(unwrapServletException(ex));
response.setStatus(HttpStatus.INTERNAL_SERVER_ERROR.value());
throw ex;
} finally {
// Only stop Observation if async processing is done or has never been started.
if (!request.isAsyncStarted()) {
Throwable error = fetchException(request);
if (error != null) {
observation.error(error);
}
observation.stop();
}
}
}
Q:如果观察停止后openScope会发生什么?
1条答案
按热度按时间6jjcrrmo1#
Spring MVC中的整个请求处理都发生在
ServerHttpObservationFilter
打开的范围内。不需要打开新的作用域,因为当前观察已经在作用域中。从跟踪程序中获取traceId就足够了。