专栏首页码匠的流水账聊聊skywalking的spring-webflux-plugin
原创

聊聊skywalking的spring-webflux-plugin

本文主要研究一下skywalking的spring-webflux-plugin

DispatcherHandlerInstrumentation

skywalking-6.6.0/apm-sniffer/optional-plugins/optional-spring-plugins/spring-webflux-5.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/spring/webflux/v5/define/DispatcherHandlerInstrumentation.java

public class DispatcherHandlerInstrumentation extends ClassInstanceMethodsEnhancePluginDefine {
    @Override
    public ConstructorInterceptPoint[] getConstructorsInterceptPoints() {
        return new ConstructorInterceptPoint[0];
    }
​
    @Override
    public InstanceMethodsInterceptPoint[] getInstanceMethodsInterceptPoints() {
        return new InstanceMethodsInterceptPoint[]{
            new InstanceMethodsInterceptPoint() {
                @Override
                public ElementMatcher<MethodDescription> getMethodsMatcher() {
                    return named("handle");
                }
​
                @Override
                public String getMethodsInterceptor() {
                    return "org.apache.skywalking.apm.plugin.spring.webflux.v5.DispatcherHandlerHandleMethodInterceptor";
                }
​
                @Override
                public boolean isOverrideArgs() {
                    return false;
                }
            }
        };
    }
​
    @Override
    protected ClassMatch enhanceClass() {
        return byName("org.springframework.web.reactive.DispatcherHandler");
    }
}
  • DispatcherHandlerInstrumentation继承了ClassInstanceMethodsEnhancePluginDefine,其使用org.apache.skywalking.apm.plugin.spring.webflux.v5.DispatcherHandlerHandleMethodInterceptor增强org.springframework.web.reactive.DispatcherHandler的handle方法

DispatcherHandlerHandleMethodInterceptor

skywalking-6.6.0/apm-sniffer/optional-plugins/optional-spring-plugins/spring-webflux-5.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/spring/webflux/v5/DispatcherHandlerHandleMethodInterceptor.java

public class DispatcherHandlerHandleMethodInterceptor implements InstanceMethodsAroundInterceptor {
    private static final String DEFAULT_OPERATION_NAME = "WEBFLUX.handle";
​
    @Override
    public void beforeMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class<?>[] argumentsTypes,
                             MethodInterceptResult result) throws Throwable {
​
    }
​
    @Override
    public Object afterMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class<?>[] argumentsTypes,
                              Object ret) throws Throwable {
        EnhancedInstance instance = getInstance(allArguments[0]);
​
        ServerWebExchange exchange = (ServerWebExchange) allArguments[0];
​
        ContextCarrier carrier = new ContextCarrier();
        CarrierItem next = carrier.items();
        HttpHeaders headers = exchange.getRequest().getHeaders();
        while (next.hasNext()) {
            next = next.next();
            List<String> header = headers.get(next.getHeadKey());
            if (header != null && header.size() > 0) {
                next.setHeadValue(header.get(0));
            }
        }
​
        AbstractSpan span = ContextManager.createEntrySpan(DEFAULT_OPERATION_NAME, carrier);
        span.setComponent(ComponentsDefine.SPRING_WEBFLUX);
        SpanLayer.asHttp(span);
        Tags.URL.set(span, exchange.getRequest().getURI().toString());
        HTTP.METHOD.set(span, exchange.getRequest().getMethodValue());
        instance.setSkyWalkingDynamicField(ContextManager.capture());
        span.prepareForAsync();
        ContextManager.stopSpan(span);
​
        return ((Mono) ret).doFinally(s -> {
            try {
                Object pathPattern = exchange.getAttribute(HandlerMapping.BEST_MATCHING_PATTERN_ATTRIBUTE);
                if (pathPattern != null) {
                    span.setOperationName(((PathPattern) pathPattern).getPatternString());
                }
                HttpStatus httpStatus = exchange.getResponse().getStatusCode();
                // fix webflux-2.0.0-2.1.0 version have bug. httpStatus is null. not support
                if (httpStatus != null) {
                    Tags.STATUS_CODE.set(span, Integer.toString(httpStatus.value()));
                    if (httpStatus.isError()) {
                        span.errorOccurred();
                    }
                }
            } finally {
                span.asyncFinish();
            }
        });
​
    }
​
    @Override
    public void handleMethodException(EnhancedInstance objInst, Method method, Object[] allArguments,
                                      Class<?>[] argumentsTypes, Throwable t) {
    }
​
    public static EnhancedInstance getInstance(Object o) {
        EnhancedInstance instance = null;
        if (o instanceof DefaultServerWebExchange) {
            instance = (EnhancedInstance) o;
        } else if (o instanceof ServerWebExchangeDecorator) {
            ServerWebExchange delegate = ((ServerWebExchangeDecorator) o).getDelegate();
            return getInstance(delegate);
        }
        return instance;
    }
​
}
  • DispatcherHandlerHandleMethodInterceptor实现了InstanceMethodsAroundInterceptor接口,其afterMethod方法创建AbstractSpan,设置URL及METHOD的tag,执行span.prepareForAsync(),然后注册Mono的doFinally的Consumer,在里头设置span的operationName,statusCode,以及是否有异常,最后执行span.asyncFinish()

ServerWebExchangeInstrumentation

skywalking-6.6.0/apm-sniffer/optional-plugins/optional-spring-plugins/spring-webflux-5.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/spring/webflux/v5/define/ServerWebExchangeInstrumentation.java

public class ServerWebExchangeInstrumentation extends ClassInstanceMethodsEnhancePluginDefine {
    @Override
    public ConstructorInterceptPoint[] getConstructorsInterceptPoints() {
        return new ConstructorInterceptPoint[]{
            new ConstructorInterceptPoint() {
                @Override
                public ElementMatcher<MethodDescription> getConstructorMatcher() {
                    return any();
                }
​
                @Override
                public String getConstructorInterceptor() {
                    return "org.apache.skywalking.apm.plugin.spring.webflux.v5.ServerWebExchangeConstructorInterceptor";
                }
            }
        };
    }
​
    @Override
    public InstanceMethodsInterceptPoint[] getInstanceMethodsInterceptPoints() {
        return new InstanceMethodsInterceptPoint[0];
    }
​
    @Override
    protected ClassMatch enhanceClass() {
        return byName("org.springframework.web.server.adapter.DefaultServerWebExchange");
    }
}
  • ServerWebExchangeInstrumentation继承了ClassInstanceMethodsEnhancePluginDefine,其使用org.apache.skywalking.apm.plugin.spring.webflux.v5.ServerWebExchangeConstructorInterceptor增强org.springframework.web.server.adapter.DefaultServerWebExchange的所有方法

ServerWebExchangeConstructorInterceptor

skywalking-6.6.0/apm-sniffer/optional-plugins/optional-spring-plugins/spring-webflux-5.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/spring/webflux/v5/ServerWebExchangeConstructorInterceptor.java

public class ServerWebExchangeConstructorInterceptor implements InstanceConstructorInterceptor {
    @Override
    public void onConstruct(EnhancedInstance objInst, Object[] allArguments) {
    }
}
  • ServerWebExchangeConstructorInterceptor目前还是空实现

小结

DispatcherHandlerInstrumentation继承了ClassInstanceMethodsEnhancePluginDefine,其使用org.apache.skywalking.apm.plugin.spring.webflux.v5.DispatcherHandlerHandleMethodInterceptor增强org.springframework.web.reactive.DispatcherHandler的handle方法;ServerWebExchangeInstrumentation继承了ClassInstanceMethodsEnhancePluginDefine,其使用org.apache.skywalking.apm.plugin.spring.webflux.v5.ServerWebExchangeConstructorInterceptor增强org.springframework.web.server.adapter.DefaultServerWebExchange的所有方法

doc

原创声明,本文系作者授权云+社区发表,未经许可,不得转载。

如有侵权,请联系 yunjia_community@tencent.com 删除。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 聊聊skywalking的spring-webflux-plugin

    skywalking-6.6.0/apm-sniffer/optional-plugins/optional-spring-plugins/spring-web...

    codecraft
  • 聊聊skywalking的spring-annotation-plugin

    本文主要研究一下skywalking的spring-annotation-plugin

    codecraft
  • 聊聊spring cloud gateway的RedirectToGatewayFilter

    本文主要研究下spring cloud gateway的RedirectToGatewayFilter

    codecraft
  • 完美立方

    形如a^3= b^3 + c^3 + d^3的等式被称为完美立方等式。例如 12^3= 6^3 + 8^3 + 10^3 。编写一个程序,对任给的正整数N (N...

    AI那点小事
  • 利用NAS寻找最佳GAN:AutoGAN架构搜索方案专为GAN打造

    自从生成对抗网络(GAN)在 NIPS 2014 大会上首次发表以来,它就一直是深度学习领域的热门话题。

    机器之心
  • Spring Boot 集成 Druid 监控数据源

    Druid 是阿里巴巴开源平台上的一个项目,整个项目由数据库连接池、插件框架和 SQL 解析器组成,该项目主要是为了扩展 JDBC 的一些限制,可以让程序员实现...

    Java后端技术全栈
  • R语言 常见函数知识点梳理与解析 | 精选分析

    R语言 控制流:for、while、ifelse和自定义函数function|第5讲

    1480
  • 【深度相机系列四】深度相机原理揭秘--结构光(iPhone X 齐刘海原理)

    导读 结构光法:为解决双目匹配问题而生 深度图效果:结构光vs.双目 投射图案的编码方式     直接编码     时分复用编码     空分复用...

    用户1150922
  • 深度相机原理揭秘--结构光(iPhone X 齐刘海原理)

    ------------------------------------------------------------------

    小白学视觉
  • 区块链技术开发公司谈什么是去中心化交易所

      去中心化交易所这个词自BM创建了bitshares以来,就越来越受到大众的关注。从用户的角度出发,去中心化交易所要提高自己的用户体验,降低使用门槛,使用上应...

    YY谈网络那些事

扫码关注云+社区

领取腾讯云代金券