package org.stagemonitor.core.instrument;
import com.codahale.metrics.Counter;
import net.bytebuddy.matcher.ElementMatcher;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.stagemonitor.core.CorePlugin;
import org.stagemonitor.core.Stagemonitor;
import org.stagemonitor.core.metrics.SortedTableLogReporter;
import org.stagemonitor.core.metrics.metrics2.Metric2Registry;
import java.util.concurrent.TimeUnit;
import static org.stagemonitor.core.metrics.metrics2.MetricName.name;
public class TimedElementMatcherDecorator<T> implements ElementMatcher<T> {
private static final Logger logger = LoggerFactory.getLogger(TimedElementMatcherDecorator.class);
private static final boolean DEBUG_INSTRUMENTATION = Stagemonitor.getConfiguration().getConfig(CorePlugin.class).isDebugInstrumentation();
private static final Metric2Registry timeRegistry = new Metric2Registry();
private static final Metric2Registry countRegistry = new Metric2Registry();
private final ElementMatcher<T> delegate;
private final Counter count;
private final Counter time;
public static <T> ElementMatcher<T> timed(String type, String transformerName, ElementMatcher<T> delegate) {
if (DEBUG_INSTRUMENTATION) {
return new TimedElementMatcherDecorator<T>(delegate, type, transformerName);
} else {
return delegate;
}
}
private TimedElementMatcherDecorator(ElementMatcher<T> delegate, String type, String transformerName) {
this.delegate = delegate;
this.count = countRegistry
.counter(name("element_matcher").type(type).tag("transformer", transformerName).build());
this.time = timeRegistry
.counter(name("element_matcher").type(type).tag("transformer", transformerName).build());
}
@Override
public boolean matches(T target) {
long start = System.nanoTime();
try {
return delegate.matches(target);
} finally {
count.inc();
time.inc(System.nanoTime() - start);
}
}
public static void logMetrics() {
if (DEBUG_INSTRUMENTATION) {
logger.info("ElementMatcher TIME (nanoseconds total)");
SortedTableLogReporter.forRegistry(timeRegistry).convertDurationsTo(TimeUnit.MICROSECONDS).build().report();
logger.info("ElementMatcher COUNT");
SortedTableLogReporter.forRegistry(countRegistry).convertDurationsTo(TimeUnit.MICROSECONDS).build().report();
long totalTime = 0;
for (Counter counter : timeRegistry.getCounters().values()) {
totalTime += counter.getCount();
}
logger.info("Total time: {} ms", TimeUnit.NANOSECONDS.toMillis(totalTime));
}
}
}