jeakboy 2025-12-05 09:20 采纳率: 56.8%
浏览 3

Spring Cloud Gateway的全局过滤器如何实现请求的链路追踪和日志记录? 过滤器执行异常时应如何处理?

Spring Cloud Gateway的全局过滤器如何实现请求的链路追踪和日志记录? 过滤器执行异常时应如何处理?

  • 写回答

4条回答 默认 最新

  • 阿里嘎多学长 2025-12-05 09:29
    关注

    阿里嘎多学长整理AIGC生成,因移动端显示问题导致当前答案未能完全显示,请使用PC端查看更加详细的解答过程

    Spring Cloud Gateway全局过滤器实现请求链路追踪和日志记录

    在Spring Cloud Gateway中,可以通过实现全局过滤器来实现请求链路追踪和日志记录。下面是一个示例:

    @Component
    public class GlobalFilter implements GlobalFilter, Ordered {
        
        @Override
        public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
            // 开始时间
            long startTime = System.currentTimeMillis();
            
            // 请求链路追踪
            String traceId = exchange.getAttribute("traceId");
            if (traceId == null) {
                traceId = UUID.randomUUID().toString();
                exchange.getAttributeMap().put("traceId", traceId);
            }
            
            // 日志记录
            log.info("请求开始:traceId={}, uri={}, method={}", traceId, exchange.getRequest().getURI(), exchange.getRequest().getMethod());
            
            return chain.filter(exchange).doOnNext((response) -> {
                // 请求结束时间
                long endTime = System.currentTimeMillis();
                
                // 日志记录
                log.info("请求结束:traceId={}, uri={}, method={}, status={}, time={}", traceId, exchange.getRequest().getURI(), exchange.getRequest().getMethod(), response.getStatusCode(), endTime - startTime);
            });
        }
        
        @Override
        public int getOrder() {
            return Ordered.LOWEST_PRECEDENCE;
        }
    }
    

    在上面的示例中,我们实现了一个全局过滤器,用于记录请求的链路追踪和日志记录。我们使用 ServerWebExchange 对象获取请求的 URI、方法和状态码,并记录请求的开始和结束时间。

    过滤器执行异常时的处理

    在全局过滤器中,异常处理非常重要。我们可以使用 try-catch 块来捕获异常,并进行处理。例如:

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        try {
            // 请求链路追踪
            String traceId = exchange.getAttribute("traceId");
            if (traceId == null) {
                traceId = UUID.randomUUID().toString();
                exchange.getAttributeMap().put("traceId", traceId);
            }
            
            // 日志记录
            log.info("请求开始:traceId={}, uri={}, method={}", traceId, exchange.getRequest().getURI(), exchange.getRequest().getMethod());
            
            return chain.filter(exchange).doOnNext((response) -> {
                // 请求结束时间
                long endTime = System.currentTimeMillis();
                
                // 日志记录
                log.info("请求结束:traceId={}, uri={}, method={}, status={}, time={}", traceId, exchange.getRequest().getURI(), exchange.getRequest().getMethod(), response.getStatusCode(), endTime - startTime);
            });
        } catch (Exception e) {
            // 异常处理
            log.error("全局过滤器异常:traceId={}, uri={}, method={}, exception={}", exchange.getAttribute("traceId"), exchange.getRequest().getURI(), exchange.getRequest().getMethod(), e.getMessage());
            return Mono.error(e);
        }
    }
    

    在上面的示例中,我们捕获了异常,并记录了异常信息。我们还返回了一个错误的 Mono 对象,以便下游的过滤器可以处理异常。

    评论

报告相同问题?

问题事件

  • 创建了问题 12月5日