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

tech.mhuang.pacebox.springboot.autoconfiguration.trace.rest.TraceRestTemplateInterceptor Maven / Gradle / Ivy

The newest version!
package tech.mhuang.pacebox.springboot.autoconfiguration.trace.rest;

import io.micrometer.tracing.Span;
import io.micrometer.tracing.Tracer;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpRequest;
import org.springframework.http.client.ClientHttpRequestExecution;
import org.springframework.http.client.ClientHttpRequestInterceptor;
import org.springframework.http.client.ClientHttpResponse;
import tech.mhuang.pacebox.springboot.core.jackson.JsonUtil;

import java.io.IOException;
import java.util.Collections;
import java.util.List;
import java.util.regex.Pattern;

/**
 * restTemplate埋点
 *
 * @author mhuang
 * @since 1.0.0
 */
@Slf4j
public class TraceRestTemplateInterceptor implements ClientHttpRequestInterceptor {

    private final Tracer tracer;
    private final Pattern skipPattern;
    private final List spanDecorators;

    public TraceRestTemplateInterceptor(Tracer tracer, Pattern skipPattern) {
        this.tracer = tracer;
        this.skipPattern = skipPattern;
        this.spanDecorators = Collections.singletonList(new TraceRestTemplateSpanDecorator());
    }

    protected boolean isTraced(HttpRequest httpRequest) {
        // skip URLs matching skip pattern
        // e.g. pattern is defined as '/health|/status' then URL 'http://localhost:5000/context/health' won't be traced
        if (skipPattern != null) {
            String url = httpRequest.getURI().toString();
            return skipPattern.matcher(url).matches();
        }

        return false;
    }

    @Override
    public ClientHttpResponse intercept(HttpRequest httpRequest, byte[] body,
                                        ClientHttpRequestExecution execution) throws IOException {
        if (isTraced(httpRequest)) {
            return execution.execute(httpRequest, body);
        }
        ClientHttpResponse httpResponse;

        Span span = tracer.nextSpan().name("restTemplate");
        span.tag("request.body", new String(body));
        span.tag("request.param", httpRequest.getURI().getQuery() == null ?
                ""
                :
                httpRequest.getURI().getQuery());
        span.tag("request.header", JsonUtil.toString(httpRequest.getHeaders()));

        for (TraceRestTemplateSpanDecorator spanDecorator : spanDecorators) {
            try {
                spanDecorator.onRequest(httpRequest, span);
            } catch (RuntimeException exDecorator) {
                log.error("Exception during decorating span", exDecorator);
            }
        }

        try (Tracer.SpanInScope ws = this.tracer.withSpan(span.start())) {
            httpResponse = execution.execute(httpRequest, body);
            for (TraceRestTemplateSpanDecorator spanDecorator : spanDecorators) {
                try {
                    spanDecorator.onResponse(httpResponse, span);
                    span.event("restTemplateEnd");
                } catch (RuntimeException exDecorator) {
                    log.error("Exception during decorating span", exDecorator);
                }
            }
        } catch (Exception ex) {
            for (TraceRestTemplateSpanDecorator spanDecorator : spanDecorators) {
                try {
                    spanDecorator.onError(httpRequest, ex, span);
                } catch (RuntimeException exDecorator) {
                    log.error("Exception during decorating span", exDecorator);
                }
            }
            throw ex;
        } finally {
            span.end();
        }

        return httpResponse;
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy