package org.stagemonitor.tracing;
import com.uber.jaeger.context.TraceContext;
import com.uber.jaeger.context.TracingUtils;
import org.stagemonitor.configuration.ConfigurationRegistry;
import org.stagemonitor.core.CorePlugin;
import org.stagemonitor.core.metrics.metrics2.Metric2Registry;
import org.stagemonitor.core.metrics.metrics2.MetricName;
import org.stagemonitor.tracing.utils.SpanUtils;
import io.opentracing.Span;
import static java.util.concurrent.TimeUnit.NANOSECONDS;
import static org.stagemonitor.core.metrics.metrics2.MetricName.name;
public class RequestMonitor {
private final MetricName internalOverheadMetricName = name("internal_overhead_request_monitor").build();
private Metric2Registry metricRegistry;
private CorePlugin corePlugin;
private TracingPlugin tracingPlugin;
public RequestMonitor(ConfigurationRegistry configuration, Metric2Registry registry) {
this(configuration, registry, configuration.getConfig(TracingPlugin.class));
}
private RequestMonitor(ConfigurationRegistry configuration, Metric2Registry registry, TracingPlugin tracingPlugin) {
this.metricRegistry = registry;
this.corePlugin = configuration.getConfig(CorePlugin.class);
this.tracingPlugin = tracingPlugin;
}
public void monitorStart(MonitoredRequest monitoredRequest) {
final long start = System.nanoTime();
monitoredRequest.createSpan();
final SpanContextInformation info = SpanContextInformation.getCurrent();
if (info != null) {
info.setOverhead1(System.nanoTime() - start);
}
}
public void monitorStop() {
final TraceContext traceContext = TracingUtils.getTraceContext();
if (!traceContext.isEmpty()) {
final Span currentSpan = traceContext.getCurrentSpan();
final SpanContextInformation info = SpanContextInformation.forSpan(currentSpan);
if (info != null) {
long overhead2 = System.nanoTime();
currentSpan.finish();
trackOverhead(info.getOverhead1(), overhead2);
}
}
}
public SpanContextInformation monitor(MonitoredRequest monitoredRequest) throws Exception {
try {
monitorStart(monitoredRequest);
monitoredRequest.execute();
return SpanContextInformation.getCurrent();
} catch (Exception e) {
recordException(e);
throw e;
} finally {
monitorStop();
}
}
public void recordException(Exception e) {
SpanUtils.setException(TracingPlugin.getCurrentSpan(), e, tracingPlugin.getIgnoreExceptions(), tracingPlugin.getUnnestExceptions());
}
private void trackOverhead(long overhead1, long overhead2) {
if (corePlugin.isInternalMonitoringActive()) {
overhead2 = System.nanoTime() - overhead2;
metricRegistry.timer(internalOverheadMetricName).update(overhead2 + overhead1, NANOSECONDS);
}
}
}