Add support for opentracing trace id
See original GitHub issueIt’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:
- Created 3 years ago
- Reactions:1
- Comments:6
Top GitHub Comments
What’s the benefit of adding trace/span id to the response body in contrast to the header, where they already are?
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.