diff --git a/bootstraps/bootstrap-core/src/main/java/com/navercorp/pinpoint/bootstrap/util/ScopeUtils.java b/bootstraps/bootstrap-core/src/main/java/com/navercorp/pinpoint/bootstrap/util/ScopeUtils.java index beb6d50015f6..df604fdef198 100644 --- a/bootstraps/bootstrap-core/src/main/java/com/navercorp/pinpoint/bootstrap/util/ScopeUtils.java +++ b/bootstraps/bootstrap-core/src/main/java/com/navercorp/pinpoint/bootstrap/util/ScopeUtils.java @@ -58,4 +58,15 @@ public static boolean hasScope(final Trace trace, final String scopeName) { final TraceScope scope = trace.getScope(scopeName); return scope != null; } + + public static boolean addScope(Trace trace, String scopeName) { + // add async scope. + final TraceScope oldScope = trace.addScope(scopeName); + if (oldScope != null) { + // delete corrupted trace. +// deleteAsyncTrace(trace); + return false; + } + return true; + } } diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/AsyncContextFactory.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/AsyncContextFactory.java index 29debce17586..0db55898f1e6 100644 --- a/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/AsyncContextFactory.java +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/AsyncContextFactory.java @@ -18,6 +18,7 @@ import com.navercorp.pinpoint.bootstrap.context.AsyncContext; import com.navercorp.pinpoint.bootstrap.context.AsyncState; +import com.navercorp.pinpoint.profiler.context.id.LocalTraceRoot; import com.navercorp.pinpoint.profiler.context.id.TraceRoot; /** @@ -31,4 +32,5 @@ public interface AsyncContextFactory { AsyncContext newAsyncContext(TraceRoot traceRoot, AsyncId asyncId, boolean canSampled, AsyncState asyncState); + AsyncContext newDisableAsyncContext(LocalTraceRoot traceRoot); } diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/AsyncScopeUtils.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/AsyncScopeUtils.java new file mode 100644 index 000000000000..7c576feca53d --- /dev/null +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/AsyncScopeUtils.java @@ -0,0 +1,31 @@ +package com.navercorp.pinpoint.profiler.context; + +import com.navercorp.pinpoint.bootstrap.context.Trace; +import com.navercorp.pinpoint.bootstrap.context.scope.TraceScope; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + +public final class AsyncScopeUtils { + private static final Logger logger = LogManager.getLogger(AsyncScopeUtils.class); + + private AsyncScopeUtils() { + } + + public static boolean nested(Trace trace, String scopeName) { + // add async scope. + final TraceScope oldScope = trace.addScope(scopeName); + if (oldScope != null) { + if (logger.isWarnEnabled()) { + logger.warn("Duplicated {} scope={}", trace.getClass().getSimpleName(), oldScope.getName()); + } + // delete corrupted trace. +// deleteAsyncTrace(trace); + return true; + } else { + if (logger.isDebugEnabled()) { + logger.debug("start {} scope", trace.getClass().getSimpleName()); + } + } + return false; + } +} diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/AsyncTraceContext.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/AsyncTraceContext.java index 670099402bab..c421ba96e742 100644 --- a/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/AsyncTraceContext.java +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/AsyncTraceContext.java @@ -17,6 +17,7 @@ package com.navercorp.pinpoint.profiler.context; import com.navercorp.pinpoint.bootstrap.context.Trace; +import com.navercorp.pinpoint.profiler.context.id.LocalTraceRoot; import com.navercorp.pinpoint.profiler.context.id.TraceRoot; @@ -25,17 +26,8 @@ */ public interface AsyncTraceContext { -// Reference continueAsyncTraceObject(TraceRoot traceRoot, int asyncId, short asyncSequence); - - Reference continueAsyncContextTraceObject(TraceRoot traceRoot, LocalAsyncId localAsyncId, boolean canSampled); - - Trace newAsyncContextTraceObject(TraceRoot traceRoot, LocalAsyncId localAsyncId, boolean canSampled); - - Reference currentRawTraceObject(); - - Reference currentTraceObject(); - - void removeTraceObject(); + Trace continueAsyncContextTraceObject(TraceRoot traceRoot, LocalAsyncId localAsyncId); + Trace continueDisableAsyncContextTraceObject(LocalTraceRoot traceRoot); } diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/BaseTraceFactory.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/BaseTraceFactory.java index 8ffd60fe84c5..d64edc4cce8a 100644 --- a/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/BaseTraceFactory.java +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/BaseTraceFactory.java @@ -19,6 +19,7 @@ import com.navercorp.pinpoint.bootstrap.context.Trace; import com.navercorp.pinpoint.bootstrap.context.TraceId; import com.navercorp.pinpoint.common.annotations.InterfaceAudience; +import com.navercorp.pinpoint.profiler.context.id.LocalTraceRoot; import com.navercorp.pinpoint.profiler.context.id.TraceRoot; /** @@ -34,7 +35,9 @@ public interface BaseTraceFactory { @InterfaceAudience.LimitedPrivate("vert.x") Trace continueAsyncTraceObject(TraceId traceId); - Trace continueAsyncContextTraceObject(TraceRoot traceRoot, LocalAsyncId localAsyncId, boolean canSampled); + Trace continueAsyncContextTraceObject(TraceRoot traceRoot, LocalAsyncId localAsyncId); + + Trace continueDisableAsyncContextTraceObject(LocalTraceRoot traceRoot); Trace newTraceObject(); diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/DefaultAsyncContext.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/DefaultAsyncContext.java index 7a8b58049b79..fafee65a1393 100644 --- a/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/DefaultAsyncContext.java +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/DefaultAsyncContext.java @@ -19,12 +19,11 @@ import com.navercorp.pinpoint.bootstrap.context.AsyncContext; import com.navercorp.pinpoint.bootstrap.context.SpanEventRecorder; import com.navercorp.pinpoint.bootstrap.context.Trace; -import com.navercorp.pinpoint.bootstrap.context.scope.TraceScope; import com.navercorp.pinpoint.common.trace.ServiceType; import com.navercorp.pinpoint.common.util.Assert; import com.navercorp.pinpoint.profiler.context.id.TraceRoot; -import org.apache.logging.log4j.Logger; import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; import java.util.Objects; @@ -38,21 +37,23 @@ public class DefaultAsyncContext implements AsyncContext { private final TraceRoot traceRoot; private final AsyncId asyncId; - private final boolean canSampled; private final AsyncTraceContext asyncTraceContext; + private final Binder binder; private final int asyncMethodApiId; - public DefaultAsyncContext(AsyncTraceContext asyncTraceContext, TraceRoot traceRoot, AsyncId asyncId, int asyncMethodApiId, boolean canSampled) { + public DefaultAsyncContext(AsyncTraceContext asyncTraceContext, + Binder binder, + TraceRoot traceRoot, + AsyncId asyncId, int asyncMethodApiId) { this.asyncTraceContext = Objects.requireNonNull(asyncTraceContext, "asyncTraceContext"); + this.binder = Objects.requireNonNull(binder, "binder"); this.traceRoot = Objects.requireNonNull(traceRoot, "traceRoot"); this.asyncId = Objects.requireNonNull(asyncId, "asyncId"); - this.asyncMethodApiId = asyncMethodApiId; - this.canSampled = canSampled; } @@ -63,7 +64,7 @@ public TraceRoot getTraceRoot() { @Override public Trace continueAsyncTraceObject() { - final Reference reference = asyncTraceContext.currentRawTraceObject(); + final Reference reference = binder.get(); final Trace nestedTrace = reference.get(); if (nestedTrace != null) { // return Nested Trace Object? @@ -80,42 +81,26 @@ private Trace newAsyncContextTrace(Reference reference) { // final int asyncId = this.asyncId.getAsyncId(); // final short asyncSequence = this.asyncId.nextAsyncSequence(); final LocalAsyncId localAsyncId = this.asyncId.nextLocalAsyncId(); - final Trace asyncTrace = asyncTraceContext.newAsyncContextTraceObject(traceRoot, localAsyncId, canSampled); - + final Trace asyncTrace = asyncTraceContext.continueAsyncContextTraceObject(traceRoot, localAsyncId); bind(reference, asyncTrace); if (logger.isDebugEnabled()) { - logger.debug("asyncTraceContext.continueAsyncTraceObject() AsyncTrace:{}", asyncTrace); + logger.debug("asyncTraceContext.continuAsyncTraceObject(e) AsyncTrace:{}", asyncTrace); } - // add async scope. - final TraceScope oldScope = asyncTrace.addScope(ASYNC_TRACE_SCOPE); - if (oldScope != null) { - if (logger.isWarnEnabled()) { - logger.warn("Duplicated async trace scope={}.", oldScope.getName()); - } - // delete corrupted trace. -// deleteAsyncTrace(trace); + if (AsyncScopeUtils.nested(asyncTrace, ASYNC_TRACE_SCOPE)) { return null; - } else { - if (logger.isDebugEnabled()) { - logger.debug("start async trace scope"); - } } // first block. final SpanEventRecorder recorder = asyncTrace.currentSpanEventRecorder(); - if (recorder != null) { recorder.recordServiceType(ServiceType.ASYNC); recorder.recordApiId(asyncMethodApiId); } - if (asyncTrace.canSampled()) { - return asyncTrace; - } - return null; + return asyncTrace; } private void bind(Reference reference, Trace asyncTrace) { @@ -127,14 +112,21 @@ private void bind(Reference reference, Trace asyncTrace) { @Override public Trace currentAsyncTraceObject() { - final Reference reference = asyncTraceContext.currentTraceObject(); - return reference.get(); + final Reference reference = binder.get(); + final Trace trace = reference.get(); + if (trace == null) { + return null; + } + if (trace.canSampled()) { + return trace; + } + return null; } @Override public void close() { - asyncTraceContext.removeTraceObject(); + binder.remove(); } @Override diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/DefaultAsyncContextFactory.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/DefaultAsyncContextFactory.java index 22fdcbb11375..c7752af56c39 100644 --- a/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/DefaultAsyncContextFactory.java +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/DefaultAsyncContextFactory.java @@ -19,7 +19,9 @@ import com.navercorp.pinpoint.bootstrap.context.AsyncContext; import com.navercorp.pinpoint.bootstrap.context.AsyncState; import com.navercorp.pinpoint.bootstrap.context.MethodDescriptor; +import com.navercorp.pinpoint.bootstrap.context.Trace; import com.navercorp.pinpoint.profiler.context.id.AsyncIdGenerator; +import com.navercorp.pinpoint.profiler.context.id.LocalTraceRoot; import com.navercorp.pinpoint.profiler.context.id.TraceRoot; import com.navercorp.pinpoint.profiler.context.method.PredefinedMethodDescriptorRegistry; @@ -31,13 +33,18 @@ public class DefaultAsyncContextFactory implements AsyncContextFactory { private final AsyncTraceContext asyncTraceContext; + private final Binder binder; private final AsyncIdGenerator asyncIdGenerator; private final PredefinedMethodDescriptorRegistry predefinedMethodDescriptorRegistry; private final int asyncMethodApiId; - public DefaultAsyncContextFactory(AsyncTraceContext asyncTraceContext, AsyncIdGenerator asyncIdGenerator, PredefinedMethodDescriptorRegistry predefinedMethodDescriptorRegistry) { + public DefaultAsyncContextFactory(AsyncTraceContext asyncTraceContext, + Binder binder, + AsyncIdGenerator asyncIdGenerator, + PredefinedMethodDescriptorRegistry predefinedMethodDescriptorRegistry) { this.asyncTraceContext = Objects.requireNonNull(asyncTraceContext, "traceFactoryProvider"); this.asyncIdGenerator = Objects.requireNonNull(asyncIdGenerator, "asyncIdGenerator"); + this.binder = Objects.requireNonNull(binder, "binder"); this.predefinedMethodDescriptorRegistry = Objects.requireNonNull(predefinedMethodDescriptorRegistry, "predefinedMethodDescriptorRegistry"); @@ -59,7 +66,11 @@ public AsyncContext newAsyncContext(TraceRoot traceRoot, AsyncId asyncId, boolea Objects.requireNonNull(traceRoot, "traceRoot"); Objects.requireNonNull(asyncId, "asyncId"); - return new DefaultAsyncContext(asyncTraceContext, traceRoot, asyncId, this.asyncMethodApiId, canSampled); + if (canSampled) { + return new DefaultAsyncContext(asyncTraceContext, binder, traceRoot, asyncId, this.asyncMethodApiId); + } else { + return newDisableAsyncContext(traceRoot); + } } @Override @@ -68,8 +79,18 @@ public AsyncContext newAsyncContext(TraceRoot traceRoot, AsyncId asyncId, boolea Objects.requireNonNull(asyncId, "asyncId"); Objects.requireNonNull(asyncState, "asyncState"); - return new StatefulAsyncContext(asyncTraceContext, traceRoot, asyncId, asyncMethodApiId, asyncState, canSampled); + if (canSampled) { + return new StatefulAsyncContext(asyncTraceContext, binder, traceRoot, asyncId, asyncMethodApiId, asyncState); + } else { + // TODO + return new StatefulDisableAsyncContext(asyncTraceContext, binder, traceRoot, asyncState); + } + } + @Override + public AsyncContext newDisableAsyncContext(LocalTraceRoot traceRoot) { + return new DisableAsyncContext(asyncTraceContext, binder, traceRoot); + } } diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/DefaultAsyncTraceContext.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/DefaultAsyncTraceContext.java index a1a6c44c4d76..4259f46b147d 100644 --- a/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/DefaultAsyncTraceContext.java +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/DefaultAsyncTraceContext.java @@ -18,11 +18,10 @@ import com.google.inject.Provider; import com.navercorp.pinpoint.bootstrap.context.Trace; -import java.util.Objects; -import com.navercorp.pinpoint.exception.PinpointException; +import com.navercorp.pinpoint.profiler.context.id.LocalTraceRoot; import com.navercorp.pinpoint.profiler.context.id.TraceRoot; -import org.apache.logging.log4j.Logger; -import org.apache.logging.log4j.LogManager; + +import java.util.Objects; /** @@ -30,75 +29,23 @@ */ public class DefaultAsyncTraceContext implements AsyncTraceContext { - private final Logger logger = LogManager.getLogger(this.getClass()); - - private static final Reference EMPTY = DefaultReference.emptyReference(); - private final Provider baseTraceFactoryProvider; - private final Binder binder; - public DefaultAsyncTraceContext(Provider baseTraceFactoryProvider, Binder binder) { + public DefaultAsyncTraceContext(Provider baseTraceFactoryProvider) { this.baseTraceFactoryProvider = Objects.requireNonNull(baseTraceFactoryProvider, "baseTraceFactoryProvider"); - this.binder = Objects.requireNonNull(binder, "binder"); - } - - @Override - public Reference continueAsyncContextTraceObject(TraceRoot traceRoot, LocalAsyncId localAsyncId, boolean canSampled) { - final Reference reference = checkAndGet(); - - final Trace trace = newAsyncContextTraceObject(traceRoot, localAsyncId, canSampled); - - bind(reference, trace); - return reference; } @Override - public Trace newAsyncContextTraceObject(TraceRoot traceRoot, LocalAsyncId localAsyncId, boolean canSampled) { + public Trace continueAsyncContextTraceObject(TraceRoot traceRoot, LocalAsyncId localAsyncId) { final BaseTraceFactory baseTraceFactory = baseTraceFactoryProvider.get(); - return baseTraceFactory.continueAsyncContextTraceObject(traceRoot, localAsyncId, canSampled); + return baseTraceFactory.continueAsyncContextTraceObject(traceRoot, localAsyncId); } - @Override - public Reference currentRawTraceObject() { - return binder.get(); - } - - @Override - public Reference currentTraceObject() { - final Reference reference = binder.get(); - final Trace trace = reference.get(); - if (trace == null) { - return EMPTY; - } - if (trace.canSampled()) { - return reference; - } - return EMPTY; - } - - - @Override - public void removeTraceObject() { - binder.remove(); - } - - - private Reference checkAndGet() { - final Reference reference = this.binder.get(); - final Trace old = reference.get(); - if (old != null) { - final PinpointException exception = new PinpointException("already Trace Object exist."); - if (logger.isWarnEnabled()) { - logger.warn("beforeTrace:{}", old, exception); - } - throw exception; - } - return reference; + public Trace continueDisableAsyncContextTraceObject(LocalTraceRoot traceRoot) { + final BaseTraceFactory baseTraceFactory = baseTraceFactoryProvider.get(); + return baseTraceFactory.continueDisableAsyncContextTraceObject(traceRoot); } - private void bind(Reference reference, Trace trace) { - reference.set(trace); - } } diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/DefaultBaseTraceFactory.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/DefaultBaseTraceFactory.java index d9dc6800e911..61ad14198cf6 100644 --- a/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/DefaultBaseTraceFactory.java +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/DefaultBaseTraceFactory.java @@ -143,23 +143,23 @@ Trace newTraceObject(TraceSampler.State state) { // internal async trace. @Override - public Trace continueAsyncContextTraceObject(TraceRoot traceRoot, LocalAsyncId localAsyncId, boolean sampling) { - if (sampling) { - final SpanChunkFactory spanChunkFactory = new AsyncSpanChunkFactory(traceRoot, localAsyncId); - final Storage storage = storageFactory.createStorage(spanChunkFactory); + public Trace continueAsyncContextTraceObject(TraceRoot traceRoot, LocalAsyncId localAsyncId) { + final SpanChunkFactory spanChunkFactory = new AsyncSpanChunkFactory(traceRoot, localAsyncId); + final Storage storage = storageFactory.createStorage(spanChunkFactory); - final CallStack callStack = callStackFactory.newCallStack(); + final CallStack callStack = callStackFactory.newCallStack(); - final SpanRecorder spanRecorder = recorderFactory.newTraceRootSpanRecorder(traceRoot); + final SpanRecorder spanRecorder = recorderFactory.newTraceRootSpanRecorder(traceRoot); - final WrappedSpanEventRecorder wrappedSpanEventRecorder = recorderFactory.newWrappedSpanEventRecorder(traceRoot); + final WrappedSpanEventRecorder wrappedSpanEventRecorder = recorderFactory.newWrappedSpanEventRecorder(traceRoot); - return new AsyncChildTrace(traceRoot, callStack, storage, spanRecorder, wrappedSpanEventRecorder, localAsyncId); - } else { - return new DisableAsyncChildTrace(traceRoot, localAsyncId); - } + return new AsyncChildTrace(traceRoot, callStack, storage, spanRecorder, wrappedSpanEventRecorder, localAsyncId); } + @Override + public Trace continueDisableAsyncContextTraceObject(LocalTraceRoot traceRoot) { + return new DisableAsyncChildTrace(traceRoot); + } // entry point async trace. @InterfaceAudience.LimitedPrivate("vert.x") diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/DisableAsyncChildTrace.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/DisableAsyncChildTrace.java index c814c0de7205..62dd5a3277f4 100644 --- a/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/DisableAsyncChildTrace.java +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/DisableAsyncChildTrace.java @@ -34,11 +34,9 @@ public class DisableAsyncChildTrace implements Trace { private DefaultTraceScopePool scopePool; private final LocalTraceRoot traceRoot; - private final LocalAsyncId localAsyncId; - public DisableAsyncChildTrace(final LocalTraceRoot traceRoot, final LocalAsyncId localAsyncId) { + public DisableAsyncChildTrace(final LocalTraceRoot traceRoot) { this.traceRoot = Objects.requireNonNull(traceRoot, "traceRoot"); - this.localAsyncId = Objects.requireNonNull(localAsyncId, "localAsyncId"); } @Override @@ -148,8 +146,7 @@ public TraceScope addScope(String name) { @Override public String toString() { return "DisableAsyncChildTrace{" + - "traceRoot=" + getTraceRoot() + - ", localAsyncId=" + localAsyncId + - '}'; + "traceRoot=" + traceRoot + + '}'; } } diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/DisableAsyncContext.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/DisableAsyncContext.java new file mode 100644 index 000000000000..908ace711266 --- /dev/null +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/DisableAsyncContext.java @@ -0,0 +1,69 @@ +package com.navercorp.pinpoint.profiler.context; + +import com.navercorp.pinpoint.bootstrap.context.AsyncContext; +import com.navercorp.pinpoint.bootstrap.context.Trace; +import com.navercorp.pinpoint.common.util.Assert; +import com.navercorp.pinpoint.profiler.context.id.LocalTraceRoot; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + +import java.util.Objects; + +/** + * @author Woonduk Kang(emeroad) + */ +public class DisableAsyncContext implements AsyncContext { + private static final Logger logger = LogManager.getLogger(DisableAsyncContext.class); + private final LocalTraceRoot traceRoot; + private final AsyncTraceContext asyncTraceContext; + private final Binder binder; + + public DisableAsyncContext(AsyncTraceContext asyncTraceContext, Binder binder, LocalTraceRoot traceRoot) { + this.asyncTraceContext = Objects.requireNonNull(asyncTraceContext, "asyncTraceContext"); + this.binder = Objects.requireNonNull(binder, "binder"); + this.traceRoot = Objects.requireNonNull(traceRoot, "traceRoot"); + } + + @Override + public Trace continueAsyncTraceObject() { + final Reference reference = binder.get(); + final Trace nestedTrace = reference.get(); + if (nestedTrace != null) { + return nestedTrace; + } + + return newAsyncContextTrace(reference); + } + + private Trace newAsyncContextTrace(Reference reference) { + final Trace asyncTrace = asyncTraceContext.continueDisableAsyncContextTraceObject(traceRoot); + bind(reference, asyncTrace); + + if (logger.isDebugEnabled()) { + logger.debug("asyncTraceContext.continueDisableAsyncContextTraceObject() AsyncTrace:{}", asyncTrace); + } + + if (AsyncScopeUtils.nested(asyncTrace, ASYNC_TRACE_SCOPE)) { + return null; + } + + return asyncTrace; + } + + private void bind(Reference reference, Trace asyncTrace) { + Assert.state(reference.get() == null, "traceReference is null"); + + reference.set(asyncTrace); + } + + @Override + public Trace currentAsyncTraceObject() { + final Reference reference = binder.get(); + return reference.get(); + } + + @Override + public void close() { + binder.remove(); + } +} diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/LoggingBaseTraceFactory.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/LoggingBaseTraceFactory.java index 8abb3d1d2418..c3e3cec1f1cd 100644 --- a/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/LoggingBaseTraceFactory.java +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/LoggingBaseTraceFactory.java @@ -19,10 +19,12 @@ import com.navercorp.pinpoint.bootstrap.context.Trace; import com.navercorp.pinpoint.bootstrap.context.TraceId; import com.navercorp.pinpoint.common.annotations.InterfaceAudience; -import java.util.Objects; +import com.navercorp.pinpoint.profiler.context.id.LocalTraceRoot; import com.navercorp.pinpoint.profiler.context.id.TraceRoot; -import org.apache.logging.log4j.Logger; import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + +import java.util.Objects; /** * @author Woonduk Kang(emeroad) @@ -72,12 +74,21 @@ public Trace continueAsyncTraceObject(TraceId traceId) { } @Override - public Trace continueAsyncContextTraceObject(TraceRoot traceRoot, LocalAsyncId localAsyncId, boolean canSampled) { + public Trace continueAsyncContextTraceObject(TraceRoot traceRoot, LocalAsyncId localAsyncId) { + if (logger.isDebugEnabled()) { + logger.debug("continueAsyncTraceObject(traceRoot:{}, localAsyncId:{})", traceRoot, localAsyncId); + } + + return baseTraceFactory.continueAsyncContextTraceObject(traceRoot, localAsyncId); + } + + @Override + public Trace continueDisableAsyncContextTraceObject(LocalTraceRoot traceRoot) { if (logger.isDebugEnabled()) { - logger.debug("continueAsyncTraceObject(traceRoot:{}, localAsyncId:{}, canSampled:{})", traceRoot, localAsyncId, canSampled); + logger.debug("continueDisableAsyncContextTraceObject(traceRoot:{})", traceRoot); } - return baseTraceFactory.continueAsyncContextTraceObject(traceRoot, localAsyncId, canSampled); + return baseTraceFactory.continueDisableAsyncContextTraceObject(traceRoot); } @Override diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/StatefulAsyncContext.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/StatefulAsyncContext.java index 14c2ecc8666c..d70c206c792a 100644 --- a/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/StatefulAsyncContext.java +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/StatefulAsyncContext.java @@ -18,20 +18,24 @@ import com.navercorp.pinpoint.bootstrap.context.AsyncState; import com.navercorp.pinpoint.bootstrap.context.AsyncStateSupport; -import java.util.Objects; +import com.navercorp.pinpoint.bootstrap.context.Trace; import com.navercorp.pinpoint.profiler.context.id.TraceRoot; +import java.util.Objects; + /** * @author Woonduk Kang(emeroad) */ public class StatefulAsyncContext extends DefaultAsyncContext implements AsyncStateSupport { - private final AsyncState asyncState; - - public StatefulAsyncContext(AsyncTraceContext asyncTraceContext, TraceRoot traceRoot, AsyncId asyncId, int asyncMethodApiId, AsyncState asyncState, boolean canSampled) { - super(asyncTraceContext, traceRoot, asyncId, asyncMethodApiId, canSampled); + public StatefulAsyncContext(AsyncTraceContext asyncTraceContext, + Binder binder, + TraceRoot traceRoot, + AsyncId asyncId, int asyncMethodApiId, + AsyncState asyncState) { + super(asyncTraceContext, binder, traceRoot, asyncId, asyncMethodApiId); this.asyncState = Objects.requireNonNull(asyncState, "asyncState"); } diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/StatefulDisableAsyncContext.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/StatefulDisableAsyncContext.java new file mode 100644 index 000000000000..2fe28dea7e83 --- /dev/null +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/StatefulDisableAsyncContext.java @@ -0,0 +1,31 @@ +package com.navercorp.pinpoint.profiler.context; + +import com.navercorp.pinpoint.bootstrap.context.AsyncState; +import com.navercorp.pinpoint.bootstrap.context.AsyncStateSupport; +import com.navercorp.pinpoint.bootstrap.context.Trace; +import com.navercorp.pinpoint.profiler.context.id.LocalTraceRoot; + +import java.util.Objects; + +public class StatefulDisableAsyncContext extends DisableAsyncContext implements AsyncStateSupport { + + private final AsyncState asyncState; + + public StatefulDisableAsyncContext(AsyncTraceContext asyncTraceContext, Binder binder, LocalTraceRoot traceRoot, AsyncState asyncState) { + super(asyncTraceContext, binder, traceRoot); + this.asyncState = Objects.requireNonNull(asyncState, "asyncState"); + + } + + @Override + public AsyncState getAsyncState() { + return asyncState; + } + + @Override + public String toString() { + return "StatefulDisableAsyncContext{" + + "asyncState=" + asyncState + + "} " + super.toString(); + } +} diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/provider/AsyncContextFactoryProvider.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/provider/AsyncContextFactoryProvider.java index 9b9ce4bfdc95..7f4b75513b96 100644 --- a/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/provider/AsyncContextFactoryProvider.java +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/provider/AsyncContextFactoryProvider.java @@ -18,8 +18,10 @@ import com.google.inject.Inject; import com.google.inject.Provider; +import com.navercorp.pinpoint.bootstrap.context.Trace; import com.navercorp.pinpoint.profiler.context.AsyncContextFactory; import com.navercorp.pinpoint.profiler.context.AsyncTraceContext; +import com.navercorp.pinpoint.profiler.context.Binder; import com.navercorp.pinpoint.profiler.context.DefaultAsyncContextFactory; import com.navercorp.pinpoint.profiler.context.id.AsyncIdGenerator; import com.navercorp.pinpoint.profiler.context.method.PredefinedMethodDescriptorRegistry; @@ -33,12 +35,17 @@ public class AsyncContextFactoryProvider implements Provider asyncTraceContextProvider; private final AsyncIdGenerator asyncIdGenerator; + private final Binder binder; private final PredefinedMethodDescriptorRegistry predefinedMethodDescriptorRegistry; @Inject - public AsyncContextFactoryProvider(Provider asyncTraceContextProvider, AsyncIdGenerator asyncIdGenerator, PredefinedMethodDescriptorRegistry predefinedMethodDescriptorRegistry) { + public AsyncContextFactoryProvider(Provider asyncTraceContextProvider, + AsyncIdGenerator asyncIdGenerator, + Binder binder, + PredefinedMethodDescriptorRegistry predefinedMethodDescriptorRegistry) { this.asyncTraceContextProvider = Objects.requireNonNull(asyncTraceContextProvider, "asyncTraceContextProvider"); this.asyncIdGenerator = Objects.requireNonNull(asyncIdGenerator, "asyncIdGenerator"); + this.binder = Objects.requireNonNull(binder, "binder"); this.predefinedMethodDescriptorRegistry = Objects.requireNonNull(predefinedMethodDescriptorRegistry, "predefinedMethodDescriptorRegistry"); } @@ -47,6 +54,6 @@ public AsyncContextFactoryProvider(Provider asyncTraceContext @Override public AsyncContextFactory get() { final AsyncTraceContext asyncTraceContext = asyncTraceContextProvider.get(); - return new DefaultAsyncContextFactory(asyncTraceContext, asyncIdGenerator, predefinedMethodDescriptorRegistry); + return new DefaultAsyncContextFactory(asyncTraceContext, binder, asyncIdGenerator, predefinedMethodDescriptorRegistry); } } diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/provider/AsyncTraceContextProvider.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/provider/AsyncTraceContextProvider.java index c540191ee159..6d969816e910 100644 --- a/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/provider/AsyncTraceContextProvider.java +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/provider/AsyncTraceContextProvider.java @@ -18,10 +18,8 @@ import com.google.inject.Inject; import com.google.inject.Provider; -import com.navercorp.pinpoint.bootstrap.context.Trace; import com.navercorp.pinpoint.profiler.context.AsyncTraceContext; import com.navercorp.pinpoint.profiler.context.BaseTraceFactory; -import com.navercorp.pinpoint.profiler.context.Binder; import com.navercorp.pinpoint.profiler.context.DefaultAsyncTraceContext; import java.util.Objects; @@ -31,22 +29,16 @@ */ public class AsyncTraceContextProvider implements Provider { - - private Provider baseTraceFactoryProvider; - private final Binder binder; + private final Provider baseTraceFactoryProvider; @Inject - public AsyncTraceContextProvider(Binder binder) { - this.binder = Objects.requireNonNull(binder, "binder"); - } - - @Inject - public void setBaseTraceFactoryProvider(Provider baseTraceFactoryProvider) { + public AsyncTraceContextProvider(Provider baseTraceFactoryProvider) { this.baseTraceFactoryProvider = Objects.requireNonNull(baseTraceFactoryProvider, "baseTraceFactoryProvider"); } + @Override public AsyncTraceContext get() { - return new DefaultAsyncTraceContext(baseTraceFactoryProvider, binder); + return new DefaultAsyncTraceContext(baseTraceFactoryProvider); } } diff --git a/profiler/src/test/java/com/navercorp/pinpoint/profiler/context/AsyncContextTest.java b/profiler/src/test/java/com/navercorp/pinpoint/profiler/context/AsyncContextTest.java index f5e84060cf10..c7d1d6863ac5 100644 --- a/profiler/src/test/java/com/navercorp/pinpoint/profiler/context/AsyncContextTest.java +++ b/profiler/src/test/java/com/navercorp/pinpoint/profiler/context/AsyncContextTest.java @@ -19,7 +19,6 @@ import static org.junit.jupiter.api.Assertions.assertNull; import static org.junit.jupiter.api.Assertions.assertTrue; import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; @@ -36,7 +35,7 @@ protected AsyncTraceContext newAsyncTraceContext() { BaseTraceFactory baseTraceFactory = mock(DefaultBaseTraceFactory.class); BaseTraceFactoryProvider baseTraceFactoryProvider = mock(BaseTraceFactoryProvider.class); - when(baseTraceFactory.continueAsyncContextTraceObject(any(TraceRoot.class), any(LocalAsyncId.class), eq(true))) + when(baseTraceFactory.continueAsyncContextTraceObject(any(TraceRoot.class), any(LocalAsyncId.class))) .thenAnswer(new Answer() { @Override public Trace answer(InvocationOnMock invocationOnMock) { @@ -45,7 +44,7 @@ public Trace answer(InvocationOnMock invocationOnMock) { return trace; } }); - when(baseTraceFactory.continueAsyncContextTraceObject(any(TraceRoot.class), any(LocalAsyncId.class), eq(false))) + when(baseTraceFactory.continueDisableAsyncContextTraceObject(any(TraceRoot.class))) .thenAnswer(new Answer() { @Override public Trace answer(InvocationOnMock invocationOnMock) { @@ -54,7 +53,7 @@ public Trace answer(InvocationOnMock invocationOnMock) { }); when(baseTraceFactoryProvider.get()).thenReturn(baseTraceFactory); - return new DefaultAsyncTraceContext(baseTraceFactoryProvider, new ThreadLocalBinder()); + return new DefaultAsyncTraceContext(baseTraceFactoryProvider); } @BeforeEach @@ -77,11 +76,11 @@ public void testAsyncTraceObject() { Trace enabledTrace = enabledAsyncContext.continueAsyncTraceObject(); Trace disabledTrace = disabledAsyncContext.continueAsyncTraceObject(); assertTrue(enabledTrace instanceof AsyncChildTrace); - assertNull(disabledTrace); + assertTrue(disabledTrace instanceof DisableAsyncChildTrace); // check current trace object assertEquals(enabledTrace, enabledAsyncContext.currentAsyncTraceObject()); - assertNull(disabledAsyncContext.currentAsyncTraceObject()); + assertEquals(disabledTrace, disabledAsyncContext.currentAsyncTraceObject()); // re-invocation of continueTraceObject must not change trace object Trace anotherEnabledTrace = enabledAsyncContext.continueAsyncTraceObject(); diff --git a/profiler/src/test/java/com/navercorp/pinpoint/profiler/context/DefaultAsyncContextTest.java b/profiler/src/test/java/com/navercorp/pinpoint/profiler/context/DefaultAsyncContextTest.java index 840d04ff436c..e9cbe1644e07 100644 --- a/profiler/src/test/java/com/navercorp/pinpoint/profiler/context/DefaultAsyncContextTest.java +++ b/profiler/src/test/java/com/navercorp/pinpoint/profiler/context/DefaultAsyncContextTest.java @@ -1,11 +1,17 @@ package com.navercorp.pinpoint.profiler.context; import com.navercorp.pinpoint.bootstrap.context.AsyncContext; +import com.navercorp.pinpoint.bootstrap.context.Trace; public class DefaultAsyncContextTest extends AsyncContextTest { @Override AsyncContext newAsyncContext(boolean canSampled) { + Binder binder = new ThreadLocalBinder<>(); AsyncTraceContext asyncTraceContext = newAsyncTraceContext(); - return new DefaultAsyncContext(asyncTraceContext, traceRoot, asyncId, 0, canSampled); + if (canSampled) { + return new DefaultAsyncContext(asyncTraceContext, binder, traceRoot, asyncId, 0); + } else { + return new DisableAsyncContext(asyncTraceContext, binder, traceRoot); + } } } diff --git a/profiler/src/test/java/com/navercorp/pinpoint/profiler/context/DefaultAsyncTraceContextTest.java b/profiler/src/test/java/com/navercorp/pinpoint/profiler/context/DefaultAsyncTraceContextTest.java index 89f6360da8d7..599f08f4c5ad 100644 --- a/profiler/src/test/java/com/navercorp/pinpoint/profiler/context/DefaultAsyncTraceContextTest.java +++ b/profiler/src/test/java/com/navercorp/pinpoint/profiler/context/DefaultAsyncTraceContextTest.java @@ -1,24 +1,15 @@ package com.navercorp.pinpoint.profiler.context; import com.navercorp.pinpoint.bootstrap.context.Trace; -import com.navercorp.pinpoint.exception.PinpointException; import com.navercorp.pinpoint.profiler.context.id.TraceRoot; import com.navercorp.pinpoint.profiler.context.provider.BaseTraceFactoryProvider; -import org.junit.jupiter.api.Assertions; -import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.mockito.Mock; import org.mockito.invocation.InvocationOnMock; import org.mockito.junit.jupiter.MockitoExtension; -import org.mockito.junit.jupiter.MockitoSettings; -import org.mockito.quality.Strictness; import org.mockito.stubbing.Answer; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertNull; -import static org.junit.jupiter.api.Assertions.assertTrue; import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; @@ -35,7 +26,7 @@ protected AsyncTraceContext newAsyncTraceContext() { BaseTraceFactory baseTraceFactory = mock(DefaultBaseTraceFactory.class); BaseTraceFactoryProvider baseTraceFactoryProvider = mock(BaseTraceFactoryProvider.class); - when(baseTraceFactory.continueAsyncContextTraceObject(any(TraceRoot.class), any(LocalAsyncId.class), eq(true))) + when(baseTraceFactory.continueAsyncContextTraceObject(any(TraceRoot.class), any(LocalAsyncId.class))) .thenAnswer(new Answer() { @Override public Trace answer(InvocationOnMock invocationOnMock) { @@ -44,7 +35,7 @@ public Trace answer(InvocationOnMock invocationOnMock) { return trace; } }); - when(baseTraceFactory.continueAsyncContextTraceObject(any(TraceRoot.class), any(LocalAsyncId.class), eq(false))) + when(baseTraceFactory.continueDisableAsyncContextTraceObject(any(TraceRoot.class))) .thenAnswer(new Answer() { @Override public Trace answer(InvocationOnMock invocationOnMock) { @@ -53,53 +44,22 @@ public Trace answer(InvocationOnMock invocationOnMock) { }); when(baseTraceFactoryProvider.get()).thenReturn(baseTraceFactory); - return new DefaultAsyncTraceContext(baseTraceFactoryProvider, new ThreadLocalBinder()); + return new DefaultAsyncTraceContext(baseTraceFactoryProvider); } - @MockitoSettings(strictness = Strictness.LENIENT) - @Test - public void testNewAsyncTraceObject() { - AsyncTraceContext asyncTraceContext = newAsyncTraceContext(); +// @MockitoSettings(strictness = Strictness.LENIENT) +// @Test +// public void testNewAsyncTraceObject() { +// AsyncTraceContext asyncTraceContext = newAsyncTraceContext(); +// +// // new trace object +// Trace newTraceEnabled = asyncTraceContext.newAsyncContextTraceObject(traceRoot, localAsyncId, true); +// assertTrue(newTraceEnabled instanceof AsyncChildTrace); +// assertNull(asyncTraceContext.currentRawTraceObject().get()); +// +// Trace newTraceDisabled = asyncTraceContext.newAsyncContextTraceObject(traceRoot, localAsyncId, false); +// assertTrue(newTraceDisabled instanceof DisableAsyncChildTrace); +// assertNull(asyncTraceContext.currentRawTraceObject().get()); +// } - // new trace object - Trace newTraceEnabled = asyncTraceContext.newAsyncContextTraceObject(traceRoot, localAsyncId, true); - assertTrue(newTraceEnabled instanceof AsyncChildTrace); - assertNull(asyncTraceContext.currentRawTraceObject().get()); - - Trace newTraceDisabled = asyncTraceContext.newAsyncContextTraceObject(traceRoot, localAsyncId, false); - assertTrue(newTraceDisabled instanceof DisableAsyncChildTrace); - assertNull(asyncTraceContext.currentRawTraceObject().get()); - } - - @Test - public void testAsyncTraceContext() { - AsyncTraceContext asyncTraceContext = newAsyncTraceContext(); - - // sampling enabled - Reference continueTraceEnabled = asyncTraceContext.continueAsyncContextTraceObject(traceRoot, localAsyncId, true); - assertTrue(continueTraceEnabled.get() instanceof AsyncChildTrace); - assertEquals(continueTraceEnabled, asyncTraceContext.currentRawTraceObject()); - assertEquals(continueTraceEnabled, asyncTraceContext.currentTraceObject()); - - // remove trace object - asyncTraceContext.removeTraceObject(); - assertNull(asyncTraceContext.currentRawTraceObject().get()); - - // sampling disabled - Reference continueTraceDisabled = asyncTraceContext.continueAsyncContextTraceObject(traceRoot, localAsyncId, false); - assertTrue(continueTraceDisabled.get() instanceof DisableAsyncChildTrace); - assertEquals(continueTraceDisabled, asyncTraceContext.currentRawTraceObject()); - assertEquals(EMPTY, asyncTraceContext.currentTraceObject()); - } - - @MockitoSettings(strictness = Strictness.LENIENT) - @Test - public void testOverrideTrace() { - Assertions.assertThrows(PinpointException.class, () -> { - AsyncTraceContext asyncTraceContext = newAsyncTraceContext(); - - asyncTraceContext.continueAsyncContextTraceObject(traceRoot, localAsyncId, true); - asyncTraceContext.continueAsyncContextTraceObject(traceRoot, localAsyncId, false); - }); - } } diff --git a/profiler/src/test/java/com/navercorp/pinpoint/profiler/context/StatefulAsyncContextTest.java b/profiler/src/test/java/com/navercorp/pinpoint/profiler/context/StatefulAsyncContextTest.java index 5bfdfeee1bf4..29f3775faa96 100644 --- a/profiler/src/test/java/com/navercorp/pinpoint/profiler/context/StatefulAsyncContextTest.java +++ b/profiler/src/test/java/com/navercorp/pinpoint/profiler/context/StatefulAsyncContextTest.java @@ -2,6 +2,7 @@ import com.navercorp.pinpoint.bootstrap.context.AsyncContext; import com.navercorp.pinpoint.bootstrap.context.AsyncState; +import com.navercorp.pinpoint.bootstrap.context.Trace; import org.junit.jupiter.api.Test; import org.mockito.Mock; import org.mockito.junit.jupiter.MockitoSettings; @@ -15,8 +16,13 @@ public class StatefulAsyncContextTest extends AsyncContextTest { @Override AsyncContext newAsyncContext(boolean canSampled) { + Binder binder = new ThreadLocalBinder<>(); AsyncTraceContext asyncTraceContext = newAsyncTraceContext(); - return new StatefulAsyncContext(asyncTraceContext, traceRoot, asyncId, 0, asyncState, canSampled); + if (canSampled) { + return new StatefulAsyncContext(asyncTraceContext, binder, traceRoot, asyncId, 0, asyncState); + } else { + return new DisableAsyncContext(asyncTraceContext, binder, traceRoot); + } } @Test diff --git a/profiler/src/test/java/com/navercorp/pinpoint/profiler/context/id/LocalTraceTest.java b/profiler/src/test/java/com/navercorp/pinpoint/profiler/context/id/LocalTraceTest.java index aca552faf47c..281beeb412ff 100644 --- a/profiler/src/test/java/com/navercorp/pinpoint/profiler/context/id/LocalTraceTest.java +++ b/profiler/src/test/java/com/navercorp/pinpoint/profiler/context/id/LocalTraceTest.java @@ -5,7 +5,6 @@ import com.navercorp.pinpoint.bootstrap.context.Trace; import com.navercorp.pinpoint.profiler.context.DisableAsyncChildTrace; import com.navercorp.pinpoint.profiler.context.DisableTrace; -import com.navercorp.pinpoint.profiler.context.LocalAsyncId; import com.navercorp.pinpoint.profiler.context.active.ActiveTraceHandle; import com.navercorp.pinpoint.profiler.context.storage.UriStatStorage; import org.junit.jupiter.api.Assertions; @@ -77,7 +76,6 @@ private Trace newTrace(LocalTraceRoot traceRoot) { } private Trace newChildTrace(LocalTraceRoot traceRoot) { - LocalAsyncId localAsyncId = mock(LocalAsyncId.class); - return new DisableAsyncChildTrace(traceRoot, localAsyncId); + return new DisableAsyncChildTrace(traceRoot); } } \ No newline at end of file