Skip to content
Merged
Show file tree
Hide file tree
Changes from 8 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ Release Notes.
* Fix typos in `URLParser`.
* Add support for `Derby`/`Sybase`/`SQLite`/`DB2`/`OceanBase` jdbc url format in `URLParser`.
* Optimize spring-plugins:scheduled-annotation-plugin compatibility about Spring 6.1.x support.
* Add a forceIgnoring mechanism in a CROSS_THREAD scenario.

All issues and pull requests are [here](https://github.com/apache/skywalking/milestone/213?closed=1)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -138,4 +138,10 @@ public interface AbstractTracerContext {
* Get current primary endpoint name
*/
String getPrimaryEndpointName();

/**
* Change the current context to IgnoredTracerContext.
Comment thread
gzlicanyi marked this conversation as resolved.
Outdated
*/
AbstractTracerContext forceIgnoring();

}
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,12 @@ public static void continued(ContextSnapshot snapshot) {
throw new IllegalArgumentException("ContextSnapshot can't be null.");
}
if (!snapshot.isFromCurrent()) {
get().continued(snapshot);
if (snapshot.isValid()) {
Comment thread
gzlicanyi marked this conversation as resolved.
get().continued(snapshot);
} else {
AbstractTracerContext context = get().forceIgnoring();
CONTEXT.set(context);
}
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,13 @@ public IgnoredTracerContext() {
this.profileStatusContext = ProfileStatusContext.createWithNone();
}

public IgnoredTracerContext(int stackDepth) {
this.stackDepth = stackDepth;
this.correlationContext = new CorrelationContext();
this.extensionContext = new ExtensionContext();
this.profileStatusContext = ProfileStatusContext.createWithNone();
}

@Override
public void inject(ContextCarrier carrier) {
this.correlationContext.inject(carrier);
Expand Down Expand Up @@ -134,6 +141,11 @@ public String getPrimaryEndpointName() {
return null;
}

@Override
public AbstractTracerContext forceIgnoring() {
return this;
}

public static class ListenerManager {
private static List<IgnoreTracerContextListener> LISTENERS = new LinkedList<>();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -419,6 +419,14 @@ public String getPrimaryEndpointName() {
return primaryEndpoint.getName();
}

@Override
public AbstractTracerContext forceIgnoring() {
for (AbstractSpan span: activeSpanStack) {
span.forceIgnoring();
}
return new IgnoredTracerContext(activeSpanStack.size());
}

/**
* Re-check current trace need profiling, encase third part plugin change the operation name.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -124,4 +124,9 @@ public interface AbstractSpan extends AsyncSpan {
* Should skip analysis in the backend.
*/
void skipAnalysis();

/**
* Set to ignored status.
*/
void forceIgnoring();
}
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,8 @@ public abstract class AbstractTracingSpan implements AbstractSpan {
private volatile boolean isAsyncStopped = false;

/**
* The context to which the span belongs
* The context to which the span belongs.
* This should not be called when ignored is set to true.
Comment thread
gzlicanyi marked this conversation as resolved.
Outdated
*/
protected final TracingContext owner;

Expand Down Expand Up @@ -99,6 +100,11 @@ public abstract class AbstractTracingSpan implements AbstractSpan {
*/
protected boolean skipAnalysis;

/**
* The ignore flag of this span.
*/
protected boolean ignored;

protected AbstractTracingSpan(int spanId, int parentSpanId, String operationName, TracingContext owner) {
this.operationName = operationName;
this.spanId = spanId;
Expand Down Expand Up @@ -318,7 +324,9 @@ public AbstractSpan prepareForAsync() {
if (isInAsyncMode) {
throw new RuntimeException("Prepare for async repeatedly. Span is already in async mode.");
}
ContextManager.awaitFinishAsync(this);
if (!ignored) {
ContextManager.awaitFinishAsync(this);
}
isInAsyncMode = true;
return this;
}
Expand All @@ -332,18 +340,28 @@ public AbstractSpan asyncFinish() {
throw new RuntimeException("Can not do async finish for the span repeatedly.");
}
this.endTime = System.currentTimeMillis();
owner.asyncStop(this);
if (!ignored) {
owner.asyncStop(this);
}
isAsyncStopped = true;
return this;
}

@Override
public boolean isProfiling() {
if (ignored) {
return false;
}
return this.owner.profileStatus().isProfiling();
}

@Override
public void skipAnalysis() {
this.skipAnalysis = true;
}

@Override
public void forceIgnoring() {
this.ignored = true;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,9 @@ public String getPeer() {

@Override
public ExitSpan inject(final ContextCarrier carrier) {
this.owner.inject(this, carrier);
if (!ignored) {
this.owner.inject(this, carrier);
}
return this;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,10 @@ public boolean isProfiling() {
public void skipAnalysis() {
}

@Override
public void forceIgnoring() {
}

@Override
public AbstractSpan prepareForAsync() {
return this;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/

package org.apache.skywalking.apm.agent.core.context;

import org.apache.skywalking.apm.agent.core.boot.ServiceManager;
import org.apache.skywalking.apm.agent.core.conf.Config;
import org.apache.skywalking.apm.agent.core.context.ids.NewDistributedTraceId;
import org.apache.skywalking.apm.agent.core.context.trace.AbstractSpan;
import org.apache.skywalking.apm.agent.core.context.trace.LocalSpan;
import org.apache.skywalking.apm.agent.core.context.trace.NoopSpan;
import org.apache.skywalking.apm.agent.core.profile.ProfileStatusContext;
import org.apache.skywalking.apm.agent.core.test.tools.AgentServiceRule;
import org.apache.skywalking.apm.agent.core.test.tools.SegmentStorage;
import org.apache.skywalking.apm.agent.core.test.tools.SegmentStoragePoint;
import org.apache.skywalking.apm.agent.core.test.tools.TracingSegmentRunner;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.Assert;

@RunWith(TracingSegmentRunner.class)
public class ContinuedContextTest {

@SegmentStoragePoint
private SegmentStorage tracingData;

@Rule
public AgentServiceRule agentServiceRule = new AgentServiceRule();

@BeforeClass
public static void beforeClass() {
Config.Agent.KEEP_TRACING = true;
}

@AfterClass
public static void afterClass() {
Config.Agent.KEEP_TRACING = false;
ServiceManager.INSTANCE.shutdown();
}

@Test
public void testContinued() {

NewDistributedTraceId distributedTraceId = new NewDistributedTraceId();
ContextSnapshot snapshot = new ContextSnapshot(
"1, 2, 3",
1,
distributedTraceId,
"/for-test-continued",
new CorrelationContext(),
new ExtensionContext(),
ProfileStatusContext.createWithNone()
);

AbstractSpan span = ContextManager.createLocalSpan("test-span");
ContextManager.continued(snapshot);

Assert.assertEquals(distributedTraceId.getId(), ContextManager.getGlobalTraceId());
ContextManager.stopSpan();
}

@Test
public void testContinuedWithIgnoredSnapshot() {

ContextSnapshot snapshot =
new ContextSnapshot(null, -1, null, null, new CorrelationContext(), new ExtensionContext(), ProfileStatusContext.createWithNone());

AbstractSpan span = ContextManager.createLocalSpan("test-span");
ContextManager.continued(snapshot);

Assert.assertTrue(span instanceof LocalSpan);

AbstractSpan span2 = ContextManager.createLocalSpan("test-span2");
Assert.assertTrue(span2 instanceof NoopSpan);

ContextManager.stopSpan();
ContextManager.stopSpan();
}

}