All Downloads are FREE. Search and download functionalities are using the official Maven repository.

cn.patterncat.tracing.component.resttemplate.ExtraTracingClientHttpRequestInterceptor Maven / Gradle / Ivy

The newest version!
package cn.patterncat.tracing.component.resttemplate;

import brave.Span;
import brave.Tracer;
import brave.http.HttpClientHandler;
import brave.http.HttpTracing;
import brave.propagation.Propagation;
import brave.propagation.TraceContext;
import cn.patterncat.tracing.ExtraTracingProperties;
import cn.patterncat.tracing.helper.HttpBodyTraceHelper;
import cn.patterncat.tracing.helper.MaskHelper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpRequest;
import org.springframework.http.MediaType;
import org.springframework.http.client.AbstractClientHttpRequest;
import org.springframework.http.client.ClientHttpRequestExecution;
import org.springframework.http.client.ClientHttpRequestInterceptor;
import org.springframework.http.client.ClientHttpResponse;
import org.springframework.util.StringUtils;

import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.Objects;
import java.util.function.Supplier;

/**
 * //NOTE 这个filter到底有无执行多次?
 * brave-instrumentation-spring-web-5.1.0-sources.jar!/brave/spring/web/TracingClientHttpRequestInterceptor.java
 * Created by cat on 2018-12-04.
 */
public class ExtraTracingClientHttpRequestInterceptor implements ClientHttpRequestInterceptor {

    private static final Logger LOGGER = LoggerFactory.getLogger(ExtraTracingClientHttpRequestInterceptor.class);

    static final Propagation.Setter SETTER = new Propagation.Setter() {
        @Override public void put(HttpHeaders carrier, String key, String value) {
            carrier.set(key, value);
        }

        @Override public String toString() {
            return "HttpHeaders::set";
        }
    };

//    public static ClientHttpRequestInterceptor create(Tracing tracing) {
//        return create(HttpTracing.create(tracing));
//    }

    public static ClientHttpRequestInterceptor create(HttpTracing httpTracing,ExtraTracingProperties properties) {
        return new ExtraTracingClientHttpRequestInterceptor(httpTracing,properties);
    }

    final Tracer tracer;
    final HttpClientHandler handler;
    final TraceContext.Injector injector;
    final ExtraTracingProperties properties;

    @Autowired
    ExtraTracingClientHttpRequestInterceptor(HttpTracing httpTracing,ExtraTracingProperties properties) {
        this.tracer = httpTracing.tracing().tracer();
        this.handler = HttpClientHandler.create(httpTracing, new ExtraTracingClientHttpRequestInterceptor.HttpAdapter());
        this.injector = httpTracing.tracing().propagation().injector(SETTER);
        this.properties = properties;
    }

    @Override public ClientHttpResponse intercept(HttpRequest request, byte[] body,
                                                  ClientHttpRequestExecution execution) throws IOException {
        Span span = handler.handleSend(injector, request.getHeaders(), request);
        ClientHttpResponse response = null;
        Throwable error = null;

        //NOTE trace request body here
        if(properties.isTraceRestTemplateRequestBody()){
            try {
                if (request instanceof AbstractClientHttpRequest) {
                    HttpHeaders headers = ((AbstractClientHttpRequest) request).getHeaders();
                    headers.getContentType();
                    if(HttpBodyTraceHelper.isContentTypePrintable(properties.getPrintableMediaSubTypes(),headers.getContentType())){
                        String requestBody = new String(body,StandardCharsets.UTF_8);
                        //NOTE 这里要替换敏感的查询字段
                        String maskedRequestBody = maskIfNeeded(request,Objects.toString(requestBody,""));
                        span.tag(properties.getHttpRequestBodyTag(),maskedRequestBody);
                    }

                    String query = ((AbstractClientHttpRequest) request).getURI().getQuery();
                    //NOTE 这里要替换掉敏感的查询字段
                    String maskedQuery = maskIfNeeded(request,Objects.toString(query,""));
                    span.tag(properties.getHttpRequestQueryTag(),maskedQuery);
                }
            } catch (Exception e) {
                LOGGER.error(e.getMessage(), e);
            }
        }

        //NOTE trace

        try (Tracer.SpanInScope ws = tracer.withSpanInScope(span)) {
            return response = execution.execute(request, body);
        } catch (IOException | RuntimeException | Error e) {
            error = e;
            throw e;
        } finally {
            handler.handleReceive(response, error, span);
        }
    }

    protected String maskIfNeeded(HttpRequest request,String query){
        return properties.mask(query, new Supplier() {
            @Override
            public String get() {
                return request.getURI().getPath();
            }
        });
    }

    static final class HttpAdapter
            extends brave.http.HttpClientAdapter {

        @Override public String method(HttpRequest request) {
            return request.getMethod().name();
        }

        @Override public String url(HttpRequest request) {
            return request.getURI().toString();
        }

        @Override public String requestHeader(HttpRequest request, String name) {
            Object result = request.getHeaders().getFirst(name);
            return result != null ? result.toString() : "";
        }

        @Override public Integer statusCode(ClientHttpResponse response) {
            if(response == null){
                return null;
            }
            try {
                return response.getRawStatusCode();
            } catch (IOException e) {
                return null;
            }
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy