package org.stagemonitor.logging;
import net.bytebuddy.asm.Advice;
import net.bytebuddy.description.method.MethodDescription;
import net.bytebuddy.description.type.TypeDescription;
import net.bytebuddy.matcher.ElementMatcher;
import org.stagemonitor.core.Stagemonitor;
import org.stagemonitor.core.instrument.StagemonitorByteBuddyTransformer;
import org.stagemonitor.core.metrics.metrics2.Metric2Registry;
import org.stagemonitor.core.metrics.metrics2.MetricName;
import static net.bytebuddy.matcher.ElementMatchers.isPrivate;
import static net.bytebuddy.matcher.ElementMatchers.named;
import static net.bytebuddy.matcher.ElementMatchers.not;
import static org.stagemonitor.core.metrics.metrics2.MetricName.name;
/**
* Tracks the rate of calls to a logger.
* <p.>
* Currently has support for Logback, slf4j's simple logger and JDK14LoggerAdapter, log4j 1.x and 2.x
*/
public class MeterLoggingTransformer extends StagemonitorByteBuddyTransformer {
private final static MetricName.MetricNameTemplate logTemplate = name("logging").templateFor("log_level");
private final static Metric2Registry registry = Stagemonitor.getMetric2Registry();
@Override
public ElementMatcher.Junction<TypeDescription> getTypeMatcher() {
return named("ch.qos.logback.classic.Logger")
.or(named("org.slf4j.impl.SimpleLogger"))
.or(named("org.apache.logging.log4j.spi.AbstractLogger"))
.or(named("org.apache.log4j.Logger"))
.or(named("org.slf4j.impl.JDK14LoggerAdapter"));
}
@Override
protected ElementMatcher.Junction<MethodDescription> getExtraMethodElementMatcher() {
return not(isPrivate())
.and(named("trace")
.or(named("debug"))
.or(named("info"))
.or(named("warn"))
.or(named("error"))
.or(named("fatal"))
);
}
@Advice.OnMethodEnter(inline = false)
public static void onEnterLog(@Advice.Origin("#m") String methodName) {
registry.meter(logTemplate.build(methodName)).mark();
}
}