package org.stagemonitor.tracing.sampling;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.stagemonitor.configuration.ConfigurationRegistry;
import org.stagemonitor.tracing.SpanContextInformation;
import org.stagemonitor.tracing.wrapper.SpanWrapper;
import org.stagemonitor.tracing.wrapper.StatelessSpanEventListener;
import java.util.Collection;
import java.util.ServiceLoader;
import java.util.concurrent.CopyOnWriteArrayList;
import io.opentracing.tag.Tags;
public class SamplePriorityDeterminingSpanEventListener extends StatelessSpanEventListener {
private static final Logger logger = LoggerFactory.getLogger(SamplePriorityDeterminingSpanEventListener.class);
private final Collection<PreExecutionSpanInterceptor> preInterceptors =
new CopyOnWriteArrayList<PreExecutionSpanInterceptor>();
private final Collection<PostExecutionSpanInterceptor> postInterceptors =
new CopyOnWriteArrayList<PostExecutionSpanInterceptor>();
private final ConfigurationRegistry configuration;
public SamplePriorityDeterminingSpanEventListener(ConfigurationRegistry configuration) {
this.configuration = configuration;
registerPreInterceptors();
registerPostInterceptors();
}
private void registerPreInterceptors() {
for (PreExecutionSpanInterceptor interceptor : ServiceLoader.load(
PreExecutionSpanInterceptor.class,
SamplePriorityDeterminingSpanEventListener.class.getClassLoader())) {
addPreInterceptor(interceptor);
}
}
private void registerPostInterceptors() {
addPostInterceptor(new NameFilteringPostExecutionInterceptor());
addPostInterceptor(new FastExternalSpanExcludingPostExecutionInterceptor());
for (PostExecutionSpanInterceptor interceptor : ServiceLoader.load(
PostExecutionSpanInterceptor.class,
SamplePriorityDeterminingSpanEventListener.class.getClassLoader())) {
addPostInterceptor(interceptor);
}
}
@Override
public void onStart(SpanWrapper spanWrapper) {
final SpanContextInformation spanContext = SpanContextInformation.forSpan(spanWrapper);
if (!spanContext.isSampled()) {
return;
}
PreExecutionInterceptorContext context = new PreExecutionInterceptorContext(spanContext);
for (PreExecutionSpanInterceptor interceptor : preInterceptors) {
try {
interceptor.interceptReport(context);
} catch (Exception e) {
logger.warn(e.getMessage(), e);
}
}
spanContext.setPreExecutionInterceptorContext(context);
if (!context.isReport()) {
spanContext.setSampled(false);
Tags.SAMPLING_PRIORITY.set(spanWrapper, (short) 0);
}
}
@Override
public void onFinish(SpanWrapper spanWrapper, String operationName, long durationNanos) {
final SpanContextInformation info = SpanContextInformation.forSpan(spanWrapper);
if (!info.isSampled()) {
return;
}
PostExecutionInterceptorContext context = new PostExecutionInterceptorContext(info);
for (PostExecutionSpanInterceptor interceptor : postInterceptors) {
try {
interceptor.interceptReport(context);
} catch (Exception e) {
logger.warn(e.getMessage(), e);
}
}
info.setPostExecutionInterceptorContext(context);
if (!context.isReport()) {
info.setSampled(false);
Tags.SAMPLING_PRIORITY.set(spanWrapper, (short) 0);
}
}
public void addPreInterceptor(PreExecutionSpanInterceptor interceptor) {
interceptor.init(configuration);
preInterceptors.add(interceptor);
}
public void addPostInterceptor(PostExecutionSpanInterceptor interceptor) {
interceptor.init(configuration);
postInterceptors.add(interceptor);
}
}