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

brave.http.HttpParser Maven / Gradle / Ivy

There is a newer version: 6.1.0
Show newest version
package brave.http;

import brave.ErrorParser;
import brave.SpanCustomizer;
import brave.Tracing;
import brave.internal.Nullable;

public class HttpParser {
  static final ErrorParser DEFAULT_ERROR_PARSER = new ErrorParser();

  /**
   * Override when making custom types. Typically, you'll use {@link Tracing#errorParser()}
   *
   * 
{@code
   * class MyHttpClientParser extends HttpClientParser {
   *   ErrorParser errorParser;
   *
   *   MyHttpClientParser(Tracing tracing) {
   *     errorParser = tracing.errorParser();
   *   }
   *
   *   protected ErrorParser errorParser() {
   *     return errorParser;
   *   }
   * --snip--
   * }
*/ protected ErrorParser errorParser() { return DEFAULT_ERROR_PARSER; } /** * 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". * *

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 void request(HttpAdapter 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); } /** Returns the span name of the request. Defaults to the http method. */ protected String spanName(HttpAdapter adapter, Req req) { return adapter.method(req); } /** * Override to change what data from the http response or error are parsed into the span modeling * it. * *

By default, this tags "http.status_code" when it is not 2xx. If there's an exception or the * status code is neither 2xx nor 3xx, it tags "error". This also overrides the span name based on * the {@link HttpAdapter#methodFromResponse(Object)} and {@link HttpAdapter#route(Object)} where * possible (ex "get /users/:userId"). * *

If routing is supported, and a GET didn't match due to 404, the span name will be * "get not_found". If it didn't match due to redirect, the span name will be "get redirected". * If routing is not supported, the span name is left alone. * *

If you only want to change how exceptions are parsed, override {@link #error(Integer, * Throwable, SpanCustomizer)} instead. * *

Note: Either the response or error parameters may be null, but not both. * * @see #error(Integer, Throwable, SpanCustomizer) */ // This accepts response or exception because sometimes http 500 is an exception and sometimes not // If this were not an abstraction, we'd use separate hooks for response and error. public void response(HttpAdapter adapter, @Nullable Resp res, @Nullable Throwable error, SpanCustomizer customizer) { int statusCode = 0; if (res != null) { statusCode = adapter.statusCodeAsInt(res); String nameFromRoute = spanNameFromRoute(adapter, res, statusCode); if (nameFromRoute != null) customizer.name(nameFromRoute); String maybeStatus = maybeStatusAsString(statusCode, 299); if (maybeStatus != null) customizer.tag("http.status_code", maybeStatus); } error(statusCode, error, customizer); } static String spanNameFromRoute(HttpAdapter 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 to change what data from the http error are parsed into the span modeling it. By * default, this tags "error" as the exception or the status code if it is neither 2xx nor 3xx. * *

Note: Either the httpStatus or error parameters may be null, but not both * *

Conventionally associated with the tag key "error" */ // BRAVE6: httpStatus is a Integer, not a int. We can't change this api as users expect this to be // called by default. Unfortunately, this implies boxing until we can change it. protected void error(@Nullable Integer httpStatus, @Nullable Throwable error, SpanCustomizer customizer) { if (error != null) { errorParser().error(error, customizer); } else if (httpStatus != null) { String maybeErrorStatus = maybeStatusAsString(httpStatus, 399); if (maybeErrorStatus != null) customizer.tag("error", maybeErrorStatus); } } @Nullable String maybeStatusAsString(int statusCode, int upperRange) { if (statusCode != 0 && (statusCode < 200 || statusCode > upperRange)) { return String.valueOf(statusCode); } return null; } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy