org.springframework.cloud.sleuth.instrument.web.ExtraSleuthHttpClientParser Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of extra-sleuth-tracing-configuration Show documentation
Show all versions of extra-sleuth-tracing-configuration Show documentation
extra-sleuth-tracing-configuration
The newest version!
package org.springframework.cloud.sleuth.instrument.web;
import brave.SpanCustomizer;
import brave.http.HttpAdapter;
import brave.http.HttpClientParser;
import cn.patterncat.tracing.ExtraTracingProperties;
import cn.patterncat.tracing.helper.MaskHelper;
import org.springframework.cloud.sleuth.util.SpanNameUtil;
import java.net.URI;
import java.util.function.Supplier;
/**
* SleuthHttpClientParser
* Created by cat on 2019-01-23.
*/
public class ExtraSleuthHttpClientParser extends HttpClientParser {
private static final String HOST_KEY = "http.host";
private static final String METHOD_KEY = "http.method";
private static final String PATH_KEY = "http.path";
private static final String URL_KEY = "http.url";
private static final String STATUS_CODE_KEY = "http.status";
private static final String NO_RESPONSE_STATUS = "-1";
private final TraceKeys traceKeys;
private final ExtraTracingProperties properties;
ExtraSleuthHttpClientParser(TraceKeys traceKeys, ExtraTracingProperties properties) {
this.traceKeys = traceKeys;
this.properties = properties;
}
@Override
protected String spanName(HttpAdapter adapter, Req req) {
return getName(URI.create(adapter.url(req)));
}
@Override
public void request(HttpAdapter adapter, Req req,
SpanCustomizer customizer) {
super.request(adapter, req, customizer);
String url = adapter.url(req);
URI uri = URI.create(url);
addRequestTags(customizer, url, uri,
adapter.method(req));
this.traceKeys.getHttp().getHeaders().forEach(((s) -> {
String headerValue = adapter.requestHeader(req, s);
if (headerValue != null) {
customizer.tag(key(s), headerValue);
}
}));
}
private String key(String key) {
return this.traceKeys.getHttp().getPrefix() + key.toLowerCase();
}
private String getName(URI uri) {
// The returned name should comply with RFC 882 - Section 3.1.2.
// i.e Header values must composed of printable ASCII values.
return SpanNameUtil.shorten(uriScheme(uri) + ":" + uri.getRawPath());
}
private String uriScheme(URI uri) {
return uri.getScheme() == null ? "http" : uri.getScheme();
}
private void addRequestTags(SpanCustomizer customizer,String url, URI uri, String method) {
String path = uri.getPath();
//NOTE url可能包含需要mask的queryString,但是url包含了host:port,单纯host缺少port信息
String maskedUrl = properties.mask(url, new Supplier() {
@Override
public String get() {
return path;
}
});
customizer.tag(URL_KEY, maskedUrl);
String host = uri.getHost();
if (host != null) {
customizer.tag(HOST_KEY, host);
}
customizer.tag(PATH_KEY, path);
customizer.tag(METHOD_KEY, method);
}
@Override
public void response(HttpAdapter, Resp> adapter, Resp res, Throwable error, SpanCustomizer customizer) {
Integer statusCode = null;
if (res != null) {
statusCode = adapter.statusCode(res);
String nameFromRoute = spanNameFromRoute(adapter, res, statusCode);
if (nameFromRoute != null) customizer.name(nameFromRoute);
customizer.tag(STATUS_CODE_KEY, statusCode == null ? NO_RESPONSE_STATUS : String.valueOf(statusCode));
} else {
customizer.tag(STATUS_CODE_KEY, NO_RESPONSE_STATUS);
}
error(statusCode, error, customizer);
}
static String spanNameFromRoute(HttpAdapter, Resp> adapter, Resp res, int statusCode) {
String method = adapter.methodFromResponse(res);
if (method == null) return null; // don't undo a valid name elsewhere
String route = adapter.route(res);
if (route == null) return null; // don't undo a valid name elsewhere
if (!"".equals(route)) return method + " " + route;
if (statusCode / 100 == 3) return method + " redirected";
if (statusCode == 404) return method + " not_found";
return null; // unexpected
}
}