TBLEG
扫描微信账号

扫一扫微信二维码

调用链监控CAT之URL埋点实践

2020-05-16 信息
区块链白皮书代写

文章首发于公众号《程序员果果》地址:https://mp.weixin.qq.com/s/0tLjjlUtKTyOlH-5elj0Xw

URL监控埋点作用一个http请求来了之后,会自动打点,能够记录每个url访问情况,并将以此请求后续调用链路串起来,可以在cat上查看logview可以在cat Transaction及Event 页面上都看到URL和URL.Forward(如果有Forward请求话)两类数据;Transaction数据中URL点进去数据就是被访问具体URL(去掉参数前缀部分)请将catFilter存放filter第一个,这样可以保证最大可能性监控所有请求实践工程说明工程名端口作用cat-ui8082调用入口服务cat-business-consumer8083业务消费服务cat-order-service8084订单服务cat-storage-service8085库存服务

上图是本节实例埋点图,首先 cat-ui 入口 和 调用点 加入cat埋点,cat-business-consumer入口和调用点加入埋点,cat-order-service 和 cat-storage-service 不再调用其他微服务,所以只在入口加入埋点。通过这样埋点,可以组成一条完整调用链。

关键代码调用链上下文通用类CatContextImpl.java
/** * Cat.context接口实现类,用于context调用链传递,相关方法Cat.logRemoteCall()和Cat.logRemoteServer() */public class CatContextImpl implements Cat.Context {    private Map<String, String> properties = new HashMap<>(16);    @Override    public void addProperty(String key, String value) {        properties.put(key, value);    }    @Override    public String getProperty(String key) {        return properties.get(key);    }}
CatHttpConstants
/** * 添加header常量,用于http协议传输rootId、parentId、childId三个context属性 */public class CatHttpConstants {    /**     * http header 常量     */    public static final String CAT_HTTP_HEADER_ROOT_MESSAGE_ID = "X-CAT-ROOT-MESSAGE-ID";    public static final String CAT_HTTP_HEADER_PARENT_MESSAGE_ID = "X-CAT-ROOT-PARENT-ID";    public static final String CAT_HTTP_HEADER_CHILD_MESSAGE_ID = "X-CAT-ROOT-CHILD-ID";}
CatServletFilter
/** * http协议传输,远程调用链目标端接收contextfilter, * 通过header接收rootId、parentId、childId并放入CatContextImpl中,调用Cat.logRemoteCallServer()进行调用链关联 * 注:若不涉及调用链,则直接使用cat-client.jar中提供filter即可 * 使用方法(视项目框架而定): *      1、web项目:在web.xml中引用此filter *      2、Springboot项目,通过注入bean方式注入此filter */public class CatServletFilter implements Filter {    private String[] urlPatterns = new String[0];    @Override    public void init(FilterConfig filterConfig) throws ServletException {        String patterns = filterConfig.getInitParameter("CatHttpModuleUrlPatterns");        if (patterns != null) {            patterns = patterns.trim();            urlPatterns = patterns.split(",");            for (int i = 0; i < urlPatterns.length; i++) {                urlPatterns[i] = urlPatterns[i].trim();            }        }    }    @Override    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {        HttpServletRequest request = (HttpServletRequest) servletRequest;        String url = request.getRequestURL().toString();        for (String urlPattern : urlPatterns) {            if (url.startsWith(urlPattern)) {                url = urlPattern;            }        }        CatContextImpl catContext = new CatContextImpl();        catContext.addProperty( Cat.Context.ROOT, request.getHeader(CatHttpConstants.CAT_HTTP_HEADER_ROOT_MESSAGE_ID));        catContext.addProperty(Cat.Context.PARENT, request.getHeader(CatHttpConstants.CAT_HTTP_HEADER_PARENT_MESSAGE_ID));        catContext.addProperty(Cat.Context.CHILD, request.getHeader(CatHttpConstants.CAT_HTTP_HEADER_CHILD_MESSAGE_ID));        Cat.logRemoteCallServer(catContext);        Transaction t = Cat.newTransaction( CatConstants.TYPE_URL, url);        try {            Cat.logEvent("Service.method", request.getMethod(), Message.SUCCESS, request.getRequestURL().toString());            Cat.logEvent("Service.client", request.getRemoteHost());            filterChain.doFilter(servletRequest, servletResponse);            t.setStatus(Transaction.SUCCESS);        } catch (Exception ex) {            t.setStatus(ex);            Cat.logError(ex);            throw ex;        } finally {            t.complete();        }    }    @Override    public void destroy() {    }}

本节实例中每个工程都会用到调用链上下文通用类。

cat-ui 工程CatRestInterceptor
@Componentpublic class CatRestInterceptor implements ClientHttpRequestInterceptor {    @Override    public ClientHttpResponse intercept(HttpRequest request, byte[] body, ClientHttpRequestExecution execution) throws IOException {        Transaction t = Cat.newTransaction(CatConstants.TYPE_REMOTE_CALL, request.getURI().toString());        try {            HttpHeaders headers = request.getHeaders();            // 保存和传递CAT调用链上下文            Cat.Context ctx = new CatContextImpl();            Cat.logRemoteCallClient(ctx);            headers.add(CatHttpConstants.CAT_HTTP_HEADER_ROOT_MESSAGE_ID, ctx.getProperty(Cat.Context.ROOT));            headers.add(CatHttpConstants.CAT_HTTP_HEADER_PARENT_MESSAGE_ID, ctx.getProperty(Cat.Context.PARENT));            headers.add(CatHttpConstants.CAT_HTTP_HEADER_CHILD_MESSAGE_ID, ctx.getProperty(Cat.Context.CHILD));            // 保证请求继续被执行            ClientHttpResponse response =  execution.execute(request, body);            t.setStatus(Transaction
全文阅读
文章关键词
request
class
java
Transaction
string
监控
url
cat
springcloud
扫描关注微信账号

试试长按二维码加关注