You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@dubbo.apache.org by GitBox <gi...@apache.org> on 2018/07/06 12:26:17 UTC

[GitHub] chickenlj closed pull request #1966: [Dubbo-1922] Add dubbo metrics API.

chickenlj closed pull request #1966: [Dubbo-1922] Add dubbo metrics API.
URL: https://github.com/apache/incubator-dubbo/pull/1966
 
 
   

This is a PR merged from a forked repository.
As GitHub hides the original diff on merge, it is displayed below for
the sake of provenance:

As this is a foreign pull request (from a fork), the diff is supplied
below (as it won't show otherwise due to GitHub magic):

diff --git a/dubbo-metrics/dubbo-metrics-api/pom.xml b/dubbo-metrics/dubbo-metrics-api/pom.xml
new file mode 100644
index 0000000000..3ebdc20552
--- /dev/null
+++ b/dubbo-metrics/dubbo-metrics-api/pom.xml
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <parent>
+        <artifactId>dubbo-metrics</artifactId>
+        <groupId>org.apache.dubbo</groupId>
+        <version>2.7.0-SNAPSHOT</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>dubbo-metrics-api</artifactId>
+
+
+</project>
\ No newline at end of file
diff --git a/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/BucketCounter.java b/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/BucketCounter.java
new file mode 100644
index 0000000000..8c449fb4df
--- /dev/null
+++ b/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/BucketCounter.java
@@ -0,0 +1,57 @@
+/*
+ * 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.
+ */
+package org.apache.dubbo.metrics;
+
+import java.util.Map;
+
+/**
+ * Store the count in multiple buckets,
+ * every event will go into one specific bucket according to the happening timestamp.
+ * The BucketCounter will reserve data for the last N time interval,
+ * older values will be automatically discarded.
+ */
+public interface BucketCounter extends Metric {
+
+    /**
+     * update the counter to the given bucket
+     */
+    void update();
+
+    /**
+     * update the counter to the given bucket
+     */
+    void update(long n);
+
+    /**
+     * Return the bucket count, keyed by timestamp
+     * @return the bucket count, keyed by timestamp
+     */
+    Map<Long, Long> getBucketCounts();
+
+    /**
+     * Return the bucket count, keyed by timestamp, since (including) the startTime.
+     * @param startTime the start time
+     * @return the bucket count, keyed by timestamp
+     */
+    Map<Long, Long> getBucketCounts(long startTime);
+
+    /**
+     * Get the interval of the bucket
+     * @return the interval of the bucket
+     */
+    int getBucketInterval();
+}
diff --git a/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/Compass.java b/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/Compass.java
new file mode 100644
index 0000000000..eff395d111
--- /dev/null
+++ b/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/Compass.java
@@ -0,0 +1,75 @@
+/*
+ * 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.
+ */
+package org.apache.dubbo.metrics;
+
+import java.util.Map;
+
+/**
+ * A metric that provides an easy way to collect method invocation,
+ * response time, success count, and error code count.
+ */
+public interface Compass extends Metric {
+
+    /**
+     * record a method invocation with execution time and sub-categories
+     * @param duration must be milliseconds
+     * @param subCategory all the sub-categories should be orthogonal,
+     *                    which will be added up to the total number of method invocations
+     */
+    void record(long duration, String subCategory);
+    
+    /**
+     * return method count per bucket per category
+     * @return
+     */
+    Map<String, Map<Long, Long>> getMethodCountPerCategory();
+
+    /**
+     * return method count per bucket per category
+     * @return
+     */
+    Map<String, Map<Long, Long>> getMethodCountPerCategory(long startTime);
+
+    /**
+     * return method execution time per bucket per category
+     * @return
+     */
+    Map<String, Map<Long, Long>> getMethodRtPerCategory();
+
+    /**
+     * return method execution time per bucket per category
+     * @return
+     */
+    Map<String, Map<Long, Long>> getMethodRtPerCategory(long startTime);
+
+    /**
+     * return method execution time and count per bucket per category
+     * @return
+     */
+    Map<String, Map<Long, Long>> getCountAndRtPerCategory();
+    
+    /**
+     * return method execution time and count per bucket per category
+     * @return
+     */
+    Map<String, Map<Long, Long>> getCountAndRtPerCategory(long startTime);
+    
+    /**
+     * @return the bucket interval
+     */
+    int getBucketInterval();
+}
diff --git a/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/Counter.java b/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/Counter.java
new file mode 100644
index 0000000000..22be662038
--- /dev/null
+++ b/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/Counter.java
@@ -0,0 +1,50 @@
+/*
+ * 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.
+ */
+package org.apache.dubbo.metrics;
+
+/**
+ * <pre>
+ * An incrementing and decrementing counter metric.
+ * </pre>
+ */
+public interface Counter extends Metric, Counting {
+
+    /**
+     * Increment the counter by one.
+     */
+    void inc();
+
+    /**
+     * Increment the counter by {@code n}.
+     *
+     * @param n the amount by which the counter will be increased
+     */
+    void inc(long n);
+
+    /**
+     * Decrement the counter by one.
+     */
+    void dec();
+
+    /**
+     * Decrement the counter by {@code n}.
+     *
+     * @param n the amount by which the counter will be decreased
+     */
+    void dec(long n);
+
+}
\ No newline at end of file
diff --git a/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/Counting.java b/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/Counting.java
new file mode 100644
index 0000000000..6795902e06
--- /dev/null
+++ b/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/Counting.java
@@ -0,0 +1,29 @@
+/*
+ * 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.
+ */
+package org.apache.dubbo.metrics;
+
+/**
+ * An interface for metric types which have counts.
+ */
+public interface Counting {
+    /**
+     * Returns the current count.
+     *
+     * @return the current count
+     */
+    long getCount();
+}
diff --git a/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/Gauge.java b/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/Gauge.java
new file mode 100644
index 0000000000..a094225f67
--- /dev/null
+++ b/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/Gauge.java
@@ -0,0 +1,42 @@
+/*
+ * 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.
+ */
+package org.apache.dubbo.metrics;
+
+
+/**
+ * <pre>
+ * A gauge metric is an instantaneous reading of a particular value. To instrument a queue's depth,
+ * for example:
+ *
+ * final Queue&lt;String&gt; queue = new ConcurrentLinkedQueue&lt;String&gt;();
+ * final Gauge&lt;Integer&gt; queueDepth = new Gauge&lt;Integer&gt;() {
+ *     public Integer getValue() {
+ *         return queue.size();
+ *     }
+ * };
+ * </pre>
+ *
+ * @param <T> the type of the metric's value
+ */
+public interface Gauge<T> extends Metric {
+    /**
+     * Returns the metric's current value.
+     *
+     * @return the metric's current value
+     */
+    T getValue();
+}
diff --git a/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/IMetricManager.java b/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/IMetricManager.java
new file mode 100644
index 0000000000..eef6720e2b
--- /dev/null
+++ b/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/IMetricManager.java
@@ -0,0 +1,104 @@
+/*
+ * 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.
+ */
+package org.apache.dubbo.metrics;
+
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+public interface IMetricManager {
+
+    /**
+     * Create a {@link Counter} metric in given group, and name.
+     * if not exist, an instance will be created.
+     *
+     * @param group the group of MetricRegistry
+     * @param name the name of the metric
+     * @return an instance of counter
+     */
+    Counter getCounter(String group, MetricName name);
+
+    /**
+     * Create a {@link BucketCounter} metric in given group, and name.
+     * if not exist, an instance will be created.
+     *
+     * @param group the group of MetricRegistry
+     * @param name the name of the metric
+     * @return an instance of {@link BucketCounter}
+     */
+    BucketCounter getBucketCounter(String group, MetricName name);
+
+    /**
+     * Create a {@link Compass} metric in give group, name, and type
+     * if not exist, an instance will be created.
+     * @param group the group of MetricRegistry
+     * @param name the name of the metric
+     * @return an instance of {@link Compass}
+     */
+    Compass getCompass(String group, MetricName name);
+
+    /**
+     * Register a customized metric to specified group.
+     * @param group: the group name of MetricRegistry
+     * @param metric the metric to register
+     */
+    void register(String group, MetricName name, Metric metric);
+
+    /**
+     * Get a list of group in current MetricManager
+     * @return a list of group name
+     */
+    List<String> listMetricGroups();
+
+    /**
+     * list all metric names by group
+     * @return a map of metric name set, keyed by group name
+     */
+    Map<String, Set<MetricName>> listMetricNamesByGroup();
+
+    /**
+     * Get metric registry by group name,
+     * if not found, null will be returned
+     * @param group the group name to query
+     * @return the MetricRegistry that is correspondent to the group
+     */
+    MetricRegistry getMetricRegistryByGroup(String group);
+
+    /**
+     * Get all the counters by the specific group and filter
+     * @param group the given group
+     * @param filter the given filter
+     * @return the MetricName to Counter map
+     */
+    Map<MetricName, Counter> getCounters(String group, MetricFilter filter);
+
+    /**
+     * Get all the compasses by the specific group and filter
+     * @param group the given group
+     * @param filter the given filter
+     * @return the MetricName to Compass map
+     */
+    Map<MetricName, Compass> getCompasses(String group, MetricFilter filter);
+
+    /**
+     * A map of metric names to metrics.
+     *
+     * @return all the metrics
+     */
+    Map<MetricName, Metric> getMetrics(String group);
+
+}
diff --git a/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/Metric.java b/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/Metric.java
new file mode 100644
index 0000000000..70823f0998
--- /dev/null
+++ b/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/Metric.java
@@ -0,0 +1,29 @@
+/*
+ * 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.
+ */
+package org.apache.dubbo.metrics;
+
+/**
+ * A tag interface to indicate that a class is a metric.
+ */
+public interface Metric {
+
+    /**
+     * Return the last update time in milliseconds
+     * @return the last updated time in milliseconds
+     */
+    long lastUpdateTime();
+}
diff --git a/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/MetricFilter.java b/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/MetricFilter.java
new file mode 100644
index 0000000000..243c3b7813
--- /dev/null
+++ b/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/MetricFilter.java
@@ -0,0 +1,42 @@
+/*
+ * 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.
+ */
+package org.apache.dubbo.metrics;
+
+/**
+ * A filter used to determine whether or not a metric should be reported, among other things.
+ */
+public interface MetricFilter {
+
+    /**
+     * Matches all metrics, regardless of type or name.
+     */
+    MetricFilter ALL = new MetricFilter() {
+        @Override
+        public boolean matches(MetricName name, Metric metric) {
+            return true;
+        }
+    };
+
+    /**
+     * Returns {@code true} if the metric matches the filter; {@code false} otherwise.
+     *
+     * @param name      the metric's name
+     * @param metric    the metric
+     * @return {@code true} if the metric matches the filter
+     */
+    boolean matches(MetricName name, Metric metric);
+}
diff --git a/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/MetricLevel.java b/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/MetricLevel.java
new file mode 100644
index 0000000000..66343070a3
--- /dev/null
+++ b/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/MetricLevel.java
@@ -0,0 +1,53 @@
+/*
+ * 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.
+ */
+package org.apache.dubbo.metrics;
+
+/**
+ * An enumeration class to represent the metric level
+ */
+public enum MetricLevel {
+
+    TRIVIAL, // trivial metrics
+
+    MINOR,   // minor metrics
+
+    NORMAL,  // normal metrics
+
+    MAJOR,   // major metrics
+
+    CRITICAL; // critical metrics
+
+    static {
+        for (MetricLevel level : MetricLevel.values()) {
+            if (level.ordinal() < 0) {
+                throw new RuntimeException("MetricLevel can not < 0");
+            }
+        }
+    }
+
+    public static int getMaxValue() {
+        MetricLevel[] levels = MetricLevel.values();
+        int max = levels[0].ordinal();
+        for (MetricLevel level : levels) {
+            int value = level.ordinal();
+            if (value > max) {
+                max = value;
+            }
+        }
+        return max;
+    }
+}
diff --git a/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/MetricManager.java b/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/MetricManager.java
new file mode 100644
index 0000000000..1c032ace08
--- /dev/null
+++ b/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/MetricManager.java
@@ -0,0 +1,108 @@
+/*
+ * 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.
+ */
+package org.apache.dubbo.metrics;
+
+import java.lang.reflect.Method;
+
+/**
+ * The design concept is heavily borrowed from SLF4j (http://www.slf4j.org/), the logging framework.
+ * The application only depends on the metrics api.
+ * The implementation will be dynamically bound.
+ * If the implementation if not found in classpath, by default the {@link NOPMetricManager} will be bound.
+ */
+public class MetricManager {
+
+    private static final String BINDER_CLASS = "org.apache.dubbo.metrics.MetricManagerBinder";
+
+    private static final IMetricManager NOP_METRIC_MANAGER = new NOPMetricManager();
+
+    private static volatile IMetricManager iMetricManager;
+
+    /**
+     * Create a {@link Counter} metric in given group, and name.
+     * if not exist, an instance will be created.
+     *
+     * @param group the group of MetricRegistry
+     * @param name the name of the metric
+     * @return an instance of counter
+     */
+    public static Counter getCounter(String group, MetricName name) {
+        IMetricManager manager = getIMetricManager();
+        return manager.getCounter(group, name);
+    }
+
+    /**
+     * Create a {@link BucketCounter} metric in given group, and name.
+     * if not exist, an instance will be created.
+     *
+     * @param group the group of MetricRegistry
+     * @param name the name of the metric
+     * @return an instance of {@link BucketCounter}
+     */
+    public static BucketCounter getBucketCounters(String group, MetricName name) {
+        IMetricManager manager = getIMetricManager();
+        return manager.getBucketCounter(group, name);
+    }
+
+    /**
+     * Create a {@link Compass} metric in given group, and name
+     * if not exist, an instance will be created.
+     *
+     * @param group the group of MetricRegistry
+     * @param name the name of the metric
+     * @return an instance of {@link Compass}
+     */
+    public static Compass getCompass(String group, MetricName name) {
+        IMetricManager manager = getIMetricManager();
+        return manager.getCompass(group, name);
+    }
+
+    /**
+     * Register a customized metric to specified group.
+     * @param group the group name of MetricRegistry
+     * @param metric the metric to register
+     */
+    public static void register(String group, MetricName name, Metric metric) {
+        IMetricManager manager = getIMetricManager();
+        manager.register(group, name, metric);
+    }
+
+    /**
+     * get dynamically bound {@link IMetricManager} instance
+     * @return the {@link IMetricManager} instance bound
+     */
+    @SuppressWarnings("unchecked")
+    public static IMetricManager getIMetricManager() {
+        if (iMetricManager == null) {
+            synchronized (MetricManager.class) {
+                if (iMetricManager == null) {
+                    try {
+                        Class binderClazz = MetricManager.class.getClassLoader().loadClass(BINDER_CLASS);
+                        Method getSingleton = binderClazz.getMethod("getSingleton");
+                        Object binderObject = getSingleton.invoke(null);
+                        Method getMetricManager = binderClazz.getMethod("getMetricManager");
+                        iMetricManager = (IMetricManager) getMetricManager.invoke(binderObject);
+                    } catch (Exception e) {
+                        iMetricManager = NOP_METRIC_MANAGER;
+                    }
+                }
+            }
+        }
+        return iMetricManager;
+    }
+
+}
diff --git a/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/MetricName.java b/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/MetricName.java
new file mode 100644
index 0000000000..93ae922696
--- /dev/null
+++ b/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/MetricName.java
@@ -0,0 +1,367 @@
+/*
+ * 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.
+ */
+package org.apache.dubbo.metrics;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
+import java.util.TreeSet;
+
+/**
+ * This class is based on Dropwizard metrics, see io/dropwizard/metrics/MetricName.java
+ *
+ * The following changes are made:
+ *   * Add metric level
+ *   * Cache the hash code
+ *
+ */
+public class MetricName implements Comparable<MetricName> {
+
+    public static final String SEPARATOR = ".";
+    public static final Map<String, String> EMPTY_TAGS = Collections.emptyMap();
+    public static final MetricName EMPTY = new MetricName();
+
+    private final String key;
+    private final Map<String, String> tags;
+    // the level to indicate the importance of a metric
+    private MetricLevel level;
+
+    private int hashCode = 0;
+    
+    private boolean hashCodeCached = false;
+    
+    public MetricName() {
+        this(null, null, null);
+    }
+
+    public MetricName(String key) {
+        this(key, null, null);
+    }
+
+    public MetricName(String key, Map<String, String> tags) {
+        this(key, tags, null);
+    }
+
+    public MetricName(String key, MetricLevel level) {
+        this(key, null, level);
+    }
+
+    public MetricName(String key, Map<String, String> tags, MetricLevel level) {
+        this.key = key;
+        this.tags = checkTags(tags);
+        this.level = level == null ? MetricLevel.NORMAL : level;
+    }
+
+    private Map<String, String> checkTags(Map<String, String> tags) {
+        if (tags == null || tags.isEmpty()) {
+            return EMPTY_TAGS;
+        }
+
+        return Collections.unmodifiableMap(tags);
+    }
+
+    public String getKey() {
+        return key;
+    }
+
+    public Map<String, String> getTags() {
+        return tags;
+    }
+
+    /**
+     * Return the level of this metric
+     * The level indicates the importance of the metric
+     *
+     * @return when level tag do not exist or illegal tag, will return null.
+     */
+    public MetricLevel getMetricLevel() {
+        return level;
+    }
+
+
+    /**
+     * Metric level can be changed during runtime
+     * @param level the level to set
+     */
+    public MetricName level(MetricLevel level) {
+        this.level = level;
+        return this;
+    }
+
+
+    /**
+     * @see {@link #resolve(String, boolean)}
+     */
+    public MetricName resolve(String p) {
+        return resolve(p, true);
+    }
+
+    /**
+     * Build the MetricName that is this with another path appended to it.
+     *
+     * The new MetricName inherits the tags of this one.
+     *
+     * @param p The extra path element to add to the new metric.
+     * @param inheritTags if true, tags will be inherited
+     * @return A new metric name relative to the original by the path specified
+     *         in p.
+     */
+    public MetricName resolve(String p, boolean inheritTags) {
+        final String next;
+
+        if (p != null && !p.isEmpty()) {
+            if (key != null && !key.isEmpty()) {
+                next = key + SEPARATOR + p;
+            } else {
+                next = p;
+            }
+        } else {
+            next = this.key;
+        }
+
+        return inheritTags ? new MetricName(next, tags, level) : new MetricName(next, level);
+    }
+
+    /**
+     * Add tags to a metric name and return the newly created MetricName.
+     *
+     * @param add Tags to add.
+     * @return A newly created metric name with the specified tags associated with it.
+     */
+    public MetricName tag(Map<String, String> add) {
+        final Map<String, String> tags = new HashMap<String, String>(add);
+        tags.putAll(this.tags);
+        return new MetricName(key, tags, level);
+    }
+
+    /**
+     * Same as {@link #tag(Map)}, but takes a variadic list
+     * of arguments.
+     *
+     * @see #tag(Map)
+     * @param pairs An even list of strings acting as key-value pairs.
+     * @return A newly created metric name with the specified tags associated
+     *         with it.
+     */
+    public MetricName tag(String... pairs) {
+        if (pairs == null) {
+            return this;
+        }
+
+        if (pairs.length % 2 != 0) {
+            throw new IllegalArgumentException("Argument count must be even");
+        }
+
+        final Map<String, String> add = new HashMap<String, String>();
+
+        for (int i = 0; i < pairs.length; i += 2) {
+            add.put(pairs[i], pairs[i+1]);
+        }
+
+        return tag(add);
+    }
+
+    /**
+     * Join the specified set of metric names.
+     *
+     * @param parts Multiple metric names to join using the separator.
+     * @return A newly created metric name which has the name of the specified
+     *         parts and includes all tags of all child metric names.
+     **/
+    public static MetricName join(MetricName... parts) {
+        final StringBuilder nameBuilder = new StringBuilder();
+        final Map<String, String> tags = new HashMap<String, String>();
+
+        boolean first = true;
+        MetricName firstName = null;
+
+        for (MetricName part : parts) {
+            final String name = part.getKey();
+
+            if (name != null && !name.isEmpty()) {
+                if (first) {
+                    first = false;
+                    firstName = part;
+                } else {
+                    nameBuilder.append(SEPARATOR);
+                }
+
+                nameBuilder.append(name);
+            }
+
+            if (!part.getTags().isEmpty())
+                tags.putAll(part.getTags());
+        }
+
+        MetricLevel level = firstName == null ? null : firstName.getMetricLevel();
+        return new MetricName(nameBuilder.toString(), tags, level);
+    }
+
+    /**
+     * Build a new metric name using the specific path components.
+     *
+     * @param parts Path of the new metric name.
+     * @return A newly created metric name with the specified path.
+     **/
+    public static MetricName build(String... parts) {
+        if (parts == null || parts.length == 0)
+            return MetricName.EMPTY;
+
+        if (parts.length == 1)
+            return new MetricName(parts[0], EMPTY_TAGS);
+
+        return new MetricName(buildName(parts), EMPTY_TAGS);
+    }
+
+    private static String buildName(String... names) {
+        final StringBuilder builder = new StringBuilder();
+        boolean first = true;
+
+        for (String name : names) {
+            if (name == null || name.isEmpty())
+                continue;
+
+            if (first) {
+                first = false;
+            } else {
+                builder.append(SEPARATOR);
+            }
+
+            builder.append(name);
+        }
+
+        return builder.toString();
+    }
+
+    @Override
+    public String toString() {
+        if (tags.isEmpty()) {
+            return key;
+        }
+
+        return key + tags;
+    }
+
+    @Override
+    public int hashCode() {
+        
+        if (!hashCodeCached){
+            
+            final int prime = 31;
+            int result = 1;
+            result = prime * result + ((key == null) ? 0 : key.hashCode());
+            result = prime * result + ((tags == null) ? 0 : tags.hashCode());
+            
+            hashCode = result;
+            hashCodeCached = true;
+        }
+
+        return hashCode;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj)
+            return true;
+
+        if (obj == null)
+            return false;
+
+        if (getClass() != obj.getClass())
+            return false;
+
+        MetricName other = (MetricName) obj;
+
+        if (key == null) {
+            if (other.key != null)
+                return false;
+        } else if (!key.equals(other.key))
+            return false;
+
+        if (!tags.equals(other.tags))
+            return false;
+
+        return true;
+    }
+
+    @Override
+    public int compareTo(MetricName o) {
+        if (o == null)
+            return -1;
+
+        int c = compareName(key, o.getKey());
+
+        if (c != 0)
+            return c;
+
+        return compareTags(tags, o.getTags());
+    }
+
+    private int compareName(String left, String right) {
+        if (left == null && right == null)
+            return 0;
+
+        if (left == null)
+            return 1;
+
+        if (right == null)
+            return -1;
+
+        return left.compareTo(right);
+    }
+
+    private int compareTags(Map<String, String> left, Map<String, String> right) {
+        if (left == null && right == null)
+            return 0;
+
+        if (left == null)
+            return 1;
+
+        if (right == null)
+            return -1;
+
+        final Iterable<String> keys = uniqueSortedKeys(left, right);
+
+        for (final String key : keys) {
+            final String a = left.get(key);
+            final String b = right.get(key);
+
+            if (a == null && b == null)
+                continue;
+
+            if (a == null)
+                return -1;
+
+            if (b == null)
+                return 1;
+
+            int c = a.compareTo(b);
+
+            if (c != 0)
+                return c;
+        }
+
+        return 0;
+    }
+
+    private Iterable<String> uniqueSortedKeys(Map<String, String> left, Map<String, String> right) {
+        final Set<String> set = new TreeSet<String>(left.keySet());
+        set.addAll(right.keySet());
+        return set;
+    }
+}
diff --git a/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/MetricRegistry.java b/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/MetricRegistry.java
new file mode 100644
index 0000000000..abb467a319
--- /dev/null
+++ b/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/MetricRegistry.java
@@ -0,0 +1,158 @@
+/*
+ * 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.
+ */
+package org.apache.dubbo.metrics;
+
+
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * A registry of metric instances.
+ */
+public abstract class MetricRegistry implements MetricSet {
+
+    /**
+     * Given a {@link Metric}, registers it under the given name.
+     *
+     * @param name   the name of the metric
+     * @param metric the metric
+     * @param <T>    the type of the metric
+     * @return {@code metric}
+     * @throws IllegalArgumentException if the name is already registered
+     */
+    public abstract <T extends Metric> T register(String name, T metric) throws IllegalArgumentException;
+
+    /**
+     * Given a {@link Metric}, registers it under the given name.
+     *
+     * @param name   the name of the metric
+     * @param metric the metric
+     * @param <T>    the type of the metric
+     * @return {@code metric}
+     * @throws IllegalArgumentException if the name is already registered
+     */
+    public abstract <T extends Metric> T register(MetricName name, T metric) throws IllegalArgumentException;
+
+    /**
+     * Given a metric set, registers them.
+     *
+     * @param metrics    a set of metrics
+     * @throws IllegalArgumentException if any of the names are already registered
+     */
+    public abstract void registerAll(MetricSet metrics) throws IllegalArgumentException;
+
+    /**
+     * Creates a new {@link Counter} and registers it under the given name.
+     *
+     * @param name the name of the metric
+     * @return a new {@link Counter}
+     */
+    public abstract Counter counter(String name);
+
+    /**
+     * Return the {@link Counter} registered under this name; or create and register
+     * a new {@link Counter} if none is registered.
+     *
+     * @param name the name of the metric
+     * @return a new or pre-existing {@link Counter}
+     */
+    public abstract Counter counter(MetricName name);
+
+    /**
+     * Create a FastCompass with given name
+     * @param name the name of the metric
+     * @return a FastCompass instance
+     */
+    public abstract Compass compass(MetricName name);
+
+    /**
+     * Removes the metric with the given name.
+     *
+     * @param name the name of the metric
+     * @return whether or not the metric was removed
+     */
+    public abstract boolean remove(MetricName name);
+
+    /**
+     * Removes all metrics which match the given filter.
+     *
+     * @param filter a filter
+     */
+    public abstract void removeMatching(MetricFilter filter);
+
+    /**
+     * Returns a set of the names of all the metrics in the registry.
+     *
+     * @return the names of all the metrics
+     */
+    public abstract Set<MetricName> getNames();
+
+    /**
+     * Returns a map of all the gauges in the registry and their names.
+     *
+     * @return all the gauges in the registry
+     */
+    public abstract Map<MetricName, Gauge> getGauges();
+
+    /**
+     * Returns a map of all the gauges in the registry and their names which match the given filter.
+     *
+     * @param filter    the metric filter to match
+     * @return all the gauges in the registry
+     */
+    public abstract Map<MetricName, Gauge> getGauges(MetricFilter filter);
+
+    /**
+     * Returns a map of all the counters in the registry and their names.
+     *
+     * @return all the counters in the registry
+     */
+    public abstract Map<MetricName, Counter> getCounters();
+
+    /**
+     * Returns a map of all the counters in the registry and their names which match the given
+     * filter.
+     *
+     * @param filter    the metric filter to match
+     * @return all the counters in the registry
+     */
+    public abstract Map<MetricName, Counter> getCounters(MetricFilter filter);
+
+    /**
+     * Returns a map of all the compasses in the registry and their names.
+     *
+     * @return all the compasses in the registry
+     */
+    public abstract Map<MetricName, Compass> getCompasses();
+
+    /**
+     * Returns a map of all the compasses in the registry and their names which match the given filter.
+     *
+     * @param filter    the metric filter to match
+     * @return all the compasses in the registry
+     */
+    public abstract Map<MetricName, Compass> getCompasses(MetricFilter filter);
+
+    /**
+     * Returns a map of all the metrics in the registry and their names which match the given filter
+     * @param filter the metric filter to match
+     * @return all the metrics in the registry
+     */
+    public abstract Map<MetricName, Metric> getMetrics(MetricFilter filter);
+
+
+}
diff --git a/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/MetricSet.java b/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/MetricSet.java
new file mode 100644
index 0000000000..68c95a124e
--- /dev/null
+++ b/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/MetricSet.java
@@ -0,0 +1,33 @@
+/*
+ * 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.
+ */
+package org.apache.dubbo.metrics;
+
+import java.util.Map;
+
+/**
+ * A set of named metrics.
+ *
+ * @see MetricRegistry#registerAll(MetricSet)
+ */
+public interface MetricSet extends Metric {
+    /**
+     * A map of metric names to metrics.
+     *
+     * @return the metrics
+     */
+    Map<MetricName, Metric> getMetrics();
+}
diff --git a/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/NOPMetricManager.java b/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/NOPMetricManager.java
new file mode 100644
index 0000000000..2228fd774a
--- /dev/null
+++ b/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/NOPMetricManager.java
@@ -0,0 +1,292 @@
+/*
+ * 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.
+ */
+package org.apache.dubbo.metrics;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * The empty implementation for IMetricManager
+ */
+public class NOPMetricManager implements IMetricManager {
+
+    private static final Map emptyMap = new HashMap();
+    private static final Set emptySet = new HashSet();
+
+    @Override
+    public Counter getCounter(String group, MetricName name) {
+        return NOP_COUNTER;
+    }
+
+    @Override
+    public BucketCounter getBucketCounter(String group, MetricName name) {
+        return NOP_BUCKET_COUNTER;
+    }
+
+    @Override
+    public Compass getCompass(String group, MetricName name) {
+        return NOP_COMPASS;
+    }
+
+    @Override
+    public List<String> listMetricGroups() {
+        return Collections.emptyList();
+    }
+
+    @Override
+    public Map<String, Set<MetricName>> listMetricNamesByGroup() {
+        return Collections.emptyMap();
+    }
+
+    @Override
+    public MetricRegistry getMetricRegistryByGroup(String group) {
+        return NOP_REGISTRY;
+    }
+
+    @Override
+    @SuppressWarnings("unchecked")
+    public Map<MetricName, Counter> getCounters(String group, MetricFilter filter) {
+        return emptyMap;
+    }
+
+    @Override
+    @SuppressWarnings("unchecked")
+    public Map<MetricName, Compass> getCompasses(String group, MetricFilter filter) {
+        return emptyMap;
+    }
+
+    @Override
+    public void register(String group, MetricName name, Metric metric) {
+
+    }
+
+    static final BucketCounter NOP_BUCKET_COUNTER = new BucketCounter() {
+        @Override
+        public void update() {
+
+        }
+
+        @Override
+        public void update(long n) {
+
+        }
+
+        @Override
+        public Map<Long, Long> getBucketCounts() {
+            return emptyMap;
+        }
+
+        @Override
+        public Map<Long, Long> getBucketCounts(long startTime) {
+            return emptyMap;
+        }
+
+        @Override
+        public int getBucketInterval() {
+            return 0;
+        }
+
+        @Override
+        public long lastUpdateTime() {
+            return 0;
+        }
+    };
+
+    static final Counter NOP_COUNTER = new Counter() {
+        @Override
+        public void inc() {
+        }
+
+        @Override
+        public void inc(long n) {
+        }
+
+        @Override
+        public void dec() {
+        }
+
+        @Override
+        public void dec(long n) {
+        }
+
+        @Override
+        public long getCount() {
+            return 0;
+        }
+
+        @Override
+        public long lastUpdateTime() {
+            return 0;
+        }
+    };
+
+    static final Compass NOP_COMPASS = new Compass() {
+        @Override
+        public void record(long duration, String subCategory) {
+
+        }
+
+        @Override
+        public Map<String, Map<Long, Long>> getMethodCountPerCategory() {
+            return emptyMap;
+        }
+
+        @Override
+        public Map<String, Map<Long, Long>> getMethodRtPerCategory() {
+            return emptyMap;
+        }
+
+        @Override
+        public Map<String, Map<Long, Long>> getMethodCountPerCategory(long startTime) {
+            return emptyMap;
+        }
+
+        @Override
+        public Map<String, Map<Long, Long>> getMethodRtPerCategory(long startTime) {
+            return emptyMap;
+        }
+
+        @Override
+        public int getBucketInterval() {
+            return 0;
+        }
+
+        @Override
+        public Map<String, Map<Long, Long>> getCountAndRtPerCategory() {
+            return emptyMap;
+        }
+
+        @Override
+        public Map<String, Map<Long, Long>> getCountAndRtPerCategory(long startTime) {
+            return emptyMap;
+        }
+
+        @Override
+        public long lastUpdateTime() {
+            return 0;
+        }
+    };
+
+    private static final MetricRegistry NOP_REGISTRY = new MetricRegistry() {
+        @Override
+        public <T extends Metric> T register(String name, T metric) throws IllegalArgumentException {
+            return metric;
+        }
+
+        @Override
+        public <T extends Metric> T register(MetricName name, T metric) throws IllegalArgumentException {
+            return metric;
+        }
+
+        @Override
+        public void registerAll(MetricSet metrics) throws IllegalArgumentException {
+
+        }
+
+        @Override
+        public Counter counter(String name) {
+            return NOP_COUNTER;
+        }
+
+        @Override
+        public Counter counter(MetricName name) {
+            return NOP_COUNTER;
+        }
+
+        @Override
+        public Compass compass(MetricName name) {
+            return NOP_COMPASS;
+        }
+
+        @Override
+        public boolean remove(MetricName name) {
+            return false;
+        }
+
+        @Override
+        public void removeMatching(MetricFilter filter) {
+
+        }
+
+        @Override
+        @SuppressWarnings("unchecked")
+        public Set<MetricName> getNames() {
+            return emptySet;
+        }
+
+        @Override
+        @SuppressWarnings("unchecked")
+        public Map<MetricName, Gauge> getGauges() {
+            return emptyMap;
+        }
+
+        @Override
+        @SuppressWarnings("unchecked")
+        public Map<MetricName, Gauge> getGauges(MetricFilter filter) {
+            return emptyMap;
+        }
+
+        @Override
+        @SuppressWarnings("unchecked")
+        public Map<MetricName, Counter> getCounters() {
+            return emptyMap;
+        }
+
+        @Override
+        @SuppressWarnings("unchecked")
+        public Map<MetricName, Counter> getCounters(MetricFilter filter) {
+            return emptyMap;
+        }
+
+        @Override
+        public Map<MetricName, Compass> getCompasses() {
+            return emptyMap;
+        }
+
+        @Override
+        public Map<MetricName, Compass> getCompasses(MetricFilter filter) {
+            return emptyMap;
+        }
+
+        @Override
+        @SuppressWarnings("unchecked")
+        public Map<MetricName, Metric> getMetrics(MetricFilter filter) {
+            return emptyMap;
+        }
+
+        @Override
+        @SuppressWarnings("unchecked")
+        public Map<MetricName, Metric> getMetrics() {
+            return emptyMap;
+        }
+
+        @Override
+        public long lastUpdateTime() {
+            return 0;
+        }
+    };
+
+    @Override
+    public Map<MetricName, Metric> getMetrics(String group) {
+        return emptyMap;
+    }
+
+}
diff --git a/dubbo-metrics/dubbo-metrics-api/src/test/java/org/apache/dubbo/metrics/MetricManagerTest.java b/dubbo-metrics/dubbo-metrics-api/src/test/java/org/apache/dubbo/metrics/MetricManagerTest.java
new file mode 100644
index 0000000000..fcadbf58db
--- /dev/null
+++ b/dubbo-metrics/dubbo-metrics-api/src/test/java/org/apache/dubbo/metrics/MetricManagerTest.java
@@ -0,0 +1,40 @@
+package org.apache.dubbo.metrics;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+/**
+ * @author wangtao 2016-07-09 08:43.
+ */
+public class MetricManagerTest {
+
+    @Test
+    public void testNOPMetricManager() {
+        Assert.assertTrue(MetricManager.getIMetricManager() instanceof NOPMetricManager);
+    }
+
+    @Test
+    public void testNOPCompass() {
+        Compass compass = MetricManager.getCompass("test", MetricName.build("test"));
+        compass.record(10, "success");
+
+        Assert.assertEquals(0, compass.getCountAndRtPerCategory().size());
+        Assert.assertEquals(0, compass.getMethodCountPerCategory().size());
+        Assert.assertEquals(0, compass.getMethodRtPerCategory().size());
+    }
+
+    @Test
+    public void testNopCounter() {
+        Counter counter = MetricManager.getCounter("test", MetricName.build("test2"));
+        counter.inc();
+        Assert.assertEquals(0, counter.getCount());
+    }
+
+    @Test
+    public void testBucketCounter() {
+        BucketCounter bc = MetricManager.getBucketCounters("test", MetricName.build("test3"));
+        bc.update();
+        Assert.assertEquals(0, bc.getBucketInterval());
+        Assert.assertEquals(0, bc.getBucketCounts().size());
+    }
+}
diff --git a/dubbo-metrics/dubbo-metrics-api/src/test/java/org/apache/dubbo/metrics/MetricNameTest.java b/dubbo-metrics/dubbo-metrics-api/src/test/java/org/apache/dubbo/metrics/MetricNameTest.java
new file mode 100644
index 0000000000..74399d8978
--- /dev/null
+++ b/dubbo-metrics/dubbo-metrics-api/src/test/java/org/apache/dubbo/metrics/MetricNameTest.java
@@ -0,0 +1,125 @@
+package org.apache.dubbo.metrics;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+import java.util.HashMap;
+import java.util.Map;
+
+
+/**
+ * @author wangtao 2016-07-08 17:56.
+ */
+public class MetricNameTest {
+
+    @Test
+    public void testEmpty() {
+        Assert.assertEquals(MetricName.EMPTY.getTags(), MetricName.EMPTY_TAGS);
+        Assert.assertNull(MetricName.EMPTY.getKey());
+        Assert.assertEquals(new MetricName().getTags(), MetricName.EMPTY_TAGS);
+
+        Assert.assertEquals(MetricName.EMPTY, new MetricName());
+        Assert.assertEquals(MetricName.build(), MetricName.EMPTY);
+        Assert.assertEquals(MetricName.EMPTY.resolve(null), MetricName.EMPTY);
+    }
+
+    @Test
+    public void testEmptyResolve() {
+        final MetricName name = new MetricName();
+        Assert.assertEquals(name.resolve("foo"), new MetricName("foo"));
+    }
+
+    @Test
+    public void testResolveToEmpty() {
+        final MetricName name = new MetricName("foo");
+        Assert.assertEquals(name.resolve(null), new MetricName("foo"));
+    }
+
+    @Test
+    public void testResolve() {
+        final MetricName name = new MetricName("foo");
+        Assert.assertEquals(name.resolve("bar"), new MetricName("foo.bar"));
+    }
+
+    @Test
+    public void testResolveWithTags() {
+        final MetricName name = new MetricName("foo").tag("key", "value");
+        Assert.assertEquals(name.resolve("bar"), new MetricName("foo.bar").tag("key", "value"));
+    }
+
+    @Test
+    public void testResolveWithoutTags() {
+        final MetricName name = new MetricName("foo").tag("key", "value");
+        Assert.assertEquals(name.resolve("bar", false), new MetricName("foo.bar"));
+    }
+
+    @Test
+    public void testResolveBothEmpty() {
+        final MetricName name = new MetricName(null);
+        Assert.assertEquals(name.resolve(null), new MetricName());
+    }
+
+    @Test
+    public void testAddTagsVarious() {
+        final Map<String, String> refTags = new HashMap<String, String>();
+        refTags.put("foo", "bar");
+        final MetricName test = MetricName.EMPTY.tag("foo", "bar");
+        final MetricName test2 = MetricName.EMPTY.tag(refTags);
+
+        Assert.assertEquals(test, new MetricName(null, refTags));
+        Assert.assertEquals(test.getTags(), refTags);
+
+        Assert.assertEquals(test2, new MetricName(null, refTags));
+        Assert.assertEquals(test2.getTags(), refTags);
+    }
+
+    @Test
+    public void testTaggedMoreArguments() {
+        final Map<String, String> refTags = new HashMap<String, String>();
+        refTags.put("foo", "bar");
+        refTags.put("baz", "biz");
+        Assert.assertEquals(MetricName.EMPTY.tag("foo", "bar", "baz", "biz").getTags(), refTags);
+    }
+
+    @Test(expected=IllegalArgumentException.class)
+    public void testTaggedNotPairs() {
+        MetricName.EMPTY.tag("foo");
+    }
+
+    @Test(expected=IllegalArgumentException.class)
+    public void testTaggedNotPairs2() {
+        MetricName.EMPTY.tag("foo", "bar", "baz");
+    }
+
+    @Test
+    public void testCompareTo() {
+        final MetricName a = MetricName.EMPTY.tag("foo", "bar");
+        final MetricName b = MetricName.EMPTY.tag("foo", "baz");
+
+        Assert.assertTrue(a.compareTo(b) < 0);
+        Assert.assertTrue(b.compareTo(a) > 0);
+        Assert.assertTrue(b.compareTo(b) == 0);
+        Assert.assertTrue(b.resolve("key").compareTo(b) < 0);
+        Assert.assertTrue(b.compareTo(b.resolve("key")) > 0);
+    }
+
+    @Test
+    public void testTaggedWithLevel() {
+        MetricName name = MetricName.build("test").level(MetricLevel.CRITICAL);
+        MetricName tagged = name.tag("foo", "bar");
+        Assert.assertEquals(tagged.getMetricLevel(), MetricLevel.CRITICAL);
+    }
+
+    @Test
+    public void testJoinWithLevel() {
+        MetricName name = MetricName.build("test").level(MetricLevel.CRITICAL);
+        MetricName tagged = MetricName.join(name, MetricName.build("abc"));
+        Assert.assertEquals(tagged.getMetricLevel(), MetricLevel.CRITICAL);
+    }
+
+    @Test
+    public void testResolveWithLevel() {
+        final MetricName name = new MetricName("foo").level(MetricLevel.CRITICAL).tag("key", "value");
+        Assert.assertEquals(name.resolve("bar"), new MetricName("foo.bar").tag("key", "value").level(MetricLevel.CRITICAL));
+    }
+}
diff --git a/dubbo-metrics/pom.xml b/dubbo-metrics/pom.xml
new file mode 100644
index 0000000000..d76e4e737d
--- /dev/null
+++ b/dubbo-metrics/pom.xml
@@ -0,0 +1,41 @@
+<!--
+  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.
+  -->
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <parent>
+        <groupId>org.apache.dubbo</groupId>
+        <artifactId>dubbo-parent</artifactId>
+        <version>2.7.0-SNAPSHOT</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>dubbo-metrics</artifactId>
+    <packaging>pom</packaging>
+    <name>${project.artifactId}</name>
+    <description>The metrics module of dubbo project</description>
+
+    <properties>
+        <skip_maven_deploy>false</skip_maven_deploy>
+    </properties>
+
+    <modules>
+        <module>dubbo-metrics-api</module>
+    </modules>
+
+
+</project>
\ No newline at end of file
diff --git a/pom.xml b/pom.xml
index 2413fe2f6f..152788ed9c 100644
--- a/pom.xml
+++ b/pom.xml
@@ -144,6 +144,7 @@
         <module>bom</module>
         <module>all</module>
         <module>distribution</module>
+        <module>dubbo-metrics</module>
     </modules>
 
     <dependencyManagement>


 

----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on GitHub and use the
URL above to go to the specific comment.
 
For queries about this service, please contact Infrastructure at:
users@infra.apache.org


With regards,
Apache Git Services

---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@dubbo.apache.org
For additional commands, e-mail: notifications-help@dubbo.apache.org