You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.24 20:18:20