diff --git a/NOTICE b/NOTICE
new file mode 100644
index 0000000..4fe83de
--- /dev/null
+++ b/NOTICE
@@ -0,0 +1,11 @@
+Metrics
+Copyright 2010-2013 Coda Hale and Yammer, Inc.
+
+This product includes software developed by Coda Hale and Yammer, Inc.
+
+This product includes code derived from the JSR-166 project (ThreadLocalRandom, Striped64,
+LongAdder), which was released with the following comments:
+
+ Written by Doug Lea with assistance from members of JCP JSR-166
+ Expert Group and released to the public domain, as explained at
+ http://creativecommons.org/publicdomain/zero/1.0/
diff --git a/pom.xml b/pom.xml
index 064814f..8e62694 100644
--- a/pom.xml
+++ b/pom.xml
@@ -37,6 +37,16 @@
guava
18.0
+
+ com.yammer.metrics
+ metrics-core
+ 2.2.0
+
+
+ com.google.collections
+ google-collections
+ 1.0
+
diff --git a/src/main/java/com/cloudius/urchin/metrics/APIMetrics.java b/src/main/java/com/cloudius/urchin/metrics/APIMetrics.java
new file mode 100644
index 0000000..380e136
--- /dev/null
+++ b/src/main/java/com/cloudius/urchin/metrics/APIMetrics.java
@@ -0,0 +1,397 @@
+package com.cloudius.urchin.metrics;
+
+/*
+ * Copyright 2015 Cloudius Systems
+ *
+ * Modified by Cloudius Systems
+ */
+
+import java.util.concurrent.TimeUnit;
+
+import com.yammer.metrics.core.APIMetricsRegistry;
+import com.yammer.metrics.core.Counter;
+import com.yammer.metrics.core.Gauge;
+import com.yammer.metrics.core.Histogram;
+import com.yammer.metrics.core.Meter;
+import com.yammer.metrics.core.MetricName;
+import com.yammer.metrics.core.Timer;
+import com.yammer.metrics.reporting.JmxReporter;
+
+public class APIMetrics {
+ private static final APIMetricsRegistry DEFAULT_REGISTRY = new APIMetricsRegistry();
+ private static final Thread SHUTDOWN_HOOK = new Thread() {
+ public void run() {
+ JmxReporter.shutdownDefault();
+ }
+ };
+
+ static {
+ JmxReporter.startDefault(DEFAULT_REGISTRY);
+ Runtime.getRuntime().addShutdownHook(SHUTDOWN_HOOK);
+ }
+
+ private APIMetrics() { /* unused */
+ }
+
+ /**
+ * Given a new {@link com.yammer.metrics.core.Gauge}, registers it under the
+ * given class and name.
+ *
+ * @param klass
+ * the class which owns the metric
+ * @param name
+ * the name of the metric
+ * @param metric
+ * the metric
+ * @param
+ * the type of the value returned by the metric
+ * @return {@code metric}
+ */
+ public static Gauge newGauge(Class> klass, String name,
+ Gauge metric) {
+ return DEFAULT_REGISTRY.newGauge(klass, name, metric);
+ }
+
+ /**
+ * Given a new {@link com.yammer.metrics.core.Gauge}, registers it under the
+ * given class and name.
+ *
+ * @param klass
+ * the class which owns the metric
+ * @param name
+ * the name of the metric
+ * @param scope
+ * the scope of the metric
+ * @param metric
+ * the metric
+ * @param
+ * the type of the value returned by the metric
+ * @return {@code metric}
+ */
+ public static Gauge newGauge(Class> klass, String name,
+ String scope, Gauge metric) {
+ return DEFAULT_REGISTRY.newGauge(klass, name, scope, metric);
+ }
+
+ /**
+ * Given a new {@link com.yammer.metrics.core.Gauge}, registers it under the
+ * given metric name.
+ *
+ * @param metricName
+ * the name of the metric
+ * @param metric
+ * the metric
+ * @param
+ * the type of the value returned by the metric
+ * @return {@code metric}
+ */
+ public static Gauge newGauge(MetricName metricName, Gauge metric) {
+ return DEFAULT_REGISTRY.newGauge(metricName, metric);
+ }
+
+ /**
+ * Creates a new {@link com.yammer.metrics.core.Counter} and registers it
+ * under the given class and name.
+ *
+ * @param klass
+ * the class which owns the metric
+ * @param name
+ * the name of the metric
+ * @return a new {@link com.yammer.metrics.core.Counter}
+ */
+ public static Counter newCounter(String url, Class> klass, String name) {
+ return DEFAULT_REGISTRY.newCounter(url, klass, name);
+ }
+
+ /**
+ * Creates a new {@link com.yammer.metrics.core.Counter} and registers it
+ * under the given class and name.
+ *
+ * @param klass
+ * the class which owns the metric
+ * @param name
+ * the name of the metric
+ * @param scope
+ * the scope of the metric
+ * @return a new {@link com.yammer.metrics.core.Counter}
+ */
+ public static Counter newCounter(String url, Class> klass, String name,
+ String scope) {
+ return DEFAULT_REGISTRY.newCounter(url, klass, name, scope);
+ }
+
+ /**
+ * Creates a new {@link com.yammer.metrics.core.Counter} and registers it
+ * under the given metric name.
+ *
+ * @param metricName
+ * the name of the metric
+ * @return a new {@link com.yammer.metrics.core.Counter}
+ */
+ public static Counter newCounter(String url, MetricName metricName) {
+ return DEFAULT_REGISTRY.newCounter(url, metricName);
+ }
+
+ /**
+ * Creates a new {@link com.yammer.metrics.core.Histogram} and registers it
+ * under the given class and name.
+ *
+ * @param klass
+ * the class which owns the metric
+ * @param name
+ * the name of the metric
+ * @param biased
+ * whether or not the histogram should be biased
+ * @return a new {@link com.yammer.metrics.core.Histogram}
+ */
+ public static Histogram newHistogram(Class> klass, String name,
+ boolean biased) {
+ return DEFAULT_REGISTRY.newHistogram(klass, name, biased);
+ }
+
+ /**
+ * Creates a new {@link com.yammer.metrics.core.Histogram} and registers it
+ * under the given class, name, and scope.
+ *
+ * @param klass
+ * the class which owns the metric
+ * @param name
+ * the name of the metric
+ * @param scope
+ * the scope of the metric
+ * @param biased
+ * whether or not the histogram should be biased
+ * @return a new {@link com.yammer.metrics.core.Histogram}
+ */
+ public static Histogram newHistogram(Class> klass, String name,
+ String scope, boolean biased) {
+ return DEFAULT_REGISTRY.newHistogram(klass, name, scope, biased);
+ }
+
+ /**
+ * Creates a new {@link com.yammer.metrics.core.Histogram} and registers it
+ * under the given metric name.
+ *
+ * @param metricName
+ * the name of the metric
+ * @param biased
+ * whether or not the histogram should be biased
+ * @return a new {@link com.yammer.metrics.core.Histogram}
+ */
+ public static Histogram newHistogram(MetricName metricName, boolean biased) {
+ return DEFAULT_REGISTRY.newHistogram(metricName, biased);
+ }
+
+ /**
+ * Creates a new non-biased {@link com.yammer.metrics.core.Histogram} and
+ * registers it under the given class and name.
+ *
+ * @param klass
+ * the class which owns the metric
+ * @param name
+ * the name of the metric
+ * @return a new {@link com.yammer.metrics.core.Histogram}
+ */
+ public static Histogram newHistogram(Class> klass, String name) {
+ return DEFAULT_REGISTRY.newHistogram(klass, name);
+ }
+
+ /**
+ * Creates a new non-biased {@link com.yammer.metrics.core.Histogram} and
+ * registers it under the given class, name, and scope.
+ *
+ * @param klass
+ * the class which owns the metric
+ * @param name
+ * the name of the metric
+ * @param scope
+ * the scope of the metric
+ * @return a new {@link com.yammer.metrics.core.Histogram}
+ */
+ public static Histogram newHistogram(Class> klass, String name,
+ String scope) {
+ return DEFAULT_REGISTRY.newHistogram(klass, name, scope);
+ }
+
+ /**
+ * Creates a new non-biased {@link com.yammer.metrics.core.Histogram} and
+ * registers it under the given metric name.
+ *
+ * @param metricName
+ * the name of the metric
+ * @return a new {@link com.yammer.metrics.core.Histogram}
+ */
+ public static Histogram newHistogram(MetricName metricName) {
+ return newHistogram(metricName, false);
+ }
+
+ /**
+ * Creates a new {@link com.yammer.metrics.core.Meter} and registers it
+ * under the given class and name.
+ *
+ * @param klass
+ * the class which owns the metric
+ * @param name
+ * the name of the metric
+ * @param eventType
+ * the plural name of the type of events the meter is measuring
+ * (e.g., {@code "requests"})
+ * @param unit
+ * the rate unit of the new meter
+ * @return a new {@link com.yammer.metrics.core.Meter}
+ */
+ public static Meter newMeter(String url, Class> klass, String name,
+ String eventType, TimeUnit unit) {
+ return DEFAULT_REGISTRY.newMeter(url, klass, name, eventType, unit);
+ }
+
+ /**
+ * Creates a new {@link com.yammer.metrics.core.Meter} and registers it
+ * under the given class, name, and scope.
+ *
+ * @param klass
+ * the class which owns the metric
+ * @param name
+ * the name of the metric
+ * @param scope
+ * the scope of the metric
+ * @param eventType
+ * the plural name of the type of events the meter is measuring
+ * (e.g., {@code "requests"})
+ * @param unit
+ * the rate unit of the new meter
+ * @return a new {@link com.yammer.metrics.core.Meter}
+ */
+ public static Meter newMeter(String url, Class> klass, String name,
+ String scope, String eventType, TimeUnit unit) {
+ return DEFAULT_REGISTRY.newMeter(url, klass, name, scope, eventType,
+ unit);
+ }
+
+ /**
+ * Creates a new {@link com.yammer.metrics.core.Meter} and registers it
+ * under the given metric name.
+ *
+ * @param metricName
+ * the name of the metric
+ * @param eventType
+ * the plural name of the type of events the meter is measuring
+ * (e.g., {@code "requests"})
+ * @param unit
+ * the rate unit of the new meter
+ * @return a new {@link com.yammer.metrics.core.Meter}
+ */
+ public static Meter newMeter(String url, MetricName metricName,
+ String eventType, TimeUnit unit) {
+ return DEFAULT_REGISTRY.newMeter(url, metricName, eventType, unit);
+ }
+
+ /**
+ * Creates a new {@link com.yammer.metrics.core.Timer} and registers it
+ * under the given class and name.
+ *
+ * @param klass
+ * the class which owns the metric
+ * @param name
+ * the name of the metric
+ * @param durationUnit
+ * the duration scale unit of the new timer
+ * @param rateUnit
+ * the rate scale unit of the new timer
+ * @return a new {@link com.yammer.metrics.core.Timer}
+ */
+ public static Timer newTimer(Class> klass, String name,
+ TimeUnit durationUnit, TimeUnit rateUnit) {
+ return DEFAULT_REGISTRY.newTimer(klass, name, durationUnit, rateUnit);
+ }
+
+ /**
+ * Creates a new {@link com.yammer.metrics.core.Timer} and registers it
+ * under the given class and name, measuring elapsed time in milliseconds
+ * and invocations per second.
+ *
+ * @param klass
+ * the class which owns the metric
+ * @param name
+ * the name of the metric
+ * @return a new {@link com.yammer.metrics.core.Timer}
+ */
+ public static Timer newTimer(Class> klass, String name) {
+ return DEFAULT_REGISTRY.newTimer(klass, name);
+ }
+
+ /**
+ * Creates a new {@link com.yammer.metrics.core.Timer} and registers it
+ * under the given class, name, and scope.
+ *
+ * @param klass
+ * the class which owns the metric
+ * @param name
+ * the name of the metric
+ * @param scope
+ * the scope of the metric
+ * @param durationUnit
+ * the duration scale unit of the new timer
+ * @param rateUnit
+ * the rate scale unit of the new timer
+ * @return a new {@link com.yammer.metrics.core.Timer}
+ */
+ public static Timer newTimer(Class> klass, String name, String scope,
+ TimeUnit durationUnit, TimeUnit rateUnit) {
+ return DEFAULT_REGISTRY.newTimer(klass, name, scope, durationUnit,
+ rateUnit);
+ }
+
+ /**
+ * Creates a new {@link com.yammer.metrics.core.Timer} and registers it
+ * under the given class, name, and scope, measuring elapsed time in
+ * milliseconds and invocations per second.
+ *
+ * @param klass
+ * the class which owns the metric
+ * @param name
+ * the name of the metric
+ * @param scope
+ * the scope of the metric
+ * @return a new {@link com.yammer.metrics.core.Timer}
+ */
+ public static Timer newTimer(Class> klass, String name, String scope) {
+ return DEFAULT_REGISTRY.newTimer(klass, name, scope);
+ }
+
+ /**
+ * Creates a new {@link com.yammer.metrics.core.Timer} and registers it
+ * under the given metric name.
+ *
+ * @param metricName
+ * the name of the metric
+ * @param durationUnit
+ * the duration scale unit of the new timer
+ * @param rateUnit
+ * the rate scale unit of the new timer
+ * @return a new {@link com.yammer.metrics.core.Timer}
+ */
+ public static Timer newTimer(MetricName metricName, TimeUnit durationUnit,
+ TimeUnit rateUnit) {
+ return DEFAULT_REGISTRY.newTimer(metricName, durationUnit, rateUnit);
+ }
+
+ /**
+ * Returns the (static) default registry.
+ *
+ * @return the metrics registry
+ */
+ public static APIMetricsRegistry defaultRegistry() {
+ return DEFAULT_REGISTRY;
+ }
+
+ /**
+ * Shuts down all thread pools for the default registry.
+ */
+ public static void shutdown() {
+ DEFAULT_REGISTRY.shutdown();
+ JmxReporter.shutdownDefault();
+ Runtime.getRuntime().removeShutdownHook(SHUTDOWN_HOOK);
+ }
+
+}
diff --git a/src/main/java/com/cloudius/urchin/metrics/DefaultNameFactory.java b/src/main/java/com/cloudius/urchin/metrics/DefaultNameFactory.java
new file mode 100644
index 0000000..1c65fb5
--- /dev/null
+++ b/src/main/java/com/cloudius/urchin/metrics/DefaultNameFactory.java
@@ -0,0 +1,72 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.
+ */
+
+/*
+ * Copyright 2015 Cloudius Systems
+ *
+ * Modified by Cloudius Systems
+ */
+package com.cloudius.urchin.metrics;
+
+import com.yammer.metrics.core.MetricName;
+
+/**
+ * MetricNameFactory that generates default MetricName of metrics.
+ */
+public class DefaultNameFactory implements MetricNameFactory {
+ public static final String GROUP_NAME = "org.apache.cassandra.metrics";
+
+ private final String type;
+ private final String scope;
+
+ public DefaultNameFactory(String type) {
+ this(type, null);
+ }
+
+ public DefaultNameFactory(String type, String scope) {
+ this.type = type;
+ this.scope = scope;
+ }
+
+ public MetricName createMetricName(String metricName) {
+ return createMetricName(type, metricName, scope);
+ }
+
+ public static MetricName createMetricName(String type, String metricName,
+ String scope) {
+ return new MetricName(GROUP_NAME, type, metricName, scope,
+ createDefaultMBeanName(type, metricName, scope));
+ }
+
+ protected static String createDefaultMBeanName(String type, String name,
+ String scope) {
+ final StringBuilder nameBuilder = new StringBuilder();
+ nameBuilder.append(GROUP_NAME);
+ nameBuilder.append(":type=");
+ nameBuilder.append(type);
+ if (scope != null) {
+ nameBuilder.append(",scope=");
+ nameBuilder.append(scope);
+ }
+ if (name.length() > 0) {
+ nameBuilder.append(",name=");
+ nameBuilder.append(name);
+ }
+ return nameBuilder.toString();
+ }
+}
diff --git a/src/main/java/com/cloudius/urchin/metrics/MetricNameFactory.java b/src/main/java/com/cloudius/urchin/metrics/MetricNameFactory.java
new file mode 100644
index 0000000..3bd92e5
--- /dev/null
+++ b/src/main/java/com/cloudius/urchin/metrics/MetricNameFactory.java
@@ -0,0 +1,37 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.
+ */
+/*
+ * Copyright 2015 Cloudius Systems
+ *
+ * Modified by Cloudius Systems
+ */
+
+package com.cloudius.urchin.metrics;
+
+import com.yammer.metrics.core.MetricName;
+
+public interface MetricNameFactory
+{
+ /**
+ * Create a qualified name from given metric name.
+ *
+ * @param metricName part of qualified name.
+ * @return new String with given metric name.
+ */
+ MetricName createMetricName(String metricName);
+}
diff --git a/src/main/java/com/yammer/metrics/core/APICounter.java b/src/main/java/com/yammer/metrics/core/APICounter.java
new file mode 100644
index 0000000..85ddc87
--- /dev/null
+++ b/src/main/java/com/yammer/metrics/core/APICounter.java
@@ -0,0 +1,29 @@
+package com.yammer.metrics.core;
+/*
+ * Copyright 2015 Cloudius Systems
+ *
+ * Modified by Cloudius Systems
+ */
+
+import com.cloudius.urchin.api.APIClient;
+import com.yammer.metrics.core.Counter;
+
+public class APICounter extends Counter {
+ String url;
+ private APIClient c = new APIClient();
+
+ public APICounter(String _url) {
+ super();
+ url = _url;
+ }
+ /**
+ * Returns the counter's current value.
+ *
+ * @return the counter's current value
+ */
+ public long count() {
+ return c.getLongValue(url);
+ }
+
+
+}
diff --git a/src/main/java/com/yammer/metrics/core/APIHistogram.java b/src/main/java/com/yammer/metrics/core/APIHistogram.java
new file mode 100644
index 0000000..8ccdbb0
--- /dev/null
+++ b/src/main/java/com/yammer/metrics/core/APIHistogram.java
@@ -0,0 +1,112 @@
+package com.yammer.metrics.core;
+
+/*
+ * Copyright 2015 Cloudius Systems
+ *
+ * Modified by Cloudius Systems
+ */
+
+import com.cloudius.urchin.api.APIClient;
+import com.yammer.metrics.stats.Sample;
+import com.yammer.metrics.stats.Snapshot;
+
+public class APIHistogram extends Histogram {
+ long last_update = 0;
+ static final long UPDATE_INTERVAL = 50;
+ String url;
+ private APIClient c = new APIClient();
+
+ public APIHistogram(String _url, Sample sample) {
+ super(sample);
+ url = _url;
+ }
+
+ public APIHistogram(String _url, SampleType type) {
+ super(type);
+ url = _url;
+ }
+
+ public void update() {
+ long now = System.currentTimeMillis();
+ if (now - last_update < UPDATE_INTERVAL) {
+ return;
+ }
+ last_update = now;
+ clear();
+ long[] vals = c.getLongArrValue(url);
+ for (long v : vals) {
+ update(v);
+ }
+ }
+
+ /**
+ * Returns the number of values recorded.
+ *
+ * @return the number of values recorded
+ */
+ public long count() {
+ update();
+ return super.count();
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see com.yammer.metrics.core.Summarizable#max()
+ */
+ @Override
+ public double max() {
+ update();
+ return super.max();
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see com.yammer.metrics.core.Summarizable#min()
+ */
+ @Override
+ public double min() {
+ update();
+ return super.min();
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see com.yammer.metrics.core.Summarizable#mean()
+ */
+ @Override
+ public double mean() {
+ update();
+ return super.mean();
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see com.yammer.metrics.core.Summarizable#stdDev()
+ */
+ @Override
+ public double stdDev() {
+ update();
+ return super.stdDev();
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see com.yammer.metrics.core.Summarizable#sum()
+ */
+ @Override
+ public double sum() {
+ update();
+ return super.sum();
+ }
+
+ @Override
+ public Snapshot getSnapshot() {
+ update();
+ return super.getSnapshot();
+ }
+}
diff --git a/src/main/java/com/yammer/metrics/core/APIMeter.java b/src/main/java/com/yammer/metrics/core/APIMeter.java
new file mode 100644
index 0000000..fc1a801
--- /dev/null
+++ b/src/main/java/com/yammer/metrics/core/APIMeter.java
@@ -0,0 +1,29 @@
+package com.yammer.metrics.core;
+
+/*
+ * Copyright 2015 Cloudius Systems
+ *
+ * Modified by Cloudius Systems
+ */
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.TimeUnit;
+
+import com.cloudius.urchin.api.APIClient;
+
+public class APIMeter extends Meter {
+ String url;
+ private APIClient c = new APIClient();
+
+ public APIMeter(String _url, ScheduledExecutorService tickThread,
+ String eventType, TimeUnit rateUnit, Clock clock) {
+ super(tickThread, eventType, rateUnit, clock);
+ // TODO Auto-generated constructor stub
+ url = _url;
+ }
+
+ @Override
+ public long count() {
+ return c.getLongValue(url);
+ }
+
+}
diff --git a/src/main/java/com/yammer/metrics/core/APIMetricsRegistry.java b/src/main/java/com/yammer/metrics/core/APIMetricsRegistry.java
new file mode 100644
index 0000000..b9242b0
--- /dev/null
+++ b/src/main/java/com/yammer/metrics/core/APIMetricsRegistry.java
@@ -0,0 +1,234 @@
+package com.yammer.metrics.core;
+
+import java.lang.reflect.Field;
+import java.util.concurrent.ConcurrentMap;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.TimeUnit;
+
+import com.yammer.metrics.core.APICounter;
+import com.yammer.metrics.core.APIMeter;
+import com.yammer.metrics.core.Clock;
+import com.yammer.metrics.core.Counter;
+import com.yammer.metrics.core.Meter;
+import com.yammer.metrics.core.Metric;
+import com.yammer.metrics.core.MetricName;
+import com.yammer.metrics.core.MetricsRegistry;
+import com.yammer.metrics.core.ThreadPools;
+import com.yammer.metrics.core.Histogram.SampleType;
+
+/*
+ * Copyright 2015 Cloudius Systems
+ *
+ * Modified by Cloudius Systems
+ */
+
+public class APIMetricsRegistry extends MetricsRegistry {
+ Field field_metrics;
+ Field field_clock;
+ Field field_thread_pool;
+
+ public APIMetricsRegistry() {
+ try {
+ field_metrics = MetricsRegistry.class.getDeclaredField("metrics");
+ field_metrics.setAccessible(true);
+ field_clock = MetricsRegistry.class.getDeclaredField("clock");
+ field_clock.setAccessible(true);
+ field_thread_pool = MetricsRegistry.class.getDeclaredField("threadPools");
+ field_thread_pool.setAccessible(true);
+ } catch (NoSuchFieldException | SecurityException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ }
+
+ public ThreadPools getThreadPools() {
+ try {
+ return (ThreadPools)field_thread_pool.get(this);
+ } catch (IllegalArgumentException | IllegalAccessException e) {
+ e.printStackTrace();
+ }
+ return null;
+ }
+
+ public Clock getClock() {
+ try {
+ return (Clock)field_clock.get(this);
+ } catch (IllegalArgumentException | IllegalAccessException e) {
+ e.printStackTrace();
+ }
+ return null;
+ }
+
+ @SuppressWarnings("unchecked")
+ public ConcurrentMap get_metrics() {
+ try {
+ return (ConcurrentMap)field_metrics.get(this);
+ } catch (IllegalArgumentException | IllegalAccessException e) {
+ e.printStackTrace();
+ }
+ return null;
+ }
+ /**
+ * Creates a new {@link Counter} and registers it under the given class and name.
+ *
+ * @param klass the class which owns the metric
+ * @param name the name of the metric
+ * @return a new {@link Counter}
+ */
+ public Counter newCounter(String url, Class> klass,
+ String name) {
+ return newCounter(url, klass, name, null);
+ }
+
+ /**
+ * Creates a new {@link Counter} and registers it under the given class and name.
+ *
+ * @param klass the class which owns the metric
+ * @param name the name of the metric
+ * @param scope the scope of the metric
+ * @return a new {@link Counter}
+ */
+ public Counter newCounter(String url, Class> klass,
+ String name,
+ String scope) {
+ return newCounter(url, createName(klass, name, scope));
+ }
+ /**
+ * Creates a new {@link Counter} and registers it under the given metric name.
+ *
+ * @param metricName the name of the metric
+ * @return a new {@link Counter}
+ */
+ public Counter newCounter(String url, MetricName metricName) {
+ return getOrAdd(metricName, new APICounter(url));
+ }
+
+ /**
+ * Creates a new {@link Meter} and registers it under the given class and name.
+ *
+ * @param klass the class which owns the metric
+ * @param name the name of the metric
+ * @param eventType the plural name of the type of events the meter is measuring (e.g., {@code
+ * "requests"})
+ * @param unit the rate unit of the new meter
+ * @return a new {@link Meter}
+ */
+ public Meter newMeter(String url, Class> klass,
+ String name,
+ String eventType,
+ TimeUnit unit) {
+ return newMeter(url, klass, name, null, eventType, unit);
+ }
+
+ /**
+ * Creates a new {@link Meter} and registers it under the given class, name, and scope.
+ *
+ * @param klass the class which owns the metric
+ * @param name the name of the metric
+ * @param scope the scope of the metric
+ * @param eventType the plural name of the type of events the meter is measuring (e.g., {@code
+ * "requests"})
+ * @param unit the rate unit of the new meter
+ * @return a new {@link Meter}
+ */
+ public Meter newMeter(String url,
+ Class> klass,
+ String name,
+ String scope,
+ String eventType,
+ TimeUnit unit) {
+ return newMeter(url, createName(klass, name, scope), eventType, unit);
+ }
+
+ private ScheduledExecutorService newMeterTickThreadPool() {
+ return getThreadPools().newScheduledThreadPool(2, "meter-tick");
+ }
+ /**
+ * Creates a new {@link Meter} and registers it under the given metric name.
+ *
+ * @param metricName the name of the metric
+ * @param eventType the plural name of the type of events the meter is measuring (e.g., {@code
+ * "requests"})
+ * @param unit the rate unit of the new meter
+ * @return a new {@link Meter}
+ */
+ public Meter newMeter(String url, MetricName metricName,
+ String eventType,
+ TimeUnit unit) {
+ final Metric existingMetric = get_metrics().get(metricName);
+ if (existingMetric != null) {
+ return (Meter) existingMetric;
+ }
+ return getOrAdd(metricName, new APIMeter(url, newMeterTickThreadPool(), eventType, unit, getClock()));
+ }
+
+ /**
+ * Creates a new {@link Histogram} and registers it under the given class and name.
+ *
+ * @param klass the class which owns the metric
+ * @param name the name of the metric
+ * @param biased whether or not the histogram should be biased
+ * @return a new {@link Histogram}
+ */
+ public Histogram newHistogram(String url, Class> klass,
+ String name,
+ boolean biased) {
+ return newHistogram(url, klass, name, null, biased);
+ }
+
+ /**
+ * Creates a new {@link Histogram} and registers it under the given class, name, and scope.
+ *
+ * @param klass the class which owns the metric
+ * @param name the name of the metric
+ * @param scope the scope of the metric
+ * @param biased whether or not the histogram should be biased
+ * @return a new {@link Histogram}
+ */
+ public Histogram newHistogram(String url, Class> klass,
+ String name,
+ String scope,
+ boolean biased) {
+ return newHistogram(url, createName(klass, name, scope), biased);
+ }
+
+ /**
+ * Creates a new non-biased {@link Histogram} and registers it under the given class and name.
+ *
+ * @param klass the class which owns the metric
+ * @param name the name of the metric
+ * @return a new {@link Histogram}
+ */
+ public Histogram newHistogram(String url, Class> klass,
+ String name) {
+ return newHistogram(url, klass, name, false);
+ }
+
+ /**
+ * Creates a new non-biased {@link Histogram} and registers it under the given class, name, and
+ * scope.
+ *
+ * @param klass the class which owns the metric
+ * @param name the name of the metric
+ * @param scope the scope of the metric
+ * @return a new {@link Histogram}
+ */
+ public Histogram newHistogram(String url, Class> klass,
+ String name,
+ String scope) {
+ return newHistogram(url, klass, name, scope, false);
+ }
+
+ /**
+ * Creates a new {@link Histogram} and registers it under the given metric name.
+ *
+ * @param metricName the name of the metric
+ * @param biased whether or not the histogram should be biased
+ * @return a new {@link Histogram}
+ */
+ public Histogram newHistogram(String url, MetricName metricName,
+ boolean biased) {
+ return getOrAdd(metricName,
+ new APIHistogram(url, biased ? SampleType.BIASED : SampleType.UNIFORM));
+ }
+}