-
Notifications
You must be signed in to change notification settings - Fork 715
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Adds ScopeDecorator and backports log correlation to use it (#683)
- Loading branch information
1 parent
5172fc3
commit bf2ddde
Showing
59 changed files
with
851 additions
and
420 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
91 changes: 91 additions & 0 deletions
91
brave/src/main/java/brave/internal/propagation/CorrelationFieldScopeDecorator.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,91 @@ | ||
package brave.internal.propagation; | ||
|
||
import brave.internal.HexCodec; | ||
import brave.internal.Nullable; | ||
import brave.propagation.CurrentTraceContext.Scope; | ||
import brave.propagation.CurrentTraceContext.ScopeDecorator; | ||
import brave.propagation.TraceContext; | ||
|
||
import static brave.internal.HexCodec.lowerHexEqualsTraceId; | ||
import static brave.internal.HexCodec.lowerHexEqualsUnsignedLong; | ||
|
||
/** | ||
* Adds correlation properties "traceId", "parentId" and "spanId" when a {@link | ||
* brave.Tracer#currentSpan() span is current}. | ||
*/ | ||
public abstract class CorrelationFieldScopeDecorator implements ScopeDecorator { | ||
|
||
/** | ||
* When the input is not null "traceId", "parentId" and "spanId" correlation properties are saved | ||
* off and replaced with those of the current span. When the input is null, these properties are | ||
* removed. Either way, "traceId", "parentId" and "spanId" properties are restored on {@linkplain | ||
* Scope#close()}. | ||
*/ | ||
@Override public Scope decorateScope(@Nullable TraceContext currentSpan, Scope scope) { | ||
String previousTraceId = get("traceId"); | ||
String previousSpanId = get("spanId"); | ||
String previousParentId = get("parentId"); | ||
|
||
if (currentSpan != null) { | ||
maybeReplaceTraceContext(currentSpan, previousTraceId, previousParentId, previousSpanId); | ||
} else { | ||
remove("traceId"); | ||
remove("parentId"); | ||
remove("spanId"); | ||
} | ||
|
||
class CorrelationFieldCurrentTraceContextScope implements Scope { | ||
@Override public void close() { | ||
scope.close(); | ||
replace("traceId", previousTraceId); | ||
replace("parentId", previousParentId); | ||
replace("spanId", previousSpanId); | ||
} | ||
} | ||
return new CorrelationFieldCurrentTraceContextScope(); | ||
} | ||
|
||
/** | ||
* Idempotently sets correlation properties to hex representation of trace identifiers in this | ||
* context. | ||
*/ | ||
void maybeReplaceTraceContext( | ||
TraceContext currentSpan, | ||
String previousTraceId, | ||
@Nullable String previousParentId, | ||
String previousSpanId | ||
) { | ||
boolean sameTraceId = lowerHexEqualsTraceId(previousTraceId, currentSpan); | ||
if (!sameTraceId) put("traceId", currentSpan.traceIdString()); | ||
|
||
long parentId = currentSpan.parentIdAsLong(); | ||
if (parentId == 0L) { | ||
remove("parentId"); | ||
} else { | ||
boolean sameParentId = lowerHexEqualsUnsignedLong(previousParentId, parentId); | ||
if (!sameParentId) put("parentId", HexCodec.toLowerHex(parentId)); | ||
} | ||
|
||
boolean sameSpanId = lowerHexEqualsUnsignedLong(previousSpanId, currentSpan.spanId()); | ||
if (!sameSpanId) put("spanId", HexCodec.toLowerHex(currentSpan.spanId())); | ||
} | ||
|
||
/** | ||
* Returns the correlation property of the specified name iff it is a string, or null otherwise. | ||
*/ | ||
protected abstract @Nullable String get(String key); | ||
|
||
/** Replaces the correlation property of the specified name */ | ||
protected abstract void put(String key, String value); | ||
|
||
/** Removes the correlation property of the specified name */ | ||
protected abstract void remove(String key); | ||
|
||
final void replace(String key, @Nullable String value) { | ||
if (value != null) { | ||
put(key, value); | ||
} else { | ||
remove(key); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
52 changes: 10 additions & 42 deletions
52
brave/src/main/java/brave/propagation/StrictCurrentTraceContext.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,53 +1,21 @@ | ||
package brave.propagation; | ||
|
||
import brave.internal.Nullable; | ||
|
||
/** | ||
* Useful when developing instrumentation as state is enforced more strictly. | ||
* | ||
* <p>For example, it is instance scoped as opposed to static scoped, not inheritable and throws an | ||
* exception if a scope is closed on a different thread that it was opened on. | ||
* | ||
* @see CurrentTraceContext.Default | ||
* @deprecated use {@linkplain StrictScopeDecorator}. This will be removed in Brave v6. | ||
*/ | ||
public final class StrictCurrentTraceContext extends CurrentTraceContext { | ||
// intentionally not inheritable to ensure instrumentation propagation doesn't accidentally work | ||
// intentionally not static to make explicit when instrumentation need per thread semantics | ||
final ThreadLocal<TraceContext> local = new ThreadLocal<>(); | ||
|
||
@Override public TraceContext get() { | ||
return local.get(); | ||
} | ||
|
||
/** Identifies problems by throwing assertion errors when a scope is closed on a different thread. */ | ||
@Override public Scope newScope(@Nullable TraceContext currentSpan) { | ||
TraceContext previous = local.get(); | ||
local.set(currentSpan); | ||
return new StrictScope(previous, new Error(String.format("Thread %s opened scope for %s here:", | ||
Thread.currentThread().getName(), currentSpan))); | ||
} | ||
|
||
class StrictScope implements Scope { | ||
final TraceContext previous; | ||
final Throwable caller; | ||
final long threadId = Thread.currentThread().getId(); | ||
|
||
StrictScope(TraceContext previous, Throwable caller) { | ||
this.previous = previous; | ||
this.caller = caller; | ||
} | ||
|
||
@Override public void close() { | ||
if (Thread.currentThread().getId() != threadId) { | ||
throw new IllegalStateException( | ||
"scope closed in a different thread: " + Thread.currentThread().getName(), | ||
caller); | ||
} | ||
local.set(previous); | ||
} | ||
|
||
@Override public String toString() { | ||
return caller.toString(); | ||
} | ||
@Deprecated | ||
public final class StrictCurrentTraceContext extends ThreadLocalCurrentTraceContext { | ||
static final CurrentTraceContext.Builder SCOPE_DECORATING_BUILDER = | ||
ThreadLocalCurrentTraceContext.newBuilder().addScopeDecorator(new StrictScopeDecorator()); | ||
|
||
public StrictCurrentTraceContext() { // Preserve historical public ctor | ||
// intentionally not inheritable to ensure instrumentation propagation doesn't accidentally work | ||
// intentionally not static to make explicit when instrumentation need per thread semantics | ||
super(SCOPE_DECORATING_BUILDER, new ThreadLocal<>()); | ||
} | ||
} |
Oops, something went wrong.