Skip to content

Commit

Permalink
Support multiple Metrics annotations per method
Browse files Browse the repository at this point in the history
  • Loading branch information
astefanutti committed Oct 19, 2014
1 parent a87be36 commit 507235c
Show file tree
Hide file tree
Showing 24 changed files with 357 additions and 85 deletions.
@@ -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";
}
}
@@ -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";
}
}
Expand Up @@ -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() {
}
}
Expand Up @@ -39,7 +39,7 @@ public class GaugeMethodWithVisibilityModifiersTest {
private GaugeMethodWithVisibilityModifiers instance;

private Set<String> absoluteMetricNames() {
return MetricsUtil.absoluteMetricNameSet(GaugeMethodWithVisibilityModifiers.class, GAUGE_NAMES);
return MetricsUtil.absoluteMetricNames(GaugeMethodWithVisibilityModifiers.class, GAUGE_NAMES);
}

@Before
Expand Down
Expand Up @@ -38,7 +38,7 @@ public class MeteredMethodWithExceptionsTest {
private MeteredMethodWithExceptions instance;

private Set<String> absoluteMetricNames() {
return MetricsUtil.absoluteMetricNameSet(MeteredMethodWithExceptions.class, METER_NAMES);
return MetricsUtil.absoluteMetricNames(MeteredMethodWithExceptions.class, METER_NAMES);
}

private String absoluteMetricName(int index) {
Expand Down
Expand Up @@ -35,7 +35,7 @@ public class MeteredStaticMethodWithExceptionsTest {
private final static AtomicLong[] METER_COUNTS = {new AtomicLong(), new AtomicLong()};

private static Set<String> absoluteMetricNames() {
return MetricsUtil.absoluteMetricNameSet(MeteredStaticMethodWithExceptions.class, METER_NAMES);
return MetricsUtil.absoluteMetricNames(MeteredStaticMethodWithExceptions.class, METER_NAMES);
}

private static String absoluteMetricName(int index) {
Expand Down
Expand Up @@ -39,7 +39,7 @@ public class MetricMethodWithDefaultNamesTest {
private MetricMethodWithDefaultNames instance;

private Set<String> metricNames() {
Set<String> names = MetricsUtil.absoluteMetricNameSet(MetricMethodWithDefaultNames.class, METRIC_NAMES);
Set<String> names = MetricsUtil.absoluteMetricNames(MetricMethodWithDefaultNames.class, METRIC_NAMES);
names.addAll(Arrays.asList(ABSOLUTE_METRIC_NAMES));
return names;
}
Expand Down
@@ -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<String> 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"))));
}
}
@@ -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<String> 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"))));
}
}
Expand Up @@ -39,7 +39,7 @@ public class TimedMethodOverloadedTest {
private TimedMethodOverloaded instance;

private Set<String> absoluteMetricNames() {
return MetricsUtil.absoluteMetricNameSet(TimedMethodOverloaded.class, TIMER_NAMES);
return MetricsUtil.absoluteMetricNames(TimedMethodOverloaded.class, TIMER_NAMES);
}

@Before
Expand Down
Expand Up @@ -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;

Expand Down Expand Up @@ -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)));
}
}
Expand Up @@ -39,7 +39,7 @@ public class TimedMethodWithVisibilityModifiersTest {
private TimedMethodWithVisibilityModifiers instance;

private Set<String> absoluteMetricNames() {
return MetricsUtil.absoluteMetricNameSet(TimedMethodWithVisibilityModifiers.class, TIMER_NAMES);
return MetricsUtil.absoluteMetricNames(TimedMethodWithVisibilityModifiers.class, TIMER_NAMES);
}

@Before
Expand Down
Expand Up @@ -35,7 +35,7 @@ public class TimedStaticMethodWithVisibilityModifiersTest {
private final static String[] TIMER_NAMES = {"publicTimedStaticMethod", "packagePrivateTimedStaticMethod", "protectedTimedStaticMethod", "privateTimedStaticMethod"};

private static Set<String> absoluteMetricNames() {
return MetricsUtil.absoluteMetricNameSet(TimedStaticMethodWithVisibilityModifiers.class, TIMER_NAMES);
return MetricsUtil.absoluteMetricNames(TimedStaticMethodWithVisibilityModifiers.class, TIMER_NAMES);
}

@Test
Expand Down
Expand Up @@ -25,11 +25,10 @@ public final class MetricsUtil {
private MetricsUtil() {
}

public static Set<String> absoluteMetricNameSet(Class<?> clazz, String... names) {
public static Set<String> absoluteMetricNames(Class<?> clazz, String... names) {
Set<String> set = new HashSet<String>(names.length);
for (String name : names) {
for (String name : names)
set.add(absoluteMetricName(clazz, name));
}

return set;
}
Expand Down
Expand Up @@ -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 extends Metric> {
T metric(MetricRegistry registry, String name, boolean absolute);
}

protected <T extends Metric> AnnotatedMetric<T> metricAnnotation(Method method, Class<? extends Annotation> clazz, MetricRegistry registry, MetricFactory<T> factory) {
if (method.isAnnotationPresent(clazz)) {
Annotation annotation = method.getAnnotation(clazz);
T metric = factory.metric(registry, metricAnnotationName(annotation), metricAnnotationAbsolute(annotation));
return new AnnotatedMetric.IsPresent<T>(metric, annotation);
} else {
return new AnnotatedMetric.IsNotPresent<T>();
}
}

protected static String metricAnnotationName(Annotation annotation) {
Expand Down
Expand Up @@ -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<Meter> metric = object.meters.get(methodSignature);
if (metric.getAnnotation(ExceptionMetered.class).cause().isInstance(throwable))
metric.getMetric().mark();
}
}
Expand Up @@ -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<Meter> metric = MetricStaticAspect.METERS.get(methodSignature);
if (metric.getAnnotation(ExceptionMetered.class).cause().isInstance(throwable))
metric.getMetric().mark();
}
}
Expand Up @@ -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();
}
}
Expand Up @@ -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();
}
}

0 comments on commit 507235c

Please sign in to comment.