Spring Boot 接入Jager后,访问接口时,默认显示对应控制器的方法名。如下图:
控制器方法名经常会重名,也不利于我们利用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。方便我们查看搜索。
扩展延伸
- 设置Span的OperationName当然可以不仅仅用Filter实现。有时候,针对
/article/{id}
的场景,我们或许会期望将同一接口的日志归类在一起。有或者希望完整保留/article?id=xxx
的URI。这时候就需要针对这些情况,可能可以考虑在接口中处理?或者用Interceptor读取handler的注解?这就需要大家根据实际情况做处理了。 - 既然我们通过
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