Spring Cloud Gateway路由未找到(404)时如何记录请求日志?
解决Spring Cloud Gateway路由未找到(404)时的请求日志记录问题
问题原因
你的过滤器当前存在两个核心问题导致404场景下无日志:
- 当路由未找到时,
GATEWAY_ROUTE_ATTR属性为null,调用route.getId()会抛出空指针异常,日志语句无法执行完成。 - 原逻辑仅在请求进入网关时同步记录日志,未处理路由匹配失败后网关直接返回404的异步流程。
解决方案
修改过滤器逻辑,解决空指针问题,并通过响应生命周期钩子确保所有请求(包括路由未找到的情况)都能被记录:
修改后的LoggingFilter代码
@Slf4j @Component public class LoggingFilter implements GlobalFilter, Ordered { @Override public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) { // 获取原始请求URI Set<URI> uris = exchange.getAttributeOrDefault(GATEWAY_ORIGINAL_REQUEST_URL_ATTR, Collections.emptySet()); String originalUri = uris.isEmpty() ? "Unknown" : uris.iterator().next().toString(); // 先记录请求进入的基础信息,不依赖路由属性 log.info("Incoming request: {}", originalUri); return chain.filter(exchange) // 无论请求成功、失败或路由未找到,最终都会执行此逻辑 .doFinally(signalType -> { Route route = exchange.getAttribute(GATEWAY_ROUTE_ATTR); URI routeUri = exchange.getAttribute(GATEWAY_REQUEST_URL_ATTR); HttpStatus statusCode = exchange.getResponse().getStatusCode(); if (route != null) { log.info("Request {} routed to id: {}, uri: {}, status: {}", originalUri, route.getId(), routeUri, statusCode); } else { // 路由未找到的场景单独记录 log.warn("Request {} failed to find route, status: {}", originalUri, statusCode); } }); } @Override public int getOrder() { // 设置过滤器顺序为-1,确保在路由查找逻辑之后执行,能正确获取路由属性(如果存在) return -1; } }
关键优化点
- 空指针防护:增加
route != null的判断,避免路由未找到时的异常。 - 全流程覆盖:使用
doFinally钩子,无论请求链路是正常完成还是异常终止,都会触发日志记录,覆盖404场景。 - 状态码补充:新增响应状态码记录,更清晰区分请求结果。
- 顺序控制:实现
Ordered接口并设置order=-1,确保过滤器在路由匹配逻辑执行后运行,能正确获取路由属性(如果存在)。
额外说明
如果需要更早记录请求(比如在路由查找之前),可以将order设置为更小的负数(如-100),此时路由属性会是null,可以单独记录请求进入的日志,再通过doFinally记录最终结果。
内容的提问来源于stack exchange,提问作者Maxiko
相关产品推荐
相关产品推荐

