提交 112547b5 编写于 作者: wu-sheng's avatar wu-sheng

Finish almost all codes about ignore, sample and analytic trace mechanism....

Finish almost all codes about ignore, sample and analytic trace mechanism. Left analytic trace only for collector.
上级 c88cf2af
......@@ -2,12 +2,14 @@ package org.skywalking.apm.agent.core.context;
import java.util.LinkedList;
import java.util.List;
import org.skywalking.apm.agent.core.boot.ServiceManager;
import org.skywalking.apm.agent.core.conf.Config;
import org.skywalking.apm.agent.core.context.trace.AbstractSpan;
import org.skywalking.apm.agent.core.context.trace.LeafSpan;
import org.skywalking.apm.agent.core.context.trace.Span;
import org.skywalking.apm.agent.core.context.trace.TraceSegment;
import org.skywalking.apm.agent.core.context.trace.TraceSegmentRef;
import org.skywalking.apm.agent.core.sampling.SamplingService;
/**
* {@link TracerContext} maintains the context.
......@@ -73,17 +75,42 @@ public final class TracerContext implements AbstractTracerContext {
span = new Span(spanIdGenerator++, operationName, startTime);
}
push(span);
} else if (parentSpan.isLeaf()) {
span = parentSpan;
LeafSpan leafSpan = (LeafSpan)span;
leafSpan.push();
} else {
if (isLeaf) {
span = new LeafSpan(spanIdGenerator++, parentSpan, operationName, startTime);
/**
* Don't have ref yet, means this isn't part of distributed trace.
* Use sampling mechanism
* Only check this on the second span,
* because the {@link #extract(ContextCarrier)} invoke before create the second span.
*/
if (spanIdGenerator == 1) {
SamplingService samplingService = ServiceManager.INSTANCE.findService(SamplingService.class);
if (segment.hasRef()) {
samplingService.forceSampled();
} else {
if (!samplingService.trySampling()) {
/**
* Don't sample this trace.
* Now, switch this trace as an {@link IgnoredTracerContext},
* further more, we will provide an analytic tracer context for all metrics in this trace.
*/
ContextManager.ContextSwitcher.INSTANCE.toNew(new IgnoredTracerContext(2));
return ContextManager.activeSpan();
}
}
}
if (parentSpan.isLeaf()) {
span = parentSpan;
LeafSpan leafSpan = (LeafSpan)span;
leafSpan.push();
} else {
span = new Span(spanIdGenerator++, parentSpan, operationName, startTime);
if (isLeaf) {
span = new LeafSpan(spanIdGenerator++, parentSpan, operationName, startTime);
} else {
span = new Span(spanIdGenerator++, parentSpan, operationName, startTime);
}
push(span);
}
push(span);
}
return span;
}
......
......@@ -178,6 +178,10 @@ public class TraceSegment {
return Collections.unmodifiableList(refs);
}
public boolean hasRef() {
return !(refs == null || refs.size() == 0);
}
public List<DistributedTraceId> getRelatedGlobalTraces() {
return relatedGlobalTraces.getRelatedGlobalTraces();
}
......
package org.skywalking.apm.agent.core.sampling;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
import org.skywalking.apm.agent.core.boot.BootService;
import org.skywalking.apm.agent.core.conf.Config;
import org.skywalking.apm.agent.core.context.ContextCarrier;
import org.skywalking.apm.agent.core.context.trace.TraceSegment;
import org.skywalking.apm.logging.ILog;
import org.skywalking.apm.logging.LogManager;
......@@ -20,29 +23,53 @@ public class SamplingService implements BootService {
private static final ILog logger = LogManager.getLogger(SamplingService.class);
private volatile boolean on = false;
private volatile int rollingSeed = 1;
private volatile AtomicInteger samplingFactorHolder;
@Override
public void bootUp() throws Throwable {
if (Config.Agent.SAMPLE_N_PER_10_SECS > 0) {
on = true;
this.resetSamplingFactor();
ScheduledExecutorService service = Executors
.newSingleThreadScheduledExecutor();
service.scheduleAtFixedRate(new Runnable() {
@Override
public void run() {
resetSamplingFactor();
}
}, 1, 1, TimeUnit.SECONDS);
logger.debug("Agent sampling mechanism started. Sample {} traces in 10 seconds.", Config.Agent.SAMPLE_N_PER_10_SECS);
}
}
public void trySampling(TraceSegment segment) {
/**
* @return true, if sampling mechanism is on, and get the sampling factor successfully.
*/
public boolean trySampling() {
if (on) {
int factor = samplingFactorHolder.get();
if (factor < Config.Agent.SAMPLE_N_PER_10_SECS) {
return samplingFactorHolder.compareAndSet(factor, factor + 1);
} else {
return false;
}
}
return true;
}
/**
* Set the {@link TraceSegment} to sampled, when {@link ContextCarrier} contains "isSampled" flag.
* <p>
* A -> B, if TraceSegment is sampled in A, then the related TraceSegment in B must be sampled, no matter you
* sampling rate. And reset the {@link #rollingSeed}, in case of too many {@link TraceSegment}s, which started in
* this JVM, are sampled.
*
* @param segment the current TraceSegment.
* @param carrier
* Increase the sampling factor by force,
* to avoid sampling too many traces.
* If many distributed traces require sampled,
* the trace beginning at local, has less chance to be sampled.
*/
public void setSampleWhenExtract(TraceSegment segment, ContextCarrier carrier) {
public void forceSampled() {
if (on) {
samplingFactorHolder.incrementAndGet();
}
}
private void resetSamplingFactor() {
samplingFactorHolder = new AtomicInteger(0);
}
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册