sequence

This article focuses on the HttpClient-plugin for Skywalking

skywalking-plugin.def

Skywalking 6.6.0 / apm – sniffers/apm – SDK – the plugin/httpClient – 4 x – the plugin/SRC/main/resources/skywalking – plugin. Def

httpclient-4.x=org.apache.skywalking.apm.plugin.httpClient.v4.define.AbstractHttpClientInstrumentation
httpclient-4.x=org.apache.skywalking.apm.plugin.httpClient.v4.define.InternalHttpClientInstrumentation
httpclient-4.x=org.apache.skywalking.apm.plugin.httpClient.v4.define.MinimalHttpClientInstrumentation
httpclient-4.x=org.apache.skywalking.apm.plugin.httpClient.v4.define.DefaultRequestDirectorInstrumentation
Copy the code
  • The httpClient-4.x-plugin defines four enhancements, AbstractHttpClientInstrumentation, InternalHttpClientInstrumentation, MinimalHttpClientInstrumentation, DefaultRequestDi RectorInstrumentation; They all inherited HttpClientInstrumentation

HttpClientInstrumentation

Skywalking 6.6.0 / apm – sniffers/apm – SDK – the plugin/httpClient – 4 x – the plugin/SRC/main/Java/org/apache/skywalking/apm/plugins/httpCli ent/v4/define/HttpClientInstrumentation.java

public abstract class HttpClientInstrumentation extends ClassInstanceMethodsEnhancePluginDefine {

    private static final String INTERCEPT_CLASS = "org.apache.skywalking.apm.plugin.httpClient.v4.HttpClientExecuteInterceptor";

    @Override
    public ConstructorInterceptPoint[] getConstructorsInterceptPoints() {
        return null;
    }

    protected String getInstanceMethodsInterceptor() {
        returnINTERCEPT_CLASS; }}Copy the code
  • HttpClientInstrumentation inherited ClassInstanceMethodsEnhancePluginDefine, The use of the interceptor is org. Apache. Skywalking. Apm. Plugin. HttpClient. V4. HttpClientExecuteInterceptor

AbstractHttpClientInstrumentation

Skywalking 6.6.0 / apm – sniffers/apm – SDK – the plugin/httpClient – 4 x – the plugin/SRC/main/Java/org/apache/skywalking/apm/plugins/httpCli ent/v4/define/AbstractHttpClientInstrumentation.java

public class AbstractHttpClientInstrumentation extends HttpClientInstrumentation {

    private static final String ENHANCE_CLASS = "org.apache.http.impl.client.AbstractHttpClient";

    @Override
    public ClassMatch enhanceClass() {
        return byName(ENHANCE_CLASS);
    }

    /**
     * version 4.2, intercept method: execute, intercept
     * public final HttpResponse execute(HttpHost target, HttpRequest request, HttpContext context)
     */
    @Override
    public InstanceMethodsInterceptPoint[] getInstanceMethodsInterceptPoints() {
        return new InstanceMethodsInterceptPoint[] {
            new InstanceMethodsInterceptPoint() {
                @Override
                public ElementMatcher<MethodDescription> getMethodsMatcher() {
                    return named("doExecute");
                }

                @Override
                public String getMethodsInterceptor() {
                    return getInstanceMethodsInterceptor();
                }

                @Override
                public boolean isOverrideArgs() {
                    return false; }}}; }}Copy the code
  • AbstractHttpClientInstrumentation inherited HttpClientInstrumentation, Its enhanced is org. Apache. HTTP. Impl. Client. DefaultRequestDirector the doExecute method

InternalHttpClientInstrumentation

Skywalking 6.6.0 / apm – sniffers/apm – SDK – the plugin/httpClient – 4 x – the plugin/SRC/main/Java/org/apache/skywalking/apm/plugins/httpCli ent/v4/define/InternalHttpClientInstrumentation.java

public class InternalHttpClientInstrumentation extends HttpClientInstrumentation {

    private static final String ENHANCE_CLASS = "org.apache.http.impl.client.InternalHttpClient";

    @Override
    public ClassMatch enhanceClass() {
        return NameMatch.byName(ENHANCE_CLASS);
    }

    @Override
    public InstanceMethodsInterceptPoint[] getInstanceMethodsInterceptPoints() {
        return new InstanceMethodsInterceptPoint[] {
            new InstanceMethodsInterceptPoint() {
                @Override
                public ElementMatcher<MethodDescription> getMethodsMatcher() {
                    return named("doExecute");
                }

                @Override
                public String getMethodsInterceptor() {
                    return getInstanceMethodsInterceptor();
                }

                @Override
                public boolean isOverrideArgs() {
                    return false; }}}; }}Copy the code
  • InternalHttpClientInstrumentation inherited HttpClientInstrumentation, Its enhanced is org. Apache. HTTP. Impl. Client. InternalHttpClient the doExecute method

MinimalHttpClientInstrumentation

Skywalking 6.6.0 / apm – sniffers/apm – SDK – the plugin/httpClient – 4 x – the plugin/SRC/main/Java/org/apache/skywalking/apm/plugins/httpCli ent/v4/define/MinimalHttpClientInstrumentation.java

public class MinimalHttpClientInstrumentation extends HttpClientInstrumentation {

    private static final String ENHANCE_CLASS = "org.apache.http.impl.client.MinimalHttpClient";

    @Override
    public ClassMatch enhanceClass() {
        return NameMatch.byName(ENHANCE_CLASS);
    }

    @Override
    public InstanceMethodsInterceptPoint[] getInstanceMethodsInterceptPoints() {
        return new InstanceMethodsInterceptPoint[] {
            new InstanceMethodsInterceptPoint() {
                @Override
                public ElementMatcher<MethodDescription> getMethodsMatcher() {
                    return named("doExecute");
                }

                @Override
                public String getMethodsInterceptor() {
                    return getInstanceMethodsInterceptor();
                }

                @Override
                public boolean isOverrideArgs() {
                    return false; }}}; }}Copy the code
  • MinimalHttpClientInstrumentation inherited HttpClientInstrumentation, Its enhanced is org. Apache. HTTP. Impl. Client. MinimalHttpClient the doExecute method

DefaultRequestDirectorInstrumentation

Skywalking 6.6.0 / apm – sniffers/apm – SDK – the plugin/httpClient – 4 x – the plugin/SRC/main/Java/org/apache/skywalking/apm/plugins/httpCli ent/v4/define/DefaultRequestDirectorInstrumentation.java

public class DefaultRequestDirectorInstrumentation extends HttpClientInstrumentation {

    /**
     * Enhance class.
     */
    private static final String ENHANCE_CLASS = "org.apache.http.impl.client.DefaultRequestDirector";

    /**
     * DefaultRequestDirector is default implement.
     * usually use inVersion 4.0-4.2 * since 4.3, this class is Deprecated. */ @override public ClassMatchenhanceClass() {
        return NameMatch.byName(ENHANCE_CLASS);
    }

    @Override
    public InstanceMethodsInterceptPoint[] getInstanceMethodsInterceptPoints() {
        return new InstanceMethodsInterceptPoint[] {
            new InstanceMethodsInterceptPoint() {
                @Override
                public ElementMatcher<MethodDescription> getMethodsMatcher() {
                    return named("execute");
                }

                @Override
                public String getMethodsInterceptor() {
                    return getInstanceMethodsInterceptor();
                }

                @Override
                public boolean isOverrideArgs() {
                    return false; }}}; }}Copy the code
  • DefaultRequestDirectorInstrumentation inherited HttpClientInstrumentation, The enhanced is org. Apache. HTTP. Impl. Client. DefaultRequestDirector the execute method

HttpClientExecuteInterceptor

Skywalking 6.6.0 / apm – sniffers/apm – SDK – the plugin/httpClient – 4 x – the plugin/SRC/main/Java/org/apache/skywalking/apm/plugins/httpCli ent/v4/HttpClientExecuteInterceptor.java

public class HttpClientExecuteInterceptor implements InstanceMethodsAroundInterceptor { @Override public void beforeMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class<? >[] argumentsTypes, MethodInterceptResult result) throws Throwable {if (allArguments[0] == null || allArguments[1] == null) {
            // illegal args, can't trace. ignore. return; } final HttpHost httpHost = (HttpHost)allArguments[0]; HttpRequest httpRequest = (HttpRequest)allArguments[1]; final ContextCarrier contextCarrier = new ContextCarrier(); String remotePeer = httpHost.getHostName() + ":" + port(httpHost); String uri = httpRequest.getRequestLine().getUri(); String requestURI = getRequestURI(uri); String operationName = requestURI; AbstractSpan span = ContextManager.createExitSpan(operationName, contextCarrier, remotePeer); span.setComponent(ComponentsDefine.HTTPCLIENT); Tags.URL.set(span, buildSpanValue(httpHost,uri)); Tags.HTTP.METHOD.set(span, httpRequest.getRequestLine().getMethod()); SpanLayer.asHttp(span); CarrierItem next = contextCarrier.items(); while (next.hasNext()) { next = next.next(); httpRequest.setHeader(next.getHeadKey(), next.getHeadValue()); } } @Override public Object afterMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class
      [] argumentsTypes, Object ret) throws Throwable { if (allArguments[0] == null || allArguments[1] == null) { return ret;  } if (ret ! = null) { HttpResponse response = (HttpResponse)ret; StatusLine responseStatusLine = response.getStatusLine(); if (responseStatusLine ! = null) { int statusCode = responseStatusLine.getStatusCode(); AbstractSpan span = ContextManager.activeSpan(); if (statusCode >= 400) { span.errorOccurred(); Tags.STATUS_CODE.set(span, Integer.toString(statusCode)); } } } ContextManager.stopSpan(); return ret; } @Override public void handleMethodException(EnhancedInstance objInst, Method method, Object[] allArguments, Class
      [] argumentsTypes, Throwable t) { AbstractSpan activeSpan = ContextManager.activeSpan(); activeSpan.errorOccurred(); activeSpan.log(t); } private String getRequestURI(String uri) throws MalformedURLException { if (isUrl(uri)) { String requestPath = new URL(uri).getPath(); return requestPath ! = null && requestPath.length() > 0 ? requestPath : "/"; } else { return uri; } } private boolean isUrl(String uri) { String lowerUrl = uri.toLowerCase(); return lowerUrl.startsWith("http") || lowerUrl.startsWith("https"); } private String buildSpanValue(HttpHost httpHost, String uri) { if (isUrl(uri)) { return uri; } else { StringBuilder buff = new StringBuilder(); buff.append(httpHost.getSchemeName().toLowerCase()); buff.append("://"); buff.append(httpHost.getHostName()); buff.append(":"); buff.append(port(httpHost)); buff.append(uri); return buff.toString(); } } private int port(HttpHost httpHost) { int port = httpHost.getPort(); return port > 0 ? port : "https".equals(httpHost.getSchemeName().toLowerCase()) ? 443-80; }}Copy the code
  • HttpClientExecuteInterceptor InstanceMethodsAroundInterceptor interface is achieved, BeforeMethod constructs requestURI, operationName and other information according to httpHost and httpRequest parameters and passes contextCarrier.items() via httpRequest’s header. Contextmanager.stopspan (); contextManager.stopspan (); contextManager.stopspan (); contextManager.stopspan (); The handleMethodException method mainly executes activespan.ErrorOccurred () and Activespan.log (t).

summary

The httpClient-4.x-plugin defines four enhancements, AbstractHttpClientInstrumentation, InternalHttpClientInstrumentation, MinimalHttpClientInstrumentation, DefaultRequestDi RectorInstrumentation; They all inherited HttpClientInstrumentation; Using HttpClientExecuteInterceptor to enhance org. Apache. HTTP. Impl. Client. The method of the doExecute DefaultRequestDirector, org. Apache. HTTP. Impl. Cli Ent. The method of the doExecute InternalHttpClient, org. Apache. HTTP. Impl. Client. The method of the doExecute MinimalHttpClient, org. Apache. HTTP. Impl. Client Execute method of DefaultRequestDirector

doc

  • skywalking-plugin