@Override public <Req> Boolean trySample(HttpAdapter<Req, ?> adapter, Req request) { String method = adapter.method(request); String path = adapter.path(request); if (method == null || path == null) return null; // use default if we couldn't parse return sampler.sample(new MethodAndPath(method, path)).sampled(); }
@Override public <Req> void request(HttpAdapter<Req, ?> adapter, Req req, SpanCustomizer customizer) { customizer.name(adapter.method(req).toLowerCase() + " " + adapter.path(req)); customizer.tag("http.url", adapter.url(req)); // just the path is logged by default customizer.tag("context.visible", String.valueOf(currentTraceContext.get() != null)); customizer.tag("request_customizer.is_span", (customizer instanceof brave.Span) + ""); }
static <Resp> 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 }
@Override public <Req> void request(HttpAdapter<Req, ?> adapter, Req req, SpanCustomizer customizer) { super.request(adapter, req, customizer); String url = adapter.url(req); URI uri = URI.create(url); addRequestTags(customizer, url, uri.getHost(), uri.getPath(), adapter.method(req)); this.traceKeys.getHttp().getHeaders().forEach(((s) -> { String headerValue = adapter.requestHeader(req, s); if (headerValue != null) { customizer.tag(key(s), headerValue); } })); }
/** * The absolute http path, without any query parameters or null if unreadable. Ex. * "/objects/abcd-ff" * * <p>Conventionally associated with the key "http.path" * @see #route(Object) */ @Nullable public String path(Req request) { String url = url(request); if (url == null) return null; return URI.create(url).getPath(); // TODO benchmark }
@Override public <Req> Boolean trySample(HttpAdapter<Req, ?> adapter, Req request) { String url = adapter.path(request); boolean shouldSkip = this.pattern.matcher(url).matches(); if (shouldSkip) { return false; } return null; }
/** Returns the span name of the request. Defaults to the http method. */ protected <Req> String spanName(HttpAdapter<Req, ?> adapter, Req req) { return adapter.method(req); }
@Override public <Resp> void response(HttpAdapter<?, Resp> adapter, Resp res, Throwable error, SpanCustomizer customizer) { int statusCode = 0; if (res != null) { String route = adapter.route(res); if (route != null) { customizer.tag("http.route", route); } // Always send status code to Stackdriver statusCode = adapter.statusCodeAsInt(res); customizer.tag("http.status_code", String.valueOf(statusCode)); } error(statusCode, error, customizer); } }
/** * Like {@link #statusCode(Object)} except returns a primitive where zero implies absent. * * <p>Using this method usually avoids allocation, so is encouraged when parsing data. */ public int statusCodeAsInt(Resp response) { Integer maybeStatus = statusCode(response); return maybeStatus != null ? maybeStatus : 0; }
int statusCode = 0; if (res != null) { statusCode = adapter.statusCodeAsInt(res); String nameFromRoute = spanNameFromRoute(adapter, res, statusCode); if (nameFromRoute != null) customizer.name(nameFromRoute);
@Override public <Req> void request(HttpAdapter<Req, ?> adapter, Req req, SpanCustomizer customizer) { super.request(adapter, req, customizer); String url = adapter.url(req); URI uri = URI.create(url); addRequestTags(customizer, url, uri.getHost(), uri.getPath(), adapter.method(req)); this.traceKeys.getHttp().getHeaders().forEach(((s) -> { String headerValue = adapter.requestHeader(req, s); if (headerValue != null) { customizer.tag(key(s), headerValue); } })); }
@Override protected <Req> String spanName(HttpAdapter<Req, ?> adapter, Req req) { return getName(URI.create(adapter.url(req))); }
@Override public <Req> Boolean trySample(HttpAdapter<Req, ?> adapter, Req request) { String path = adapter.path(request); if (path == null) { return null; } return path.matches(this.properties.getClient().getSkipPattern()) ? false : null; }
@Override public <Resp> void response(HttpAdapter<?, Resp> adapter, Resp res, Throwable error, SpanCustomizer customizer) { if (res == null) { error(null, error, customizer); return; } Integer httpStatus = adapter.statusCode(res); if (httpStatus == null) { error(httpStatus, error, customizer); return; } if (httpStatus == HttpServletResponse.SC_OK && error != null) { // Filter chain threw exception but the response status may not have been set // yet, so we have to guess. customizer.tag(STATUS_CODE_KEY, String.valueOf(HttpServletResponse.SC_INTERNAL_SERVER_ERROR)); } // only tag valid http statuses else if (httpStatus >= 100 && (httpStatus < 200) || (httpStatus > 399)) { customizer.tag(STATUS_CODE_KEY, String.valueOf(httpStatus)); } error(httpStatus, error, customizer); }
/** * Override to change what data from the http request are parsed into the span representing it. By * default, this sets the span name to the http method and tags "http.method" and "http.path". * * <p>If you only want to change the span name, you can override {@link #spanName(HttpAdapter, * Object)} instead. * * @see #spanName(HttpAdapter, Object) */ // Eventhough the default span name is the method, we have no way of knowing that a user hasn't // overwritten the name to something else. If that occurs during response parsing, it is too late // to go back and get the http method. Adding http method by default ensures span naming doesn't // prevent basic HTTP info from being visible. A cost of this is another tag, but it is small with // very limited cardinality. Moreover, users who care strictly about size can override this. public <Req> void request(HttpAdapter<Req, ?> adapter, Req req, SpanCustomizer customizer) { customizer.name(spanName(adapter, req)); String method = adapter.method(req); if (method != null) customizer.tag("http.method", method); String path = adapter.path(req); if (path != null) customizer.tag("http.path", path); }
@Override public <Req> void request(HttpAdapter<Req, ?> adapter, Req req, SpanCustomizer customizer) { customizer.name(adapter.method(req).toLowerCase() + " " + adapter.path(req)); customizer.tag("http.url", adapter.url(req)); // just the path is logged by default customizer.tag("context.visible", String.valueOf(currentTraceContext.get() != null)); customizer.tag("request_customizer.is_span", (customizer instanceof brave.Span) + ""); }
@Override public <Req> void request(HttpAdapter<Req, ?> adapter, Req req, SpanCustomizer customizer) { super.request(adapter, req, customizer); String url = adapter.url(req); URI uri = URI.create(url); customizer.tag("http.url", url); if (uri.getHost() != null) { customizer.tag("http.host", uri.getHost()); } customizer.tag("http.path", uri.getPath()); customizer.tag("http.method", adapter.method(req)); }
@Override public <Req> void request(HttpAdapter<Req, ?> adapter, Req req, SpanCustomizer customizer) { super.request(adapter, req, customizer); customizer.tag("http.url", adapter.url(req)); // just the path is logged by default } };