question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Add support for opentracing trace id

See original GitHub issue

It’s currently rather difficult to add support in a general fashion for adding opentracing span/trace information (considering the instance member seems a ready fit for the info).

Detailed Description

I’d like to incorporate the opentracing span info in error payloads to help client developers better troubleshoot issues. I’d also like to avoid duplicating the code across all the different exceptions that might be thrown. To do that I believe better support in the framework needs to exist to hook in common code at the right spots.

Context

Opentracing is a common methodology in distributed systems, many folks would benefit from this working out-of-the-box.

Possible Implementation

Currently I’ve implemented a TraceableAdviceTrait that abstracts the work of extracting opentracing info from headers. However, I haven’t been able to determine the least-effort solution in the current framework, and the sample implementation only works for custom exceptions we define outside the bounds of the standard exceptions. So this is only a partial solution.

/** Base class for extracting OpenTracing info from request headers. */
@API(status = STABLE)
public interface TraceableAdviceTrait extends AdviceTrait {

  @API(status = INTERNAL)
  default String getUriRoot() {
    return "https://example.com";
  }

  @API(status = INTERNAL)
  default String getTypeUri(String typename) {
    return String.format("%s/%s", getUriRoot(), typename);
  }

  @API(status = INTERNAL)
  default String getTraceHeaderName() {
    return "traceparent";
  }

  /**
   * extract opentracing trace/span info and return a URI.
   *
   * @param request web request
   * @param headers http headers
   * @return URI containing trace/span info
   */
  @API(status = INTERNAL)
  default URI extractInstance(final NativeWebRequest request, final HttpHeaders headers) {
    // TODO
    try {
      String trace = "FIXME-opentracing/span";
      if (null != request) {
        trace = request.getHeaderValues(getTraceHeaderName())[0];
      }
      return new URI(String.format("%s/%s", getUriRoot(), trace));
    } catch (URISyntaxException ex) {
      // What to report here?
      return null;
    }
  }

  /**
   * construct a ProblemBuilder using standard *Advice foundational methods.
   *
   * @param status result of API call (http status codes)
   * @param throwable the exception thrown
   * @param request the web request info
   * @param headers additional headers
   * @param type the URI type of the error payload
   * @return a ProblemBuilder that can be further modified before finalizing the Problem object
   */
  @API(status = INTERNAL)
  default ProblemBuilder getProblemBuilder(
      final StatusType status,
      final Throwable throwable,
      final NativeWebRequest request,
      final HttpHeaders headers,
      final URI type) {

    Problem base = toProblem(throwable, status, type);
    return Problem.builder()
        .withDetail(base.getDetail())
        .withTitle(base.getTitle())
        .withStatus(base.getStatus())
        .withType(base.getType())
        .withInstance(extractInstance(request, headers));
  }
}

And the specific *AdviceTrait interface:

@API(status = STABLE)
public interface ResourceNotFoundAdviceTrait extends TraceableAdviceTrait {

  /**
   * handle ResourceNotFoundExceptions thrown during API calls.
   *
   * @param exception ResourceNotFoundException
   * @param request web request info
   * @return standardized error payload according to RFC7807
   */
  @API(status = INTERNAL)
  @ExceptionHandler
  default ResponseEntity<Problem> handleResourceNotFound(
      final ResourceNotFoundException exception, final NativeWebRequest request) {

    return create(
        exception,
        getProblemBuilder(
                Status.NOT_FOUND,
                exception,
                request,
                new HttpHeaders(),
                URI.create(getTypeUri("not-found")))
            .build(),
        request);
  }
}

One note, the ResourceNotFoundException is just a normal RuntimeException to minimize dependencies on the defined exceptions. Seems logical that all the mapping of exceptions to Problem payloads should take place in the ControllerAdvice classes, and not pollute normal exception definitions.

Issue Analytics

  • State:closed
  • Created 3 years ago
  • Reactions:1
  • Comments:6

github_iconTop GitHub Comments

1reaction
whiskeysierracommented, May 12, 2021

What’s the benefit of adding trace/span id to the response body in contrast to the header, where they already are?

0reactions
no-response[bot]commented, May 28, 2021

This issue has been automatically closed because there has been no response to our request for more information from the original author. With only the information that is currently in the issue, we don’t have enough information to take action. Please reach out if you have or find the answers we need so that we can investigate further.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Using OpenTracing - Quarkus
This guide explains how your Quarkus application can utilize OpenTracing to provide ... 4, Add trace IDs into log message. ... quarkus.jaeger.service-name.
Read more >
Tracing API - OpenTelemetry
The OpenTelemetry SpanContext representation conforms to the W3C TraceContext specification. It contains two identifiers - a TraceId and a SpanId - along with...
Read more >
Tracing — envoy 1.25.0-dev-ed55e0 documentation
This can be achieved by using the LightStep (via OpenTracing API) or Zipkin tracer directly within the service itself, to extract the trace...
Read more >
Tracing with Spring Boot, OpenTelemetry, and Jaeger
I.e. Sleuth automatically configures the RestTemplate used in the API service to add the trace ID in an HTTP header and the customer...
Read more >
The OpenTracing project
Vendor-neutral APIs and instrumentation for distributed tracing ... Add OpenTracing to your open source project and help your users in the process.
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found