Spring Boot 对接 Jaeger 时利用Filter修改 Span 的 OperationName

发布时间:2022年05月04日 // 分类:代码 // 暂无评论

Spring Boot 接入Jager后,访问接口时,默认显示对应控制器的方法名。如下图:

jaeger-operation-name-1.png

控制器方法名经常会重名,也不利于我们利用URL查询接口。在这种情况下,我们可以利用Opentracing提供的方法获取到当前Span,并修改OperationName。

1、新建一个Filter用于修改OperationName

通过GlobalTracer获取到当前Span,并写入HttpServletRequest的URI。

需要注意的是,这里代码默认ServletRequest一定是HttpServletRequest。而实际上ServletRequest设计时不仅仅可以是HttpServletRequest,只不过在大多数HTTP项目上可以这样操作。这里简单强制规定一定是HttpServletRequest

package com.gentleltd.todo965.backend.infra.filter;

import io.opentracing.util.GlobalTracer;

import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;

public class JaegerSetOperationNameFilter implements Filter {
    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        filterChain.doFilter(servletRequest, servletResponse);
        // 设置 Jaeger Span 的 OperationName
        var span = GlobalTracer.get().activeSpan();
        if (span != null) {
            span.setOperationName(((HttpServletRequest) servletRequest).getRequestURI());
        }
    }
}

2、配置引入Filter

需要注意的是,如果项目中有多个Filter,最好调整JaegerSetOperationNameFilter的优先级,将Order设置成最小的那一个。尽量将这个Filter放在最外层(最早调用最晚返回)。

package com.gentleltd.todo965.backend.config;

import com.gentleltd.todo965.backend.infra.filter.JaegerSetOperationNameFilter;
import com.gentleltd.todo965.backend.infra.filter.LogFilter;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class FilterConfig {
    @Bean
    public FilterRegistrationBean<JaegerSetOperationNameFilter> JaegerSetOperationNameFilterRegistration() {
        return new FilterRegistrationBean<>(new JaegerSetOperationNameFilter()) {{
            addUrlPatterns("/*"); // 对所有URL生效
            setName("JaegerSetOperationNameFilterRegistration");
            setOrder(1);
        }};
    }
}

效果

通过以上设置后,我们可以看到Jaeger记录的日志里,OperationName已经变成了URI。方便我们查看搜索。

jaeger-operation-name-2.png

扩展延伸

  1. 设置Span的OperationName当然可以不仅仅用Filter实现。有时候,针对/article/{id}的场景,我们或许会期望将同一接口的日志归类在一起。有或者希望完整保留/article?id=xxx的URI。这时候就需要针对这些情况,可能可以考虑在接口中处理?或者用Interceptor读取handler的注解?这就需要大家根据实际情况做处理了。
  2. 既然我们通过GlobalTracer.get().activeSpan()获取到了Span,在需要的时候我们也可以对Span打Tag。利用Span的setTag方法,我们可以方便地打上一些Tag,如用户ID、客户端ID等信息,方便在Jaeger中查询。

本文固定链接
https://www.ywlib.com/archives/198.html

标签
Spring Boot, Jaeger, Filter, Span, OperationName, setOperationName

添加新评论 »

分类
随机文章
最新文章
最近回复