diff --git a/metrics-core/pom.xml b/metrics-core/pom.xml
index 5cf45c4a45..09cd53374f 100644
--- a/metrics-core/pom.xml
+++ b/metrics-core/pom.xml
@@ -13,6 +13,11 @@
bundle
+
+ com.yammer.metrics
+ metrics-annotation
+ ${project.version}
+
org.slf4j
slf4j-api
diff --git a/metrics-core/src/main/java/com/yammer/metrics/core/MetricName.java b/metrics-core/src/main/java/com/yammer/metrics/core/MetricName.java
index 117427e3ea..76826efdd2 100644
--- a/metrics-core/src/main/java/com/yammer/metrics/core/MetricName.java
+++ b/metrics-core/src/main/java/com/yammer/metrics/core/MetricName.java
@@ -1,16 +1,17 @@
package com.yammer.metrics.core;
+import com.yammer.metrics.annotation.ExceptionMetered;
+
import java.lang.reflect.Method;
/**
* A value class encapsulating a metric's owning class and name.
*/
public class MetricName implements Comparable {
- private final String group;
+ private final String domain;
private final String type;
private final String name;
private final String scope;
- private final String mBeanName;
/**
* Creates a new {@link MetricName} without a scope.
@@ -25,12 +26,12 @@ public MetricName(Class> klass, String name) {
/**
* Creates a new {@link MetricName} without a scope.
*
- * @param group the group to which the {@link Metric} belongs
+ * @param domain the domain to which the {@link Metric} belongs
* @param type the type to which the {@link Metric} belongs
* @param name the name of the {@link Metric}
*/
- public MetricName(String group, String type, String name) {
- this(group, type, name, null);
+ public MetricName(String domain, String type, String name) {
+ this(domain, type, name, null);
}
/**
@@ -41,8 +42,8 @@ public MetricName(String group, String type, String name) {
* @param scope the scope of the {@link Metric}
*/
public MetricName(Class> klass, String name, String scope) {
- this(klass.getPackage() == null ? "" : klass.getPackage().getName(),
- klass.getSimpleName().replaceAll("\\$$", ""),
+ this(getPackageName(klass),
+ getClassName(klass),
name,
scope);
}
@@ -50,47 +51,32 @@ public MetricName(Class> klass, String name, String scope) {
/**
* Creates a new {@link MetricName} without a scope.
*
- * @param group the group to which the {@link Metric} belongs
+ * @param domain the domain to which the {@link Metric} belongs
* @param type the type to which the {@link Metric} belongs
* @param name the name of the {@link Metric}
* @param scope the scope of the {@link Metric}
*/
- public MetricName(String group, String type, String name, String scope) {
- this(group, type, name, scope, createMBeanName(group, type, name, scope));
- }
-
- /**
- * Creates a new {@link MetricName} without a scope.
- *
- * @param group the group to which the {@link Metric} belongs
- * @param type the type to which the {@link Metric} belongs
- * @param name the name of the {@link Metric}
- * @param scope the scope of the {@link Metric}
- * @param mBeanName the 'ObjectName', represented as a string, to use when registering the
- * MBean.
- */
- public MetricName(String group, String type, String name, String scope, String mBeanName) {
- if (group == null || type == null) {
- throw new IllegalArgumentException("Both group and type need to be specified");
+ public MetricName(String domain, String type, String name, String scope) {
+ if (domain == null || type == null) {
+ throw new IllegalArgumentException("Both domain and type need to be specified");
}
if (name == null) {
throw new IllegalArgumentException("Name needs to be specified");
}
- this.group = group;
+ this.domain = domain;
this.type = type;
this.name = name;
this.scope = scope;
- this.mBeanName = mBeanName;
}
/**
- * Returns the group to which the {@link Metric} belongs. For class-based metrics, this will be
+ * Returns the domain to which the {@link Metric} belongs. For class-based metrics, this will be
* the package name of the {@link Class} to which the {@link Metric} belongs.
*
- * @return the group to which the {@link Metric} belongs
+ * @return the domain to which the {@link Metric} belongs
*/
- public String getGroup() {
- return group;
+ public String getDomain() {
+ return domain;
}
/**
@@ -130,90 +116,113 @@ public boolean hasScope() {
return scope != null;
}
- /**
- * Returns the MBean name for the {@link Metric} identified by this metric name.
- *
- * @return the MBean name
- */
- public String getMBeanName() {
- return mBeanName;
- }
-
@Override
public boolean equals(Object o) {
if (this == o) { return true; }
if (o == null || getClass() != o.getClass()) { return false; }
final MetricName that = (MetricName) o;
- return mBeanName.equals(that.mBeanName);
+ return domain.equals(that.domain) &&
+ name.equals(that.name) &&
+ type.equals(that.type) &&
+ (scope == null ? that.scope == null : scope.equals(that.scope));
}
@Override
public int hashCode() {
- return mBeanName.hashCode();
+ int result = domain.hashCode();
+ result = 31 * result + type.hashCode();
+ result = 31 * result + name.hashCode();
+ result = 31 * result + (scope != null ? scope.hashCode() : 0);
+ return result;
}
@Override
public String toString() {
- return mBeanName;
+ return domain + '.' + type + '.' + name + (scope == null ? "" : '.' + scope);
}
@Override
public int compareTo(MetricName o) {
- return mBeanName.compareTo(o.mBeanName);
- }
+ int result = domain.compareTo(o.domain);
+ if (result != 0) {
+ return result;
+ }
- private static String createMBeanName(String group, String type, String name, String scope) {
- final StringBuilder nameBuilder = new StringBuilder();
- nameBuilder.append(group);
- nameBuilder.append(":type=");
- nameBuilder.append(type);
- if (scope != null) {
- nameBuilder.append(",scope=");
- nameBuilder.append(scope);
+ result = type.compareTo(o.type);
+ if (result != 0) {
+ return result;
}
- if (name.length() > 0) {
- nameBuilder.append(",name=");
- nameBuilder.append(name);
+
+ result = name.compareTo(o.name);
+ if (result != 0) {
+ return result;
+ }
+
+ if (scope == null) {
+ if (o.scope != null) {
+ return -1;
+ }
+ return 0;
+ }
+
+ if (o.scope != null) {
+ return scope.compareTo(o.scope);
}
- return nameBuilder.toString();
+ return 1;
}
- /**
- * If the group is empty, use the package name of the given class. Otherwise use group
- * @param group The group to use by default
- * @param klass The class being tracked
- * @return a group for the metric
- */
- public static String chooseGroup(String group, Class> klass) {
- if(group == null || group.isEmpty()) {
- group = klass.getPackage() == null ? "" : klass.getPackage().getName();
+ private static String getPackageName(Class> klass) {
+ return klass.getPackage() == null ? "" : klass.getPackage().getName();
+ }
+
+ private static String getClassName(Class> klass) {
+ return klass.getSimpleName().replaceAll("\\$$", "");
+ }
+
+ private static String chooseDomain(String domain, Class> klass) {
+ if(domain == null || domain.isEmpty()) {
+ domain = getPackageName(klass);
}
- return group;
+ return domain;
}
- /**
- * If the type is empty, use the simple name of the given class. Otherwise use type
- * @param type The type to use by default
- * @param klass The class being tracked
- * @return a type for the metric
- */
- public static String chooseType(String type, Class> klass) {
+ private static String chooseType(String type, Class> klass) {
if(type == null || type.isEmpty()) {
- type = klass.getSimpleName().replaceAll("\\$$", "");
+ type = getClassName(klass);
}
return type;
}
- /**
- * If name is empty, use the name of the given method. Otherwise use name
- * @param name The name to use by default
- * @param method The method being tracked
- * @return a name for the metric
- */
- public static String chooseName(String name, Method method) {
+ private static String chooseName(String name, Method method) {
if(name == null || name.isEmpty()) {
name = method.getName();
}
return name;
}
+
+ public static MetricName forTimedMethod(Class> klass, Method method, com.yammer.metrics.annotation.Timed annotation) {
+ return new MetricName(chooseDomain(annotation.group(), klass),
+ chooseType(annotation.type(), klass),
+ chooseName(annotation.name(), method));
+ }
+
+ public static MetricName forMeteredMethod(Class> klass, Method method, com.yammer.metrics.annotation.Metered annotation) {
+ return new MetricName(chooseDomain(annotation.group(), klass),
+ chooseType(annotation.type(), klass),
+ chooseName(annotation.name(), method));
+ }
+
+ public static MetricName forGaugeMethod(Class> klass, Method method, com.yammer.metrics.annotation.Gauge annotation) {
+ return new MetricName(chooseDomain(annotation.group(), klass),
+ chooseType(annotation.type(), klass),
+ chooseName(annotation.name(), method));
+ }
+
+ public static MetricName forExceptionMeteredMethod(Class> klass, Method method, com.yammer.metrics.annotation.ExceptionMetered annotation) {
+ return new MetricName(chooseDomain(annotation.group(), klass),
+ chooseType(annotation.type(), klass),
+ annotation.name() == null || annotation.name().isEmpty() ?
+ method.getName() + ExceptionMetered.DEFAULT_NAME_SUFFIX :
+ annotation.name());
+ }
}
diff --git a/metrics-core/src/main/java/com/yammer/metrics/core/MetricsRegistry.java b/metrics-core/src/main/java/com/yammer/metrics/core/MetricsRegistry.java
index 60b7ba962c..e0220bf31f 100644
--- a/metrics-core/src/main/java/com/yammer/metrics/core/MetricsRegistry.java
+++ b/metrics-core/src/main/java/com/yammer/metrics/core/MetricsRegistry.java
@@ -348,7 +348,7 @@ public SortedMap> getGroupedMetrics(Metric
final SortedMap> groups =
new TreeMap>();
for (Map.Entry entry : metrics.entrySet()) {
- final String qualifiedTypeName = entry.getKey().getGroup() + "." + entry.getKey()
+ final String qualifiedTypeName = entry.getKey().getDomain() + "." + entry.getKey()
.getType();
if (predicate.matches(entry.getKey(), entry.getValue())) {
final String scopedName;
diff --git a/metrics-core/src/main/java/com/yammer/metrics/reporting/JmxReporter.java b/metrics-core/src/main/java/com/yammer/metrics/reporting/JmxReporter.java
index 3a6957a662..2cbdbfa80f 100644
--- a/metrics-core/src/main/java/com/yammer/metrics/reporting/JmxReporter.java
+++ b/metrics-core/src/main/java/com/yammer/metrics/reporting/JmxReporter.java
@@ -394,13 +394,29 @@ public JmxReporter(MetricsRegistry registry) {
public void onMetricAdded(MetricName name, Metric metric) {
if (metric != null) {
try {
- dispatcher.dispatch(metric, name, this, new Context(name, new ObjectName(name.getMBeanName())));
+ dispatcher.dispatch(metric, name, this, new Context(name, createObjectName(name)));
} catch (Exception e) {
LOGGER.warn("Error processing {}", name, e);
}
}
}
+ private ObjectName createObjectName(MetricName name) throws MalformedObjectNameException {
+ final StringBuilder nameBuilder = new StringBuilder();
+ nameBuilder.append(name.getDomain());
+ nameBuilder.append(":type=");
+ nameBuilder.append(name.getType());
+ if (name.hasScope()) {
+ nameBuilder.append(",scope=");
+ nameBuilder.append(name.getScope());
+ }
+ if (!name.getName().isEmpty()) {
+ nameBuilder.append(",name=");
+ nameBuilder.append(name);
+ }
+ return new ObjectName(nameBuilder.toString());
+ }
+
@Override
public void onMetricRemoved(MetricName name) {
final ObjectName objectName = registeredBeans.remove(name);
diff --git a/metrics-core/src/test/java/com/yammer/metrics/core/tests/MetricNameTest.java b/metrics-core/src/test/java/com/yammer/metrics/core/tests/MetricNameTest.java
index e61a4e1675..ff9e52f34f 100644
--- a/metrics-core/src/test/java/com/yammer/metrics/core/tests/MetricNameTest.java
+++ b/metrics-core/src/test/java/com/yammer/metrics/core/tests/MetricNameTest.java
@@ -7,11 +7,11 @@
import static org.junit.Assert.*;
public class MetricNameTest {
- private final MetricName name = new MetricName("group", "type", "name", "scope", "bean");
+ private final MetricName name = new MetricName("group", "type", "name", "scope");
@Test
public void hasAGroup() throws Exception {
- assertThat(name.getGroup(),
+ assertThat(name.getDomain(),
is("group"));
}
@@ -36,16 +36,10 @@ public void hasAScope() throws Exception {
is(true));
}
- @Test
- public void hasAnMBeanName() throws Exception {
- assertThat(name.getMBeanName(),
- is("bean"));
- }
-
@Test
public void isHumanReadable() throws Exception {
assertThat(name.toString(),
- is("bean"));
+ is("group.type.name.scope"));
}
@Test
@@ -53,7 +47,7 @@ public void createsNamesForSimpleMetrics() throws Exception {
final MetricName simple = new MetricName(MetricNameTest.class, "name");
assertThat("it uses the package name as the group",
- simple.getGroup(),
+ simple.getDomain(),
is("com.yammer.metrics.core.tests"));
assertThat("it uses the class name as the type",
@@ -67,10 +61,6 @@ public void createsNamesForSimpleMetrics() throws Exception {
assertThat("it has a name",
simple.getName(),
is("name"));
-
- assertThat("it has an MBean name",
- simple.getMBeanName(),
- is("com.yammer.metrics.core.tests:type=MetricNameTest,name=name"));
}
@Test
@@ -78,7 +68,7 @@ public void createsNamesForScopedMetrics() throws Exception {
final MetricName scoped = new MetricName(MetricNameTest.class, "name", "scope");
assertThat("it uses the package name as the group",
- scoped.getGroup(),
+ scoped.getDomain(),
is("com.yammer.metrics.core.tests"));
assertThat("it uses the class name as the type",
@@ -92,10 +82,6 @@ public void createsNamesForScopedMetrics() throws Exception {
assertThat("it has a name",
scoped.getName(),
is("name"));
-
- assertThat("it has an MBean name",
- scoped.getMBeanName(),
- is("com.yammer.metrics.core.tests:type=MetricNameTest,scope=scope,name=name"));
}
@Test
@@ -110,15 +96,15 @@ public void hasAWorkingEqualsImplementation() throws Exception {
is(not(equalTo((Object) ""))));
assertThat(name,
- is(equalTo(new MetricName("group", "type", "name", "scope", "bean"))));
+ is(equalTo(new MetricName("group", "type", "name", "scope"))));
}
@Test
public void hasAWorkingHashCodeImplementation() throws Exception {
- assertThat(new MetricName("group", "type", "name", "scope", "bean").hashCode(),
- is(equalTo(new MetricName("group", "type", "name", "scope", "bean").hashCode())));
+ assertThat(new MetricName("group", "type", "name", "scope").hashCode(),
+ is(equalTo(new MetricName("group", "type", "name", "scope").hashCode())));
- assertThat(new MetricName("group", "type", "name", "scope", "bean").hashCode(),
- is(not(equalTo(new MetricName("group", "type", "name", "scope", "bean2").hashCode()))));
+ assertThat(new MetricName("group", "type", "name", "scope").hashCode(),
+ is(not(equalTo(new MetricName("group", "type", "name", "scope2").hashCode()))));
}
}
diff --git a/metrics-ganglia/src/main/java/com/yammer/metrics/ganglia/GangliaReporter.java b/metrics-ganglia/src/main/java/com/yammer/metrics/ganglia/GangliaReporter.java
index fc1891f9a9..5d90053008 100644
--- a/metrics-ganglia/src/main/java/com/yammer/metrics/ganglia/GangliaReporter.java
+++ b/metrics-ganglia/src/main/java/com/yammer/metrics/ganglia/GangliaReporter.java
@@ -461,7 +461,7 @@ protected String sanitizeName(MetricName name) {
if (name == null) {
return "";
}
- final String qualifiedTypeName = name.getGroup() + "." + name.getType() + "." + name.getName();
+ final String qualifiedTypeName = name.getDomain() + "." + name.getType() + "." + name.getName();
final String metricName = name.hasScope() ? qualifiedTypeName + '.' + name.getScope() : qualifiedTypeName;
final StringBuilder sb = new StringBuilder();
for (int i = 0; i < metricName.length(); i++) {
diff --git a/metrics-graphite/src/main/java/com/yammer/metrics/graphite/GraphiteReporter.java b/metrics-graphite/src/main/java/com/yammer/metrics/graphite/GraphiteReporter.java
index 1186e5d5f3..502268b3a3 100644
--- a/metrics-graphite/src/main/java/com/yammer/metrics/graphite/GraphiteReporter.java
+++ b/metrics-graphite/src/main/java/com/yammer/metrics/graphite/GraphiteReporter.java
@@ -287,7 +287,7 @@ protected void sendToGraphite(long timestamp, String name, String value) {
protected String sanitizeName(MetricName name) {
final StringBuilder sb = new StringBuilder()
- .append(name.getGroup())
+ .append(name.getDomain())
.append('.')
.append(name.getType())
.append('.');
diff --git a/metrics-jersey/src/main/java/com/yammer/metrics/jersey/InstrumentedResourceMethodDispatchProvider.java b/metrics-jersey/src/main/java/com/yammer/metrics/jersey/InstrumentedResourceMethodDispatchProvider.java
index ad5c2c08d9..c74b1c4410 100644
--- a/metrics-jersey/src/main/java/com/yammer/metrics/jersey/InstrumentedResourceMethodDispatchProvider.java
+++ b/metrics-jersey/src/main/java/com/yammer/metrics/jersey/InstrumentedResourceMethodDispatchProvider.java
@@ -7,15 +7,10 @@
import com.yammer.metrics.annotation.ExceptionMetered;
import com.yammer.metrics.annotation.Metered;
import com.yammer.metrics.annotation.Timed;
-import com.yammer.metrics.core.Meter;
-import com.yammer.metrics.core.MetricName;
-import com.yammer.metrics.core.MetricsRegistry;
-import com.yammer.metrics.core.Timer;
-import com.yammer.metrics.core.TimerContext;
+import com.yammer.metrics.core.*;
import sun.misc.Unsafe;
import java.lang.reflect.Field;
-import java.util.concurrent.TimeUnit;
class InstrumentedResourceMethodDispatchProvider implements ResourceMethodDispatchProvider {
private static class TimedRequestDispatcher implements RequestDispatcher {
@@ -92,7 +87,7 @@ private static Unsafe getUnsafe() {
}
private final ResourceMethodDispatchProvider provider;
- private MetricsRegistry registry;
+ private final MetricsRegistry registry;
public InstrumentedResourceMethodDispatchProvider(ResourceMethodDispatchProvider provider, MetricsRegistry registry) {
this.provider = provider;
@@ -108,57 +103,34 @@ public RequestDispatcher create(AbstractResourceMethod method) {
if (method.getMethod().isAnnotationPresent(Timed.class)) {
final Timed annotation = method.getMethod().getAnnotation(Timed.class);
-
- Class> klass = method.getDeclaringResource().getResourceClass();
- String group = MetricName.chooseGroup(annotation.group(), klass);
- String type = MetricName.chooseType(annotation.type(), klass);
- String name = MetricName.chooseName(annotation.name(), method.getMethod());
- MetricName metricName = new MetricName(group, type, name);
-
- final Timer timer = registry.newTimer(metricName,
- annotation.durationUnit() == null ?
- TimeUnit.MILLISECONDS : annotation.durationUnit(),
- annotation.rateUnit() == null ?
- TimeUnit.SECONDS : annotation.rateUnit());
+ final MetricName name = MetricName.forTimedMethod(method.getDeclaringResource()
+ .getResourceClass(),
+ method.getMethod(),
+ annotation);
+ final Timer timer = registry.newTimer(name, annotation.durationUnit(), annotation.rateUnit());
dispatcher = new TimedRequestDispatcher(dispatcher, timer);
}
if (method.getMethod().isAnnotationPresent(Metered.class)) {
final Metered annotation = method.getMethod().getAnnotation(Metered.class);
-
- Class> klass = method.getDeclaringResource().getResourceClass();
- String group = MetricName.chooseGroup(annotation.group(), klass);
- String type = MetricName.chooseType(annotation.type(), klass);
- String name = MetricName.chooseName(annotation.name(), method.getMethod());
- MetricName metricName = new MetricName(group, type, name);
-
- final Meter meter = registry.newMeter(metricName,
- annotation.eventType() == null ?
- "requests" : annotation.eventType(),
- annotation.rateUnit() == null ?
- TimeUnit.SECONDS : annotation.rateUnit());
+ final MetricName name = MetricName.forMeteredMethod(method.getDeclaringResource()
+ .getResourceClass(),
+ method.getMethod(),
+ annotation);
+ final Meter meter = registry.newMeter(name, annotation.eventType(), annotation.rateUnit());
dispatcher = new MeteredRequestDispatcher(dispatcher, meter);
}
if (method.getMethod().isAnnotationPresent(ExceptionMetered.class)) {
final ExceptionMetered annotation = method.getMethod().getAnnotation(ExceptionMetered.class);
-
- Class> klass = method.getDeclaringResource().getResourceClass();
- String group = MetricName.chooseGroup(annotation.group(), klass);
- String type = MetricName.chooseType(annotation.type(), klass);
- String name = annotation.name() == null || annotation.name().equals("") ?
- method.getMethod().getName() + ExceptionMetered.DEFAULT_NAME_SUFFIX : annotation.name();
- MetricName metricName = new MetricName(group, type, name);
-
- final Meter meter = registry.newMeter(metricName,
- annotation.eventType() == null ?
- "requests" : annotation.eventType(),
- annotation.rateUnit() == null ?
- TimeUnit.SECONDS : annotation.rateUnit());
+ final MetricName name = MetricName.forExceptionMeteredMethod(method.getDeclaringResource()
+ .getResourceClass(),
+ method.getMethod(),
+ annotation);
+ final Meter meter = registry.newMeter(name, annotation.eventType(), annotation.rateUnit());
dispatcher = new ExceptionMeteredRequestDispatcher(dispatcher, meter, annotation.cause());
}
return dispatcher;
}
-
}