Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Introduce requestId MDC property #364

Closed
wants to merge 2 commits into from
Closed

Introduce requestId MDC property #364

wants to merge 2 commits into from

Conversation

JacekLach
Copy link

@JacekLach JacekLach commented Nov 25, 2019

Logs from concurrent incoming requests with the same traceid are currently difficult
to tell apart (one can look at thread names etc, but not across executors).

After this PR

==COMMIT_MSG==
Introduce a new MDC property managed by Tracers, which stores a unique identifier
when the top span of the current trace is a SERVER_INCOMING span.
==COMMIT_MSG==

Possible downsides?

Logs from concurrent incoming requests with the same traceid are currently difficult
to tell apart (one can look at thread names etc, but not across executors).

This introduces a new MDC property managed by Tracers, which stores a unique identifier
when the top span of the current trace is a SERVER_INCOMING span.
String requestId;

// Set up thread-local span that inherits state from HTTP headers
if (Strings.isNullOrEmpty(traceIdHeader)) {
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I had to inline the trace creation to get both the span id and the trace id out, without creating a wrapper object. Maybe just reading the MDC here is simpler?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ya, I'd prefer the minimal change where we read the requestId from MDC here.

@@ -136,6 +136,8 @@ final String getTraceId() {
return traceId;
}

abstract Optional<String> getRequestId();
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We still store the request id so that it can be restored when a trace is set. However this getter is not exposed to clients of Tracers / Tracer

@@ -146,7 +146,13 @@ public static void initTrace(Observability observability, String traceId) {
*/
@CheckReturnValue
public static OpenSpan startSpan(String operation, String parentSpanId, SpanType type) {
return getOrCreateCurrentTrace().startSpan(operation, parentSpanId, type);
Trace trace = getOrCreateCurrentTrace();
boolean wasEmpty = trace.isEmpty();
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is kinda sad - but definitely don't want to be setting the MDC property on every span open, so we have to know if it could have become active here. If traces had to be initialized with a span, this would be part of init/setTrace :(

if (top.type() != SpanType.SERVER_INCOMING) {
return Optional.empty();
}
return Optional.of(top.getSpanId());
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we have to pass around the value like originatingSpanId, when we create deferred traces we don't pass the full stack of spans (we don't want to allow other code to complete spans from our thread) but we still want to pass the same requestId.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hm, but we don't do that for originatingSpanId, do we? Not for sampled spans. So while I agree with this, I think it should be fixed for originatingSpanId and requestId together in a follow-up pr

@carterkozak
Copy link
Contributor

Perhaps it's time to deprecate Tracer.initTrace in favor of a method to initialize a trace with a root span. That way we can continue to support the deprecated method for now (without this new functinoality), and support the new, safe things with the new method.

boolean wasEmpty = trace.isEmpty();
OpenSpan result = trace.startSpan(operation, type);
if (wasEmpty) {
setRequestIdIfPresent(trace.getRequestId());
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This feels like the wrong place to do this.
I think we should do what carter recommended (#364 (comment)) which then means that this only has to happen in one code path.

Copy link
Contributor

@dansanduleac dansanduleac left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should instead

  1. initialize the requestId once via a new API (as Carter recommended), when creating a new trace initialized via a SERVER_INCOMING
  2. set the MDC when setting a trace as the current trace (i.e. in Tracer.setTrace, just like we set the traceId MDC key) which has the advantage that whenever we apply a deferred trace on another thread (via DeferredTracer.withTrace) it will set the requestId at the right time too

@carterkozak thoughts? I had initial context on this but it seems like you/@ferozco have been review-requested by the load-balancing bots

@carterkozak
Copy link
Contributor

Yep, that's exactly what I was thinking, thanks Dan.

@carterkozak
Copy link
Contributor

Proposal is up #574

@carterkozak
Copy link
Contributor

Closing this out because #574 has been released.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants