-
Notifications
You must be signed in to change notification settings - Fork 19
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
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
type: feature | ||
feature: | ||
description: Introduce a new MDC property, _requestId, that disambiguates span stacks | ||
that belong to the same traceid but are different requests. | ||
links: | ||
- https://github.com/palantir/tracing-java/pull/364 |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -136,6 +136,8 @@ final String getTraceId() { | |
return traceId; | ||
} | ||
|
||
abstract Optional<String> getRequestId(); | ||
|
||
abstract Optional<String> getOriginatingSpanId(); | ||
|
||
/** Returns a copy of this Trace which can be independently mutated. */ | ||
|
@@ -195,6 +197,18 @@ boolean isObservable() { | |
return true; | ||
} | ||
|
||
@Override | ||
Optional<String> getRequestId() { | ||
if (stack.isEmpty()) { | ||
return Optional.empty(); | ||
} | ||
OpenSpan top = stack.peekFirst(); | ||
if (top.type() != SpanType.SERVER_INCOMING) { | ||
return Optional.empty(); | ||
} | ||
return Optional.of(top.getSpanId()); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Hm, but we don't do that for |
||
} | ||
|
||
@Override | ||
Optional<String> getOriginatingSpanId() { | ||
if (stack.isEmpty()) { | ||
|
@@ -220,36 +234,52 @@ private static final class Unsampled extends Trace { | |
* This allows thread trace state to be cleared when all "started" spans have been "removed". | ||
*/ | ||
private int numberOfSpans; | ||
private Optional<String> originatingSpanId = Optional.empty(); | ||
|
||
private Unsampled(int numberOfSpans, String traceId) { | ||
private Optional<String> originatingSpanId; | ||
private Optional<String> requestId; | ||
|
||
private Unsampled( | ||
int numberOfSpans, | ||
String traceId, | ||
Optional<String> originatingSpanId, | ||
Optional<String> requestId) { | ||
super(traceId); | ||
this.numberOfSpans = numberOfSpans; | ||
this.originatingSpanId = originatingSpanId; | ||
this.requestId = requestId; | ||
validateNumberOfSpans(); | ||
} | ||
|
||
private Unsampled(String traceId) { | ||
this(0, traceId); | ||
this(0, traceId, Optional.empty(), Optional.empty()); | ||
} | ||
|
||
@Override | ||
void fastStartSpan(String _operation, String parentSpanId, SpanType _type) { | ||
startSpan(Optional.of(parentSpanId)); | ||
void fastStartSpan(String _operation, String parentSpanId, SpanType type) { | ||
if (numberOfSpans == 0) { | ||
originatingSpanId = Optional.of(parentSpanId); | ||
if (type == SpanType.SERVER_INCOMING) { | ||
requestId = Optional.of(Tracers.randomId()); | ||
} | ||
} | ||
numberOfSpans++; | ||
} | ||
|
||
@Override | ||
void fastStartSpan(String _operation, SpanType _type) { | ||
void fastStartSpan(String _operation, SpanType type) { | ||
if (numberOfSpans == 0 && type == SpanType.SERVER_INCOMING) { | ||
requestId = Optional.of(Tracers.randomId()); | ||
} | ||
numberOfSpans++; | ||
} | ||
|
||
@Override | ||
protected void push(OpenSpan span) { | ||
startSpan(span.getParentSpanId()); | ||
} | ||
|
||
private void startSpan(Optional<String> parentSpanId) { | ||
if (numberOfSpans == 0) { | ||
originatingSpanId = parentSpanId; | ||
originatingSpanId = span.getParentSpanId(); | ||
|
||
if (span.type() == SpanType.SERVER_INCOMING) { | ||
requestId = Optional.of(span.getSpanId()); | ||
} | ||
} | ||
numberOfSpans++; | ||
} | ||
|
@@ -267,6 +297,7 @@ Optional<OpenSpan> pop() { | |
} | ||
if (numberOfSpans == 0) { | ||
originatingSpanId = Optional.empty(); | ||
requestId = Optional.empty(); | ||
} | ||
return Optional.empty(); | ||
} | ||
|
@@ -282,14 +313,19 @@ boolean isObservable() { | |
return false; | ||
} | ||
|
||
@Override | ||
Optional<String> getRequestId() { | ||
return requestId; | ||
} | ||
|
||
@Override | ||
Optional<String> getOriginatingSpanId() { | ||
return originatingSpanId; | ||
} | ||
|
||
@Override | ||
Trace deepCopy() { | ||
return new Unsampled(numberOfSpans, getTraceId()); | ||
return new Unsampled(numberOfSpans, getTraceId(), getOriginatingSpanId(), getRequestId()); | ||
} | ||
|
||
/** Internal validation, this should never fail because {@link #pop()} only decrements positive values. */ | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -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(); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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 |
||
OpenSpan result = trace.startSpan(operation, parentSpanId, type); | ||
if (wasEmpty) { | ||
setRequestIdIfPresent(trace.getRequestId()); | ||
} | ||
return result; | ||
} | ||
|
||
/** | ||
|
@@ -155,7 +161,13 @@ public static OpenSpan startSpan(String operation, String parentSpanId, SpanType | |
*/ | ||
@CheckReturnValue | ||
public static OpenSpan startSpan(String operation, SpanType type) { | ||
return getOrCreateCurrentTrace().startSpan(operation, type); | ||
Trace trace = getOrCreateCurrentTrace(); | ||
boolean wasEmpty = trace.isEmpty(); | ||
OpenSpan result = trace.startSpan(operation, type); | ||
if (wasEmpty) { | ||
setRequestIdIfPresent(trace.getRequestId()); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This feels like the wrong place to do this. |
||
} | ||
return result; | ||
} | ||
|
||
/** | ||
|
@@ -171,14 +183,24 @@ public static OpenSpan startSpan(String operation) { | |
* Like {@link #startSpan(String, String, SpanType)}, but does not return an {@link OpenSpan}. | ||
*/ | ||
public static void fastStartSpan(String operation, String parentSpanId, SpanType type) { | ||
getOrCreateCurrentTrace().fastStartSpan(operation, parentSpanId, type); | ||
Trace trace = getOrCreateCurrentTrace(); | ||
boolean wasEmpty = trace.isEmpty(); | ||
trace.fastStartSpan(operation, parentSpanId, type); | ||
if (wasEmpty) { | ||
setRequestIdIfPresent(trace.getRequestId()); | ||
} | ||
} | ||
|
||
/** | ||
* Like {@link #startSpan(String, SpanType)}, but does not return an {@link OpenSpan}. | ||
*/ | ||
public static void fastStartSpan(String operation, SpanType type) { | ||
getOrCreateCurrentTrace().fastStartSpan(operation, type); | ||
Trace trace = getOrCreateCurrentTrace(); | ||
boolean wasEmpty = trace.isEmpty(); | ||
trace.fastStartSpan(operation, type); | ||
if (wasEmpty) { | ||
setRequestIdIfPresent(trace.getRequestId()); | ||
} | ||
} | ||
|
||
/** | ||
|
@@ -525,6 +547,7 @@ static void setTrace(Trace trace) { | |
// Give log appenders access to the trace id and whether the trace is being sampled | ||
MDC.put(Tracers.TRACE_ID_KEY, trace.getTraceId()); | ||
setTraceSampledMdcIfObservable(trace.isObservable()); | ||
setRequestIdIfPresent(trace.getRequestId()); | ||
} | ||
|
||
private static void setTraceSampledMdcIfObservable(boolean observable) { | ||
|
@@ -537,6 +560,14 @@ private static void setTraceSampledMdcIfObservable(boolean observable) { | |
} | ||
} | ||
|
||
private static void setRequestIdIfPresent(Optional<String> requestId) { | ||
if (requestId.isPresent()) { | ||
MDC.put(Tracers.REQUEST_ID_KEY, requestId.get()); | ||
} else { | ||
MDC.remove(Tracers.REQUEST_ID_KEY); | ||
} | ||
} | ||
|
||
private static Trace getOrCreateCurrentTrace() { | ||
Trace trace = currentTrace.get(); | ||
if (trace == null) { | ||
|
@@ -551,5 +582,6 @@ static void clearCurrentTrace() { | |
currentTrace.remove(); | ||
MDC.remove(Tracers.TRACE_ID_KEY); | ||
MDC.remove(Tracers.TRACE_SAMPLED_KEY); | ||
MDC.remove(Tracers.REQUEST_ID_KEY); | ||
} | ||
} |
There was a problem hiding this comment.
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