From 507235c04bc2d30d6b0c4f62f1adea3988b7a078 Mon Sep 17 00:00:00 2001 From: Antonin Stefanutti Date: Sun, 19 Oct 2014 22:44:20 +0200 Subject: [PATCH] Support multiple Metrics annotations per method --- .../aspectj/se/MultipleMetricsMethod.java | 34 ++++++++ .../se/MultipleMetricsStaticMethod.java | 34 ++++++++ .../se/TimedMethodWithAbsoluteName.java | 4 +- ...augeMethodWithVisibilityModifiersTest.java | 2 +- .../se/MeteredMethodWithExceptionsTest.java | 2 +- ...MeteredStaticMethodWithExceptionsTest.java | 2 +- .../se/MetricMethodWithDefaultNamesTest.java | 2 +- .../aspectj/se/MultipleMetricsMethodTest.java | 86 +++++++++++++++++++ .../se/MultipleMetricsStaticMethodTest.java | 61 +++++++++++++ .../aspectj/se/TimedMethodOverloadedTest.java | 2 +- .../se/TimedMethodWithAbsoluteNameTest.java | 4 +- ...imedMethodWithVisibilityModifiersTest.java | 2 +- ...aticMethodWithVisibilityModifiersTest.java | 2 +- .../metrics/aspectj/se/util/MetricsUtil.java | 5 +- .../metrics/aspectj/AbstractMetricAspect.aj | 14 ++- .../metrics/aspectj/ExceptionMeteredAspect.aj | 7 +- .../aspectj/ExceptionMeteredStaticAspect.aj | 7 +- .../metrics/aspectj/MeteredAspect.aj | 2 +- .../metrics/aspectj/MeteredStaticAspect.aj | 2 +- .../metrics/aspectj/MetricAspect.aj | 52 ++++++----- .../metrics/aspectj/MetricStaticAspect.aj | 52 ++++++----- .../stefanutti/metrics/aspectj/TimedAspect.aj | 2 +- .../metrics/aspectj/TimedStaticAspect.aj | 2 +- .../metrics/aspectj/AnnotatedMetric.java | 60 ++++++++++--- 24 files changed, 357 insertions(+), 85 deletions(-) create mode 100644 envs/se/src/main/java/org/stefanutti/metrics/aspectj/se/MultipleMetricsMethod.java create mode 100644 envs/se/src/main/java/org/stefanutti/metrics/aspectj/se/MultipleMetricsStaticMethod.java create mode 100644 envs/se/src/test/java/org/stefanutti/metrics/aspectj/se/MultipleMetricsMethodTest.java create mode 100644 envs/se/src/test/java/org/stefanutti/metrics/aspectj/se/MultipleMetricsStaticMethodTest.java diff --git a/envs/se/src/main/java/org/stefanutti/metrics/aspectj/se/MultipleMetricsMethod.java b/envs/se/src/main/java/org/stefanutti/metrics/aspectj/se/MultipleMetricsMethod.java new file mode 100644 index 0000000..35cfc3f --- /dev/null +++ b/envs/se/src/main/java/org/stefanutti/metrics/aspectj/se/MultipleMetricsMethod.java @@ -0,0 +1,34 @@ +/** + * Copyright (C) 2013 Antonin Stefanutti (antonin.stefanutti@gmail.com) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.stefanutti.metrics.aspectj.se; + +import com.codahale.metrics.annotation.ExceptionMetered; +import com.codahale.metrics.annotation.Gauge; +import com.codahale.metrics.annotation.Metered; +import com.codahale.metrics.annotation.Timed; +import org.stefanutti.metrics.aspectj.Metrics; + +@Metrics(registry = "multipleMetricsRegistry") +public class MultipleMetricsMethod { + + @ExceptionMetered(name = "exception") + @Gauge(name = "gauge") + @Metered(name = "meter") + @Timed(name = "timer") + public String metricsMethod() { + return "value"; + } +} diff --git a/envs/se/src/main/java/org/stefanutti/metrics/aspectj/se/MultipleMetricsStaticMethod.java b/envs/se/src/main/java/org/stefanutti/metrics/aspectj/se/MultipleMetricsStaticMethod.java new file mode 100644 index 0000000..ece2c36 --- /dev/null +++ b/envs/se/src/main/java/org/stefanutti/metrics/aspectj/se/MultipleMetricsStaticMethod.java @@ -0,0 +1,34 @@ +/** + * Copyright (C) 2013 Antonin Stefanutti (antonin.stefanutti@gmail.com) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.stefanutti.metrics.aspectj.se; + +import com.codahale.metrics.annotation.ExceptionMetered; +import com.codahale.metrics.annotation.Gauge; +import com.codahale.metrics.annotation.Metered; +import com.codahale.metrics.annotation.Timed; +import org.stefanutti.metrics.aspectj.Metrics; + +@Metrics(registry = "multipleMetricsStaticRegistry") +public class MultipleMetricsStaticMethod { + + @ExceptionMetered(name = "exception") + @Gauge(name = "gauge") + @Metered(name = "meter") + @Timed(name = "timer") + public static String metricsMethod() { + return "value"; + } +} diff --git a/envs/se/src/main/java/org/stefanutti/metrics/aspectj/se/TimedMethodWithAbsoluteName.java b/envs/se/src/main/java/org/stefanutti/metrics/aspectj/se/TimedMethodWithAbsoluteName.java index c2c2771..ade39cb 100644 --- a/envs/se/src/main/java/org/stefanutti/metrics/aspectj/se/TimedMethodWithAbsoluteName.java +++ b/envs/se/src/main/java/org/stefanutti/metrics/aspectj/se/TimedMethodWithAbsoluteName.java @@ -21,7 +21,7 @@ @Metrics(registry = "timerRegistryForAbsoluteNamedTimer") public class TimedMethodWithAbsoluteName { - @Timed(name = "absolutelyTimedMethod", absolute = true) - public void absolutelyTimedMethod() { + @Timed(name = "absoluteTimedMethod", absolute = true) + public void absoluteTimedMethod() { } } diff --git a/envs/se/src/test/java/org/stefanutti/metrics/aspectj/se/GaugeMethodWithVisibilityModifiersTest.java b/envs/se/src/test/java/org/stefanutti/metrics/aspectj/se/GaugeMethodWithVisibilityModifiersTest.java index 80d3b21..ebc6452 100644 --- a/envs/se/src/test/java/org/stefanutti/metrics/aspectj/se/GaugeMethodWithVisibilityModifiersTest.java +++ b/envs/se/src/test/java/org/stefanutti/metrics/aspectj/se/GaugeMethodWithVisibilityModifiersTest.java @@ -39,7 +39,7 @@ public class GaugeMethodWithVisibilityModifiersTest { private GaugeMethodWithVisibilityModifiers instance; private Set absoluteMetricNames() { - return MetricsUtil.absoluteMetricNameSet(GaugeMethodWithVisibilityModifiers.class, GAUGE_NAMES); + return MetricsUtil.absoluteMetricNames(GaugeMethodWithVisibilityModifiers.class, GAUGE_NAMES); } @Before diff --git a/envs/se/src/test/java/org/stefanutti/metrics/aspectj/se/MeteredMethodWithExceptionsTest.java b/envs/se/src/test/java/org/stefanutti/metrics/aspectj/se/MeteredMethodWithExceptionsTest.java index 83a2a3a..a960e1a 100644 --- a/envs/se/src/test/java/org/stefanutti/metrics/aspectj/se/MeteredMethodWithExceptionsTest.java +++ b/envs/se/src/test/java/org/stefanutti/metrics/aspectj/se/MeteredMethodWithExceptionsTest.java @@ -38,7 +38,7 @@ public class MeteredMethodWithExceptionsTest { private MeteredMethodWithExceptions instance; private Set absoluteMetricNames() { - return MetricsUtil.absoluteMetricNameSet(MeteredMethodWithExceptions.class, METER_NAMES); + return MetricsUtil.absoluteMetricNames(MeteredMethodWithExceptions.class, METER_NAMES); } private String absoluteMetricName(int index) { diff --git a/envs/se/src/test/java/org/stefanutti/metrics/aspectj/se/MeteredStaticMethodWithExceptionsTest.java b/envs/se/src/test/java/org/stefanutti/metrics/aspectj/se/MeteredStaticMethodWithExceptionsTest.java index d7c6eb2..9b8ab97 100644 --- a/envs/se/src/test/java/org/stefanutti/metrics/aspectj/se/MeteredStaticMethodWithExceptionsTest.java +++ b/envs/se/src/test/java/org/stefanutti/metrics/aspectj/se/MeteredStaticMethodWithExceptionsTest.java @@ -35,7 +35,7 @@ public class MeteredStaticMethodWithExceptionsTest { private final static AtomicLong[] METER_COUNTS = {new AtomicLong(), new AtomicLong()}; private static Set absoluteMetricNames() { - return MetricsUtil.absoluteMetricNameSet(MeteredStaticMethodWithExceptions.class, METER_NAMES); + return MetricsUtil.absoluteMetricNames(MeteredStaticMethodWithExceptions.class, METER_NAMES); } private static String absoluteMetricName(int index) { diff --git a/envs/se/src/test/java/org/stefanutti/metrics/aspectj/se/MetricMethodWithDefaultNamesTest.java b/envs/se/src/test/java/org/stefanutti/metrics/aspectj/se/MetricMethodWithDefaultNamesTest.java index a0a9d75..6471369 100644 --- a/envs/se/src/test/java/org/stefanutti/metrics/aspectj/se/MetricMethodWithDefaultNamesTest.java +++ b/envs/se/src/test/java/org/stefanutti/metrics/aspectj/se/MetricMethodWithDefaultNamesTest.java @@ -39,7 +39,7 @@ public class MetricMethodWithDefaultNamesTest { private MetricMethodWithDefaultNames instance; private Set metricNames() { - Set names = MetricsUtil.absoluteMetricNameSet(MetricMethodWithDefaultNames.class, METRIC_NAMES); + Set names = MetricsUtil.absoluteMetricNames(MetricMethodWithDefaultNames.class, METRIC_NAMES); names.addAll(Arrays.asList(ABSOLUTE_METRIC_NAMES)); return names; } diff --git a/envs/se/src/test/java/org/stefanutti/metrics/aspectj/se/MultipleMetricsMethodTest.java b/envs/se/src/test/java/org/stefanutti/metrics/aspectj/se/MultipleMetricsMethodTest.java new file mode 100644 index 0000000..ab0cddb --- /dev/null +++ b/envs/se/src/test/java/org/stefanutti/metrics/aspectj/se/MultipleMetricsMethodTest.java @@ -0,0 +1,86 @@ +/** + * Copyright (C) 2013 Antonin Stefanutti (antonin.stefanutti@gmail.com) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.stefanutti.metrics.aspectj.se; + +import com.codahale.metrics.MetricRegistry; +import com.codahale.metrics.SharedMetricRegistries; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.stefanutti.metrics.aspectj.se.util.MetricsUtil; + +import java.util.Set; + +import static org.hamcrest.Matchers.equalTo; +import static org.hamcrest.Matchers.hasItem; +import static org.hamcrest.Matchers.hasToString; +import static org.hamcrest.Matchers.is; +import static org.junit.Assert.assertThat; + +public class MultipleMetricsMethodTest { + + private final static String REGISTRY_NAME = "multipleMetricsRegistry"; + + private final static String[] METRIC_NAMES = {"exception", "gauge", "meter", "timer"}; + + private Set absoluteMetricNames() { + return MetricsUtil.absoluteMetricNames(MultipleMetricsMethod.class, METRIC_NAMES); + } + + private String absoluteMetricName(String name) { + return MetricsUtil.absoluteMetricName(MultipleMetricsMethod.class, name); + } + + private MultipleMetricsMethod instance; + + @Before + public void createInstance() { + instance = new MultipleMetricsMethod(); + } + + @After + public void clearSharedMetricRegistries() { + SharedMetricRegistries.clear(); + } + + @Test + public void metricsMethodNotCalledYet() { + assertThat("Shared metric registry is not created", SharedMetricRegistries.names(), hasItem(REGISTRY_NAME)); + MetricRegistry registry = SharedMetricRegistries.getOrCreate(REGISTRY_NAME); + assertThat("Metrics are not registered correctly", registry.getMetrics().keySet(), is(equalTo(absoluteMetricNames()))); + + // Make sure that the metrics haven't been called yet + assertThat("Meter count is incorrect", registry.getMeters().get(absoluteMetricName("exception")).getCount(), is(equalTo(0L))); + assertThat("Meter count is incorrect", registry.getMeters().get(absoluteMetricName("meter")).getCount(), is(equalTo(0L))); + assertThat("Timer count is incorrect", registry.getTimers().get(absoluteMetricName("timer")).getCount(), is(equalTo(0L))); + } + + @Test + public void callMetricsMethodOnce() { + assertThat("Shared metric registry is not created", SharedMetricRegistries.names(), hasItem(REGISTRY_NAME)); + MetricRegistry registry = SharedMetricRegistries.getOrCreate(REGISTRY_NAME); + assertThat("Metrics are not registered correctly", registry.getMetrics().keySet(), is(equalTo(absoluteMetricNames()))); + + // Call the monitored method and assert it's been instrumented + instance.metricsMethod(); + + // Make sure that the metrics have been called + assertThat("Meter count is incorrect", registry.getMeters().get(absoluteMetricName("exception")).getCount(), is(equalTo(0L))); + assertThat("Meter count is incorrect", registry.getMeters().get(absoluteMetricName("meter")).getCount(), is(equalTo(1L))); + assertThat("Timer count is incorrect", registry.getTimers().get(absoluteMetricName("timer")).getCount(), is(equalTo(1L))); + assertThat("Gauge value is incorrect", registry.getGauges().get(absoluteMetricName("gauge")).getValue(), hasToString((equalTo("value")))); + } +} diff --git a/envs/se/src/test/java/org/stefanutti/metrics/aspectj/se/MultipleMetricsStaticMethodTest.java b/envs/se/src/test/java/org/stefanutti/metrics/aspectj/se/MultipleMetricsStaticMethodTest.java new file mode 100644 index 0000000..7a7cf39 --- /dev/null +++ b/envs/se/src/test/java/org/stefanutti/metrics/aspectj/se/MultipleMetricsStaticMethodTest.java @@ -0,0 +1,61 @@ +/** + * Copyright (C) 2013 Antonin Stefanutti (antonin.stefanutti@gmail.com) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.stefanutti.metrics.aspectj.se; + +import com.codahale.metrics.MetricRegistry; +import com.codahale.metrics.SharedMetricRegistries; +import org.junit.Test; +import org.stefanutti.metrics.aspectj.se.util.MetricsUtil; + +import java.util.Set; + +import static org.hamcrest.Matchers.equalTo; +import static org.hamcrest.Matchers.hasItem; +import static org.hamcrest.Matchers.hasToString; +import static org.hamcrest.Matchers.is; +import static org.junit.Assert.assertThat; + +public class MultipleMetricsStaticMethodTest { + + private final static String REGISTRY_NAME = "multipleMetricsStaticRegistry"; + + private final static String[] METRIC_NAMES = {"exception", "gauge", "meter", "timer"}; + + private Set absoluteMetricNames() { + return MetricsUtil.absoluteMetricNames(MultipleMetricsStaticMethod.class, METRIC_NAMES); + } + + private String absoluteMetricName(String name) { + return MetricsUtil.absoluteMetricName(MultipleMetricsStaticMethod.class, name); + } + + @Test + public void callMetricsStaticMethodsOnce() { + // Call the monitored method and assert all the metrics have been created and marked + MultipleMetricsStaticMethod.metricsMethod(); + + assertThat("Shared metric registry is not created", SharedMetricRegistries.names(), hasItem(REGISTRY_NAME)); + MetricRegistry registry = SharedMetricRegistries.getOrCreate(REGISTRY_NAME); + + assertThat("Metrics are not registered correctly", registry.getMetrics().keySet(), is(equalTo(absoluteMetricNames()))); + + // Make sure that the metrics have been called + assertThat("Meter count is incorrect", registry.getMeters().get(absoluteMetricName("exception")).getCount(), is(equalTo(0L))); + assertThat("Meter count is incorrect", registry.getMeters().get(absoluteMetricName("meter")).getCount(), is(equalTo(1L))); + assertThat("Timer count is incorrect", registry.getTimers().get(absoluteMetricName("timer")).getCount(), is(equalTo(1L))); + assertThat("Gauge value is incorrect", registry.getGauges().get(absoluteMetricName("gauge")).getValue(), hasToString((equalTo("value")))); + } +} diff --git a/envs/se/src/test/java/org/stefanutti/metrics/aspectj/se/TimedMethodOverloadedTest.java b/envs/se/src/test/java/org/stefanutti/metrics/aspectj/se/TimedMethodOverloadedTest.java index 2e1ecc9..f487340 100644 --- a/envs/se/src/test/java/org/stefanutti/metrics/aspectj/se/TimedMethodOverloadedTest.java +++ b/envs/se/src/test/java/org/stefanutti/metrics/aspectj/se/TimedMethodOverloadedTest.java @@ -39,7 +39,7 @@ public class TimedMethodOverloadedTest { private TimedMethodOverloaded instance; private Set absoluteMetricNames() { - return MetricsUtil.absoluteMetricNameSet(TimedMethodOverloaded.class, TIMER_NAMES); + return MetricsUtil.absoluteMetricNames(TimedMethodOverloaded.class, TIMER_NAMES); } @Before diff --git a/envs/se/src/test/java/org/stefanutti/metrics/aspectj/se/TimedMethodWithAbsoluteNameTest.java b/envs/se/src/test/java/org/stefanutti/metrics/aspectj/se/TimedMethodWithAbsoluteNameTest.java index c24f8ca..4e07474 100644 --- a/envs/se/src/test/java/org/stefanutti/metrics/aspectj/se/TimedMethodWithAbsoluteNameTest.java +++ b/envs/se/src/test/java/org/stefanutti/metrics/aspectj/se/TimedMethodWithAbsoluteNameTest.java @@ -29,7 +29,7 @@ public class TimedMethodWithAbsoluteNameTest { private final static String REGISTRY_NAME = "timerRegistryForAbsoluteNamedTimer"; - private final static String TIMER_NAME = "absolutelyTimedMethod"; + private final static String TIMER_NAME = "absoluteTimedMethod"; private TimedMethodWithAbsoluteName instance; @@ -62,7 +62,7 @@ public void callTimedMethodOnce() { Timer timer = registry.getTimers().get(TIMER_NAME); // Call the timed method and assert it's been timed - instance.absolutelyTimedMethod(); + instance.absoluteTimedMethod(); assertThat("Timer count is incorrect", timer.getCount(), is(equalTo(1L))); } } diff --git a/envs/se/src/test/java/org/stefanutti/metrics/aspectj/se/TimedMethodWithVisibilityModifiersTest.java b/envs/se/src/test/java/org/stefanutti/metrics/aspectj/se/TimedMethodWithVisibilityModifiersTest.java index 1f6ffc8..659ac76 100644 --- a/envs/se/src/test/java/org/stefanutti/metrics/aspectj/se/TimedMethodWithVisibilityModifiersTest.java +++ b/envs/se/src/test/java/org/stefanutti/metrics/aspectj/se/TimedMethodWithVisibilityModifiersTest.java @@ -39,7 +39,7 @@ public class TimedMethodWithVisibilityModifiersTest { private TimedMethodWithVisibilityModifiers instance; private Set absoluteMetricNames() { - return MetricsUtil.absoluteMetricNameSet(TimedMethodWithVisibilityModifiers.class, TIMER_NAMES); + return MetricsUtil.absoluteMetricNames(TimedMethodWithVisibilityModifiers.class, TIMER_NAMES); } @Before diff --git a/envs/se/src/test/java/org/stefanutti/metrics/aspectj/se/TimedStaticMethodWithVisibilityModifiersTest.java b/envs/se/src/test/java/org/stefanutti/metrics/aspectj/se/TimedStaticMethodWithVisibilityModifiersTest.java index 4796827..4fa8dce 100644 --- a/envs/se/src/test/java/org/stefanutti/metrics/aspectj/se/TimedStaticMethodWithVisibilityModifiersTest.java +++ b/envs/se/src/test/java/org/stefanutti/metrics/aspectj/se/TimedStaticMethodWithVisibilityModifiersTest.java @@ -35,7 +35,7 @@ public class TimedStaticMethodWithVisibilityModifiersTest { private final static String[] TIMER_NAMES = {"publicTimedStaticMethod", "packagePrivateTimedStaticMethod", "protectedTimedStaticMethod", "privateTimedStaticMethod"}; private static Set absoluteMetricNames() { - return MetricsUtil.absoluteMetricNameSet(TimedStaticMethodWithVisibilityModifiers.class, TIMER_NAMES); + return MetricsUtil.absoluteMetricNames(TimedStaticMethodWithVisibilityModifiers.class, TIMER_NAMES); } @Test diff --git a/envs/se/src/test/java/org/stefanutti/metrics/aspectj/se/util/MetricsUtil.java b/envs/se/src/test/java/org/stefanutti/metrics/aspectj/se/util/MetricsUtil.java index 6d0c4b1..f0e18d8 100644 --- a/envs/se/src/test/java/org/stefanutti/metrics/aspectj/se/util/MetricsUtil.java +++ b/envs/se/src/test/java/org/stefanutti/metrics/aspectj/se/util/MetricsUtil.java @@ -25,11 +25,10 @@ public final class MetricsUtil { private MetricsUtil() { } - public static Set absoluteMetricNameSet(Class clazz, String... names) { + public static Set absoluteMetricNames(Class clazz, String... names) { Set set = new HashSet(names.length); - for (String name : names) { + for (String name : names) set.add(absoluteMetricName(clazz, name)); - } return set; } diff --git a/impl/src/main/aspect/org/stefanutti/metrics/aspectj/AbstractMetricAspect.aj b/impl/src/main/aspect/org/stefanutti/metrics/aspectj/AbstractMetricAspect.aj index ac33d1a..33109f3 100644 --- a/impl/src/main/aspect/org/stefanutti/metrics/aspectj/AbstractMetricAspect.aj +++ b/impl/src/main/aspect/org/stefanutti/metrics/aspectj/AbstractMetricAspect.aj @@ -29,8 +29,18 @@ import java.lang.reflect.Method; abstract aspect AbstractMetricAspect { - protected interface MetricFactory { - Metric metric(MetricRegistry registry, String name, boolean absolute); + protected interface MetricFactory { + T metric(MetricRegistry registry, String name, boolean absolute); + } + + protected AnnotatedMetric metricAnnotation(Method method, Class clazz, MetricRegistry registry, MetricFactory factory) { + if (method.isAnnotationPresent(clazz)) { + Annotation annotation = method.getAnnotation(clazz); + T metric = factory.metric(registry, metricAnnotationName(annotation), metricAnnotationAbsolute(annotation)); + return new AnnotatedMetric.IsPresent(metric, annotation); + } else { + return new AnnotatedMetric.IsNotPresent(); + } } protected static String metricAnnotationName(Annotation annotation) { diff --git a/impl/src/main/aspect/org/stefanutti/metrics/aspectj/ExceptionMeteredAspect.aj b/impl/src/main/aspect/org/stefanutti/metrics/aspectj/ExceptionMeteredAspect.aj index c1fe108..17f7026 100644 --- a/impl/src/main/aspect/org/stefanutti/metrics/aspectj/ExceptionMeteredAspect.aj +++ b/impl/src/main/aspect/org/stefanutti/metrics/aspectj/ExceptionMeteredAspect.aj @@ -25,9 +25,8 @@ final aspect ExceptionMeteredAspect { after(Profiled object) throwing (Throwable throwable) : exceptionMetered(object) { String methodSignature = ((MethodSignature) thisJoinPointStaticPart.getSignature()).getMethod().toString(); - AnnotatedMetric metric = object.metrics.get(methodSignature); - if (metric.getAnnotation(ExceptionMetered.class).cause().isInstance(throwable)) { - metric.getMetric(Meter.class).mark(); - } + AnnotatedMetric metric = object.meters.get(methodSignature); + if (metric.getAnnotation(ExceptionMetered.class).cause().isInstance(throwable)) + metric.getMetric().mark(); } } \ No newline at end of file diff --git a/impl/src/main/aspect/org/stefanutti/metrics/aspectj/ExceptionMeteredStaticAspect.aj b/impl/src/main/aspect/org/stefanutti/metrics/aspectj/ExceptionMeteredStaticAspect.aj index dff2889..f035007 100644 --- a/impl/src/main/aspect/org/stefanutti/metrics/aspectj/ExceptionMeteredStaticAspect.aj +++ b/impl/src/main/aspect/org/stefanutti/metrics/aspectj/ExceptionMeteredStaticAspect.aj @@ -25,9 +25,8 @@ final aspect ExceptionMeteredStaticAspect { after() throwing (Throwable throwable) : exceptionMetered() { String methodSignature = ((MethodSignature) thisJoinPointStaticPart.getSignature()).getMethod().toString(); - AnnotatedMetric metric = MetricStaticAspect.metrics.get(methodSignature); - if (metric.getAnnotation(ExceptionMetered.class).cause().isInstance(throwable)) { - metric.getMetric(Meter.class).mark(); - } + AnnotatedMetric metric = MetricStaticAspect.METERS.get(methodSignature); + if (metric.getAnnotation(ExceptionMetered.class).cause().isInstance(throwable)) + metric.getMetric().mark(); } } \ No newline at end of file diff --git a/impl/src/main/aspect/org/stefanutti/metrics/aspectj/MeteredAspect.aj b/impl/src/main/aspect/org/stefanutti/metrics/aspectj/MeteredAspect.aj index d769b9e..5b42890 100644 --- a/impl/src/main/aspect/org/stefanutti/metrics/aspectj/MeteredAspect.aj +++ b/impl/src/main/aspect/org/stefanutti/metrics/aspectj/MeteredAspect.aj @@ -25,7 +25,7 @@ final aspect MeteredAspect { before(Profiled object) : metered(object) { String methodSignature = ((MethodSignature) thisJoinPointStaticPart.getSignature()).getMethod().toString(); - Meter meter = object.metrics.get(methodSignature).getMetric(Meter.class); + Meter meter = object.meters.get(methodSignature).getMetric(); meter.mark(); } } \ No newline at end of file diff --git a/impl/src/main/aspect/org/stefanutti/metrics/aspectj/MeteredStaticAspect.aj b/impl/src/main/aspect/org/stefanutti/metrics/aspectj/MeteredStaticAspect.aj index eab045b..b76553e 100644 --- a/impl/src/main/aspect/org/stefanutti/metrics/aspectj/MeteredStaticAspect.aj +++ b/impl/src/main/aspect/org/stefanutti/metrics/aspectj/MeteredStaticAspect.aj @@ -25,7 +25,7 @@ final aspect MeteredStaticAspect { before() : metered() { String methodSignature = ((MethodSignature) thisJoinPointStaticPart.getSignature()).getMethod().toString(); - Meter meter = MetricStaticAspect.metrics.get(methodSignature).getMetric(Meter.class); + Meter meter = MetricStaticAspect.METERS.get(methodSignature).getMetric(); meter.mark(); } } \ No newline at end of file diff --git a/impl/src/main/aspect/org/stefanutti/metrics/aspectj/MetricAspect.aj b/impl/src/main/aspect/org/stefanutti/metrics/aspectj/MetricAspect.aj index e322350..b4ae856 100644 --- a/impl/src/main/aspect/org/stefanutti/metrics/aspectj/MetricAspect.aj +++ b/impl/src/main/aspect/org/stefanutti/metrics/aspectj/MetricAspect.aj @@ -15,14 +15,14 @@ */ package org.stefanutti.metrics.aspectj; -import com.codahale.metrics.Metric; +import com.codahale.metrics.Meter; import com.codahale.metrics.MetricRegistry; -import com.codahale.metrics.annotation.Gauge; +import com.codahale.metrics.Timer; import com.codahale.metrics.annotation.ExceptionMetered; +import com.codahale.metrics.annotation.Gauge; import com.codahale.metrics.annotation.Metered; import com.codahale.metrics.annotation.Timed; -import java.lang.annotation.Annotation; import java.lang.reflect.Method; import java.lang.reflect.Modifier; import java.util.Map; @@ -34,55 +34,63 @@ final aspect MetricAspect extends AbstractMetricAspect { declare parents : (@Metrics *) implements Profiled; - /* packaged-private */ - final Map Profiled.metrics = new ConcurrentHashMap(); + final Map> Profiled.gauges = new ConcurrentHashMap>(); + + final Map> Profiled.meters = new ConcurrentHashMap>(); + + final Map> Profiled.timers = new ConcurrentHashMap>(); pointcut profiled(Profiled object) : execution((@Metrics Profiled+).new(..)) && this(object); after(final Profiled object) : profiled(object) { final MetricStrategy strategy = MetricStrategyFactory.newInstance(object); + for (final Method method : object.getClass().getDeclaredMethods()) { // Skip advising static methods if (Modifier.isStatic(method.getModifiers())) continue; - metricAnnotation(object, method, strategy, ExceptionMetered.class, new MetricFactory() { + final MetricRegistry registry = strategy.resolveMetricRegistry(object.getClass().getAnnotation(Metrics.class).registry()); + + AnnotatedMetric exception = metricAnnotation(method, ExceptionMetered.class, registry, new MetricFactory() { @Override - public Metric metric(MetricRegistry registry, String name, boolean absolute) { + public Meter metric(MetricRegistry registry, String name, boolean absolute) { String finalName = name.isEmpty() ? method.getName() + "." + ExceptionMetered.DEFAULT_NAME_SUFFIX : strategy.resolveMetricName(name); return registry.meter(absolute ? finalName : MetricRegistry.name(object.getClass(), finalName)); } }); - metricAnnotation(object, method, strategy, Gauge.class, new MetricFactory() { + if (exception.isPresent()) + object.meters.put(method.toString(), exception); + + AnnotatedMetric gauge = metricAnnotation(method, Gauge.class, registry, new MetricFactory() { @Override - public Metric metric(MetricRegistry registry, String name, boolean absolute) { + public com.codahale.metrics.Gauge metric(MetricRegistry registry, String name, boolean absolute) { String finalName = name.isEmpty() ? method.getName() : strategy.resolveMetricName(name); return registry.register(absolute ? finalName : MetricRegistry.name(object.getClass(), finalName), new ForwardingGauge(method, object)); } }); - metricAnnotation(object, method, strategy, Metered.class, new MetricFactory() { + if (gauge.isPresent()) + object.gauges.put(method.toString(), gauge); + + AnnotatedMetric meter = metricAnnotation(method, Metered.class, registry, new MetricFactory() { @Override - public Metric metric(MetricRegistry registry, String name, boolean absolute) { + public Meter metric(MetricRegistry registry, String name, boolean absolute) { String finalName = name.isEmpty() ? method.getName() : strategy.resolveMetricName(name); return registry.meter(absolute ? finalName : MetricRegistry.name(object.getClass(), finalName)); } }); - metricAnnotation(object, method, strategy, Timed.class, new MetricFactory() { + if (meter.isPresent()) + object.meters.put(method.toString(), meter); + + AnnotatedMetric timer = metricAnnotation(method, Timed.class, registry, new MetricFactory() { @Override - public Metric metric(MetricRegistry registry, String name, boolean absolute) { + public Timer metric(MetricRegistry registry, String name, boolean absolute) { String finalName = name.isEmpty() ? method.getName() : strategy.resolveMetricName(name); return registry.timer(absolute ? finalName : MetricRegistry.name(object.getClass(), finalName)); } }); - } - } - - private void metricAnnotation(Profiled object, Method method, MetricStrategy strategy, Class clazz, MetricFactory factory) { - if (method.isAnnotationPresent(clazz)) { - MetricRegistry registry = strategy.resolveMetricRegistry(object.getClass().getAnnotation(Metrics.class).registry()); - Annotation annotation = method.getAnnotation(clazz); - Metric metric = factory.metric(registry, metricAnnotationName(annotation), metricAnnotationAbsolute(annotation)); - object.metrics.put(method.toString(), new AnnotatedMetric(metric, annotation)); + if (timer.isPresent()) + object.timers.put(method.toString(), timer); } } } \ No newline at end of file diff --git a/impl/src/main/aspect/org/stefanutti/metrics/aspectj/MetricStaticAspect.aj b/impl/src/main/aspect/org/stefanutti/metrics/aspectj/MetricStaticAspect.aj index fc4700e..f3633fe 100644 --- a/impl/src/main/aspect/org/stefanutti/metrics/aspectj/MetricStaticAspect.aj +++ b/impl/src/main/aspect/org/stefanutti/metrics/aspectj/MetricStaticAspect.aj @@ -15,69 +15,77 @@ */ package org.stefanutti.metrics.aspectj; -import com.codahale.metrics.Metric; +import com.codahale.metrics.Meter; import com.codahale.metrics.MetricRegistry; +import com.codahale.metrics.Timer; import com.codahale.metrics.annotation.ExceptionMetered; import com.codahale.metrics.annotation.Gauge; import com.codahale.metrics.annotation.Metered; import com.codahale.metrics.annotation.Timed; -import java.lang.annotation.Annotation; import java.lang.reflect.Method; import java.lang.reflect.Modifier; +import java.util.Map; import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.ConcurrentMap; final aspect MetricStaticAspect extends AbstractMetricAspect { - /* packaged-private */ - final static ConcurrentMap metrics = new ConcurrentHashMap(); + static final Map> GAUGES = new ConcurrentHashMap>(); + + static final Map> METERS = new ConcurrentHashMap>(); + + static final Map> TIMERS = new ConcurrentHashMap>(); pointcut profiled() : staticinitialization(@Metrics *); after() : profiled() { final Class clazz = thisJoinPointStaticPart.getSignature().getDeclaringType(); final MetricStrategy strategy = MetricStrategyFactory.newInstance(clazz); + for (final Method method : clazz.getDeclaredMethods()) { if (Modifier.isStatic(method.getModifiers()) && !method.isSynthetic()) { - metricAnnotation(clazz, method, strategy, ExceptionMetered.class, new MetricFactory() { + final MetricRegistry registry = strategy.resolveMetricRegistry(clazz.getAnnotation(Metrics.class).registry()); + + AnnotatedMetric exception = metricAnnotation(method, ExceptionMetered.class, registry, new MetricFactory() { @Override - public Metric metric(MetricRegistry registry, String name, boolean absolute) { + public Meter metric(MetricRegistry registry, String name, boolean absolute) { String finalName = name.isEmpty() ? method.getName() + "." + ExceptionMetered.DEFAULT_NAME_SUFFIX : strategy.resolveMetricName(name); return registry.meter(absolute ? finalName : MetricRegistry.name(clazz, finalName)); } }); - metricAnnotation(clazz, method, strategy, Gauge.class, new MetricFactory() { + if (exception.isPresent()) + METERS.put(method.toString(), exception); + + AnnotatedMetric gauge = metricAnnotation(method, Gauge.class, registry, new MetricFactory() { @Override - public Metric metric(MetricRegistry registry, String name, boolean absolute) { + public com.codahale.metrics.Gauge metric(MetricRegistry registry, String name, boolean absolute) { String finalName = name.isEmpty() ? method.getName() : strategy.resolveMetricName(name); return registry.register(absolute ? finalName : MetricRegistry.name(clazz, finalName), new ForwardingGauge(method, clazz)); } }); - metricAnnotation(clazz, method, strategy, Metered.class, new MetricFactory() { + if (gauge.isPresent()) + GAUGES.put(method.toString(), gauge); + + AnnotatedMetric meter = metricAnnotation(method, Metered.class, registry, new MetricFactory() { @Override - public Metric metric(MetricRegistry registry, String name, boolean absolute) { + public Meter metric(MetricRegistry registry, String name, boolean absolute) { String finalName = name.isEmpty() ? method.getName() : strategy.resolveMetricName(name); return registry.meter(absolute ? finalName : MetricRegistry.name(clazz, finalName)); } }); - metricAnnotation(clazz, method, strategy, Timed.class, new MetricFactory() { + if (meter.isPresent()) + METERS.put(method.toString(), meter); + + AnnotatedMetric timer = metricAnnotation(method, Timed.class, registry, new MetricFactory() { @Override - public Metric metric(MetricRegistry registry, String name, boolean absolute) { + public Timer metric(MetricRegistry registry, String name, boolean absolute) { String finalName = name.isEmpty() ? method.getName() : strategy.resolveMetricName(name); return registry.timer(absolute ? finalName : MetricRegistry.name(clazz, finalName)); } }); + if (timer.isPresent()) + TIMERS.put(method.toString(), timer); } } } - - private void metricAnnotation(Class annotated, Method method, MetricStrategy strategy, Class clazz, MetricFactory factory) { - if (method.isAnnotationPresent(clazz)) { - MetricRegistry registry = strategy.resolveMetricRegistry(annotated.getAnnotation(Metrics.class).registry()); - Annotation annotation = method.getAnnotation(clazz); - Metric metric = factory.metric(registry, metricAnnotationName(annotation), metricAnnotationAbsolute(annotation)); - metrics.put(method.toString(), new AnnotatedMetric(metric, annotation)); - } - } } \ No newline at end of file diff --git a/impl/src/main/aspect/org/stefanutti/metrics/aspectj/TimedAspect.aj b/impl/src/main/aspect/org/stefanutti/metrics/aspectj/TimedAspect.aj index 70fd1fe..1375b33 100644 --- a/impl/src/main/aspect/org/stefanutti/metrics/aspectj/TimedAspect.aj +++ b/impl/src/main/aspect/org/stefanutti/metrics/aspectj/TimedAspect.aj @@ -25,7 +25,7 @@ final aspect TimedAspect { Object around(Profiled object) : timed(object) { String methodSignature = ((MethodSignature) thisJoinPointStaticPart.getSignature()).getMethod().toString(); - Timer timer = object.metrics.get(methodSignature).getMetric(Timer.class); + Timer timer = object.timers.get(methodSignature).getMetric(); Timer.Context context = timer.time(); try { return proceed(object); diff --git a/impl/src/main/aspect/org/stefanutti/metrics/aspectj/TimedStaticAspect.aj b/impl/src/main/aspect/org/stefanutti/metrics/aspectj/TimedStaticAspect.aj index 8cff223..f4e427c 100644 --- a/impl/src/main/aspect/org/stefanutti/metrics/aspectj/TimedStaticAspect.aj +++ b/impl/src/main/aspect/org/stefanutti/metrics/aspectj/TimedStaticAspect.aj @@ -25,7 +25,7 @@ final aspect TimedStaticAspect { Object around() : timed() { String methodSignature = ((MethodSignature) thisJoinPointStaticPart.getSignature()).getMethod().toString(); - Timer timer = MetricStaticAspect.metrics.get(methodSignature).getMetric(Timer.class); + Timer timer = MetricStaticAspect.TIMERS.get(methodSignature).getMetric(); Timer.Context context = timer.time(); try { return proceed(); diff --git a/impl/src/main/java/org/stefanutti/metrics/aspectj/AnnotatedMetric.java b/impl/src/main/java/org/stefanutti/metrics/aspectj/AnnotatedMetric.java index 5ae380e..afc3dd9 100644 --- a/impl/src/main/java/org/stefanutti/metrics/aspectj/AnnotatedMetric.java +++ b/impl/src/main/java/org/stefanutti/metrics/aspectj/AnnotatedMetric.java @@ -19,24 +19,58 @@ import java.lang.annotation.Annotation; -/* packaged-private */ class AnnotatedMetric { +/* packaged-private */ interface AnnotatedMetric { - private final Metric metric; + boolean isPresent(); - private final Annotation annotation; + T getMetric(); - AnnotatedMetric(Metric metric, Annotation annotation) { - this.metric = metric; - this.annotation = annotation; - } + A getAnnotation(Class clazz); + + static final class IsPresent implements AnnotatedMetric { + + private final T metric; + + private final Annotation annotation; + + IsPresent(T metric, Annotation annotation) { + this.metric = metric; + this.annotation = annotation; + } - @SuppressWarnings("unchecked") - T getMetric(Class clazz) { - return (T) metric; + @Override + public boolean isPresent() { + return true; + } + + @Override + public T getMetric() { + return metric; + } + + @Override + @SuppressWarnings("unchecked") + public A getAnnotation(Class clazz) { + return (A) annotation; + } } - @SuppressWarnings("unchecked") - A getAnnotation(Class clazz) { - return (A) annotation; + static final class IsNotPresent implements AnnotatedMetric { + + @Override + public boolean isPresent() { + return false; + } + + @Override + public T getMetric() { + throw new UnsupportedOperationException(); + } + + @Override + @SuppressWarnings("unchecked") + public A getAnnotation(Class clazz) { + throw new UnsupportedOperationException(); + } } }