package org.stagemonitor.core.metrics.annotations; import com.codahale.metrics.annotation.Metered; import net.bytebuddy.asm.Advice; import net.bytebuddy.description.method.MethodDescription; import net.bytebuddy.matcher.ElementMatcher; import org.stagemonitor.core.Stagemonitor; import org.stagemonitor.core.instrument.StagemonitorByteBuddyTransformer; import org.stagemonitor.core.metrics.metrics2.MetricName; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; import java.util.Collections; import java.util.List; import static net.bytebuddy.matcher.ElementMatchers.isAnnotatedWith; import static org.stagemonitor.core.metrics.metrics2.MetricName.name; /** * Implementation for the {@link Metered} annotation */ public class MeteredTransformer extends StagemonitorByteBuddyTransformer { public static final MetricName.MetricNameTemplate metricNameTemplate = name("rate").templateFor("signature"); @Override protected ElementMatcher.Junction<MethodDescription> getExtraMethodElementMatcher() { return isAnnotatedWith(Metered.class); } @Advice.OnMethodEnter public static void meter(@MeteredSignature String signature) { Stagemonitor.getMetric2Registry().meter(metricNameTemplate.build(signature)).mark(); } @Override protected List<StagemonitorDynamicValue<?>> getDynamicValues() { return Collections.<StagemonitorDynamicValue<?>>singletonList(new MeteredSignatureDynamicValue()); } @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.PARAMETER) public @interface MeteredSignature { } public static class MeteredSignatureDynamicValue extends MetricAnnotationSignatureDynamicValue<MeteredSignature> { @Override protected NamingParameters getNamingParameters(MethodDescription instrumentedMethod) { final Metered metered = instrumentedMethod.getDeclaredAnnotations().ofType(Metered.class).loadSilent(); return new NamingParameters(metered.name(), metered.absolute()); } @Override public Class<MeteredSignature> getAnnotationClass() { return MeteredSignature.class; } } }