You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@servicecomb.apache.org by ni...@apache.org on 2018/02/26 13:33:42 UTC

[incubator-servicecomb-java-chassis] 01/07: SCB-327 adjust metrics publish format to spring cloud netflix style

This is an automated email from the ASF dual-hosted git repository.

ningjiang pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-servicecomb-java-chassis.git

commit 09835598a60f9fc53ce20ff5e9c183f4efe51f79
Author: zhengyangyong <ya...@huawei.com>
AuthorDate: Mon Feb 12 11:22:23 2018 +0800

    SCB-327 adjust metrics publish format to spring cloud netflix style
    
    Signed-off-by: zhengyangyong <ya...@huawei.com>
---
 .../common/rest/AbstractRestInvocation.java        |   2 +-
 .../org/apache/servicecomb/core/Invocation.java    |  11 +-
 .../core/metrics/InvocationFinishedEvent.java      |  16 +-
 .../metrics/InvocationStartProcessingEvent.java    |   9 +-
 .../core/provider/consumer/InvokerUtils.java       |  12 +-
 demo/demo-springmvc/springmvc-client/pom.xml       |   6 -
 .../demo/springmvc/client/SpringmvcClient.java     |  35 +--
 .../META-INF/spring/springmvc.client.bean.xml      |  16 +-
 .../src/main/resources/microservice.yaml           |   4 +
 .../demo/perf/PerfMetricsFilePublisher.java        | 124 ++++----
 .../foundation/metrics}/MetricsConst.java          |  28 +-
 .../publish}/DefaultHealthCheckExtraData.java      |   2 +-
 .../metrics/publish}/HealthCheckResult.java        |   2 +-
 .../foundation/metrics/publish}/HealthChecker.java |   2 +-
 .../foundation/metrics/publish/Metric.java         |  66 +++++
 .../foundation/metrics/publish/MetricNode.java     | 108 +++++++
 .../foundation/metrics/publish/MetricsLoader.java  |  56 ++++
 metrics/metrics-common/pom.xml                     |  39 ---
 .../servicecomb/metrics/common/CallMetric.java     |  92 ------
 .../metrics/common/ConsumerInvocationMetric.java   |  59 ----
 .../metrics/common/DoubleMetricValue.java          |  56 ----
 .../metrics/common/HealthCheckerPublisher.java     |  26 --
 .../servicecomb/metrics/common/InstanceMetric.java |  59 ----
 .../metrics/common/InvocationMetric.java           |  37 ---
 .../metrics/common/LongMetricValue.java            |  56 ----
 .../servicecomb/metrics/common/MetricValue.java    |  70 -----
 .../metrics/common/MetricsDimension.java           |  46 ---
 .../metrics/common/MetricsPublisher.java           |  59 ----
 .../metrics/common/ProducerInvocationMetric.java   |  89 ------
 .../servicecomb/metrics/common/RegistryMetric.java |  91 ------
 .../servicecomb/metrics/common/SystemMetric.java   | 119 --------
 .../servicecomb/metrics/common/TimerMetric.java    |  99 -------
 metrics/metrics-core/pom.xml                       |   2 +-
 .../servicecomb/metrics/core/MetricsConfig.java    |   2 -
 .../core/event/DefaultEventListenerManager.java    |  17 +-
 .../event/InvocationFinishedEventListener.java     |  19 +-
 .../InvocationStartProcessingEventListener.java    |   1 -
 .../core/event/InvocationStartedEventListener.java |   6 -
 .../event/dimension/CodeGroupStatusConvertor.java  |  45 ---
 .../core/event/dimension/CodeStatusConvertor.java  |  25 --
 .../core/event/dimension/StatusConvertor.java      |  22 --
 .../event/dimension/StatusConvertorFactory.java    |  53 ----
 .../dimension/SuccessFailedStatusConvertor.java    |  28 --
 .../health/DefaultMicroserviceHealthChecker.java   |   6 +-
 .../metrics/core/monitor/CallMonitor.java          |  89 +++---
 .../core/monitor/ConsumerInvocationMonitor.java    |  22 +-
 .../metrics/core/monitor/DefaultSystemMonitor.java |  30 +-
 .../metrics/core/monitor/InvocationMonitor.java    |  37 ---
 .../core/monitor/ProducerInvocationMonitor.java    |  44 +--
 .../metrics/core/monitor/RegistryMonitor.java      |  15 +-
 .../metrics/core/monitor/SystemMonitor.java        |   4 +-
 .../metrics/core/monitor/TimerMonitor.java         | 100 +++++--
 .../metrics/core/publish/DataSource.java           |  25 +-
 .../metrics/core/publish/DefaultDataSource.java    |  40 +--
 .../core/publish/DefaultHealthCheckerManager.java  |   4 +-
 .../publish/DefaultHealthCheckerPublisher.java     |   7 +-
 .../core/publish/DefaultMetricsPublisher.java      |  30 +-
 .../metrics/core/publish/HealthCheckerManager.java |   5 +-
 .../metrics/core/utils/MonitorUtils.java           |  45 +--
 .../metrics/core/TestEventAndRunner.java           | 313 +++++++--------------
 .../metrics/core/TestHealthCheckerManager.java     |  22 +-
 .../metrics/core/TestHealthCheckerPublisher.java   |   9 +-
 ...estPublisher.java => TestMetricsPublisher.java} |  30 +-
 .../metrics/core/TestStatusDimension.java          | 159 -----------
 .../metrics/prometheus/MetricsCollector.java       |  96 ++-----
 metrics/pom.xml                                    |   2 +-
 .../CustomHealthCheckerAnnotation.java             |   4 +-
 .../extendhealthcheck/MySqlHealthChecker.java      |   5 +-
 .../samples/mwf/FileContentConvertor.java          |   4 +-
 .../samples/mwf/SimpleFileContentConvertor.java    |  33 ++-
 .../samples/mwf/WriteFileInitializer.java          |   5 +-
 .../servicecomb/samples/mwf/TestWriteFile.java     | 174 ------------
 .../transport/highway/HighwayServerInvoke.java     |   2 +-
 73 files changed, 808 insertions(+), 2269 deletions(-)

diff --git a/common/common-rest/src/main/java/org/apache/servicecomb/common/rest/AbstractRestInvocation.java b/common/common-rest/src/main/java/org/apache/servicecomb/common/rest/AbstractRestInvocation.java
index 5e87436..3cef720 100644
--- a/common/common-rest/src/main/java/org/apache/servicecomb/common/rest/AbstractRestInvocation.java
+++ b/common/common-rest/src/main/java/org/apache/servicecomb/common/rest/AbstractRestInvocation.java
@@ -189,7 +189,7 @@ public abstract class AbstractRestInvocation {
     invocation.next(resp -> {
       sendResponseQuietly(resp);
 
-      invocation.triggerFinishedEvent(resp.getStatusCode(), resp.isSuccessed());
+      invocation.triggerFinishedEvent(resp.getStatusCode());
     });
   }
 
diff --git a/core/src/main/java/org/apache/servicecomb/core/Invocation.java b/core/src/main/java/org/apache/servicecomb/core/Invocation.java
index 96a84b9..882b9e6 100644
--- a/core/src/main/java/org/apache/servicecomb/core/Invocation.java
+++ b/core/src/main/java/org/apache/servicecomb/core/Invocation.java
@@ -188,15 +188,16 @@ public class Invocation extends SwaggerInvocation {
   public void triggerStartProcessingEvent() {
     this.startProcessingTime = System.nanoTime();
     EventUtils.triggerEvent(new InvocationStartProcessingEvent(
-        operationMeta.getMicroserviceQualifiedName(), this.invocationType, startProcessingTime - startTime));
+        operationMeta.getMicroserviceQualifiedName(), this.invocationType));
   }
 
-  public void triggerFinishedEvent(int statusCode, boolean success) {
+  public void triggerFinishedEvent(int statusCode) {
     long finishedTime = System.nanoTime();
     EventUtils
-        .triggerEvent(new InvocationFinishedEvent(operationMeta.getMicroserviceQualifiedName(),
-            this.invocationType, finishedTime - startProcessingTime,
-            finishedTime - startTime, statusCode, success));
+        .triggerEvent(new InvocationFinishedEvent(operationMeta.getMicroserviceQualifiedName(), this.invocationType,
+            startProcessingTime - startTime,
+            finishedTime - startProcessingTime,
+            finishedTime - startTime, statusCode));
   }
 
   public boolean isSync() {
diff --git a/core/src/main/java/org/apache/servicecomb/core/metrics/InvocationFinishedEvent.java b/core/src/main/java/org/apache/servicecomb/core/metrics/InvocationFinishedEvent.java
index 4de6154..ee7c684 100644
--- a/core/src/main/java/org/apache/servicecomb/core/metrics/InvocationFinishedEvent.java
+++ b/core/src/main/java/org/apache/servicecomb/core/metrics/InvocationFinishedEvent.java
@@ -25,14 +25,14 @@ public class InvocationFinishedEvent implements Event {
 
   private final InvocationType invocationType;
 
+  private final long inQueueNanoTime;
+
   private final long processElapsedNanoTime;
 
   private final long totalElapsedNanoTime;
 
   private final int statusCode;
 
-  private final boolean success;
-
   public String getOperationName() {
     return operationName;
   }
@@ -41,6 +41,10 @@ public class InvocationFinishedEvent implements Event {
     return invocationType;
   }
 
+  public long getInQueueNanoTime() {
+    return inQueueNanoTime;
+  }
+
   public long getProcessElapsedNanoTime() {
     return processElapsedNanoTime;
   }
@@ -53,17 +57,13 @@ public class InvocationFinishedEvent implements Event {
     return statusCode;
   }
 
-  public boolean isSuccess() {
-    return success;
-  }
-
   public InvocationFinishedEvent(String operationName, InvocationType invocationType,
-      long processElapsedNanoTime, long totalElapsedNanoTime, int statusCode, boolean success) {
+      long inQueueNanoTime, long processElapsedNanoTime, long totalElapsedNanoTime, int statusCode) {
     this.operationName = operationName;
     this.invocationType = invocationType;
+    this.inQueueNanoTime = inQueueNanoTime;
     this.processElapsedNanoTime = processElapsedNanoTime;
     this.totalElapsedNanoTime = totalElapsedNanoTime;
     this.statusCode = statusCode;
-    this.success = success;
   }
 }
diff --git a/core/src/main/java/org/apache/servicecomb/core/metrics/InvocationStartProcessingEvent.java b/core/src/main/java/org/apache/servicecomb/core/metrics/InvocationStartProcessingEvent.java
index dd579e8..3e7ed6b 100644
--- a/core/src/main/java/org/apache/servicecomb/core/metrics/InvocationStartProcessingEvent.java
+++ b/core/src/main/java/org/apache/servicecomb/core/metrics/InvocationStartProcessingEvent.java
@@ -25,8 +25,6 @@ public class InvocationStartProcessingEvent implements Event {
 
   private final InvocationType invocationType;
 
-  private final long inQueueNanoTime;
-
   public String getOperationName() {
     return operationName;
   }
@@ -35,14 +33,9 @@ public class InvocationStartProcessingEvent implements Event {
     return invocationType;
   }
 
-  public long getInQueueNanoTime() {
-    return inQueueNanoTime;
-  }
 
-  public InvocationStartProcessingEvent(String operationName, InvocationType invocationType,
-      long inQueueNanoTime) {
+  public InvocationStartProcessingEvent(String operationName, InvocationType invocationType) {
     this.operationName = operationName;
     this.invocationType = invocationType;
-    this.inQueueNanoTime = inQueueNanoTime;
   }
 }
diff --git a/core/src/main/java/org/apache/servicecomb/core/provider/consumer/InvokerUtils.java b/core/src/main/java/org/apache/servicecomb/core/provider/consumer/InvokerUtils.java
index 2504ab0..8977e87 100644
--- a/core/src/main/java/org/apache/servicecomb/core/provider/consumer/InvokerUtils.java
+++ b/core/src/main/java/org/apache/servicecomb/core/provider/consumer/InvokerUtils.java
@@ -34,9 +34,6 @@ import org.slf4j.LoggerFactory;
 public final class InvokerUtils {
   private static final Logger LOGGER = LoggerFactory.getLogger(InvokerUtils.class);
 
-  private InvokerUtils() {
-  }
-
   public static Object syncInvoke(String microserviceName, String schemaId, String operationName, Object[] args) {
     ReferenceConfig referenceConfig = ReferenceConfigUtils.getForInvoke(microserviceName);
     SchemaMeta schemaMeta = referenceConfig.getMicroserviceMeta().ensureFindSchemaMeta(schemaId);
@@ -59,7 +56,7 @@ public final class InvokerUtils {
       return response.getResult();
     }
 
-    throw ExceptionFactory.convertConsumerException((Throwable) response.getResult());
+    throw ExceptionFactory.convertConsumerException(response.getResult());
   }
 
   public static Response innerSyncInvoke(Invocation invocation) {
@@ -73,7 +70,6 @@ public final class InvokerUtils {
       invocation.next(respExecutor::setResponse);
 
       Response response = respExecutor.waitResponse();
-      success = response.isSuccessed();
       statusCode = response.getStatusCode();
       return response;
     } catch (Throwable e) {
@@ -82,7 +78,7 @@ public final class InvokerUtils {
       LOGGER.debug(msg, e);
       return Response.createConsumerFail(e);
     } finally {
-      invocation.triggerFinishedEvent(statusCode, success);
+      invocation.triggerFinishedEvent(statusCode);
     }
   }
 
@@ -97,7 +93,7 @@ public final class InvokerUtils {
       invocation.next(ar -> {
         ContextUtils.setInvocationContext(invocation.getParentContext());
         try {
-          invocation.triggerFinishedEvent(ar.getStatusCode(), ar.isSuccessed());
+          invocation.triggerFinishedEvent(ar.getStatusCode());
           asyncResp.handle(ar);
         } finally {
           ContextUtils.removeInvocationContext();
@@ -105,7 +101,7 @@ public final class InvokerUtils {
       });
     } catch (Throwable e) {
       //if throw exception,we can use 500 for status code ?
-      invocation.triggerFinishedEvent(500, false);
+      invocation.triggerFinishedEvent(500);
       LOGGER.error("invoke failed, {}", invocation.getOperationMeta().getMicroserviceQualifiedName());
       asyncResp.consumerFail(e);
     }
diff --git a/demo/demo-springmvc/springmvc-client/pom.xml b/demo/demo-springmvc/springmvc-client/pom.xml
index 9810241..c77d148 100644
--- a/demo/demo-springmvc/springmvc-client/pom.xml
+++ b/demo/demo-springmvc/springmvc-client/pom.xml
@@ -41,12 +41,6 @@
 			<groupId>org.apache.servicecomb</groupId>
 			<artifactId>provider-pojo</artifactId>
 		</dependency>
-
-		<dependency>
-			<groupId>org.apache.servicecomb</groupId>
-			<artifactId>metrics-common</artifactId>
-		</dependency>
-
 	</dependencies>
 
 	<properties>
diff --git a/demo/demo-springmvc/springmvc-client/src/main/java/org/apache/servicecomb/demo/springmvc/client/SpringmvcClient.java b/demo/demo-springmvc/springmvc-client/src/main/java/org/apache/servicecomb/demo/springmvc/client/SpringmvcClient.java
index c49fc05..70904b8 100644
--- a/demo/demo-springmvc/springmvc-client/src/main/java/org/apache/servicecomb/demo/springmvc/client/SpringmvcClient.java
+++ b/demo/demo-springmvc/springmvc-client/src/main/java/org/apache/servicecomb/demo/springmvc/client/SpringmvcClient.java
@@ -27,9 +27,6 @@ import org.apache.servicecomb.demo.controller.Controller;
 import org.apache.servicecomb.demo.controller.Person;
 import org.apache.servicecomb.foundation.common.utils.BeanUtils;
 import org.apache.servicecomb.foundation.common.utils.Log4jUtils;
-import org.apache.servicecomb.metrics.common.MetricsDimension;
-import org.apache.servicecomb.metrics.common.MetricsPublisher;
-import org.apache.servicecomb.metrics.common.RegistryMetric;
 import org.apache.servicecomb.provider.springmvc.reference.CseRestTemplate;
 import org.apache.servicecomb.provider.springmvc.reference.RestTemplateBuilder;
 import org.apache.servicecomb.provider.springmvc.reference.UrlWithServiceNameClientHttpRequestFactory;
@@ -46,8 +43,6 @@ public class SpringmvcClient {
 
   private static Controller controller;
 
-  private static MetricsPublisher metricsPublisher;
-
   public static void main(String[] args) throws Exception {
     Log4jUtils.init();
     BeanUtils.init();
@@ -61,7 +56,6 @@ public class SpringmvcClient {
     templateUrlWithServiceName.setRequestFactory(new UrlWithServiceNameClientHttpRequestFactory());
     restTemplate = RestTemplateBuilder.create();
     controller = BeanUtils.getBean("controller");
-    metricsPublisher = BeanUtils.getBean("metricsPublisher");
 
     String prefix = "cse://springmvc";
 
@@ -103,14 +97,15 @@ public class SpringmvcClient {
 
     //0.5.0 later version metrics integration test
     try {
-      RegistryMetric metric = metricsPublisher.metrics();
+      Thread.sleep(1000);
+      Map<String, Double> metrics = restTemplate.getForObject(prefix + "/metrics", Map.class);
 
       TestMgr
-          .check(true, metric.getInstanceMetric().getSystemMetric().getHeapUsed() != 0);
-      TestMgr.check(true, metric.getProducerMetrics().size() > 0);
-      TestMgr.check(true,
-          metric.getProducerMetrics().get("springmvc.codeFirst.saySomething").getProducerCall()
-              .getTotalValue(MetricsDimension.DIMENSION_STATUS, MetricsDimension.DIMENSION_STATUS_ALL).getValue() > 0);
+          .check(true, metrics.get("jvm(statistic=gauge,name=heapUsed)") != 0);
+      TestMgr.check(true, metrics.size() > 0);
+      TestMgr.check(true, metrics.get(
+          "servicecomb.invocation(operation=springmvc.codeFirst.saySomething,role=producer,stage=whole,statistic=count,status=200)")
+          > 0);
     } catch (Exception e) {
       TestMgr.check("true", "false");
     }
@@ -119,20 +114,20 @@ public class SpringmvcClient {
     try {
       String content = restTemplate.getForObject("cse://springmvc/codeFirstSpringmvc/prometheusForTest", String.class);
 
-      TestMgr.check(true, content.contains("servicecomb_springmvc_codeFirst_addDate"));
-      TestMgr.check(true, content.contains("servicecomb_springmvc_codeFirst_sayHello"));
-      TestMgr.check(true, content.contains("servicecomb_springmvc_codeFirst_fallbackFromCache"));
-      TestMgr.check(true, content.contains("servicecomb_springmvc_codeFirst_isTrue_producer"));
-      TestMgr.check(true, content.contains("servicecomb_springmvc_codeFirst_add"));
-      TestMgr.check(true, content.contains("servicecomb_springmvc_codeFirst_sayHi2"));
-      TestMgr.check(true, content.contains("servicecomb_springmvc_codeFirst_saySomething"));
+      TestMgr.check(true, content.contains("servicecomb_invocation_springmvc_codeFirst_addDate"));
+      TestMgr.check(true, content.contains("servicecomb_invocation_springmvc_codeFirst_sayHello"));
+      TestMgr.check(true, content.contains("servicecomb_invocation_springmvc_codeFirst_fallbackFromCache"));
+      TestMgr.check(true, content.contains("servicecomb_invocation_springmvc_codeFirst_isTrue"));
+      TestMgr.check(true, content.contains("servicecomb_invocation_springmvc_codeFirst_add"));
+      TestMgr.check(true, content.contains("servicecomb_invocation_springmvc_codeFirst_sayHi2"));
+      TestMgr.check(true, content.contains("servicecomb_invocation_springmvc_codeFirst_saySomething"));
 
       String[] metricLines = content.split("\n");
       if (metricLines.length > 0) {
         for (String metricLine : metricLines) {
           if (!metricLine.startsWith("#")) {
             String[] metricKeyAndValue = metricLine.split(" ");
-            if (!metricKeyAndValue[0].startsWith("servicecomb_instance_system")) {
+            if (!metricKeyAndValue[0].startsWith("jvm")) {
               if (Double.parseDouble(metricKeyAndValue[1]) < 0) {
                 TestMgr.check("true", "false");
                 break;
diff --git a/demo/demo-springmvc/springmvc-client/src/main/resources/META-INF/spring/springmvc.client.bean.xml b/demo/demo-springmvc/springmvc-client/src/main/resources/META-INF/spring/springmvc.client.bean.xml
index 23ba32b..d5836ef 100644
--- a/demo/demo-springmvc/springmvc-client/src/main/resources/META-INF/spring/springmvc.client.bean.xml
+++ b/demo/demo-springmvc/springmvc-client/src/main/resources/META-INF/spring/springmvc.client.bean.xml
@@ -17,18 +17,14 @@
   -->
 
 <beans xmlns="http://www.springframework.org/schema/beans" xmlns:context="http://www.springframework.org/schema/context"
-	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
-	xmlns:util="http://www.springframework.org/schema/util" xmlns:cse="http://www.huawei.com/schema/paas/cse/rpc"
-	xsi:schemaLocation="
+  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
+  xmlns:util="http://www.springframework.org/schema/util" xmlns:cse="http://www.huawei.com/schema/paas/cse/rpc"
+  xsi:schemaLocation="
 		http://www.springframework.org/schema/beans classpath:org/springframework/beans/factory/xml/spring-beans-3.0.xsd
 		http://www.huawei.com/schema/paas/cse/rpc classpath:META-INF/spring/spring-paas-cse-rpc.xsd
 		http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd">
 
-    <context:component-scan base-package="org.apache.servicecomb.demo.springmvc.client" />
-	<cse:rpc-reference id="controller" microservice-name="springmvc"
-		schema-id="controller" interface="org.apache.servicecomb.demo.controller.Controller"></cse:rpc-reference>
-
-	<cse:rpc-reference id="metricsPublisher" microservice-name="springmvc"
-		schema-id="metricsEndpoint" interface="org.apache.servicecomb.metrics.common.MetricsPublisher"></cse:rpc-reference>
-
+  <context:component-scan base-package="org.apache.servicecomb.demo.springmvc.client"/>
+  <cse:rpc-reference id="controller" microservice-name="springmvc"
+    schema-id="controller" interface="org.apache.servicecomb.demo.controller.Controller"></cse:rpc-reference>
 </beans>
diff --git a/demo/demo-springmvc/springmvc-server/src/main/resources/microservice.yaml b/demo/demo-springmvc/springmvc-server/src/main/resources/microservice.yaml
index 34b582a..9b0abbb 100644
--- a/demo/demo-springmvc/springmvc-server/src/main/resources/microservice.yaml
+++ b/demo/demo-springmvc/springmvc-server/src/main/resources/microservice.yaml
@@ -75,3 +75,7 @@ ssl.keyStoreType: PKCS12
 ssl.keyStoreValue: Changeme_123
 ssl.crl: revoke.crl
 ssl.sslCustomClass: org.apache.servicecomb.demo.DemoSSLCustom
+
+servicecomb:
+  metrics:
+    window_time: 1000
diff --git a/demo/perf/src/main/java/org/apache/servicecomb/demo/perf/PerfMetricsFilePublisher.java b/demo/perf/src/main/java/org/apache/servicecomb/demo/perf/PerfMetricsFilePublisher.java
index 1f00bc2..915b404 100644
--- a/demo/perf/src/main/java/org/apache/servicecomb/demo/perf/PerfMetricsFilePublisher.java
+++ b/demo/perf/src/main/java/org/apache/servicecomb/demo/perf/PerfMetricsFilePublisher.java
@@ -16,17 +16,19 @@
  */
 package org.apache.servicecomb.demo.perf;
 
+import java.util.Map;
 import java.util.Map.Entry;
 
+import org.apache.servicecomb.foundation.metrics.MetricsConst;
+import org.apache.servicecomb.foundation.metrics.publish.MetricNode;
+import org.apache.servicecomb.foundation.metrics.publish.MetricsLoader;
 import org.apache.servicecomb.foundation.vertx.VertxUtils;
-import org.apache.servicecomb.metrics.common.ConsumerInvocationMetric;
-import org.apache.servicecomb.metrics.common.MetricsDimension;
-import org.apache.servicecomb.metrics.common.ProducerInvocationMetric;
-import org.apache.servicecomb.metrics.common.RegistryMetric;
 import org.apache.servicecomb.metrics.core.publish.DataSource;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import com.google.common.collect.Lists;
+
 import io.vertx.core.impl.VertxImplEx;
 
 public class PerfMetricsFilePublisher {
@@ -39,21 +41,21 @@ public class PerfMetricsFilePublisher {
   }
 
   public void onCycle() {
-    RegistryMetric metric = dataSource.getRegistryMetric();
+    Map<String, Double> metrics = dataSource.measure(dataSource.getAppliedWindowTime().get(0), true);
+    MetricsLoader loader = new MetricsLoader(metrics);
 
     StringBuilder sb = new StringBuilder();
     sb.append("\n");
 
-    collectSystemMetrics(metric, sb);
-    collectVertxMetrics(metric, sb);
-    collectConsumerMetrics(metric, sb);
-    collectProducerMetrics(metric, sb);
+    collectSystemMetrics(loader, sb);
+    collectVertxMetrics(loader, sb);
+    collectMetrics(loader, sb);
 
     LOGGER.info(sb.toString());
   }
 
-  protected void collectSystemMetrics(RegistryMetric metric, StringBuilder sb) {
-    double cpu = metric.getInstanceMetric().getSystemMetric().getCpuLoad();
+  private void collectSystemMetrics(MetricsLoader loader, StringBuilder sb) {
+    double cpu = loader.getFirstMatchMetricValue(MetricsConst.JVM, MetricsConst.TAG_NAME, "cpuLoad");
     // can not get cpu usage in windows, so skip this information
     if (cpu >= 0) {
       sb.append("cpu: ")
@@ -62,7 +64,7 @@ public class PerfMetricsFilePublisher {
     }
   }
 
-  protected void collectVertxMetrics(RegistryMetric metric, StringBuilder sb) {
+  private void collectVertxMetrics(MetricsLoader loader, StringBuilder sb) {
     sb.append("vertx:\n")
         .append("  name       eventLoopContext-created\n");
     for (Entry<String, VertxImplEx> entry : VertxUtils.getVertxMap().entrySet()) {
@@ -72,55 +74,55 @@ public class PerfMetricsFilePublisher {
     }
   }
 
-  protected void collectProducerMetrics(RegistryMetric metric, StringBuilder sb) {
-    if (metric.getProducerMetrics().isEmpty()) {
-      return;
-    }
-
-    sb.append("producer:\n"
-        + "  total               tps     latency(ms) queue(ms) execute(ms) name\n");
-    for (Entry<String, ProducerInvocationMetric> entry : metric.getProducerMetrics().entrySet()) {
-      String opName = entry.getKey();
-      sb.append(
-          String.format("  %-19d %-7d %-11.3f %-9.3f %-11.3f %s\n",
-              entry.getValue()
-                  .getProducerCall()
-                  .getTotalValue(MetricsDimension.DIMENSION_STATUS, MetricsDimension.DIMENSION_STATUS_ALL)
-                  .getValue(),
-              entry.getValue()
-                  .getProducerCall()
-                  .getTpsValue(MetricsDimension.DIMENSION_STATUS, MetricsDimension.DIMENSION_STATUS_ALL)
-                  .getValue()
-                  .longValue(),
-              entry.getValue().getProducerLatency().getAverage(),
-              entry.getValue().getLifeTimeInQueue().getAverage(),
-              entry.getValue().getExecutionTime().getAverage(),
-              opName));
-    }
-  }
-
-  protected void collectConsumerMetrics(RegistryMetric metric, StringBuilder sb) {
-    if (metric.getConsumerMetrics().isEmpty()) {
-      return;
-    }
-
-    sb.append("consumer:\n"
-        + "  total               tps     latency(ms) name\n");
-    for (Entry<String, ConsumerInvocationMetric> entry : metric.getConsumerMetrics().entrySet()) {
-      String opName = entry.getKey();
-      sb.append(String
-          .format("  %-19d %-7d %-11.3f %s\n",
-              entry.getValue()
-                  .getConsumerCall()
-                  .getTotalValue(MetricsDimension.DIMENSION_STATUS, MetricsDimension.DIMENSION_STATUS_ALL)
-                  .getValue(),
-              entry.getValue()
-                  .getConsumerCall()
-                  .getTpsValue(MetricsDimension.DIMENSION_STATUS, MetricsDimension.DIMENSION_STATUS_ALL)
-                  .getValue()
-                  .longValue(),
-              entry.getValue().getConsumerLatency().getAverage(),
-              opName));
+  private void collectMetrics(MetricsLoader loader, StringBuilder sb) {
+    MetricNode treeNode = loader
+        .getMetricTree(MetricsConst.SERVICECOMB_INVOCATION, MetricsConst.TAG_ROLE, MetricsConst.TAG_OPERATION,
+            MetricsConst.TAG_STATUS);
+
+    if (treeNode != null && treeNode.getChildren().size() != 0) {
+      MetricNode consumerNode = treeNode.getChildren().get(MetricsConst.ROLE_CONSUMER);
+      if (consumerNode != null) {
+        sb.append("consumer:\n");
+        sb.append("  tps     latency(ms) status  operation\n");
+        for (Entry<String, MetricNode> operationNode : consumerNode.getChildren().entrySet()) {
+          for (Entry<String, MetricNode> statusNode : operationNode.getValue().getChildren().entrySet()) {
+            sb.append(String.format("  %-7.0f %-11.3f %-9s %s\n",
+                statusNode.getValue()
+                    .getFirstMatchMetricValue(Lists.newArrayList(MetricsConst.TAG_STAGE, MetricsConst.TAG_STATISTIC),
+                        Lists.newArrayList(MetricsConst.STAGE_WHOLE, "tps")),
+                statusNode.getValue()
+                    .getFirstMatchMetricValue(Lists.newArrayList(MetricsConst.TAG_STAGE, MetricsConst.TAG_STATISTIC),
+                        Lists.newArrayList(MetricsConst.STAGE_WHOLE, "latency")),
+                statusNode.getKey(),
+                operationNode.getKey()));
+          }
+        }
+      }
+
+      MetricNode producerNode = treeNode.getChildren().get(MetricsConst.ROLE_PRODUCER);
+      if (producerNode != null) {
+        sb.append("producer:\n");
+        sb.append("  tps     latency(ms) queue(ms) execute(ms) status  operation\n");
+        for (Entry<String, MetricNode> operationNode : producerNode.getChildren().entrySet()) {
+          for (Entry<String, MetricNode> statusNode : operationNode.getValue().getChildren().entrySet()) {
+            sb.append(String.format("  %-7.0f %-11.3f %-9.3f %-11.3f %-7s %s\n",
+                statusNode.getValue()
+                    .getFirstMatchMetricValue(Lists.newArrayList(MetricsConst.TAG_STAGE, MetricsConst.TAG_STATISTIC),
+                        Lists.newArrayList(MetricsConst.STAGE_WHOLE, "tps")),
+                statusNode.getValue()
+                    .getFirstMatchMetricValue(Lists.newArrayList(MetricsConst.TAG_STAGE, MetricsConst.TAG_STATISTIC),
+                        Lists.newArrayList(MetricsConst.STAGE_WHOLE, "latency")),
+                statusNode.getValue()
+                    .getFirstMatchMetricValue(Lists.newArrayList(MetricsConst.TAG_STAGE, MetricsConst.TAG_STATISTIC),
+                        Lists.newArrayList(MetricsConst.STAGE_QUEUE, "latency")),
+                statusNode.getValue()
+                    .getFirstMatchMetricValue(Lists.newArrayList(MetricsConst.TAG_STAGE, MetricsConst.TAG_STATISTIC),
+                        Lists.newArrayList(MetricsConst.STAGE_EXECUTION, "latency")),
+                statusNode.getKey(),
+                operationNode.getKey()));
+          }
+        }
+      }
     }
   }
 }
diff --git a/metrics/metrics-common/src/main/java/org/apache/servicecomb/metrics/common/MetricsConst.java b/foundations/foundation-metrics/src/main/java/org/apache/servicecomb/foundation/metrics/MetricsConst.java
similarity index 51%
rename from metrics/metrics-common/src/main/java/org/apache/servicecomb/metrics/common/MetricsConst.java
rename to foundations/foundation-metrics/src/main/java/org/apache/servicecomb/foundation/metrics/MetricsConst.java
index a47b055..7bb0198 100644
--- a/metrics/metrics-common/src/main/java/org/apache/servicecomb/metrics/common/MetricsConst.java
+++ b/foundations/foundation-metrics/src/main/java/org/apache/servicecomb/foundation/metrics/MetricsConst.java
@@ -15,14 +15,32 @@
  * limitations under the License.
  */
 
-package org.apache.servicecomb.metrics.common;
+package org.apache.servicecomb.foundation.metrics;
 
 public class MetricsConst {
-  public static final String CONSUMER_PREFIX_TEMPLATE = "servicecomb.%s.consumer";
+  public static final String JVM = "jvm";
 
-  public static final String PRODUCER_PREFIX_TEMPLATE = "servicecomb.%s.producer";
+  public static final String SERVICECOMB_INVOCATION = "servicecomb.invocation";
 
-  public static final String INSTANCE_CONSUMER_PREFIX = String.format(CONSUMER_PREFIX_TEMPLATE, "instance");
+  public static final String TAG_NAME = "name";
 
-  public static final String INSTANCE_PRODUCER_PREFIX = String.format(PRODUCER_PREFIX_TEMPLATE, "instance");
+  public static final String TAG_OPERATION = "operation";
+
+  public static final String TAG_STATUS = "status";
+
+  public static final String TAG_STAGE = "stage";
+
+  public static final String TAG_ROLE = "role";
+
+  public static final String TAG_STATISTIC = "statistic";
+
+  public static final String STAGE_WHOLE = "whole";
+
+  public static final String STAGE_QUEUE = "queue";
+
+  public static final String STAGE_EXECUTION = "execution";
+
+  public static final String ROLE_CONSUMER = "consumer";
+
+  public static final String ROLE_PRODUCER = "producer";
 }
diff --git a/metrics/metrics-common/src/main/java/org/apache/servicecomb/metrics/common/DefaultHealthCheckExtraData.java b/foundations/foundation-metrics/src/main/java/org/apache/servicecomb/foundation/metrics/publish/DefaultHealthCheckExtraData.java
similarity index 96%
rename from metrics/metrics-common/src/main/java/org/apache/servicecomb/metrics/common/DefaultHealthCheckExtraData.java
rename to foundations/foundation-metrics/src/main/java/org/apache/servicecomb/foundation/metrics/publish/DefaultHealthCheckExtraData.java
index 00f7736..6415927 100644
--- a/metrics/metrics-common/src/main/java/org/apache/servicecomb/metrics/common/DefaultHealthCheckExtraData.java
+++ b/foundations/foundation-metrics/src/main/java/org/apache/servicecomb/foundation/metrics/publish/DefaultHealthCheckExtraData.java
@@ -15,7 +15,7 @@
  * limitations under the License.
  */
 
-package org.apache.servicecomb.metrics.common;
+package org.apache.servicecomb.foundation.metrics.publish;
 
 public class DefaultHealthCheckExtraData {
   private String instanceId;
diff --git a/metrics/metrics-common/src/main/java/org/apache/servicecomb/metrics/common/HealthCheckResult.java b/foundations/foundation-metrics/src/main/java/org/apache/servicecomb/foundation/metrics/publish/HealthCheckResult.java
similarity index 96%
rename from metrics/metrics-common/src/main/java/org/apache/servicecomb/metrics/common/HealthCheckResult.java
rename to foundations/foundation-metrics/src/main/java/org/apache/servicecomb/foundation/metrics/publish/HealthCheckResult.java
index 880bdc3..19bad42 100644
--- a/metrics/metrics-common/src/main/java/org/apache/servicecomb/metrics/common/HealthCheckResult.java
+++ b/foundations/foundation-metrics/src/main/java/org/apache/servicecomb/foundation/metrics/publish/HealthCheckResult.java
@@ -15,7 +15,7 @@
  * limitations under the License.
  */
 
-package org.apache.servicecomb.metrics.common;
+package org.apache.servicecomb.foundation.metrics.publish;
 
 public class HealthCheckResult {
   private boolean healthy;
diff --git a/metrics/metrics-common/src/main/java/org/apache/servicecomb/metrics/common/HealthChecker.java b/foundations/foundation-metrics/src/main/java/org/apache/servicecomb/foundation/metrics/publish/HealthChecker.java
similarity index 93%
rename from metrics/metrics-common/src/main/java/org/apache/servicecomb/metrics/common/HealthChecker.java
rename to foundations/foundation-metrics/src/main/java/org/apache/servicecomb/foundation/metrics/publish/HealthChecker.java
index 3ae1d8c..2236a5e 100644
--- a/metrics/metrics-common/src/main/java/org/apache/servicecomb/metrics/common/HealthChecker.java
+++ b/foundations/foundation-metrics/src/main/java/org/apache/servicecomb/foundation/metrics/publish/HealthChecker.java
@@ -15,7 +15,7 @@
  * limitations under the License.
  */
 
-package org.apache.servicecomb.metrics.common;
+package org.apache.servicecomb.foundation.metrics.publish;
 
 public interface HealthChecker {
   String getName();
diff --git a/foundations/foundation-metrics/src/main/java/org/apache/servicecomb/foundation/metrics/publish/Metric.java b/foundations/foundation-metrics/src/main/java/org/apache/servicecomb/foundation/metrics/publish/Metric.java
new file mode 100644
index 0000000..3a01644
--- /dev/null
+++ b/foundations/foundation-metrics/src/main/java/org/apache/servicecomb/foundation/metrics/publish/Metric.java
@@ -0,0 +1,66 @@
+/*
+ * 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.servicecomb.foundation.metrics.publish;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+public class Metric {
+  private final String name;
+
+  private final Map<String, String> tags;
+
+  private double value;
+
+  public String getName() {
+    return name;
+  }
+
+  public Map<String, String> getTags() {
+    return tags;
+  }
+
+  public double getValue() {
+    return value;
+  }
+
+  public Metric(String id, double value) {
+    String[] nameAndTag = id.split("\\(");
+    this.tags = new HashMap<>();
+    String[] tagAnValues = nameAndTag[1].split("[=,)]");
+    for (int i = 0; i < tagAnValues.length; i += 2) {
+      this.tags.put(tagAnValues[i], tagAnValues[i + 1]);
+    }
+    this.name = nameAndTag[0];
+    this.value = value;
+  }
+
+  public boolean containTag(List<String> tagKeys, List<String> tagValues) {
+    for (int i = 0; i < tagKeys.size(); i++) {
+      if (!containTag(tagKeys.get(i), tagValues.get(i))) {
+        return false;
+      }
+    }
+    return true;
+  }
+
+  public boolean containTag(String tagKey, String tagValue) {
+    return tags.containsKey(tagKey) && tagValue.equals(tags.get(tagKey));
+  }
+}
diff --git a/foundations/foundation-metrics/src/main/java/org/apache/servicecomb/foundation/metrics/publish/MetricNode.java b/foundations/foundation-metrics/src/main/java/org/apache/servicecomb/foundation/metrics/publish/MetricNode.java
new file mode 100644
index 0000000..c23d9e2
--- /dev/null
+++ b/foundations/foundation-metrics/src/main/java/org/apache/servicecomb/foundation/metrics/publish/MetricNode.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.servicecomb.foundation.metrics.publish;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+
+import org.apache.servicecomb.foundation.metrics.MetricsConst;
+
+public class MetricNode {
+  private final String tagKey;
+
+  private final List<Metric> metrics;
+
+  private final Map<String, MetricNode> children;
+
+  public List<Metric> getMetrics() {
+    return metrics;
+  }
+
+  public Map<String, MetricNode> getChildren() {
+    return children;
+  }
+
+  public MetricNode getChildrenNode(String tagValue) {
+    return children.get(tagValue);
+  }
+
+  public Double getFirstMatchMetricValue(String tagKey, String tagValue) {
+    for (Metric metric : this.metrics) {
+      if (metric.containTag(tagKey, tagValue)) {
+        return metric.getValue();
+      }
+    }
+    return Double.NaN;
+  }
+
+  public Double getFirstMatchMetricValue(List<String> tagKeys, List<String> tagValues) {
+    for (Metric metric : this.metrics) {
+      if (metric.containTag(tagKeys, tagValues)) {
+        return metric.getValue();
+      }
+    }
+    return Double.NaN;
+  }
+
+  public double getMatchStatisticMetricValue(String statisticValue) {
+    return getFirstMatchMetricValue(MetricsConst.TAG_STATISTIC, statisticValue);
+  }
+
+  public MetricNode(List<Metric> metrics, String... groupTagKeys) {
+    if (groupTagKeys == null || groupTagKeys.length == 0) {
+      this.tagKey = null;
+      this.metrics = metrics;
+      this.children = null;
+    } else {
+      this.tagKey = groupTagKeys[0];
+      this.metrics = null;
+      this.children = new HashMap<>();
+      Map<String, List<Metric>> groups = groupByTag(metrics, this.tagKey);
+      if (groupTagKeys.length == 1) {
+        for (Entry<String, List<Metric>> group : groups.entrySet()) {
+          this.children.put(group.getKey(), new MetricNode(null, group.getValue(), null));
+        }
+      } else {
+        for (Entry<String, List<Metric>> group : groups.entrySet()) {
+          this.children.put(group.getKey(),
+              new MetricNode(group.getValue(), Arrays.copyOfRange(groupTagKeys, 1, groupTagKeys.length)));
+        }
+      }
+    }
+  }
+
+  private MetricNode(String tagKey, List<Metric> metrics, Map<String, MetricNode> children) {
+    this.tagKey = tagKey;
+    this.metrics = metrics;
+    this.children = children;
+  }
+
+  private Map<String, List<Metric>> groupByTag(List<Metric> metrics, String tagKey) {
+    Map<String, List<Metric>> groups = new HashMap<>();
+    for (Metric metric : metrics) {
+      if (metric.getTags().containsKey(tagKey)) {
+        groups.computeIfAbsent(metric.getTags().get(tagKey), g -> new ArrayList<>()).add(metric);
+      }
+    }
+    return groups;
+  }
+}
diff --git a/foundations/foundation-metrics/src/main/java/org/apache/servicecomb/foundation/metrics/publish/MetricsLoader.java b/foundations/foundation-metrics/src/main/java/org/apache/servicecomb/foundation/metrics/publish/MetricsLoader.java
new file mode 100644
index 0000000..073eaf6
--- /dev/null
+++ b/foundations/foundation-metrics/src/main/java/org/apache/servicecomb/foundation/metrics/publish/MetricsLoader.java
@@ -0,0 +1,56 @@
+/*
+ * 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.servicecomb.foundation.metrics.publish;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+
+//load origin metrics value and publish tree
+public class MetricsLoader {
+
+  private final Map<String, List<Metric>> metrics;
+
+  public MetricsLoader(Map<String, Double> metrics) {
+    this.metrics = new HashMap<>();
+    for (Entry<String, Double> entry : metrics.entrySet()) {
+      Metric metric = new Metric(entry.getKey(), entry.getValue());
+      this.metrics.computeIfAbsent(metric.getName(), m -> new ArrayList<>()).add(metric);
+    }
+  }
+
+  public MetricNode getMetricTree(String id, String... groupTagKeys) {
+    if (metrics.containsKey(id)) {
+      return new MetricNode(metrics.get(id), groupTagKeys);
+    }
+    return null;
+  }
+
+  public double getFirstMatchMetricValue(String name, String tagKey, String tagValue) {
+    if (metrics.containsKey(name)) {
+      for (Metric metric : this.metrics.get(name)) {
+        if (metric.containTag(tagKey, tagValue)) {
+          return metric.getValue();
+        }
+      }
+    }
+    return Double.NaN;
+  }
+}
diff --git a/metrics/metrics-common/pom.xml b/metrics/metrics-common/pom.xml
index 0d28c6d..e69de29 100644
--- a/metrics/metrics-common/pom.xml
+++ b/metrics/metrics-common/pom.xml
@@ -1,39 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-  ~ 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>
-    <artifactId>metrics</artifactId>
-    <groupId>org.apache.servicecomb</groupId>
-    <version>1.0.0-m1-SNAPSHOT</version>
-  </parent>
-  <modelVersion>4.0.0</modelVersion>
-
-  <artifactId>metrics-common</artifactId>
-  <name>Java Chassis::Metrics::Common</name>
-
-  <dependencies>
-    <dependency>
-      <groupId>org.apache.servicecomb</groupId>
-      <artifactId>foundation-common</artifactId>
-    </dependency>
-  </dependencies>
-
-</project>
diff --git a/metrics/metrics-common/src/main/java/org/apache/servicecomb/metrics/common/CallMetric.java b/metrics/metrics-common/src/main/java/org/apache/servicecomb/metrics/common/CallMetric.java
deleted file mode 100644
index 36e1d49..0000000
--- a/metrics/metrics-common/src/main/java/org/apache/servicecomb/metrics/common/CallMetric.java
+++ /dev/null
@@ -1,92 +0,0 @@
-/*
- * 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.servicecomb.metrics.common;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-import com.fasterxml.jackson.annotation.JsonProperty;
-
-public class CallMetric {
-  private final String prefix;
-
-  private final List<LongMetricValue> totalValues;
-
-  private final List<DoubleMetricValue> tpsValues;
-
-  public String getPrefix() {
-    return prefix;
-  }
-
-  public List<LongMetricValue> getTotalValues() {
-    return totalValues;
-  }
-
-  public LongMetricValue getTotalValue(String dimensionKey, String dimensionValue) {
-    for (LongMetricValue value : totalValues) {
-      if (value.containDimension(dimensionKey, dimensionValue)) {
-        return value;
-      }
-    }
-    return new LongMetricValue(dimensionValue, 0L, null);
-  }
-
-  public List<DoubleMetricValue> getTpsValues() {
-    return tpsValues;
-  }
-
-  public DoubleMetricValue getTpsValue(String dimensionKey, String dimensionValue) {
-    for (DoubleMetricValue value : tpsValues) {
-      if (value.containDimension(dimensionKey, dimensionValue)) {
-        return value;
-      }
-    }
-    return new DoubleMetricValue(dimensionValue, 0.0, null);
-  }
-
-  public CallMetric(String prefix) {
-    this(prefix, new ArrayList<>(), new ArrayList<>());
-  }
-
-  public CallMetric(@JsonProperty("prefix") String prefix,
-      @JsonProperty("totalValues") List<LongMetricValue> totalValues,
-      @JsonProperty("tpsValues") List<DoubleMetricValue> tpsValues) {
-    this.prefix = prefix;
-    this.totalValues = totalValues;
-    this.tpsValues = tpsValues;
-  }
-
-  public CallMetric merge(CallMetric metric) {
-    return new CallMetric(this.prefix,
-        LongMetricValue.merge(metric.getTotalValues(), this.getTotalValues()),
-        DoubleMetricValue.merge(metric.getTpsValues(), this.getTpsValues()));
-  }
-
-  public Map<String, Number> toMap() {
-    Map<String, Number> metrics = new HashMap<>();
-    for (LongMetricValue totalValue : totalValues) {
-      metrics.put(prefix + ".total." + totalValue.getKey(), totalValue.getValue());
-    }
-    for (DoubleMetricValue tpsValue : tpsValues) {
-      metrics.put(prefix + ".tps." + tpsValue.getKey(), tpsValue.getValue());
-    }
-    return metrics;
-  }
-}
diff --git a/metrics/metrics-common/src/main/java/org/apache/servicecomb/metrics/common/ConsumerInvocationMetric.java b/metrics/metrics-common/src/main/java/org/apache/servicecomb/metrics/common/ConsumerInvocationMetric.java
deleted file mode 100644
index 681e1d4..0000000
--- a/metrics/metrics-common/src/main/java/org/apache/servicecomb/metrics/common/ConsumerInvocationMetric.java
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * 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.servicecomb.metrics.common;
-
-import java.util.HashMap;
-import java.util.Map;
-
-import com.fasterxml.jackson.annotation.JsonProperty;
-
-public class ConsumerInvocationMetric extends InvocationMetric {
-  private final TimerMetric consumerLatency;
-
-  private final CallMetric consumerCall;
-
-  public TimerMetric getConsumerLatency() {
-    return consumerLatency;
-  }
-
-  public CallMetric getConsumerCall() {
-    return consumerCall;
-  }
-
-  public ConsumerInvocationMetric(@JsonProperty("operationName") String operationName,
-      @JsonProperty("prefix") String prefix,
-      @JsonProperty("consumerLatency") TimerMetric consumerLatency,
-      @JsonProperty("consumerCall") CallMetric consumerCall) {
-    super(operationName, prefix);
-    this.consumerLatency = consumerLatency;
-    this.consumerCall = consumerCall;
-  }
-
-  public ConsumerInvocationMetric merge(ConsumerInvocationMetric metric) {
-    return new ConsumerInvocationMetric(this.getOperationName(), this.getPrefix(),
-        consumerLatency.merge(metric.getConsumerLatency()),
-        consumerCall.merge(metric.getConsumerCall()));
-  }
-
-  public Map<String, Number> toMap() {
-    Map<String, Number> metrics = new HashMap<>();
-    metrics.putAll(consumerLatency.toMap());
-    metrics.putAll(consumerCall.toMap());
-    return metrics;
-  }
-}
diff --git a/metrics/metrics-common/src/main/java/org/apache/servicecomb/metrics/common/DoubleMetricValue.java b/metrics/metrics-common/src/main/java/org/apache/servicecomb/metrics/common/DoubleMetricValue.java
deleted file mode 100644
index e6ace95..0000000
--- a/metrics/metrics-common/src/main/java/org/apache/servicecomb/metrics/common/DoubleMetricValue.java
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * 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.servicecomb.metrics.common;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-import com.fasterxml.jackson.annotation.JsonProperty;
-
-public class DoubleMetricValue extends MetricValue<Double> {
-  public DoubleMetricValue(Double value, Map<String, String> dimensions) {
-    super(value, dimensions);
-  }
-
-  public DoubleMetricValue(@JsonProperty("key") String key,
-      @JsonProperty("value") Double value,
-      @JsonProperty("dimensions") Map<String, String> dimensions) {
-    super(key, value, dimensions);
-  }
-
-  private DoubleMetricValue merge(DoubleMetricValue value) {
-    return new DoubleMetricValue(this.getKey(), this.getValue() + value.getValue(), this.getDimensions());
-  }
-
-  public static List<DoubleMetricValue> merge(List<DoubleMetricValue> source, List<DoubleMetricValue> target) {
-    Map<String, DoubleMetricValue> finalValues = new HashMap<>();
-    for (DoubleMetricValue t : target) {
-      finalValues.put(t.getKey(), t);
-    }
-    for (DoubleMetricValue s : source) {
-      if (finalValues.containsKey(s.getKey())) {
-        finalValues.put(s.getKey(), finalValues.get(s.getKey()).merge(s));
-      } else {
-        finalValues.put(s.getKey(), s);
-      }
-    }
-    return new ArrayList<>(finalValues.values());
-  }
-}
diff --git a/metrics/metrics-common/src/main/java/org/apache/servicecomb/metrics/common/HealthCheckerPublisher.java b/metrics/metrics-common/src/main/java/org/apache/servicecomb/metrics/common/HealthCheckerPublisher.java
deleted file mode 100644
index 2f3a48a..0000000
--- a/metrics/metrics-common/src/main/java/org/apache/servicecomb/metrics/common/HealthCheckerPublisher.java
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * 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.servicecomb.metrics.common;
-
-import java.util.Map;
-
-public interface HealthCheckerPublisher {
-  Map<String, HealthCheckResult> health();
-
-  HealthCheckResult healthWithName(String name);
-}
diff --git a/metrics/metrics-common/src/main/java/org/apache/servicecomb/metrics/common/InstanceMetric.java b/metrics/metrics-common/src/main/java/org/apache/servicecomb/metrics/common/InstanceMetric.java
deleted file mode 100644
index 58ae2cd..0000000
--- a/metrics/metrics-common/src/main/java/org/apache/servicecomb/metrics/common/InstanceMetric.java
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * 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.servicecomb.metrics.common;
-
-import java.util.HashMap;
-import java.util.Map;
-
-import com.fasterxml.jackson.annotation.JsonProperty;
-
-public class InstanceMetric {
-  private final SystemMetric systemMetric;
-
-  private final ConsumerInvocationMetric consumerMetric;
-
-  private final ProducerInvocationMetric producerMetric;
-
-  public SystemMetric getSystemMetric() {
-    return systemMetric;
-  }
-
-  public ConsumerInvocationMetric getConsumerMetric() {
-    return consumerMetric;
-  }
-
-  public ProducerInvocationMetric getProducerMetric() {
-    return producerMetric;
-  }
-
-  public InstanceMetric(@JsonProperty("systemMetric") SystemMetric systemMetric,
-      @JsonProperty("consumerMetric") ConsumerInvocationMetric consumerMetric,
-      @JsonProperty("producerMetric") ProducerInvocationMetric producerMetric) {
-    this.systemMetric = systemMetric;
-    this.consumerMetric = consumerMetric;
-    this.producerMetric = producerMetric;
-  }
-
-  public Map<String, Number> toMap() {
-    Map<String, Number> metrics = new HashMap<>();
-    metrics.putAll(systemMetric.toMap());
-    metrics.putAll(consumerMetric.toMap());
-    metrics.putAll(producerMetric.toMap());
-    return metrics;
-  }
-}
diff --git a/metrics/metrics-common/src/main/java/org/apache/servicecomb/metrics/common/InvocationMetric.java b/metrics/metrics-common/src/main/java/org/apache/servicecomb/metrics/common/InvocationMetric.java
deleted file mode 100644
index 234ccec..0000000
--- a/metrics/metrics-common/src/main/java/org/apache/servicecomb/metrics/common/InvocationMetric.java
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * 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.servicecomb.metrics.common;
-
-public class InvocationMetric {
-  private final String operationName;
-
-  private final String prefix;
-
-  public String getOperationName() {
-    return operationName;
-  }
-
-  public String getPrefix() {
-    return prefix;
-  }
-
-  public InvocationMetric(String operationName, String prefix) {
-    this.operationName = operationName;
-    this.prefix = prefix;
-  }
-}
diff --git a/metrics/metrics-common/src/main/java/org/apache/servicecomb/metrics/common/LongMetricValue.java b/metrics/metrics-common/src/main/java/org/apache/servicecomb/metrics/common/LongMetricValue.java
deleted file mode 100644
index ff27134..0000000
--- a/metrics/metrics-common/src/main/java/org/apache/servicecomb/metrics/common/LongMetricValue.java
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * 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.servicecomb.metrics.common;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-import com.fasterxml.jackson.annotation.JsonProperty;
-
-public class LongMetricValue extends MetricValue<Long> {
-  public LongMetricValue(Long value, Map<String, String> dimensions) {
-    super(value, dimensions);
-  }
-
-  public LongMetricValue(@JsonProperty("key") String key,
-      @JsonProperty("value") Long value,
-      @JsonProperty("dimensions") Map<String, String> dimensions) {
-    super(key, value, dimensions);
-  }
-
-  private LongMetricValue merge(LongMetricValue value) {
-    return new LongMetricValue(this.getKey(), this.getValue() + value.getValue(), this.getDimensions());
-  }
-
-  public static List<LongMetricValue> merge(List<LongMetricValue> source, List<LongMetricValue> target) {
-    Map<String, LongMetricValue> finalValues = new HashMap<>();
-    for (LongMetricValue t : target) {
-      finalValues.put(t.getKey(), t);
-    }
-    for (LongMetricValue s : source) {
-      if (finalValues.containsKey(s.getKey())) {
-        finalValues.put(s.getKey(), finalValues.get(s.getKey()).merge(s));
-      } else {
-        finalValues.put(s.getKey(), s);
-      }
-    }
-    return new ArrayList<>(finalValues.values());
-  }
-}
diff --git a/metrics/metrics-common/src/main/java/org/apache/servicecomb/metrics/common/MetricValue.java b/metrics/metrics-common/src/main/java/org/apache/servicecomb/metrics/common/MetricValue.java
deleted file mode 100644
index 0a8d364..0000000
--- a/metrics/metrics-common/src/main/java/org/apache/servicecomb/metrics/common/MetricValue.java
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * 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.servicecomb.metrics.common;
-
-import java.util.Arrays;
-import java.util.Map;
-
-public class MetricValue<T extends Number> {
-  private final String key;
-
-  private final T value;
-
-  private final Map<String, String> dimensions;
-
-  public String getKey() {
-    return key;
-  }
-
-  public T getValue() {
-    return value;
-  }
-
-  public Map<String, String> getDimensions() {
-    return dimensions;
-  }
-
-  public MetricValue(T value, Map<String, String> dimensions) {
-    String finalKey = "{}";
-    if (dimensions != null && dimensions.size() != 0) {
-      String[] keys = dimensions.keySet().toArray(new String[0]);
-      Arrays.sort(keys);
-      StringBuilder builder = new StringBuilder("{");
-      for (String key : keys) {
-        builder.append(String.format("%s=%s,", key, dimensions.get(key)));
-      }
-      builder.deleteCharAt(builder.length() - 1);
-      builder.append("}");
-      finalKey = builder.toString();
-    }
-    this.key = finalKey;
-    this.value = value;
-    this.dimensions = dimensions;
-  }
-
-  public MetricValue(String key, T value, Map<String, String> dimensions) {
-    this.key = key;
-    this.value = value;
-    this.dimensions = dimensions;
-  }
-
-  public boolean containDimension(String dimensionKey, String dimensionValue) {
-    return this.getDimensions().containsKey(dimensionKey) &&
-        dimensionValue.equals(this.getDimensions().get(dimensionKey));
-  }
-}
diff --git a/metrics/metrics-common/src/main/java/org/apache/servicecomb/metrics/common/MetricsDimension.java b/metrics/metrics-common/src/main/java/org/apache/servicecomb/metrics/common/MetricsDimension.java
deleted file mode 100644
index 904cc25..0000000
--- a/metrics/metrics-common/src/main/java/org/apache/servicecomb/metrics/common/MetricsDimension.java
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * 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.servicecomb.metrics.common;
-
-public class MetricsDimension {
-  public static final String DIMENSION_STATUS = "Status";
-
-  public static final String DIMENSION_STATUS_ALL = "all";
-
-  public static final String DIMENSION_STATUS_SUCCESS_FAILED_SUCCESS = "success";
-
-  public static final String DIMENSION_STATUS_SUCCESS_FAILED_FAILED = "failed";
-
-  public static final String DIMENSION_STATUS_CODE_GROUP_1XX = "1xx";
-
-  public static final String DIMENSION_STATUS_CODE_GROUP_2XX = "2xx";
-
-  public static final String DIMENSION_STATUS_CODE_GROUP_3XX = "3xx";
-
-  public static final String DIMENSION_STATUS_CODE_GROUP_4XX = "4xx";
-
-  public static final String DIMENSION_STATUS_CODE_GROUP_5XX = "5xx";
-
-  public static final String DIMENSION_STATUS_CODE_GROUP_OTHER = "xxx";
-
-  public static final String DIMENSION_STATUS_OUTPUT_LEVEL_SUCCESS_FAILED = "success_failed";
-
-  public static final String DIMENSION_STATUS_OUTPUT_LEVEL_CODE_GROUP = "code_group";
-
-  public static final String DIMENSION_STATUS_OUTPUT_LEVEL_CODE = "code";
-}
diff --git a/metrics/metrics-common/src/main/java/org/apache/servicecomb/metrics/common/MetricsPublisher.java b/metrics/metrics-common/src/main/java/org/apache/servicecomb/metrics/common/MetricsPublisher.java
deleted file mode 100644
index 029ddb3..0000000
--- a/metrics/metrics-common/src/main/java/org/apache/servicecomb/metrics/common/MetricsPublisher.java
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * 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.servicecomb.metrics.common;
-
-import java.util.List;
-
-public interface MetricsPublisher {
-  /**  What's the WindowTime ?
-   We all know there are two major type of metric :
-   1.Time-unrelated,you can get the latest value any time immediately:
-   Counter -> increase or decrease
-   Guage -> set a certain one value
-   2.Time-related,only after a centain time pass you can compute the right value,"a centain time" called WindowTime
-   Max & Min -> the max value or min value in a centain time
-   Average -> average value, the simplest algorithm is f = sum / count
-   Rate -> like TPS,algorithm is f = sum / second
-  
-   Will be return "servicecomb.metrics.window_time" setting in microservice.yaml
-   */
-  List<Long> getAppliedWindowTime();
-
-  //same as getRegistryMetric({first setting windowTime})
-  RegistryMetric metrics();
-
-  /**
-   * windowTime usage example:
-   * if there is two window time set in "servicecomb.metrics.window_time" like 1000,2000
-   * then windowTime = 1000 will return result of the setting 1000(1 second)
-   * windowTime = 2000 will return result of the setting 2000(2 second)
-   *
-   * there are three monitor of max,min,total
-   * 0----------1----------2----------3----------  <-time line (second)
-   *   100,200    300,400                          <-value record
-   *
-   *                 ↑ getRegistryMetric(1000) will return max=200 min=100 total=300
-   *                   getRegistryMetric(2000) will return max=0 min=0 total=0
-   *                             ↑ getRegistryMetric(1000) will return max=300 min=400 total=700
-   *                               getRegistryMetric(2000) will return max=400 min=100 total=1000
-   *
-   * @param windowTime getAppliedWindowTime() item
-   * @return RegistryMetric
-   */
-  RegistryMetric metricsWithWindowTime(long windowTime);
-}
diff --git a/metrics/metrics-common/src/main/java/org/apache/servicecomb/metrics/common/ProducerInvocationMetric.java b/metrics/metrics-common/src/main/java/org/apache/servicecomb/metrics/common/ProducerInvocationMetric.java
deleted file mode 100644
index eb8c498..0000000
--- a/metrics/metrics-common/src/main/java/org/apache/servicecomb/metrics/common/ProducerInvocationMetric.java
+++ /dev/null
@@ -1,89 +0,0 @@
-/*
- * 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.servicecomb.metrics.common;
-
-import java.util.HashMap;
-import java.util.Map;
-
-import com.fasterxml.jackson.annotation.JsonProperty;
-
-public class ProducerInvocationMetric extends InvocationMetric {
-  private final long waitInQueue;
-
-  private final TimerMetric lifeTimeInQueue;
-
-  private final TimerMetric executionTime;
-
-  private final TimerMetric producerLatency;
-
-  private final CallMetric producerCall;
-
-  public long getWaitInQueue() {
-    return waitInQueue;
-  }
-
-  public TimerMetric getLifeTimeInQueue() {
-    return lifeTimeInQueue;
-  }
-
-  public TimerMetric getExecutionTime() {
-    return executionTime;
-  }
-
-  public TimerMetric getProducerLatency() {
-    return producerLatency;
-  }
-
-  public CallMetric getProducerCall() {
-    return producerCall;
-  }
-
-  public ProducerInvocationMetric(@JsonProperty("operationName") String operationName,
-      @JsonProperty("prefix") String prefix,
-      @JsonProperty("waitInQueue") long waitInQueue,
-      @JsonProperty("lifeTimeInQueue") TimerMetric lifeTimeInQueue,
-      @JsonProperty("executionTime") TimerMetric executionTime,
-      @JsonProperty("producerLatency") TimerMetric producerLatency,
-      @JsonProperty("producerCall") CallMetric producerCall) {
-    super(operationName, prefix);
-    this.waitInQueue = waitInQueue;
-    this.lifeTimeInQueue = lifeTimeInQueue;
-    this.executionTime = executionTime;
-    this.producerLatency = producerLatency;
-    this.producerCall = producerCall;
-  }
-
-  public ProducerInvocationMetric merge(ProducerInvocationMetric metric) {
-    return new ProducerInvocationMetric(this.getOperationName(), this.getPrefix(),
-        this.getWaitInQueue() + metric.getWaitInQueue(),
-        lifeTimeInQueue.merge(metric.getLifeTimeInQueue()),
-        executionTime.merge(metric.getExecutionTime()),
-        producerLatency.merge(metric.getProducerLatency()),
-        producerCall.merge(metric.getProducerCall()));
-  }
-
-  public Map<String, Number> toMap() {
-    Map<String, Number> metrics = new HashMap<>();
-    metrics.put(getPrefix() + ".waitInQueue.count", getWaitInQueue());
-    metrics.putAll(lifeTimeInQueue.toMap());
-    metrics.putAll(executionTime.toMap());
-    metrics.putAll(producerLatency.toMap());
-    metrics.putAll(producerCall.toMap());
-    return metrics;
-  }
-}
diff --git a/metrics/metrics-common/src/main/java/org/apache/servicecomb/metrics/common/RegistryMetric.java b/metrics/metrics-common/src/main/java/org/apache/servicecomb/metrics/common/RegistryMetric.java
deleted file mode 100644
index b9a919e..0000000
--- a/metrics/metrics-common/src/main/java/org/apache/servicecomb/metrics/common/RegistryMetric.java
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * 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.servicecomb.metrics.common;
-
-import java.util.HashMap;
-import java.util.Map;
-
-import com.fasterxml.jackson.annotation.JsonProperty;
-
-public class RegistryMetric {
-  private final InstanceMetric instanceMetric;
-
-  private final Map<String, ConsumerInvocationMetric> consumerMetrics;
-
-  private final Map<String, ProducerInvocationMetric> producerMetrics;
-
-  public InstanceMetric getInstanceMetric() {
-    return instanceMetric;
-  }
-
-  public Map<String, ConsumerInvocationMetric> getConsumerMetrics() {
-    return consumerMetrics;
-  }
-
-  public Map<String, ProducerInvocationMetric> getProducerMetrics() {
-    return producerMetrics;
-  }
-
-  public RegistryMetric(@JsonProperty("instanceMetric") InstanceMetric instanceMetric,
-      @JsonProperty("consumerMetrics") Map<String, ConsumerInvocationMetric> consumerMetrics,
-      @JsonProperty("producerMetrics") Map<String, ProducerInvocationMetric> producerMetrics) {
-    this.consumerMetrics = consumerMetrics;
-    this.producerMetrics = producerMetrics;
-    this.instanceMetric = instanceMetric;
-  }
-
-  public RegistryMetric(SystemMetric systemMetric,
-      Map<String, ConsumerInvocationMetric> consumerMetrics,
-      Map<String, ProducerInvocationMetric> producerMetrics) {
-    this.consumerMetrics = consumerMetrics;
-    this.producerMetrics = producerMetrics;
-
-    ConsumerInvocationMetric instanceConsumerInvocationMetric = new ConsumerInvocationMetric("instance",
-        MetricsConst.INSTANCE_CONSUMER_PREFIX,
-        new TimerMetric(MetricsConst.INSTANCE_CONSUMER_PREFIX + ".consumerLatency"),
-        new CallMetric(MetricsConst.INSTANCE_CONSUMER_PREFIX + ".consumerCall"));
-    ProducerInvocationMetric instanceProducerInvocationMetric = new ProducerInvocationMetric("instance",
-        MetricsConst.INSTANCE_PRODUCER_PREFIX, 0,
-        new TimerMetric(MetricsConst.INSTANCE_PRODUCER_PREFIX + ".lifeTimeInQueue"),
-        new TimerMetric(MetricsConst.INSTANCE_PRODUCER_PREFIX + ".executionTime"),
-        new TimerMetric(MetricsConst.INSTANCE_PRODUCER_PREFIX + ".producerLatency"),
-        new CallMetric(MetricsConst.INSTANCE_PRODUCER_PREFIX + ".producerCall"));
-
-    //sum instance level metric
-    for (ConsumerInvocationMetric metric : consumerMetrics.values()) {
-      instanceConsumerInvocationMetric = instanceConsumerInvocationMetric.merge(metric);
-    }
-    for (ProducerInvocationMetric metric : producerMetrics.values()) {
-      instanceProducerInvocationMetric = instanceProducerInvocationMetric.merge(metric);
-    }
-
-    this.instanceMetric = new InstanceMetric(systemMetric,
-        instanceConsumerInvocationMetric, instanceProducerInvocationMetric);
-  }
-
-  public Map<String, Number> toMap() {
-    Map<String, Number> metrics = new HashMap<>(instanceMetric.toMap());
-    for (ConsumerInvocationMetric metric : consumerMetrics.values()) {
-      metrics.putAll(metric.toMap());
-    }
-    for (ProducerInvocationMetric metric : producerMetrics.values()) {
-      metrics.putAll(metric.toMap());
-    }
-    return metrics;
-  }
-}
diff --git a/metrics/metrics-common/src/main/java/org/apache/servicecomb/metrics/common/SystemMetric.java b/metrics/metrics-common/src/main/java/org/apache/servicecomb/metrics/common/SystemMetric.java
deleted file mode 100644
index 001518d..0000000
--- a/metrics/metrics-common/src/main/java/org/apache/servicecomb/metrics/common/SystemMetric.java
+++ /dev/null
@@ -1,119 +0,0 @@
-/*
- * 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.servicecomb.metrics.common;
-
-import java.util.HashMap;
-import java.util.Map;
-
-import com.fasterxml.jackson.annotation.JsonProperty;
-
-public class SystemMetric {
-  private final double cpuLoad;
-
-  private final int cpuRunningThreads;
-
-  private final long heapInit;
-
-  private final long heapMax;
-
-  private final long heapCommit;
-
-  private final long heapUsed;
-
-  private final long nonHeapInit;
-
-  private final long nonHeapMax;
-
-  private final long nonHeapCommit;
-
-  private final long nonHeapUsed;
-
-  public double getCpuLoad() {
-    return cpuLoad;
-  }
-
-  public int getCpuRunningThreads() {
-    return cpuRunningThreads;
-  }
-
-  public long getHeapInit() {
-    return heapInit;
-  }
-
-  public long getHeapMax() {
-    return heapMax;
-  }
-
-  public long getHeapCommit() {
-    return heapCommit;
-  }
-
-  public long getHeapUsed() {
-    return heapUsed;
-  }
-
-  public long getNonHeapInit() {
-    return nonHeapInit;
-  }
-
-  public long getNonHeapMax() {
-    return nonHeapMax;
-  }
-
-  public long getNonHeapCommit() {
-    return nonHeapCommit;
-  }
-
-  public long getNonHeapUsed() {
-    return nonHeapUsed;
-  }
-
-  public SystemMetric(@JsonProperty("cpuLoad") double cpuLoad,
-      @JsonProperty("cpuRunningThreads") int cpuRunningThreads,
-      @JsonProperty("heapInit") long heapInit, @JsonProperty("heapMax") long heapMax,
-      @JsonProperty("heapCommit") long heapCommit, @JsonProperty("heapUsed") long heapUsed,
-      @JsonProperty("nonHeapInit") long nonHeapInit, @JsonProperty("nonHeapMax") long nonHeapMax,
-      @JsonProperty("nonHeapCommit") long nonHeapCommit, @JsonProperty("nonHeapUsed") long nonHeapUsed) {
-    this.cpuLoad = cpuLoad;
-    this.cpuRunningThreads = cpuRunningThreads;
-    this.heapInit = heapInit;
-    this.heapMax = heapMax;
-    this.heapCommit = heapCommit;
-    this.heapUsed = heapUsed;
-    this.nonHeapInit = nonHeapInit;
-    this.nonHeapMax = nonHeapMax;
-    this.nonHeapCommit = nonHeapCommit;
-    this.nonHeapUsed = nonHeapUsed;
-  }
-
-  public Map<String, Number> toMap() {
-    String prefix = "servicecomb.instance.system";
-    Map<String, Number> metrics = new HashMap<>();
-    metrics.put(prefix + ".cpu.load", cpuLoad);
-    metrics.put(prefix + ".cpu.runningThreads", cpuRunningThreads);
-    metrics.put(prefix + ".heap.init", heapInit);
-    metrics.put(prefix + ".heap.max", heapMax);
-    metrics.put(prefix + ".heap.commit", heapCommit);
-    metrics.put(prefix + ".heap.used", heapUsed);
-    metrics.put(prefix + ".nonHeap.init", nonHeapInit);
-    metrics.put(prefix + ".nonHeap.max", nonHeapMax);
-    metrics.put(prefix + ".nonHeap.commit", nonHeapCommit);
-    metrics.put(prefix + ".nonHeap.used", nonHeapUsed);
-    return metrics;
-  }
-}
diff --git a/metrics/metrics-common/src/main/java/org/apache/servicecomb/metrics/common/TimerMetric.java b/metrics/metrics-common/src/main/java/org/apache/servicecomb/metrics/common/TimerMetric.java
deleted file mode 100644
index 01f3b70..0000000
--- a/metrics/metrics-common/src/main/java/org/apache/servicecomb/metrics/common/TimerMetric.java
+++ /dev/null
@@ -1,99 +0,0 @@
-/*
- * 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.servicecomb.metrics.common;
-
-import java.util.HashMap;
-import java.util.Map;
-
-import com.fasterxml.jackson.annotation.JsonProperty;
-
-public class TimerMetric {
-  private final String prefix;
-
-  private final long total;
-
-  private final long count;
-
-  private final double average;
-
-  private final long min;
-
-  private final long max;
-
-  public long getTotal() {
-    return total;
-  }
-
-  public long getCount() {
-    return count;
-  }
-
-  public double getAverage() {
-    return average;
-  }
-
-  public long getMin() {
-    return min;
-  }
-
-  public long getMax() {
-    return max;
-  }
-
-  public TimerMetric(String prefix) {
-    this(prefix, 0, 0, 0, 0);
-  }
-
-  public TimerMetric(@JsonProperty("prefix") String prefix,
-      @JsonProperty("total") long total, @JsonProperty("count") long count,
-      @JsonProperty("min") long min, @JsonProperty("max") long max) {
-    this.prefix = prefix;
-    this.total = total;
-    this.count = count;
-    if (count != 0) {
-      this.average = total / (double) count;
-    } else {
-      this.average = 0;
-    }
-    this.min = min;
-    this.max = max;
-  }
-
-  public TimerMetric merge(TimerMetric metric) {
-    return new TimerMetric(this.prefix, this.total + metric.total, this.count + metric.count,
-        getMin(this.min, metric.min), getMax(this.max, metric.max));
-  }
-
-  private long getMin(long value1, long value2) {
-    return value1 == 0 || (value2 != 0 && value2 < value1) ? value2 : value1;
-  }
-
-  private long getMax(long value1, long value2) {
-    return value2 > value1 ? value2 : value1;
-  }
-
-  public Map<String, Number> toMap() {
-    Map<String, Number> metrics = new HashMap<>();
-    metrics.put(prefix + ".total", total);
-    metrics.put(prefix + ".count", count);
-    metrics.put(prefix + ".average", average);
-    metrics.put(prefix + ".max", max);
-    metrics.put(prefix + ".min", min);
-    return metrics;
-  }
-}
diff --git a/metrics/metrics-core/pom.xml b/metrics/metrics-core/pom.xml
index 4d943ca..3367c47 100644
--- a/metrics/metrics-core/pom.xml
+++ b/metrics/metrics-core/pom.xml
@@ -36,7 +36,7 @@
     </dependency>
     <dependency>
       <groupId>org.apache.servicecomb</groupId>
-      <artifactId>metrics-common</artifactId>
+      <artifactId>foundation-metrics</artifactId>
     </dependency>
     <dependency>
       <groupId>org.apache.servicecomb</groupId>
diff --git a/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/MetricsConfig.java b/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/MetricsConfig.java
index cbf6455..b903f15 100644
--- a/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/MetricsConfig.java
+++ b/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/MetricsConfig.java
@@ -19,6 +19,4 @@ package org.apache.servicecomb.metrics.core;
 
 public class MetricsConfig {
   public static final String METRICS_POLLING_TIME = "servicecomb.metrics.window_time";
-
-  public static final String METRICS_DIMENSION_STATUS_OUTPUT_LEVEL = "servicecomb.metrics.dimension.status.output_level";
 }
diff --git a/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/event/DefaultEventListenerManager.java b/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/event/DefaultEventListenerManager.java
index 6dc6df4..42aa024 100644
--- a/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/event/DefaultEventListenerManager.java
+++ b/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/event/DefaultEventListenerManager.java
@@ -19,31 +19,18 @@ package org.apache.servicecomb.metrics.core.event;
 
 import org.apache.servicecomb.foundation.common.event.EventListener;
 import org.apache.servicecomb.foundation.common.utils.EventUtils;
-import org.apache.servicecomb.metrics.common.MetricsDimension;
-import org.apache.servicecomb.metrics.core.MetricsConfig;
-import org.apache.servicecomb.metrics.core.event.dimension.StatusConvertorFactory;
 import org.apache.servicecomb.metrics.core.monitor.RegistryMonitor;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Component;
 
-import com.netflix.config.DynamicPropertyFactory;
-
 @Component
 public class DefaultEventListenerManager implements EventListenerManager {
 
   @Autowired
-  public DefaultEventListenerManager(RegistryMonitor registryMonitor, StatusConvertorFactory convertorFactory) {
-    this(registryMonitor, convertorFactory, DynamicPropertyFactory
-        .getInstance().getStringProperty(MetricsConfig.METRICS_DIMENSION_STATUS_OUTPUT_LEVEL,
-            MetricsDimension.DIMENSION_STATUS_OUTPUT_LEVEL_SUCCESS_FAILED).get());
-  }
-
-  public DefaultEventListenerManager(RegistryMonitor registryMonitor, StatusConvertorFactory convertorFactory,
-      String outputLevel) {
+  public DefaultEventListenerManager(RegistryMonitor registryMonitor) {
     this.registerEventListener(new InvocationStartedEventListener(registryMonitor));
     this.registerEventListener(new InvocationStartProcessingEventListener(registryMonitor));
-    this.registerEventListener(
-        new InvocationFinishedEventListener(registryMonitor, convertorFactory.getConvertor(outputLevel)));
+    this.registerEventListener(new InvocationFinishedEventListener(registryMonitor));
   }
 
   @Override
diff --git a/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/event/InvocationFinishedEventListener.java b/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/event/InvocationFinishedEventListener.java
index 5b886b6..948b631 100644
--- a/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/event/InvocationFinishedEventListener.java
+++ b/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/event/InvocationFinishedEventListener.java
@@ -20,8 +20,6 @@ package org.apache.servicecomb.metrics.core.event;
 import org.apache.servicecomb.core.metrics.InvocationFinishedEvent;
 import org.apache.servicecomb.foundation.common.event.Event;
 import org.apache.servicecomb.foundation.common.event.EventListener;
-import org.apache.servicecomb.metrics.common.MetricsDimension;
-import org.apache.servicecomb.metrics.core.event.dimension.StatusConvertor;
 import org.apache.servicecomb.metrics.core.monitor.ConsumerInvocationMonitor;
 import org.apache.servicecomb.metrics.core.monitor.ProducerInvocationMonitor;
 import org.apache.servicecomb.metrics.core.monitor.RegistryMonitor;
@@ -30,11 +28,8 @@ import org.apache.servicecomb.swagger.invocation.InvocationType;
 public class InvocationFinishedEventListener implements EventListener {
   private final RegistryMonitor registryMonitor;
 
-  private final StatusConvertor convertor;
-
-  public InvocationFinishedEventListener(RegistryMonitor registryMonitor, StatusConvertor convertor) {
+  public InvocationFinishedEventListener(RegistryMonitor registryMonitor) {
     this.registryMonitor = registryMonitor;
-    this.convertor = convertor;
   }
 
   @Override
@@ -45,16 +40,16 @@ public class InvocationFinishedEventListener implements EventListener {
   @Override
   public void process(Event data) {
     InvocationFinishedEvent event = (InvocationFinishedEvent) data;
-    String statusDimensionValue = convertor.convert(event.isSuccess(), event.getStatusCode());
     if (InvocationType.PRODUCER.equals(event.getInvocationType())) {
       ProducerInvocationMonitor monitor = registryMonitor.getProducerInvocationMonitor(event.getOperationName());
-      monitor.getExecutionTime().update(event.getProcessElapsedNanoTime());
-      monitor.getProducerLatency().update(event.getTotalElapsedNanoTime());
-      monitor.getProducerCall().increment(MetricsDimension.DIMENSION_STATUS, statusDimensionValue);
+      monitor.getLifeTimeInQueue().update(event.getInQueueNanoTime(), String.valueOf(event.getStatusCode()));
+      monitor.getExecutionTime().update(event.getProcessElapsedNanoTime(), String.valueOf(event.getStatusCode()));
+      monitor.getProducerLatency().update(event.getTotalElapsedNanoTime(), String.valueOf(event.getStatusCode()));
+      monitor.getProducerCall().increment(String.valueOf(event.getStatusCode()));
     } else {
       ConsumerInvocationMonitor monitor = registryMonitor.getConsumerInvocationMonitor(event.getOperationName());
-      monitor.getConsumerLatency().update(event.getTotalElapsedNanoTime());
-      monitor.getConsumerCall().increment(MetricsDimension.DIMENSION_STATUS, statusDimensionValue);
+      monitor.getConsumerLatency().update(event.getTotalElapsedNanoTime(), String.valueOf(event.getStatusCode()));
+      monitor.getConsumerCall().increment(String.valueOf(event.getStatusCode()));
     }
   }
 }
diff --git a/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/event/InvocationStartProcessingEventListener.java b/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/event/InvocationStartProcessingEventListener.java
index 3d83b2c..771810d 100644
--- a/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/event/InvocationStartProcessingEventListener.java
+++ b/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/event/InvocationStartProcessingEventListener.java
@@ -43,7 +43,6 @@ public class InvocationStartProcessingEventListener implements EventListener {
     if (InvocationType.PRODUCER.equals(event.getInvocationType())) {
       ProducerInvocationMonitor monitor = registryMonitor.getProducerInvocationMonitor(event.getOperationName());
       monitor.getWaitInQueue().increment(-1);
-      monitor.getLifeTimeInQueue().update(event.getInQueueNanoTime());
     }
   }
 }
diff --git a/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/event/InvocationStartedEventListener.java b/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/event/InvocationStartedEventListener.java
index c13d173..68defae 100644
--- a/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/event/InvocationStartedEventListener.java
+++ b/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/event/InvocationStartedEventListener.java
@@ -20,8 +20,6 @@ package org.apache.servicecomb.metrics.core.event;
 import org.apache.servicecomb.core.metrics.InvocationStartedEvent;
 import org.apache.servicecomb.foundation.common.event.Event;
 import org.apache.servicecomb.foundation.common.event.EventListener;
-import org.apache.servicecomb.metrics.common.MetricsDimension;
-import org.apache.servicecomb.metrics.core.monitor.ConsumerInvocationMonitor;
 import org.apache.servicecomb.metrics.core.monitor.ProducerInvocationMonitor;
 import org.apache.servicecomb.metrics.core.monitor.RegistryMonitor;
 import org.apache.servicecomb.swagger.invocation.InvocationType;
@@ -45,10 +43,6 @@ public class InvocationStartedEventListener implements EventListener {
     if (InvocationType.PRODUCER.equals(event.getInvocationType())) {
       ProducerInvocationMonitor monitor = registryMonitor.getProducerInvocationMonitor(event.getOperationName());
       monitor.getWaitInQueue().increment();
-      monitor.getProducerCall().increment(MetricsDimension.DIMENSION_STATUS, MetricsDimension.DIMENSION_STATUS_ALL);
-    } else {
-      ConsumerInvocationMonitor monitor = registryMonitor.getConsumerInvocationMonitor(event.getOperationName());
-      monitor.getConsumerCall().increment(MetricsDimension.DIMENSION_STATUS, MetricsDimension.DIMENSION_STATUS_ALL);
     }
   }
 }
diff --git a/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/event/dimension/CodeGroupStatusConvertor.java b/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/event/dimension/CodeGroupStatusConvertor.java
deleted file mode 100644
index 92b99d0..0000000
--- a/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/event/dimension/CodeGroupStatusConvertor.java
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * 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.servicecomb.metrics.core.event.dimension;
-
-import java.util.HashMap;
-import java.util.Map;
-
-import javax.ws.rs.core.Response.Status.Family;
-
-import org.apache.servicecomb.metrics.common.MetricsDimension;
-
-public class CodeGroupStatusConvertor implements StatusConvertor {
-
-  private final Map<Family, String> families;
-
-  public CodeGroupStatusConvertor() {
-    this.families = new HashMap<>();
-    this.families.put(Family.INFORMATIONAL, MetricsDimension.DIMENSION_STATUS_CODE_GROUP_1XX);
-    this.families.put(Family.SUCCESSFUL, MetricsDimension.DIMENSION_STATUS_CODE_GROUP_2XX);
-    this.families.put(Family.REDIRECTION, MetricsDimension.DIMENSION_STATUS_CODE_GROUP_3XX);
-    this.families.put(Family.CLIENT_ERROR, MetricsDimension.DIMENSION_STATUS_CODE_GROUP_4XX);
-    this.families.put(Family.SERVER_ERROR, MetricsDimension.DIMENSION_STATUS_CODE_GROUP_5XX);
-    this.families.put(Family.OTHER, MetricsDimension.DIMENSION_STATUS_CODE_GROUP_OTHER);
-  }
-
-  @Override
-  public String convert(boolean success, int statusCode) {
-    return families.get(Family.familyOf(statusCode));
-  }
-}
diff --git a/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/event/dimension/CodeStatusConvertor.java b/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/event/dimension/CodeStatusConvertor.java
deleted file mode 100644
index b01f5da..0000000
--- a/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/event/dimension/CodeStatusConvertor.java
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * 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.servicecomb.metrics.core.event.dimension;
-
-public class CodeStatusConvertor implements StatusConvertor {
-  @Override
-  public String convert(boolean success, int statusCode) {
-    return String.valueOf(statusCode);
-  }
-}
diff --git a/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/event/dimension/StatusConvertor.java b/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/event/dimension/StatusConvertor.java
deleted file mode 100644
index 17023b6..0000000
--- a/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/event/dimension/StatusConvertor.java
+++ /dev/null
@@ -1,22 +0,0 @@
-/*
- * 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.servicecomb.metrics.core.event.dimension;
-
-public interface StatusConvertor {
-  String convert(boolean success, int statusCode);
-}
diff --git a/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/event/dimension/StatusConvertorFactory.java b/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/event/dimension/StatusConvertorFactory.java
deleted file mode 100644
index 369cda4..0000000
--- a/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/event/dimension/StatusConvertorFactory.java
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * 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.servicecomb.metrics.core.event.dimension;
-
-import java.util.HashMap;
-import java.util.Map;
-import java.util.function.Supplier;
-
-import org.apache.servicecomb.metrics.common.MetricsDimension;
-import org.apache.servicecomb.metrics.core.MetricsConfig;
-import org.slf4j.LoggerFactory;
-import org.springframework.stereotype.Component;
-
-@Component
-public class StatusConvertorFactory {
-
-  private final Map<String, Supplier<StatusConvertor>> suppliers;
-
-  public StatusConvertorFactory() {
-    this.suppliers = new HashMap<>();
-    this.suppliers.put(MetricsDimension.DIMENSION_STATUS_OUTPUT_LEVEL_CODE, CodeStatusConvertor::new);
-    this.suppliers.put(MetricsDimension.DIMENSION_STATUS_OUTPUT_LEVEL_CODE_GROUP, CodeGroupStatusConvertor::new);
-    this.suppliers
-        .put(MetricsDimension.DIMENSION_STATUS_OUTPUT_LEVEL_SUCCESS_FAILED, SuccessFailedStatusConvertor::new);
-  }
-
-  public StatusConvertor getConvertor(String outputLevel) {
-    if (suppliers.containsKey(outputLevel)) {
-      return suppliers.get(outputLevel).get();
-    }
-    LoggerFactory.getLogger(StatusConvertorFactory.class).error("unknown config value of " +
-        MetricsConfig.METRICS_DIMENSION_STATUS_OUTPUT_LEVEL + " : " + outputLevel
-        + ", use default level : " +
-        MetricsDimension.DIMENSION_STATUS_OUTPUT_LEVEL_SUCCESS_FAILED + " replace it");
-    //return default
-    return suppliers.get(MetricsDimension.DIMENSION_STATUS_OUTPUT_LEVEL_SUCCESS_FAILED).get();
-  }
-}
diff --git a/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/event/dimension/SuccessFailedStatusConvertor.java b/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/event/dimension/SuccessFailedStatusConvertor.java
deleted file mode 100644
index c2cf998..0000000
--- a/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/event/dimension/SuccessFailedStatusConvertor.java
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * 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.servicecomb.metrics.core.event.dimension;
-
-import org.apache.servicecomb.metrics.common.MetricsDimension;
-
-public class SuccessFailedStatusConvertor implements StatusConvertor {
-  @Override
-  public String convert(boolean success, int statusCode) {
-    return success ? MetricsDimension.DIMENSION_STATUS_SUCCESS_FAILED_SUCCESS
-        : MetricsDimension.DIMENSION_STATUS_SUCCESS_FAILED_FAILED;
-  }
-}
diff --git a/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/health/DefaultMicroserviceHealthChecker.java b/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/health/DefaultMicroserviceHealthChecker.java
index 301bf15..d452591 100644
--- a/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/health/DefaultMicroserviceHealthChecker.java
+++ b/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/health/DefaultMicroserviceHealthChecker.java
@@ -20,9 +20,9 @@ package org.apache.servicecomb.metrics.core.health;
 import javax.ws.rs.core.Response.Status;
 
 import org.apache.servicecomb.foundation.common.utils.JsonUtils;
-import org.apache.servicecomb.metrics.common.DefaultHealthCheckExtraData;
-import org.apache.servicecomb.metrics.common.HealthCheckResult;
-import org.apache.servicecomb.metrics.common.HealthChecker;
+import org.apache.servicecomb.foundation.metrics.publish.DefaultHealthCheckExtraData;
+import org.apache.servicecomb.foundation.metrics.publish.HealthCheckResult;
+import org.apache.servicecomb.foundation.metrics.publish.HealthChecker;
 import org.apache.servicecomb.serviceregistry.RegistryUtils;
 import org.apache.servicecomb.serviceregistry.api.registry.Microservice;
 import org.apache.servicecomb.serviceregistry.api.registry.MicroserviceInstance;
diff --git a/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/monitor/CallMonitor.java b/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/monitor/CallMonitor.java
index 2e61440..93a3903 100644
--- a/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/monitor/CallMonitor.java
+++ b/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/monitor/CallMonitor.java
@@ -17,79 +17,76 @@
 
 package org.apache.servicecomb.metrics.core.monitor;
 
-import java.util.ArrayList;
-import java.util.List;
+import java.util.HashMap;
 import java.util.Map;
 
 import org.apache.servicecomb.foundation.common.concurrent.ConcurrentHashMapEx;
-import org.apache.servicecomb.metrics.common.CallMetric;
-import org.apache.servicecomb.metrics.common.DoubleMetricValue;
-import org.apache.servicecomb.metrics.common.LongMetricValue;
-import org.apache.servicecomb.metrics.common.MetricsDimension;
+import org.apache.servicecomb.foundation.metrics.MetricsConst;
 import org.apache.servicecomb.metrics.core.utils.MonitorUtils;
 
 import com.netflix.servo.monitor.BasicCounter;
 import com.netflix.servo.monitor.MonitorConfig;
 import com.netflix.servo.monitor.StepCounter;
+import com.netflix.servo.tag.Tags;
 
 public class CallMonitor {
-  private final String prefix;
+  private final Map<String, StatusCounter> statusCounters;
 
-  private final Map<String, Map<String, DimensionCounter>> dimensionCounters;
+  private final String operation;
 
-  public CallMonitor(String prefix) {
-    this.prefix = prefix;
-    this.dimensionCounters = new ConcurrentHashMapEx<>();
-    this.dimensionCounters.put(MetricsDimension.DIMENSION_STATUS, new ConcurrentHashMapEx<>());
+  private final String stage;
+
+  private final String role;
+
+  public CallMonitor(String operation, String stage, String role) {
+    this.operation = operation;
+    this.stage = stage;
+    this.role = role;
+
+    this.statusCounters = new ConcurrentHashMapEx<>();
   }
 
-  public void increment(String dimensionKey, String... dimensionValues) {
-    for (String dimensionValue : dimensionValues) {
-      DimensionCounter counter = dimensionCounters.get(dimensionKey)
-          .computeIfAbsent(dimensionValue, d -> new DimensionCounter(
-              new BasicCounter(MonitorConfig.builder(prefix + ".total").withTag(dimensionKey, dimensionValue).build()),
-              new StepCounter(MonitorConfig.builder(prefix + ".tps").withTag(dimensionKey, dimensionValue).build())));
-      counter.increment();
-    }
+  public void increment(String statusCode) {
+    StatusCounter counter = statusCounters
+        .computeIfAbsent(statusCode, d -> new StatusCounter(operation, stage, role, statusCode));
+    counter.increment();
   }
 
-  public CallMetric toMetric(int windowTimeIndex) {
-    List<LongMetricValue> totalValues = new ArrayList<>();
-    List<DoubleMetricValue> tpsValues = new ArrayList<>();
-    for (Map<String, DimensionCounter> dimensionCounter : dimensionCounters.values()) {
-      for (DimensionCounter counter : dimensionCounter.values()) {
-        totalValues.add(new LongMetricValue(counter.getTotal().getValue(windowTimeIndex).longValue(),
-            MonitorUtils.convertTags(counter.getTotal())));
-        tpsValues.add(
-            new DoubleMetricValue(MonitorUtils.adjustValue(counter.getTps().getValue(windowTimeIndex).doubleValue()),
-                MonitorUtils.convertTags(counter.getTps())));
-      }
+  public Map<String, Double> measure(int windowTimeIndex) {
+    Map<String, Double> metrics = new HashMap<>();
+    for (StatusCounter counter : statusCounters.values()) {
+      metrics.putAll(counter.measure(windowTimeIndex));
     }
-
-    return new CallMetric(this.prefix, totalValues, tpsValues);
+    return metrics;
   }
 
-  class DimensionCounter {
-    private final BasicCounter total;
+  class StatusCounter {
+    private final BasicCounter totalCount;
 
     private final StepCounter tps;
 
-    public BasicCounter getTotal() {
-      return total;
-    }
-
-    public StepCounter getTps() {
-      return tps;
-    }
+    public StatusCounter(String operation, String stage, String role, String statusCode) {
+      MonitorConfig config = MonitorConfig.builder(MetricsConst.SERVICECOMB_INVOCATION)
+          .withTag(MetricsConst.TAG_STATUS, statusCode).withTag(MetricsConst.TAG_OPERATION, operation)
+          .withTag(MetricsConst.TAG_STAGE, stage).withTag(MetricsConst.TAG_ROLE, role).build();
 
-    public DimensionCounter(BasicCounter total, StepCounter tps) {
-      this.total = total;
-      this.tps = tps;
+      this.totalCount = new BasicCounter(
+          config.withAdditionalTag(Tags.newTag(MetricsConst.TAG_STATISTIC, "totalCount")));
+      this.tps = new StepCounter(config.withAdditionalTag(Tags.newTag(MetricsConst.TAG_STATISTIC, "tps")));
     }
 
     public void increment() {
-      total.increment();
+      totalCount.increment();
       tps.increment();
     }
+
+    public Map<String, Double> measure(int windowTimeIndex) {
+      Map<String, Double> measurements = new HashMap<>();
+      measurements.put(MonitorUtils.getMonitorName(this.totalCount.getConfig()),
+          this.totalCount.getValue(windowTimeIndex).doubleValue());
+      measurements.put(MonitorUtils.getMonitorName(this.tps.getConfig()),
+          this.tps.getValue(windowTimeIndex).doubleValue());
+      return measurements;
+    }
   }
 }
diff --git a/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/monitor/ConsumerInvocationMonitor.java b/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/monitor/ConsumerInvocationMonitor.java
index 1f2f247..eb18198 100644
--- a/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/monitor/ConsumerInvocationMonitor.java
+++ b/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/monitor/ConsumerInvocationMonitor.java
@@ -17,11 +17,12 @@
 
 package org.apache.servicecomb.metrics.core.monitor;
 
+import java.util.HashMap;
+import java.util.Map;
 
-import org.apache.servicecomb.metrics.common.ConsumerInvocationMetric;
-import org.apache.servicecomb.metrics.common.MetricsConst;
+import org.apache.servicecomb.foundation.metrics.MetricsConst;
 
-public class ConsumerInvocationMonitor extends InvocationMonitor {
+public class ConsumerInvocationMonitor {
   private final TimerMonitor consumerLatency;
 
   private final CallMonitor consumerCall;
@@ -34,14 +35,15 @@ public class ConsumerInvocationMonitor extends InvocationMonitor {
     return consumerCall;
   }
 
-  public ConsumerInvocationMonitor(String operationName) {
-    super(operationName, String.format(MetricsConst.CONSUMER_PREFIX_TEMPLATE, operationName));
-    this.consumerLatency = new TimerMonitor(this.getPrefix() + ".consumerLatency");
-    this.consumerCall = new CallMonitor(this.getPrefix() + ".consumerCall");
+  public ConsumerInvocationMonitor(String operation) {
+    this.consumerLatency = new TimerMonitor(operation, MetricsConst.STAGE_WHOLE, MetricsConst.ROLE_CONSUMER);
+    this.consumerCall = new CallMonitor(operation, MetricsConst.STAGE_WHOLE, MetricsConst.ROLE_CONSUMER);
   }
 
-  public ConsumerInvocationMetric toMetric(int windowTimeIndex) {
-    return new ConsumerInvocationMetric(this.getOperationName(), this.getPrefix(),
-        consumerLatency.toMetric(windowTimeIndex), consumerCall.toMetric(windowTimeIndex));
+  public Map<String, Double> measure(int windowTimeIndex, boolean calculateLatency) {
+    Map<String, Double> measurements = new HashMap<>();
+    measurements.putAll(consumerCall.measure(windowTimeIndex));
+    measurements.putAll(consumerLatency.measure(windowTimeIndex, calculateLatency));
+    return measurements;
   }
 }
diff --git a/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/monitor/DefaultSystemMonitor.java b/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/monitor/DefaultSystemMonitor.java
index 5977521..e38a143 100644
--- a/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/monitor/DefaultSystemMonitor.java
+++ b/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/monitor/DefaultSystemMonitor.java
@@ -21,8 +21,10 @@ import java.lang.management.ManagementFactory;
 import java.lang.management.MemoryMXBean;
 import java.lang.management.OperatingSystemMXBean;
 import java.lang.management.ThreadMXBean;
+import java.util.HashMap;
+import java.util.Map;
 
-import org.apache.servicecomb.metrics.common.SystemMetric;
+import org.apache.servicecomb.foundation.metrics.MetricsConst;
 import org.springframework.stereotype.Component;
 
 @Component
@@ -97,8 +99,28 @@ public class DefaultSystemMonitor implements SystemMonitor {
   }
 
   @Override
-  public SystemMetric toMetric() {
-    return new SystemMetric(getCpuLoad(), getCpuRunningThreads(), getHeapInit(), getHeapMax(), getHeapCommit(),
-        getHeapUsed(), getNonHeapInit(), getNonHeapMax(), getNonHeapCommit(), getNonHeapUsed());
+  public Map<String, Double> measure() {
+    Map<String, Double> measurements = new HashMap<>();
+    measurements.put(String.format(MetricsConst.JVM + "(%s=%s,%s=%s)", MetricsConst.TAG_STATISTIC, "gauge",
+        MetricsConst.TAG_NAME, "cpuLoad"), getCpuLoad());
+    measurements.put(String.format(MetricsConst.JVM + "(%s=%s,%s=%s)", MetricsConst.TAG_STATISTIC, "gauge",
+        MetricsConst.TAG_NAME, "cpuRunningThreads"), (double) getCpuRunningThreads());
+    measurements.put(String.format(MetricsConst.JVM + "(%s=%s,%s=%s)", MetricsConst.TAG_STATISTIC, "gauge",
+        MetricsConst.TAG_NAME, "heapInit"), (double) getHeapInit());
+    measurements.put(String.format(MetricsConst.JVM + "(%s=%s,%s=%s)", MetricsConst.TAG_STATISTIC, "gauge",
+        MetricsConst.TAG_NAME, "heapMax"), (double) getHeapMax());
+    measurements.put(String.format(MetricsConst.JVM + "(%s=%s,%s=%s)", MetricsConst.TAG_STATISTIC, "gauge",
+        MetricsConst.TAG_NAME, "heapCommit"), (double) getHeapCommit());
+    measurements.put(String.format(MetricsConst.JVM + "(%s=%s,%s=%s)", MetricsConst.TAG_STATISTIC, "gauge",
+        MetricsConst.TAG_NAME, "heapUsed"), (double) getHeapUsed());
+    measurements.put(String.format(MetricsConst.JVM + "(%s=%s,%s=%s)", MetricsConst.TAG_STATISTIC, "gauge",
+        MetricsConst.TAG_NAME, "nonHeapInit"), (double) getNonHeapInit());
+    measurements.put(String.format(MetricsConst.JVM + "(%s=%s,%s=%s)", MetricsConst.TAG_STATISTIC, "gauge",
+        MetricsConst.TAG_NAME, "nonHeapMax"), (double) getNonHeapMax());
+    measurements.put(String.format(MetricsConst.JVM + "(%s=%s,%s=%s)", MetricsConst.TAG_STATISTIC, "gauge",
+        MetricsConst.TAG_NAME, "nonHeapCommit"), (double) getNonHeapCommit());
+    measurements.put(String.format(MetricsConst.JVM + "(%s=%s,%s=%s)", MetricsConst.TAG_STATISTIC, "gauge",
+        MetricsConst.TAG_NAME, "nonHeapUsed"), (double) getNonHeapUsed());
+    return measurements;
   }
 }
diff --git a/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/monitor/InvocationMonitor.java b/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/monitor/InvocationMonitor.java
deleted file mode 100644
index 229aa22..0000000
--- a/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/monitor/InvocationMonitor.java
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * 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.servicecomb.metrics.core.monitor;
-
-public class InvocationMonitor {
-  private final String operationName;
-
-  private final String prefix;
-
-  public String getOperationName() {
-    return operationName;
-  }
-
-  public String getPrefix() {
-    return prefix;
-  }
-
-  public InvocationMonitor(String operationName, String prefix) {
-    this.operationName = operationName;
-    this.prefix = prefix;
-  }
-}
diff --git a/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/monitor/ProducerInvocationMonitor.java b/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/monitor/ProducerInvocationMonitor.java
index 9c77ec8..cb75e57 100644
--- a/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/monitor/ProducerInvocationMonitor.java
+++ b/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/monitor/ProducerInvocationMonitor.java
@@ -17,13 +17,16 @@
 
 package org.apache.servicecomb.metrics.core.monitor;
 
-import org.apache.servicecomb.metrics.common.MetricsConst;
-import org.apache.servicecomb.metrics.common.ProducerInvocationMetric;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.servicecomb.foundation.metrics.MetricsConst;
+import org.apache.servicecomb.metrics.core.utils.MonitorUtils;
 
 import com.netflix.servo.monitor.BasicCounter;
 import com.netflix.servo.monitor.MonitorConfig;
 
-public class ProducerInvocationMonitor extends InvocationMonitor {
+public class ProducerInvocationMonitor {
   private final BasicCounter waitInQueue;
 
   private final TimerMonitor lifeTimeInQueue;
@@ -54,21 +57,28 @@ public class ProducerInvocationMonitor extends InvocationMonitor {
     return producerCall;
   }
 
-  public ProducerInvocationMonitor(String operationName) {
-    super(operationName, String.format(MetricsConst.PRODUCER_PREFIX_TEMPLATE, operationName));
-    this.waitInQueue = new BasicCounter(MonitorConfig.builder(this.getPrefix() + ".waitInQueue.count").build());
-    this.lifeTimeInQueue = new TimerMonitor(this.getPrefix() + ".lifeTimeInQueue");
-    this.executionTime = new TimerMonitor(this.getPrefix() + ".executionTime");
-    this.producerLatency = new TimerMonitor(this.getPrefix() + ".producerLatency");
-    this.producerCall = new CallMonitor(this.getPrefix() + ".producerCall");
+  public ProducerInvocationMonitor(String operation) {
+    this.waitInQueue = new BasicCounter(MonitorConfig.builder(MetricsConst.SERVICECOMB_INVOCATION)
+        .withTag(MetricsConst.TAG_OPERATION, operation)
+        .withTag(MetricsConst.TAG_STAGE, MetricsConst.STAGE_QUEUE)
+        .withTag(MetricsConst.TAG_ROLE, MetricsConst.ROLE_PRODUCER)
+        .withTag(MetricsConst.TAG_STATISTIC, "waitInQueue")
+        .build());
+
+    this.lifeTimeInQueue = new TimerMonitor(operation, MetricsConst.STAGE_QUEUE, MetricsConst.ROLE_PRODUCER);
+    this.executionTime = new TimerMonitor(operation, MetricsConst.STAGE_EXECUTION, MetricsConst.ROLE_PRODUCER);
+    this.producerLatency = new TimerMonitor(operation, MetricsConst.STAGE_WHOLE, MetricsConst.ROLE_PRODUCER);
+    this.producerCall = new CallMonitor(operation, MetricsConst.STAGE_WHOLE, MetricsConst.ROLE_PRODUCER);
   }
 
-  public ProducerInvocationMetric toMetric(int windowTimeIndex) {
-    return new ProducerInvocationMetric(this.getOperationName(), this.getPrefix(),
-        this.getWaitInQueue().getValue(windowTimeIndex).longValue(),
-        lifeTimeInQueue.toMetric(windowTimeIndex),
-        executionTime.toMetric(windowTimeIndex),
-        producerLatency.toMetric(windowTimeIndex),
-        producerCall.toMetric(windowTimeIndex));
+  public Map<String, Double> measure(int windowTimeIndex, boolean calculateLatency) {
+    Map<String, Double> measurements = new HashMap<>();
+    measurements.put(MonitorUtils.getMonitorName(waitInQueue.getConfig()),
+        waitInQueue.getValue(windowTimeIndex).doubleValue());
+    measurements.putAll(lifeTimeInQueue.measure(windowTimeIndex, calculateLatency));
+    measurements.putAll(executionTime.measure(windowTimeIndex, calculateLatency));
+    measurements.putAll(producerLatency.measure(windowTimeIndex, calculateLatency));
+    measurements.putAll(producerCall.measure(windowTimeIndex));
+    return measurements;
   }
 }
diff --git a/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/monitor/RegistryMonitor.java b/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/monitor/RegistryMonitor.java
index 78be282..1cbaae4 100644
--- a/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/monitor/RegistryMonitor.java
+++ b/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/monitor/RegistryMonitor.java
@@ -21,9 +21,6 @@ import java.util.HashMap;
 import java.util.Map;
 
 import org.apache.servicecomb.foundation.common.concurrent.ConcurrentHashMapEx;
-import org.apache.servicecomb.metrics.common.ConsumerInvocationMetric;
-import org.apache.servicecomb.metrics.common.ProducerInvocationMetric;
-import org.apache.servicecomb.metrics.common.RegistryMetric;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Component;
 
@@ -51,16 +48,14 @@ public class RegistryMonitor {
     return producerInvocationMonitors.computeIfAbsent(operationName, i -> new ProducerInvocationMonitor(operationName));
   }
 
-  public RegistryMetric toRegistryMetric(int windowTimeIndex) {
-    Map<String, ConsumerInvocationMetric> consumerInvocationMetrics = new HashMap<>();
+  public Map<String, Double> measure(int windowTimeIndex, boolean calculateLatency) {
+    Map<String, Double> measurements = new HashMap<>(systemMonitor.measure());
     for (ConsumerInvocationMonitor monitor : this.consumerInvocationMonitors.values()) {
-      consumerInvocationMetrics.put(monitor.getOperationName(), monitor.toMetric(windowTimeIndex));
+      measurements.putAll(monitor.measure(windowTimeIndex, calculateLatency));
     }
-    Map<String, ProducerInvocationMetric> producerInvocationMetrics = new HashMap<>();
     for (ProducerInvocationMonitor monitor : this.producerInvocationMonitors.values()) {
-      producerInvocationMetrics.put(monitor.getOperationName(), monitor.toMetric(windowTimeIndex));
+      measurements.putAll(monitor.measure(windowTimeIndex, calculateLatency));
     }
-
-    return new RegistryMetric(systemMonitor.toMetric(), consumerInvocationMetrics, producerInvocationMetrics);
+    return measurements;
   }
 }
diff --git a/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/monitor/SystemMonitor.java b/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/monitor/SystemMonitor.java
index 43bc165..098d685 100644
--- a/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/monitor/SystemMonitor.java
+++ b/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/monitor/SystemMonitor.java
@@ -17,7 +17,7 @@
 
 package org.apache.servicecomb.metrics.core.monitor;
 
-import org.apache.servicecomb.metrics.common.SystemMetric;
+import java.util.Map;
 
 public interface SystemMonitor {
   double getCpuLoad();
@@ -40,5 +40,5 @@ public interface SystemMonitor {
 
   long getNonHeapUsed();
 
-  SystemMetric toMetric();
+  Map<String, Double> measure();
 }
diff --git a/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/monitor/TimerMonitor.java b/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/monitor/TimerMonitor.java
index a88a604..6c63bfe 100644
--- a/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/monitor/TimerMonitor.java
+++ b/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/monitor/TimerMonitor.java
@@ -17,50 +17,92 @@
 
 package org.apache.servicecomb.metrics.core.monitor;
 
-import org.apache.servicecomb.metrics.common.TimerMetric;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.servicecomb.foundation.common.concurrent.ConcurrentHashMapEx;
+import org.apache.servicecomb.foundation.metrics.MetricsConst;
 import org.apache.servicecomb.metrics.core.utils.MonitorUtils;
 
 import com.netflix.servo.monitor.MaxGauge;
-import com.netflix.servo.monitor.MinGauge;
 import com.netflix.servo.monitor.MonitorConfig;
 import com.netflix.servo.monitor.StepCounter;
+import com.netflix.servo.tag.Tags;
 
 public class TimerMonitor {
-  private final String prefix;
+  private final Map<String, StatusCounter> statusCounters;
 
-  //nanosecond sum
-  private final StepCounter total;
+  private final String operation;
 
-  private final StepCounter count;
+  private final String stage;
 
-  //nanosecond min
-  private final MinGauge min;
+  private final String role;
 
-  //nanosecond max
-  private final MaxGauge max;
+  public TimerMonitor(String operation, String stage, String role) {
+    this.operation = operation;
+    this.stage = stage;
+    this.role = role;
 
-  public void update(long value) {
-    if (value > 0) {
-      total.increment(value);
-      count.increment();
-      max.update(value);
-      min.update(value);
-    }
+    this.statusCounters = new ConcurrentHashMapEx<>();
+  }
+
+  public void update(long value, String statusCode) {
+    StatusCounter counter = statusCounters
+        .computeIfAbsent(statusCode, d -> new StatusCounter(operation, stage, role, statusCode));
+    counter.update(value);
   }
 
-  public TimerMonitor(String prefix) {
-    this.prefix = prefix;
-    total = new StepCounter(MonitorConfig.builder(prefix + ".total").build());
-    count = new StepCounter(MonitorConfig.builder(prefix + ".count").build());
-    min = new MinGauge(MonitorConfig.builder(prefix + ".min").build());
-    max = new MaxGauge(MonitorConfig.builder(prefix + ".max").build());
+  public Map<String, Double> measure(int windowTimeIndex, boolean calculateLatency) {
+    Map<String, Double> measurements = new HashMap<>();
+    for (StatusCounter counter : statusCounters.values()) {
+      measurements.putAll(counter.measure(windowTimeIndex, calculateLatency));
+    }
+    return measurements;
   }
 
-  public TimerMetric toMetric(int windowTimeIndex) {
-    return new TimerMetric(this.prefix,
-        MonitorUtils.convertNanosecondToMillisecond(MonitorUtils.adjustValue(total.getCount(windowTimeIndex))),
-        MonitorUtils.adjustValue(count.getCount(windowTimeIndex)),
-        MonitorUtils.convertNanosecondToMillisecond(MonitorUtils.adjustValue(min.getValue(windowTimeIndex))),
-        MonitorUtils.convertNanosecondToMillisecond(MonitorUtils.adjustValue(max.getValue(windowTimeIndex))));
+  class StatusCounter {
+    //nanosecond sum
+    private final StepCounter totalTime;
+
+    private final StepCounter count;
+
+    //nanosecond max
+    private final MaxGauge max;
+
+    private final MonitorConfig latency;
+
+    public StatusCounter(String operation, String stage, String role, String statusCode) {
+      MonitorConfig config = MonitorConfig.builder(MetricsConst.SERVICECOMB_INVOCATION)
+          .withTag(MetricsConst.TAG_STATUS, statusCode).withTag(MetricsConst.TAG_OPERATION, operation)
+          .withTag(MetricsConst.TAG_STAGE, stage).withTag(MetricsConst.TAG_ROLE, role).build();
+
+      this.latency = config.withAdditionalTag(Tags.newTag(MetricsConst.TAG_STATISTIC, "latency"));
+      this.totalTime = new StepCounter(config.withAdditionalTag(Tags.newTag(MetricsConst.TAG_STATISTIC, "totalTime")));
+      this.count = new StepCounter(config.withAdditionalTag(Tags.newTag(MetricsConst.TAG_STATISTIC, "count")));
+      this.max = new MaxGauge(config.withAdditionalTag(Tags.newTag(MetricsConst.TAG_STATISTIC, "max")));
+    }
+
+    public void update(long value) {
+      if (value > 0) {
+        totalTime.increment(value);
+        count.increment();
+        max.update(value);
+      }
+    }
+
+    public Map<String, Double> measure(int windowTimeIndex, boolean calculateLatency) {
+      Map<String, Double> measurements = new HashMap<>();
+      double totalTime = (double) MonitorUtils.convertNanosecondToMillisecond(
+          MonitorUtils.adjustValue(this.totalTime.getCount(windowTimeIndex)));
+      double count = (double) MonitorUtils.adjustValue(this.count.getCount(windowTimeIndex));
+      measurements.put(MonitorUtils.getMonitorName(this.totalTime.getConfig()), totalTime);
+      measurements.put(MonitorUtils.getMonitorName(this.count.getConfig()), count);
+      measurements.put(MonitorUtils.getMonitorName(this.max.getConfig()), (double) MonitorUtils
+          .convertNanosecondToMillisecond(MonitorUtils.adjustValue(this.max.getValue(windowTimeIndex))));
+      if (calculateLatency) {
+        measurements.put(MonitorUtils.getMonitorName(latency), totalTime / count);
+      }
+      return measurements;
+    }
   }
 }
diff --git a/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/publish/DataSource.java b/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/publish/DataSource.java
index 0f5d889..89bf40e 100644
--- a/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/publish/DataSource.java
+++ b/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/publish/DataSource.java
@@ -18,8 +18,7 @@
 package org.apache.servicecomb.metrics.core.publish;
 
 import java.util.List;
-
-import org.apache.servicecomb.metrics.common.RegistryMetric;
+import java.util.Map;
 
 public interface DataSource {
 
@@ -32,13 +31,16 @@ public interface DataSource {
    Max & Min -> the max value or min value in a centain time
    Average -> average value, the simplest algorithm is f = sum / count
    Rate -> like TPS,algorithm is f = sum / second
-  
+
    Will be return "servicecomb.metrics.window_time" setting in microservice.yaml
    */
   List<Long> getAppliedWindowTime();
 
-  //same as getRegistryMetric({first setting windowTime})
-  RegistryMetric getRegistryMetric();
+  //same as call measure(getAppliedWindowTime().get(0),false)
+  Map<String, Double> measure();
+
+  //same as call measure(windowTime,false)
+  Map<String, Double> measure(long windowTime);
 
   /**
    * windowTime usage example:
@@ -50,13 +52,14 @@ public interface DataSource {
    * 0----------1----------2----------3----------  <-time line (second)
    *   100,200    300,400                          <-value record
    *
-   *                 ↑ getRegistryMetric(1000) will return max=200 min=100 total=300
-   *                   getRegistryMetric(2000) will return max=0 min=0 total=0
-   *                             ↑ getRegistryMetric(1000) will return max=300 min=400 total=700
-   *                               getRegistryMetric(2000) will return max=400 min=100 total=1000
+   *                 ↑ measure(1000) will return max=200 min=100 total=300
+   *                   measure(2000) will return max=0 min=0 total=0
+   *                             ↑ measure(1000) will return max=300 min=400 total=700
+   *                               measure(2000) will return max=400 min=100 total=1000
    *
    * @param windowTime getAppliedWindowTime() item
-   * @return RegistryMetric
+   * @param calculateLatency need output latency
+   * @return Map<String , Double>
    */
-  RegistryMetric getRegistryMetric(long windowTime);
+  Map<String, Double> measure(long windowTime, boolean calculateLatency);
 }
diff --git a/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/publish/DefaultDataSource.java b/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/publish/DefaultDataSource.java
index 6bb3357..661cddb 100644
--- a/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/publish/DefaultDataSource.java
+++ b/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/publish/DefaultDataSource.java
@@ -26,15 +26,14 @@ import java.util.Map;
 import java.util.Set;
 
 import org.apache.servicecomb.foundation.common.exceptions.ServiceCombException;
-import org.apache.servicecomb.metrics.common.RegistryMetric;
 import org.apache.servicecomb.metrics.core.MetricsConfig;
 import org.apache.servicecomb.metrics.core.monitor.RegistryMonitor;
 import org.apache.servicecomb.swagger.invocation.exception.InvocationException;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Component;
 
+import com.google.common.collect.Lists;
 import com.netflix.config.DynamicPropertyFactory;
-import com.netflix.servo.monitor.Pollers;
 import com.netflix.servo.util.Strings;
 
 @Component
@@ -52,9 +51,9 @@ public class DefaultDataSource implements DataSource {
   public DefaultDataSource(RegistryMonitor registryMonitor, String pollingSettings) {
     this.registryMonitor = registryMonitor;
 
-    String[] singlePollingSettings = pollingSettings.split(",");
+    String[] pollingSettingStrings = pollingSettings.split(",");
     Set<Long> parsePollingSettings = new HashSet<>();
-    for (String singlePollingSetting : singlePollingSettings) {
+    for (String singlePollingSetting : pollingSettingStrings) {
       try {
         long settingValue = Long.parseLong(singlePollingSetting);
         if (settingValue > 0) {
@@ -67,32 +66,37 @@ public class DefaultDataSource implements DataSource {
         throw new ServiceCombException("bad format servicecomb.metrics.window_time", e);
       }
     }
-    String finalPollingSettings = Strings.join(",", parsePollingSettings.iterator());
-    System.getProperties().setProperty("servo.pollers", finalPollingSettings);
-    List<Long> appliedWindowTimes = getAppliedWindowTime();
-    for (int i = 0; i < appliedWindowTimes.size(); i++) {
-      this.appliedWindowTimes.put(appliedWindowTimes.get(i), i);
+
+    List<Long> sortedPollingSettings = Lists.newArrayList(parsePollingSettings);
+    System.getProperties().setProperty("servo.pollers", Strings.join(",", sortedPollingSettings.iterator()));
+    for (int i = 0; i < sortedPollingSettings.size(); i++) {
+      this.appliedWindowTimes.put(sortedPollingSettings.get(i), i);
     }
   }
 
   @Override
-  public RegistryMetric getRegistryMetric() {
-    return getRegistryMetric(getAppliedWindowTime().get(0));
+  public List<Long> getAppliedWindowTime() {
+    return Lists.newArrayList(appliedWindowTimes.keySet());
+  }
+
+  @Override
+  public Map<String, Double> measure() {
+    return measure(getAppliedWindowTime().get(0));
+  }
+
+  @Override
+  public Map<String, Double> measure(long windowTime) {
+    return measure(windowTime, false);
   }
 
   @Override
-  public RegistryMetric getRegistryMetric(long windowTime) {
+  public Map<String, Double> measure(long windowTime, boolean calculateLatency) {
     Integer index = appliedWindowTimes.get(windowTime);
     if (index != null) {
-      return registryMonitor.toRegistryMetric(index);
+      return registryMonitor.measure(index, calculateLatency);
     }
     throw new InvocationException(BAD_REQUEST,
         "windowTime : " + windowTime + " unset in servicecomb.metrics.window_time,current available are : " +
             Strings.join(",", getAppliedWindowTime().iterator()));
   }
-
-  @Override
-  public List<Long> getAppliedWindowTime() {
-    return Pollers.getPollingIntervals();
-  }
 }
diff --git a/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/publish/DefaultHealthCheckerManager.java b/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/publish/DefaultHealthCheckerManager.java
index 6327dff..a20105c 100644
--- a/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/publish/DefaultHealthCheckerManager.java
+++ b/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/publish/DefaultHealthCheckerManager.java
@@ -25,8 +25,8 @@ import java.util.Map.Entry;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.stream.Collectors;
 
-import org.apache.servicecomb.metrics.common.HealthCheckResult;
-import org.apache.servicecomb.metrics.common.HealthChecker;
+import org.apache.servicecomb.foundation.metrics.publish.HealthCheckResult;
+import org.apache.servicecomb.foundation.metrics.publish.HealthChecker;
 import org.apache.servicecomb.swagger.invocation.exception.InvocationException;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Component;
diff --git a/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/publish/DefaultHealthCheckerPublisher.java b/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/publish/DefaultHealthCheckerPublisher.java
index 5ef5f9c..70d0482 100644
--- a/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/publish/DefaultHealthCheckerPublisher.java
+++ b/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/publish/DefaultHealthCheckerPublisher.java
@@ -19,8 +19,7 @@ package org.apache.servicecomb.metrics.core.publish;
 
 import java.util.Map;
 
-import org.apache.servicecomb.metrics.common.HealthCheckResult;
-import org.apache.servicecomb.metrics.common.HealthCheckerPublisher;
+import org.apache.servicecomb.foundation.metrics.publish.HealthCheckResult;
 import org.apache.servicecomb.provider.rest.common.RestSchema;
 import org.springframework.web.bind.annotation.CrossOrigin;
 import org.springframework.web.bind.annotation.PathVariable;
@@ -32,7 +31,7 @@ import io.swagger.annotations.ApiResponses;
 
 @RestSchema(schemaId = "healthEndpoint")
 @RequestMapping(path = "/health")
-public class DefaultHealthCheckerPublisher implements HealthCheckerPublisher {
+public class DefaultHealthCheckerPublisher {
 
   private final HealthCheckerManager manager;
 
@@ -42,7 +41,6 @@ public class DefaultHealthCheckerPublisher implements HealthCheckerPublisher {
 
   @RequestMapping(path = "/", method = RequestMethod.GET)
   @CrossOrigin
-  @Override
   public Map<String, HealthCheckResult> health() {
     return manager.check();
   }
@@ -52,7 +50,6 @@ public class DefaultHealthCheckerPublisher implements HealthCheckerPublisher {
   })
   @RequestMapping(path = "/{name}", method = RequestMethod.GET)
   @CrossOrigin
-  @Override
   public HealthCheckResult healthWithName(@PathVariable(name = "name") String name) {
     return manager.check(name);
   }
diff --git a/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/publish/DefaultMetricsPublisher.java b/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/publish/DefaultMetricsPublisher.java
index fc7e397..57bd6f9 100644
--- a/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/publish/DefaultMetricsPublisher.java
+++ b/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/publish/DefaultMetricsPublisher.java
@@ -17,13 +17,11 @@
 
 package org.apache.servicecomb.metrics.core.publish;
 
-import java.util.List;
+import java.util.Map;
 
-import org.apache.servicecomb.metrics.common.MetricsPublisher;
-import org.apache.servicecomb.metrics.common.RegistryMetric;
 import org.apache.servicecomb.provider.rest.common.RestSchema;
+import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.web.bind.annotation.CrossOrigin;
-import org.springframework.web.bind.annotation.PathVariable;
 import org.springframework.web.bind.annotation.RequestMapping;
 import org.springframework.web.bind.annotation.RequestMethod;
 
@@ -32,35 +30,21 @@ import io.swagger.annotations.ApiResponses;
 
 @RestSchema(schemaId = "metricsEndpoint")
 @RequestMapping(path = "/metrics")
-public class DefaultMetricsPublisher implements MetricsPublisher {
+public class DefaultMetricsPublisher {
 
   private final DataSource dataSource;
 
+  @Autowired
   public DefaultMetricsPublisher(DataSource dataSource) {
     this.dataSource = dataSource;
   }
 
-  @RequestMapping(path = "/appliedWindowTime", method = RequestMethod.GET)
-  @CrossOrigin
-  @Override
-  public List<Long> getAppliedWindowTime() {
-    return dataSource.getAppliedWindowTime();
-  }
-
-  @RequestMapping(path = "/", method = RequestMethod.GET)
-  @CrossOrigin
-  @Override
-  public RegistryMetric metrics() {
-    return dataSource.getRegistryMetric();
-  }
-
   @ApiResponses({
       @ApiResponse(code = 400, response = String.class, message = "illegal request content"),
   })
-  @RequestMapping(path = "/{windowTime}", method = RequestMethod.GET)
+  @RequestMapping(path = "/", method = RequestMethod.GET)
   @CrossOrigin
-  @Override
-  public RegistryMetric metricsWithWindowTime(@PathVariable(name = "windowTime") long windowTime) {
-    return dataSource.getRegistryMetric(windowTime);
+  public Map<String, Double> metrics() {
+    return dataSource.measure();
   }
 }
diff --git a/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/publish/HealthCheckerManager.java b/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/publish/HealthCheckerManager.java
index 7bcc5fe..687d6c6 100644
--- a/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/publish/HealthCheckerManager.java
+++ b/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/publish/HealthCheckerManager.java
@@ -19,8 +19,9 @@ package org.apache.servicecomb.metrics.core.publish;
 
 import java.util.Map;
 
-import org.apache.servicecomb.metrics.common.HealthCheckResult;
-import org.apache.servicecomb.metrics.common.HealthChecker;
+import org.apache.servicecomb.foundation.metrics.publish.HealthCheckResult;
+import org.apache.servicecomb.foundation.metrics.publish.HealthChecker;
+
 
 public interface HealthCheckerManager {
   void register(HealthChecker checker);
diff --git a/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/utils/MonitorUtils.java b/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/utils/MonitorUtils.java
index 20bfe4e..26183db 100644
--- a/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/utils/MonitorUtils.java
+++ b/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/utils/MonitorUtils.java
@@ -17,54 +17,37 @@
 
 package org.apache.servicecomb.metrics.core.utils;
 
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.Map;
 import java.util.concurrent.TimeUnit;
 
-import com.netflix.servo.monitor.Monitor;
+import com.netflix.servo.monitor.MonitorConfig;
 import com.netflix.servo.tag.Tag;
 import com.netflix.servo.tag.TagList;
 
 public class MonitorUtils {
 
   //for time-related monitor type, if stop poll value over one window time,
-  //the value may return -1 or NaN because servo can't known precise value of previous step
-  //so must change to return 0
-  public static double adjustValue(double value) {
-    return Double.isNaN(value) || value < 0 ? 0 : value;
-  }
-
-  //for time-related monitor type, if stop poll value over one window time,
   //the value may return -1 because servo can't known precise value of previous step
   //so must change to return 0
   public static long adjustValue(long value) {
     return value < 0 ? 0 : value;
   }
 
-  public static boolean containsTagValue(Monitor<?> monitor, String tagKey, String tagValue) {
-    TagList tags = monitor.getConfig().getTags();
-    return tags.containsKey(tagKey) && tagValue.equals(tags.getTag(tagKey).getValue());
-  }
-
-  public static Map<String, String> convertTags(Monitor<?> monitor) {
-    TagList tags = monitor.getConfig().getTags();
-    if (tags.size() != 0) {
-      Map<String, String> tagMap = new HashMap<>();
-      for (Tag tag : tags) {
-        //we don't need servo internal type tag for metrics
-        if (!"type".equals(tag.getKey())) {
-          tagMap.put(tag.getKey(), tag.getValue());
-        }
-      }
-      return tagMap;
-    }
-    return Collections.emptyMap();
-  }
-
   //Counting use System.nano get more precise time
   //so we need change unit to millisecond when ouput
   public static long convertNanosecondToMillisecond(long nanoValue) {
     return TimeUnit.NANOSECONDS.toMillis(nanoValue);
   }
+
+  public static String getMonitorName(MonitorConfig config) {
+    TagList tags = config.getTags();
+    StringBuilder tagPart = new StringBuilder("(");
+    for (Tag tag : tags) {
+      if (!"type".equals(tag.getKey())) {
+        tagPart.append(String.format("%s=%s,", tag.getKey(), tag.getValue()));
+      }
+    }
+    tagPart.deleteCharAt(tagPart.length() - 1);
+    tagPart.append(")");
+    return config.getName() + tagPart.toString();
+  }
 }
diff --git a/metrics/metrics-core/src/test/java/org/apache/servicecomb/metrics/core/TestEventAndRunner.java b/metrics/metrics-core/src/test/java/org/apache/servicecomb/metrics/core/TestEventAndRunner.java
index 85cf463..f4e2ff8 100644
--- a/metrics/metrics-core/src/test/java/org/apache/servicecomb/metrics/core/TestEventAndRunner.java
+++ b/metrics/metrics-core/src/test/java/org/apache/servicecomb/metrics/core/TestEventAndRunner.java
@@ -33,10 +33,10 @@ import org.apache.servicecomb.core.metrics.InvocationFinishedEvent;
 import org.apache.servicecomb.core.metrics.InvocationStartProcessingEvent;
 import org.apache.servicecomb.core.metrics.InvocationStartedEvent;
 import org.apache.servicecomb.foundation.common.utils.EventUtils;
-import org.apache.servicecomb.metrics.common.MetricsDimension;
-import org.apache.servicecomb.metrics.common.RegistryMetric;
+import org.apache.servicecomb.foundation.metrics.MetricsConst;
+import org.apache.servicecomb.foundation.metrics.publish.MetricNode;
+import org.apache.servicecomb.foundation.metrics.publish.MetricsLoader;
 import org.apache.servicecomb.metrics.core.event.DefaultEventListenerManager;
-import org.apache.servicecomb.metrics.core.event.dimension.StatusConvertorFactory;
 import org.apache.servicecomb.metrics.core.monitor.DefaultSystemMonitor;
 import org.apache.servicecomb.metrics.core.monitor.RegistryMonitor;
 import org.apache.servicecomb.metrics.core.publish.DefaultDataSource;
@@ -75,249 +75,136 @@ public class TestEventAndRunner {
     Assert.assertEquals(intervals.size(), 3);
     Assert.assertThat(intervals, containsInAnyOrder(Arrays.asList(1000L, 2000L, 3000L).toArray()));
 
-    new DefaultEventListenerManager(monitor, new StatusConvertorFactory(),
-        MetricsDimension.DIMENSION_STATUS_OUTPUT_LEVEL_SUCCESS_FAILED);
+    new DefaultEventListenerManager(monitor);
 
+    //==========================================================================
     //fun1 is a PRODUCER invocation call 2 time and all is completed
     //two time success
     EventUtils.triggerEvent(new InvocationStartedEvent("fun1", InvocationType.PRODUCER, System.nanoTime()));
     EventUtils.triggerEvent(
-        new InvocationStartProcessingEvent("fun1", InvocationType.PRODUCER,
-            TimeUnit.MILLISECONDS.toNanos(100)));
+        new InvocationStartProcessingEvent("fun1", InvocationType.PRODUCER));
+    EventUtils
+        .triggerEvent(new InvocationFinishedEvent("fun1", InvocationType.PRODUCER, TimeUnit.MILLISECONDS.toNanos(100),
+            TimeUnit.MILLISECONDS.toNanos(200), TimeUnit.MILLISECONDS.toNanos(300), 200));
+
+    EventUtils.triggerEvent(new InvocationStartedEvent("fun1", InvocationType.PRODUCER, System.nanoTime()));
+    EventUtils.triggerEvent(
+        new InvocationStartProcessingEvent("fun1", InvocationType.PRODUCER));
     EventUtils
-        .triggerEvent(new InvocationFinishedEvent("fun1", InvocationType.PRODUCER,
-            TimeUnit.MILLISECONDS.toNanos(200), TimeUnit.MILLISECONDS.toNanos(300), 200, true));
+        .triggerEvent(new InvocationFinishedEvent("fun1", InvocationType.PRODUCER, TimeUnit.MILLISECONDS.toNanos(300),
+            TimeUnit.MILLISECONDS.toNanos(400), TimeUnit.MILLISECONDS.toNanos(700), 200));
 
     EventUtils.triggerEvent(new InvocationStartedEvent("fun1", InvocationType.PRODUCER, System.nanoTime()));
     EventUtils.triggerEvent(
-        new InvocationStartProcessingEvent("fun1", InvocationType.PRODUCER,
-            TimeUnit.MILLISECONDS.toNanos(300)));
+        new InvocationStartProcessingEvent("fun1", InvocationType.PRODUCER));
     EventUtils
-        .triggerEvent(new InvocationFinishedEvent("fun1", InvocationType.PRODUCER,
-            TimeUnit.MILLISECONDS.toNanos(400), TimeUnit.MILLISECONDS.toNanos(700), 500, false));
+        .triggerEvent(new InvocationFinishedEvent("fun1", InvocationType.PRODUCER, TimeUnit.MILLISECONDS.toNanos(300),
+            TimeUnit.MILLISECONDS.toNanos(400), TimeUnit.MILLISECONDS.toNanos(700), 500));
 
     //==========================================================================
+    //fun2 is a CONSUMER invocation call once and completed
+    EventUtils.triggerEvent(new InvocationStartedEvent("fun2", InvocationType.CONSUMER, System.nanoTime()));
+    EventUtils.triggerEvent(
+        new InvocationStartProcessingEvent("fun2", InvocationType.CONSUMER));
+    EventUtils
+        .triggerEvent(new InvocationFinishedEvent("fun2", InvocationType.CONSUMER, TimeUnit.MILLISECONDS.toNanos(100),
+            TimeUnit.MILLISECONDS.toNanos(200), TimeUnit.MILLISECONDS.toNanos(300), 200));
 
+    //==========================================================================
     //fun3 is a PRODUCER invocation call uncompleted
     EventUtils.triggerEvent(new InvocationStartedEvent("fun3", InvocationType.PRODUCER, System.nanoTime()));
     EventUtils.triggerEvent(
-        new InvocationStartProcessingEvent("fun3", InvocationType.PRODUCER,
-            TimeUnit.MILLISECONDS.toNanos(500)));
+        new InvocationStartProcessingEvent("fun3", InvocationType.PRODUCER));
 
     //==========================================================================
-
     //fun4 is a PRODUCER call only started and no processing start and finished
     EventUtils.triggerEvent(new InvocationStartedEvent("fun4", InvocationType.PRODUCER, System.nanoTime()));
 
     //==========================================================================
 
-    //fun2 is a CONSUMER invocation call once and completed
-    EventUtils.triggerEvent(new InvocationStartedEvent("fun2", InvocationType.CONSUMER, System.nanoTime()));
-    EventUtils.triggerEvent(
-        new InvocationStartProcessingEvent("fun2", InvocationType.CONSUMER,
-            TimeUnit.MILLISECONDS.toNanos(100)));
-    EventUtils
-        .triggerEvent(new InvocationFinishedEvent("fun2", InvocationType.CONSUMER,
-            TimeUnit.MILLISECONDS.toNanos(200), TimeUnit.MILLISECONDS.toNanos(300), 200, true));
-
-    //==========================================================================
-
     //sim lease one window time
     Thread.sleep(1000);
 
-    RegistryMetric model = dataSource.getRegistryMetric(1000);
-
-    //check InstanceMetric
-    Assert.assertEquals(1, model.getInstanceMetric().getProducerMetric().getWaitInQueue());
-    Assert.assertEquals(3, model.getInstanceMetric().getProducerMetric().getLifeTimeInQueue().getCount());
-    Assert.assertEquals(900, model.getInstanceMetric().getProducerMetric().getLifeTimeInQueue().getTotal(), 0);
-    Assert.assertEquals(300, model.getInstanceMetric().getProducerMetric().getLifeTimeInQueue().getAverage(),
-        0);
-    Assert.assertEquals(500, model.getInstanceMetric().getProducerMetric().getLifeTimeInQueue().getMax(),
-        0);
-    Assert.assertEquals(100, model.getInstanceMetric().getProducerMetric().getLifeTimeInQueue().getMin(),
-        0);
+    Map<String, Double> metrics = dataSource.measure(1000, true);
 
-    Assert.assertEquals(2, model.getInstanceMetric().getProducerMetric().getExecutionTime().getCount());
-    Assert.assertEquals(600, model.getInstanceMetric().getProducerMetric().getExecutionTime().getTotal(),
-        0);
-    Assert.assertEquals(300, model.getInstanceMetric().getProducerMetric().getExecutionTime().getAverage(),
-        0);
-    Assert.assertEquals(400, model.getInstanceMetric().getProducerMetric().getExecutionTime().getMax(),
-        0);
-    Assert.assertEquals(200, model.getInstanceMetric().getProducerMetric().getExecutionTime().getMin(),
-        0);
+    MetricsLoader loader = new MetricsLoader(metrics);
 
-    Assert.assertEquals(2, model.getInstanceMetric().getProducerMetric().getProducerLatency().getCount());
-    Assert.assertEquals(1000, model.getInstanceMetric().getProducerMetric().getProducerLatency().getTotal(),
-        0);
-    Assert.assertEquals(500, model.getInstanceMetric().getProducerMetric().getProducerLatency().getAverage(),
-        0);
-    Assert.assertEquals(700, model.getInstanceMetric().getProducerMetric().getProducerLatency().getMax(),
-        0);
-    Assert.assertEquals(300, model.getInstanceMetric().getProducerMetric().getProducerLatency().getMin(),
-        0);
-
-    Assert.assertEquals(4, model.getInstanceMetric().getProducerMetric().getProducerCall()
-        .getTpsValue(MetricsDimension.DIMENSION_STATUS, MetricsDimension.DIMENSION_STATUS_ALL).getValue(), 0);
-    Assert.assertEquals(1, model.getInstanceMetric().getProducerMetric().getProducerCall()
-        .getTpsValue(MetricsDimension.DIMENSION_STATUS, MetricsDimension.DIMENSION_STATUS_SUCCESS_FAILED_SUCCESS)
-        .getValue(), 0);
-    Assert.assertEquals(1, model.getInstanceMetric().getProducerMetric().getProducerCall()
-        .getTpsValue(MetricsDimension.DIMENSION_STATUS, MetricsDimension.DIMENSION_STATUS_SUCCESS_FAILED_FAILED)
-        .getValue(), 0);
-
-    Assert.assertEquals(4, model.getInstanceMetric().getProducerMetric().getProducerCall()
-        .getTotalValue(MetricsDimension.DIMENSION_STATUS, MetricsDimension.DIMENSION_STATUS_ALL).getValue(), 0);
-    Assert.assertEquals(1, model.getInstanceMetric().getProducerMetric().getProducerCall()
-        .getTotalValue(MetricsDimension.DIMENSION_STATUS, MetricsDimension.DIMENSION_STATUS_SUCCESS_FAILED_SUCCESS)
-        .getValue(), 0);
-    Assert.assertEquals(1, model.getInstanceMetric().getProducerMetric().getProducerCall()
-        .getTotalValue(MetricsDimension.DIMENSION_STATUS, MetricsDimension.DIMENSION_STATUS_SUCCESS_FAILED_FAILED)
-        .getValue(), 0);
-
-    Assert.assertEquals(1, model.getInstanceMetric().getConsumerMetric().getConsumerLatency().getCount());
-    Assert.assertEquals(300, model.getInstanceMetric().getConsumerMetric().getConsumerLatency().getTotal(),
-        0);
-    Assert.assertEquals(300, model.getInstanceMetric().getConsumerMetric().getConsumerLatency().getAverage(),
-        0);
-    Assert.assertEquals(300, model.getInstanceMetric().getConsumerMetric().getConsumerLatency().getMax(),
-        0);
-    Assert.assertEquals(300, model.getInstanceMetric().getConsumerMetric().getConsumerLatency().getMin(),
-        0);
-
-    Assert.assertEquals(1, model.getInstanceMetric().getConsumerMetric().getConsumerCall()
-        .getTpsValue(MetricsDimension.DIMENSION_STATUS, MetricsDimension.DIMENSION_STATUS_ALL).getValue(), 0);
-    Assert.assertEquals(1, model.getInstanceMetric().getConsumerMetric().getConsumerCall()
-        .getTpsValue(MetricsDimension.DIMENSION_STATUS, MetricsDimension.DIMENSION_STATUS_SUCCESS_FAILED_SUCCESS)
-        .getValue(), 0);
-    Assert.assertEquals(0, model.getInstanceMetric().getConsumerMetric().getConsumerCall()
-        .getTpsValue(MetricsDimension.DIMENSION_STATUS, MetricsDimension.DIMENSION_STATUS_SUCCESS_FAILED_FAILED)
-        .getValue(), 0);
-
-    Assert.assertEquals(1, model.getInstanceMetric().getConsumerMetric().getConsumerCall()
-        .getTotalValue(MetricsDimension.DIMENSION_STATUS, MetricsDimension.DIMENSION_STATUS_ALL).getValue(), 0);
-    Assert.assertEquals(1, model.getInstanceMetric().getConsumerMetric().getConsumerCall()
-        .getTotalValue(MetricsDimension.DIMENSION_STATUS, MetricsDimension.DIMENSION_STATUS_SUCCESS_FAILED_SUCCESS)
-        .getValue(), 0);
-    Assert.assertEquals(0, model.getInstanceMetric().getConsumerMetric().getConsumerCall()
-        .getTotalValue(MetricsDimension.DIMENSION_STATUS, MetricsDimension.DIMENSION_STATUS_SUCCESS_FAILED_FAILED)
-        .getValue(), 0);
+    MetricNode node = loader
+        .getMetricTree(MetricsConst.SERVICECOMB_INVOCATION, MetricsConst.TAG_OPERATION, MetricsConst.TAG_ROLE,
+            MetricsConst.TAG_STAGE);
 
     //check ProducerMetrics
-    Assert.assertEquals(0, model.getProducerMetrics().get("fun1").getWaitInQueue());
-    Assert.assertEquals(2, model.getProducerMetrics().get("fun1").getLifeTimeInQueue().getCount());
-    Assert.assertEquals(400, model.getProducerMetrics().get("fun1").getLifeTimeInQueue().getTotal(), 0);
-    Assert.assertEquals(200, model.getProducerMetrics().get("fun1").getLifeTimeInQueue().getAverage(), 0);
-    Assert.assertEquals(300, model.getProducerMetrics().get("fun1").getLifeTimeInQueue().getMax(), 0);
-    Assert.assertEquals(100, model.getProducerMetrics().get("fun1").getLifeTimeInQueue().getMin(), 0);
-
-    Assert.assertEquals(2, model.getProducerMetrics().get("fun1").getExecutionTime().getCount());
-    Assert.assertEquals(600, model.getProducerMetrics().get("fun1").getExecutionTime().getTotal(), 0);
-    Assert.assertEquals(300, model.getProducerMetrics().get("fun1").getExecutionTime().getAverage(), 0);
-    Assert.assertEquals(400, model.getProducerMetrics().get("fun1").getExecutionTime().getMax(), 0);
-    Assert.assertEquals(200, model.getProducerMetrics().get("fun1").getExecutionTime().getMin(), 0);
-
-    Assert.assertEquals(2, model.getProducerMetrics().get("fun1").getProducerLatency().getCount());
-    Assert.assertEquals(1000, model.getProducerMetrics().get("fun1").getProducerLatency().getTotal(), 0);
-    Assert.assertEquals(500, model.getProducerMetrics().get("fun1").getProducerLatency().getAverage(), 0);
-    Assert.assertEquals(700, model.getProducerMetrics().get("fun1").getProducerLatency().getMax(), 0);
-    Assert.assertEquals(300, model.getProducerMetrics().get("fun1").getProducerLatency().getMin(), 0);
-
-    Assert.assertEquals(2, model.getProducerMetrics().get("fun1").getProducerCall()
-        .getTpsValue(MetricsDimension.DIMENSION_STATUS, MetricsDimension.DIMENSION_STATUS_ALL).getValue(), 0);
-    Assert.assertEquals(1, model.getProducerMetrics().get("fun1").getProducerCall()
-        .getTpsValue(MetricsDimension.DIMENSION_STATUS, MetricsDimension.DIMENSION_STATUS_SUCCESS_FAILED_SUCCESS)
-        .getValue(), 0);
-    Assert.assertEquals(1, model.getProducerMetrics().get("fun1").getProducerCall()
-        .getTpsValue(MetricsDimension.DIMENSION_STATUS, MetricsDimension.DIMENSION_STATUS_SUCCESS_FAILED_FAILED)
-        .getValue(), 0);
-
-    Assert.assertEquals(2, model.getProducerMetrics().get("fun1").getProducerCall()
-        .getTotalValue(MetricsDimension.DIMENSION_STATUS, MetricsDimension.DIMENSION_STATUS_ALL).getValue(), 0);
-    Assert.assertEquals(1, model.getProducerMetrics().get("fun1").getProducerCall()
-        .getTotalValue(MetricsDimension.DIMENSION_STATUS, MetricsDimension.DIMENSION_STATUS_SUCCESS_FAILED_SUCCESS)
-        .getValue(), 0);
-    Assert.assertEquals(1, model.getProducerMetrics().get("fun1").getProducerCall()
-        .getTotalValue(MetricsDimension.DIMENSION_STATUS, MetricsDimension.DIMENSION_STATUS_SUCCESS_FAILED_FAILED)
-        .getValue(), 0);
-
-    //fun3
-    Assert.assertEquals(0, model.getProducerMetrics().get("fun3").getWaitInQueue());
-    Assert.assertEquals(1, model.getProducerMetrics().get("fun3").getLifeTimeInQueue().getCount());
-    Assert.assertEquals(500, model.getProducerMetrics().get("fun3").getLifeTimeInQueue().getTotal(), 0);
-    Assert.assertEquals(500, model.getProducerMetrics().get("fun3").getLifeTimeInQueue().getAverage(), 0);
-    Assert.assertEquals(500, model.getProducerMetrics().get("fun3").getLifeTimeInQueue().getMax(), 0);
-    Assert.assertEquals(500, model.getProducerMetrics().get("fun3").getLifeTimeInQueue().getMin(), 0);
-
-    Assert.assertEquals(0, model.getProducerMetrics().get("fun3").getExecutionTime().getCount());
-    Assert.assertEquals(0, model.getProducerMetrics().get("fun3").getExecutionTime().getTotal(), 0);
-    Assert.assertEquals(0, model.getProducerMetrics().get("fun3").getExecutionTime().getAverage(), 0);
-    Assert.assertEquals(0, model.getProducerMetrics().get("fun3").getExecutionTime().getMax(), 0);
-    Assert.assertEquals(0, model.getProducerMetrics().get("fun3").getExecutionTime().getMin(), 0);
-
-    Assert.assertEquals(0, model.getProducerMetrics().get("fun3").getProducerLatency().getCount());
-    Assert.assertEquals(0, model.getProducerMetrics().get("fun3").getProducerLatency().getTotal(), 0);
-    Assert.assertEquals(0, model.getProducerMetrics().get("fun3").getProducerLatency().getAverage(), 0);
-    Assert.assertEquals(0, model.getProducerMetrics().get("fun3").getProducerLatency().getMax(), 0);
-    Assert.assertEquals(0, model.getProducerMetrics().get("fun3").getProducerLatency().getMin(), 0);
-
-    Assert.assertEquals(1, model.getProducerMetrics().get("fun3").getProducerCall()
-        .getTpsValue(MetricsDimension.DIMENSION_STATUS, MetricsDimension.DIMENSION_STATUS_ALL).getValue(), 0);
-    Assert.assertEquals(0, model.getProducerMetrics().get("fun3").getProducerCall()
-        .getTpsValue(MetricsDimension.DIMENSION_STATUS, MetricsDimension.DIMENSION_STATUS_SUCCESS_FAILED_SUCCESS)
-        .getValue(), 0);
-    Assert.assertEquals(0, model.getProducerMetrics().get("fun3").getProducerCall()
-        .getTpsValue(MetricsDimension.DIMENSION_STATUS, MetricsDimension.DIMENSION_STATUS_SUCCESS_FAILED_FAILED)
-        .getValue(), 0);
-
-    Assert.assertEquals(1, model.getProducerMetrics().get("fun3").getProducerCall()
-        .getTotalValue(MetricsDimension.DIMENSION_STATUS, MetricsDimension.DIMENSION_STATUS_ALL).getValue(), 0);
-    Assert.assertEquals(0, model.getProducerMetrics().get("fun3").getProducerCall()
-        .getTotalValue(MetricsDimension.DIMENSION_STATUS, MetricsDimension.DIMENSION_STATUS_SUCCESS_FAILED_SUCCESS)
-        .getValue(), 0);
-    Assert.assertEquals(0, model.getProducerMetrics().get("fun3").getProducerCall()
-        .getTotalValue(MetricsDimension.DIMENSION_STATUS, MetricsDimension.DIMENSION_STATUS_SUCCESS_FAILED_FAILED)
-        .getValue(), 0);
+    //fun1
+    MetricNode node1_queue = node.getChildrenNode("fun1").getChildrenNode(MetricsConst.ROLE_PRODUCER)
+        .getChildrenNode(MetricsConst.STAGE_QUEUE);
+    Assert.assertEquals(0, node1_queue.getMatchStatisticMetricValue("waitInQueue"), 0);
+    MetricNode node1_queue_status = new MetricNode(node1_queue.getMetrics(), MetricsConst.TAG_STATUS);
+    Assert.assertEquals(300, node1_queue_status.getChildrenNode("200").getMatchStatisticMetricValue("max"), 0);
+    Assert.assertEquals(2, node1_queue_status.getChildrenNode("200").getMatchStatisticMetricValue("count"), 0);
+    Assert.assertEquals(400, node1_queue_status.getChildrenNode("200").getMatchStatisticMetricValue("totalTime"), 0);
+    Assert.assertEquals(300, node1_queue_status.getChildrenNode("500").getMatchStatisticMetricValue("max"), 0);
+    Assert.assertEquals(1, node1_queue_status.getChildrenNode("500").getMatchStatisticMetricValue("count"), 0);
+    Assert.assertEquals(300, node1_queue_status.getChildrenNode("500").getMatchStatisticMetricValue("totalTime"), 0);
+
+    MetricNode node1_exec = node.getChildrenNode("fun1").getChildrenNode(MetricsConst.ROLE_PRODUCER)
+        .getChildrenNode(MetricsConst.STAGE_EXECUTION);
+    MetricNode node1_exec_status = new MetricNode(node1_exec.getMetrics(), MetricsConst.TAG_STATUS);
+    Assert.assertEquals(400, node1_exec_status.getChildrenNode("200").getMatchStatisticMetricValue("max"), 0);
+    Assert.assertEquals(2, node1_exec_status.getChildrenNode("200").getMatchStatisticMetricValue("count"), 0);
+    Assert.assertEquals(600, node1_exec_status.getChildrenNode("200").getMatchStatisticMetricValue("totalTime"), 0);
+    Assert.assertEquals(400, node1_exec_status.getChildrenNode("500").getMatchStatisticMetricValue("max"), 0);
+    Assert.assertEquals(1, node1_exec_status.getChildrenNode("500").getMatchStatisticMetricValue("count"), 0);
+    Assert.assertEquals(400, node1_exec_status.getChildrenNode("500").getMatchStatisticMetricValue("totalTime"), 0);
+
+    MetricNode node1_whole = node.getChildrenNode("fun1").getChildrenNode(MetricsConst.ROLE_PRODUCER)
+        .getChildrenNode(MetricsConst.STAGE_WHOLE);
+    MetricNode node1_whole_status = new MetricNode(node1_whole.getMetrics(), MetricsConst.TAG_STATUS);
+    Assert.assertEquals(700, node1_whole_status.getChildrenNode("200").getMatchStatisticMetricValue("max"), 0);
+    Assert.assertEquals(2, node1_whole_status.getChildrenNode("200").getMatchStatisticMetricValue("count"), 0);
+    Assert.assertEquals(1000, node1_whole_status.getChildrenNode("200").getMatchStatisticMetricValue("totalTime"), 0);
+    Assert.assertEquals(700, node1_whole_status.getChildrenNode("500").getMatchStatisticMetricValue("max"), 0);
+    Assert.assertEquals(1, node1_whole_status.getChildrenNode("500").getMatchStatisticMetricValue("count"), 0);
+    Assert.assertEquals(700, node1_whole_status.getChildrenNode("500").getMatchStatisticMetricValue("totalTime"), 0);
+    Assert.assertEquals(2, node1_whole_status.getChildrenNode("200").getMatchStatisticMetricValue("tps"), 0);
+    Assert.assertEquals(2, node1_whole_status.getChildrenNode("200").getMatchStatisticMetricValue("totalCount"), 0);
+    Assert.assertEquals(1, node1_whole_status.getChildrenNode("500").getMatchStatisticMetricValue("tps"), 0);
+    Assert.assertEquals(1, node1_whole_status.getChildrenNode("500").getMatchStatisticMetricValue("totalCount"), 0);
 
     //check ConsumerMetrics
-    //no need
-    Assert.assertEquals(1, model.getConsumerMetrics().get("fun2").getConsumerLatency().getCount());
-    Assert.assertEquals(300, model.getConsumerMetrics().get("fun2").getConsumerLatency().getTotal(), 0);
-    Assert.assertEquals(300, model.getConsumerMetrics().get("fun2").getConsumerLatency().getAverage(), 0);
-    Assert.assertEquals(300, model.getConsumerMetrics().get("fun2").getConsumerLatency().getMax(), 0);
-    Assert.assertEquals(300, model.getConsumerMetrics().get("fun2").getConsumerLatency().getMin(), 0);
+    //fun2
+    MetricNode node2_whole = node.getChildrenNode("fun2").getChildrenNode(MetricsConst.ROLE_CONSUMER)
+        .getChildrenNode(MetricsConst.STAGE_WHOLE);
+    MetricNode node2_whole_status = new MetricNode(node2_whole.getMetrics(), MetricsConst.TAG_STATUS);
+    Assert.assertEquals(300, node2_whole_status.getChildrenNode("200").getMatchStatisticMetricValue("max"), 0);
+    Assert.assertEquals(1, node2_whole_status.getChildrenNode("200").getMatchStatisticMetricValue("count"), 0);
+    Assert.assertEquals(300, node2_whole_status.getChildrenNode("200").getMatchStatisticMetricValue("totalTime"), 0);
+    Assert.assertEquals(1, node2_whole_status.getChildrenNode("200").getMatchStatisticMetricValue("tps"), 0);
+    Assert.assertEquals(1, node2_whole_status.getChildrenNode("200").getMatchStatisticMetricValue("totalCount"), 0);
 
-    Assert.assertEquals(1, model.getConsumerMetrics().get("fun2").getConsumerCall()
-        .getTpsValue(MetricsDimension.DIMENSION_STATUS, MetricsDimension.DIMENSION_STATUS_ALL).getValue(), 0);
-    Assert.assertEquals(1, model.getConsumerMetrics().get("fun2").getConsumerCall()
-        .getTpsValue(MetricsDimension.DIMENSION_STATUS, MetricsDimension.DIMENSION_STATUS_SUCCESS_FAILED_SUCCESS)
-        .getValue(), 0);
-    Assert.assertEquals(0, model.getConsumerMetrics().get("fun2").getConsumerCall()
-        .getTpsValue(MetricsDimension.DIMENSION_STATUS, MetricsDimension.DIMENSION_STATUS_SUCCESS_FAILED_FAILED)
-        .getValue(), 0);
-
-    Assert.assertEquals(1, model.getConsumerMetrics().get("fun2").getConsumerCall()
-        .getTotalValue(MetricsDimension.DIMENSION_STATUS, MetricsDimension.DIMENSION_STATUS_ALL).getValue(), 0);
-    Assert.assertEquals(1, model.getConsumerMetrics().get("fun2").getConsumerCall()
-        .getTotalValue(MetricsDimension.DIMENSION_STATUS, MetricsDimension.DIMENSION_STATUS_SUCCESS_FAILED_SUCCESS)
-        .getValue(), 0);
-    Assert.assertEquals(0, model.getConsumerMetrics().get("fun2").getConsumerCall()
-        .getTotalValue(MetricsDimension.DIMENSION_STATUS, MetricsDimension.DIMENSION_STATUS_SUCCESS_FAILED_FAILED)
-        .getValue(), 0);
-
-    Map<String, Number> metrics = model.toMap();
-    Assert.assertEquals(108, metrics.size());
+    //fun3
+    MetricNode node3_queue = node.getChildrenNode("fun3").getChildrenNode(MetricsConst.ROLE_PRODUCER)
+        .getChildrenNode(MetricsConst.STAGE_QUEUE);
+    Assert.assertEquals(0, node3_queue.getMatchStatisticMetricValue("waitInQueue"), 0);
+
+    //fun4
+    MetricNode node4_queue = node.getChildrenNode("fun4").getChildrenNode(MetricsConst.ROLE_PRODUCER)
+        .getChildrenNode(MetricsConst.STAGE_QUEUE);
+    Assert.assertEquals(1, node4_queue.getMatchStatisticMetricValue("waitInQueue"), 0);
+
+    //System metrics
+    Assert.assertEquals(1.0, getSystemMetric(loader, "cpuLoad"), 0);
+    Assert.assertEquals(2, getSystemMetric(loader, "cpuRunningThreads"), 0);
+    Assert.assertEquals(100, getSystemMetric(loader, "heapCommit"), 0);
+    Assert.assertEquals(200, getSystemMetric(loader, "heapInit"), 0);
+    Assert.assertEquals(300, getSystemMetric(loader, "heapMax"), 0);
+    Assert.assertEquals(400, getSystemMetric(loader, "heapUsed"), 0);
+    Assert.assertEquals(500, getSystemMetric(loader, "nonHeapCommit"), 0);
+    Assert.assertEquals(600, getSystemMetric(loader, "nonHeapInit"), 0);
+    Assert.assertEquals(700, getSystemMetric(loader, "nonHeapMax"), 0);
+    Assert.assertEquals(800, getSystemMetric(loader, "nonHeapUsed"), 0);
+  }
 
-    Assert.assertEquals(1.0, model.getInstanceMetric().getSystemMetric().getCpuLoad(), 0);
-    Assert.assertEquals(2, model.getInstanceMetric().getSystemMetric().getCpuRunningThreads(), 0);
-    Assert.assertEquals(100, model.getInstanceMetric().getSystemMetric().getHeapCommit(), 0);
-    Assert.assertEquals(200, model.getInstanceMetric().getSystemMetric().getHeapInit(), 0);
-    Assert.assertEquals(300, model.getInstanceMetric().getSystemMetric().getHeapMax(), 0);
-    Assert.assertEquals(400, model.getInstanceMetric().getSystemMetric().getHeapUsed(), 0);
-    Assert.assertEquals(500, model.getInstanceMetric().getSystemMetric().getNonHeapCommit(), 0);
-    Assert.assertEquals(600, model.getInstanceMetric().getSystemMetric().getNonHeapInit(), 0);
-    Assert.assertEquals(700, model.getInstanceMetric().getSystemMetric().getNonHeapMax(), 0);
-    Assert.assertEquals(800, model.getInstanceMetric().getSystemMetric().getNonHeapUsed(), 0);
+  private Double getSystemMetric(MetricsLoader loader, String name) {
+    return loader.getFirstMatchMetricValue(MetricsConst.JVM, MetricsConst.TAG_NAME, name);
   }
 }
\ No newline at end of file
diff --git a/metrics/metrics-core/src/test/java/org/apache/servicecomb/metrics/core/TestHealthCheckerManager.java b/metrics/metrics-core/src/test/java/org/apache/servicecomb/metrics/core/TestHealthCheckerManager.java
index 507ff77..506d215 100644
--- a/metrics/metrics-core/src/test/java/org/apache/servicecomb/metrics/core/TestHealthCheckerManager.java
+++ b/metrics/metrics-core/src/test/java/org/apache/servicecomb/metrics/core/TestHealthCheckerManager.java
@@ -23,9 +23,9 @@ import java.util.List;
 import java.util.Map;
 
 import org.apache.servicecomb.foundation.common.utils.JsonUtils;
-import org.apache.servicecomb.metrics.common.DefaultHealthCheckExtraData;
-import org.apache.servicecomb.metrics.common.HealthCheckResult;
-import org.apache.servicecomb.metrics.common.HealthChecker;
+import org.apache.servicecomb.foundation.metrics.publish.DefaultHealthCheckExtraData;
+import org.apache.servicecomb.foundation.metrics.publish.HealthCheckResult;
+import org.apache.servicecomb.foundation.metrics.publish.HealthChecker;
 import org.apache.servicecomb.metrics.core.health.DefaultMicroserviceHealthChecker;
 import org.apache.servicecomb.metrics.core.publish.DefaultHealthCheckerManager;
 import org.apache.servicecomb.metrics.core.publish.HealthCheckerManager;
@@ -87,18 +87,18 @@ public class TestHealthCheckerManager {
 
     Map<String, HealthCheckResult> results = manager.check();
 
-    Assert.assertEquals(true,results.get("default").isHealthy());
+    Assert.assertEquals(true, results.get("default").isHealthy());
 
     DefaultHealthCheckExtraData data = JsonUtils.OBJ_MAPPER
         .readValue(results.get("default").getExtraData(), DefaultHealthCheckExtraData.class);
-    Assert.assertEquals("appId",data.getAppId());
-    Assert.assertEquals("serviceName",data.getServiceName());
-    Assert.assertEquals("0.0.1",data.getServiceVersion());
-    Assert.assertEquals("001",data.getInstanceId());
-    Assert.assertEquals("localhost",data.getHostName());
-    Assert.assertEquals("127.0.0.1,192.168.0.100",data.getEndpoints());
+    Assert.assertEquals("appId", data.getAppId());
+    Assert.assertEquals("serviceName", data.getServiceName());
+    Assert.assertEquals("0.0.1", data.getServiceVersion());
+    Assert.assertEquals("001", data.getInstanceId());
+    Assert.assertEquals("localhost", data.getHostName());
+    Assert.assertEquals("127.0.0.1,192.168.0.100", data.getEndpoints());
 
     HealthCheckResult result = manager.check("test");
-    Assert.assertEquals(false,result.isHealthy());
+    Assert.assertEquals(false, result.isHealthy());
   }
 }
diff --git a/metrics/metrics-core/src/test/java/org/apache/servicecomb/metrics/core/TestHealthCheckerPublisher.java b/metrics/metrics-core/src/test/java/org/apache/servicecomb/metrics/core/TestHealthCheckerPublisher.java
index 3fb16e6..8f91d33 100644
--- a/metrics/metrics-core/src/test/java/org/apache/servicecomb/metrics/core/TestHealthCheckerPublisher.java
+++ b/metrics/metrics-core/src/test/java/org/apache/servicecomb/metrics/core/TestHealthCheckerPublisher.java
@@ -24,8 +24,7 @@ import java.util.HashMap;
 import java.util.Map;
 
 import org.apache.servicecomb.foundation.common.utils.JsonUtils;
-import org.apache.servicecomb.metrics.common.HealthCheckResult;
-import org.apache.servicecomb.metrics.common.HealthCheckerPublisher;
+import org.apache.servicecomb.foundation.metrics.publish.HealthCheckResult;
 import org.apache.servicecomb.metrics.core.publish.DefaultHealthCheckerPublisher;
 import org.apache.servicecomb.metrics.core.publish.HealthCheckerManager;
 import org.junit.Assert;
@@ -46,11 +45,11 @@ public class TestHealthCheckerPublisher {
     when(manager.check()).thenReturn(results);
     when(manager.check("default")).thenReturn(result);
 
-    HealthCheckerPublisher publisher = new DefaultHealthCheckerPublisher(manager);
+    DefaultHealthCheckerPublisher publisher = new DefaultHealthCheckerPublisher(manager);
     Map<String, HealthCheckResult> content = publisher.health();
-    Assert.assertEquals(JsonUtils.writeValueAsString(result),JsonUtils.writeValueAsString(content.get("default")));
+    Assert.assertEquals(JsonUtils.writeValueAsString(result), JsonUtils.writeValueAsString(content.get("default")));
 
     HealthCheckResult checkResult = publisher.healthWithName("default");
-    Assert.assertEquals(JsonUtils.writeValueAsString(result),JsonUtils.writeValueAsString(checkResult));
+    Assert.assertEquals(JsonUtils.writeValueAsString(result), JsonUtils.writeValueAsString(checkResult));
   }
 }
diff --git a/metrics/metrics-core/src/test/java/org/apache/servicecomb/metrics/core/TestPublisher.java b/metrics/metrics-core/src/test/java/org/apache/servicecomb/metrics/core/TestMetricsPublisher.java
similarity index 54%
rename from metrics/metrics-core/src/test/java/org/apache/servicecomb/metrics/core/TestPublisher.java
rename to metrics/metrics-core/src/test/java/org/apache/servicecomb/metrics/core/TestMetricsPublisher.java
index bf38058..1a6bc0e 100644
--- a/metrics/metrics-core/src/test/java/org/apache/servicecomb/metrics/core/TestPublisher.java
+++ b/metrics/metrics-core/src/test/java/org/apache/servicecomb/metrics/core/TestMetricsPublisher.java
@@ -17,40 +17,22 @@
 
 package org.apache.servicecomb.metrics.core;
 
-import static org.hamcrest.Matchers.containsInAnyOrder;
-
-import java.util.Arrays;
-import java.util.List;
 import java.util.Map;
 
-import org.apache.servicecomb.metrics.common.RegistryMetric;
 import org.apache.servicecomb.metrics.core.monitor.DefaultSystemMonitor;
 import org.apache.servicecomb.metrics.core.monitor.RegistryMonitor;
-import org.apache.servicecomb.metrics.core.monitor.SystemMonitor;
 import org.apache.servicecomb.metrics.core.publish.DefaultDataSource;
 import org.apache.servicecomb.metrics.core.publish.DefaultMetricsPublisher;
 import org.junit.Assert;
 import org.junit.Test;
 
-public class TestPublisher {
-
+public class TestMetricsPublisher {
   @Test
   public void test() {
-    SystemMonitor systemMonitor = new DefaultSystemMonitor();
-    RegistryMonitor registryMonitor = new RegistryMonitor(systemMonitor);
-    DefaultDataSource dataSource = new DefaultDataSource(registryMonitor, "1000,2000,3000,3000,2000,1000");
-    DefaultMetricsPublisher publisher = new DefaultMetricsPublisher(dataSource);
-
-    RegistryMetric registryMetric = publisher.metrics();
-    Map<String, Number> metricsMap = registryMetric.toMap();
-    Assert.assertEquals(31, metricsMap.size());
-
-    registryMetric = publisher.metricsWithWindowTime(1000);
-    metricsMap = registryMetric.toMap();
-    Assert.assertEquals(31, metricsMap.size());
-
-    List<Long> appliedWindowTime = publisher.getAppliedWindowTime();
-    Assert.assertEquals(3, appliedWindowTime.size());
-    Assert.assertThat(appliedWindowTime, containsInAnyOrder(Arrays.asList(1000L, 2000L, 3000L).toArray()));
+    DefaultMetricsPublisher publisher = new DefaultMetricsPublisher(
+        new DefaultDataSource(new RegistryMonitor(new DefaultSystemMonitor())));
+    Map<String, Double> metrics = publisher.metrics();
+    //10 jvm metrics get
+    Assert.assertEquals(10, metrics.size());
   }
 }
diff --git a/metrics/metrics-core/src/test/java/org/apache/servicecomb/metrics/core/TestStatusDimension.java b/metrics/metrics-core/src/test/java/org/apache/servicecomb/metrics/core/TestStatusDimension.java
deleted file mode 100644
index 897648b..0000000
--- a/metrics/metrics-core/src/test/java/org/apache/servicecomb/metrics/core/TestStatusDimension.java
+++ /dev/null
@@ -1,159 +0,0 @@
-/*
- * 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.servicecomb.metrics.core;
-
-import java.util.concurrent.TimeUnit;
-
-import org.apache.servicecomb.core.metrics.InvocationFinishedEvent;
-import org.apache.servicecomb.core.metrics.InvocationStartProcessingEvent;
-import org.apache.servicecomb.core.metrics.InvocationStartedEvent;
-import org.apache.servicecomb.foundation.common.utils.EventUtils;
-import org.apache.servicecomb.metrics.common.MetricsDimension;
-import org.apache.servicecomb.metrics.common.RegistryMetric;
-import org.apache.servicecomb.metrics.core.event.DefaultEventListenerManager;
-import org.apache.servicecomb.metrics.core.event.dimension.StatusConvertorFactory;
-import org.apache.servicecomb.metrics.core.monitor.DefaultSystemMonitor;
-import org.apache.servicecomb.metrics.core.monitor.RegistryMonitor;
-import org.apache.servicecomb.metrics.core.publish.DefaultDataSource;
-import org.apache.servicecomb.swagger.invocation.InvocationType;
-import org.junit.Assert;
-import org.junit.Test;
-
-public class TestStatusDimension {
-
-  @Test
-  public void testCodeGroupDimension() throws InterruptedException {
-    RegistryMetric model = prepare(MetricsDimension.DIMENSION_STATUS_OUTPUT_LEVEL_CODE_GROUP);
-
-    Assert.assertEquals(5, model.getInstanceMetric().getProducerMetric().getProducerCall()
-        .getTpsValue(MetricsDimension.DIMENSION_STATUS, MetricsDimension.DIMENSION_STATUS_ALL).getValue(), 0);
-    Assert.assertEquals(1, model.getInstanceMetric().getProducerMetric().getProducerCall()
-        .getTpsValue(MetricsDimension.DIMENSION_STATUS, MetricsDimension.DIMENSION_STATUS_CODE_GROUP_2XX)
-        .getValue(), 0);
-    Assert.assertEquals(1, model.getInstanceMetric().getProducerMetric().getProducerCall()
-        .getTpsValue(MetricsDimension.DIMENSION_STATUS, MetricsDimension.DIMENSION_STATUS_CODE_GROUP_3XX)
-        .getValue(), 0);
-    Assert.assertEquals(1, model.getInstanceMetric().getProducerMetric().getProducerCall()
-        .getTpsValue(MetricsDimension.DIMENSION_STATUS, MetricsDimension.DIMENSION_STATUS_CODE_GROUP_4XX)
-        .getValue(), 0);
-    Assert.assertEquals(1, model.getInstanceMetric().getProducerMetric().getProducerCall()
-        .getTpsValue(MetricsDimension.DIMENSION_STATUS, MetricsDimension.DIMENSION_STATUS_CODE_GROUP_5XX)
-        .getValue(), 0);
-    Assert.assertEquals(1, model.getInstanceMetric().getProducerMetric().getProducerCall()
-        .getTpsValue(MetricsDimension.DIMENSION_STATUS, MetricsDimension.DIMENSION_STATUS_CODE_GROUP_OTHER)
-        .getValue(), 0);
-
-    Assert.assertEquals(1, model.getInstanceMetric().getConsumerMetric().getConsumerCall()
-        .getTotalValue(MetricsDimension.DIMENSION_STATUS, MetricsDimension.DIMENSION_STATUS_ALL).getValue(), 0);
-    Assert.assertEquals(1, model.getInstanceMetric().getConsumerMetric().getConsumerCall()
-        .getTotalValue(MetricsDimension.DIMENSION_STATUS, MetricsDimension.DIMENSION_STATUS_CODE_GROUP_2XX)
-        .getValue(), 0);
-  }
-
-  @Test
-  public void testCodeDimension() throws InterruptedException {
-    RegistryMetric model = prepare(MetricsDimension.DIMENSION_STATUS_OUTPUT_LEVEL_CODE);
-
-    Assert.assertEquals(5, model.getInstanceMetric().getProducerMetric().getProducerCall()
-        .getTpsValue(MetricsDimension.DIMENSION_STATUS, MetricsDimension.DIMENSION_STATUS_ALL).getValue(), 0);
-    Assert.assertEquals(1, model.getInstanceMetric().getProducerMetric().getProducerCall()
-        .getTpsValue(MetricsDimension.DIMENSION_STATUS, "222")
-        .getValue(), 0);
-    Assert.assertEquals(1, model.getInstanceMetric().getProducerMetric().getProducerCall()
-        .getTpsValue(MetricsDimension.DIMENSION_STATUS, "333")
-        .getValue(), 0);
-    Assert.assertEquals(1, model.getInstanceMetric().getProducerMetric().getProducerCall()
-        .getTpsValue(MetricsDimension.DIMENSION_STATUS, "444")
-        .getValue(), 0);
-    Assert.assertEquals(1, model.getInstanceMetric().getProducerMetric().getProducerCall()
-        .getTpsValue(MetricsDimension.DIMENSION_STATUS, "555")
-        .getValue(), 0);
-    Assert.assertEquals(1, model.getInstanceMetric().getProducerMetric().getProducerCall()
-        .getTpsValue(MetricsDimension.DIMENSION_STATUS, "666")
-        .getValue(), 0);
-
-    Assert.assertEquals(1, model.getInstanceMetric().getConsumerMetric().getConsumerCall()
-        .getTotalValue(MetricsDimension.DIMENSION_STATUS, MetricsDimension.DIMENSION_STATUS_ALL).getValue(), 0);
-    Assert.assertEquals(1, model.getInstanceMetric().getConsumerMetric().getConsumerCall()
-        .getTotalValue(MetricsDimension.DIMENSION_STATUS, "200")
-        .getValue(), 0);
-  }
-
-  private RegistryMetric prepare(String outputLevel) throws InterruptedException {
-    DefaultSystemMonitor systemMonitor = new DefaultSystemMonitor();
-
-    RegistryMonitor monitor = new RegistryMonitor(systemMonitor);
-    DefaultDataSource dataSource = new DefaultDataSource(monitor, "1000,2000,3000");
-
-    new DefaultEventListenerManager(monitor, new StatusConvertorFactory(), outputLevel);
-
-    EventUtils.triggerEvent(new InvocationStartedEvent("fun1", InvocationType.PRODUCER, System.nanoTime()));
-    EventUtils.triggerEvent(
-        new InvocationStartProcessingEvent("fun1", InvocationType.PRODUCER,
-            TimeUnit.MILLISECONDS.toNanos(100)));
-    EventUtils
-        .triggerEvent(new InvocationFinishedEvent("fun1", InvocationType.PRODUCER,
-            TimeUnit.MILLISECONDS.toNanos(200), TimeUnit.MILLISECONDS.toNanos(300), 222, true));
-
-    EventUtils.triggerEvent(new InvocationStartedEvent("fun1", InvocationType.PRODUCER, System.nanoTime()));
-    EventUtils.triggerEvent(
-        new InvocationStartProcessingEvent("fun1", InvocationType.PRODUCER,
-            TimeUnit.MILLISECONDS.toNanos(100)));
-    EventUtils
-        .triggerEvent(new InvocationFinishedEvent("fun1", InvocationType.PRODUCER,
-            TimeUnit.MILLISECONDS.toNanos(200), TimeUnit.MILLISECONDS.toNanos(300), 333, false));
-
-    EventUtils.triggerEvent(new InvocationStartedEvent("fun1", InvocationType.PRODUCER, System.nanoTime()));
-    EventUtils.triggerEvent(
-        new InvocationStartProcessingEvent("fun1", InvocationType.PRODUCER,
-            TimeUnit.MILLISECONDS.toNanos(100)));
-    EventUtils
-        .triggerEvent(new InvocationFinishedEvent("fun1", InvocationType.PRODUCER,
-            TimeUnit.MILLISECONDS.toNanos(200), TimeUnit.MILLISECONDS.toNanos(300), 444, false));
-
-    EventUtils.triggerEvent(new InvocationStartedEvent("fun1", InvocationType.PRODUCER, System.nanoTime()));
-    EventUtils.triggerEvent(
-        new InvocationStartProcessingEvent("fun1", InvocationType.PRODUCER,
-            TimeUnit.MILLISECONDS.toNanos(100)));
-    EventUtils
-        .triggerEvent(new InvocationFinishedEvent("fun1", InvocationType.PRODUCER,
-            TimeUnit.MILLISECONDS.toNanos(200), TimeUnit.MILLISECONDS.toNanos(300), 555, false));
-
-    EventUtils.triggerEvent(new InvocationStartedEvent("fun1", InvocationType.PRODUCER, System.nanoTime()));
-    EventUtils.triggerEvent(
-        new InvocationStartProcessingEvent("fun1", InvocationType.PRODUCER,
-            TimeUnit.MILLISECONDS.toNanos(100)));
-    EventUtils
-        .triggerEvent(new InvocationFinishedEvent("fun1", InvocationType.PRODUCER,
-            TimeUnit.MILLISECONDS.toNanos(200), TimeUnit.MILLISECONDS.toNanos(300), 666, false));
-
-    //fun2 is a CONSUMER invocation call once and completed
-    EventUtils.triggerEvent(new InvocationStartedEvent("fun2", InvocationType.CONSUMER, System.nanoTime()));
-    EventUtils.triggerEvent(
-        new InvocationStartProcessingEvent("fun2", InvocationType.CONSUMER,
-            TimeUnit.MILLISECONDS.toNanos(100)));
-    EventUtils
-        .triggerEvent(new InvocationFinishedEvent("fun2", InvocationType.CONSUMER,
-            TimeUnit.MILLISECONDS.toNanos(200), TimeUnit.MILLISECONDS.toNanos(300), 200, true));
-
-    //sim lease one window time
-    Thread.sleep(1000);
-
-    return dataSource.getRegistryMetric(1000);
-  }
-}
diff --git a/metrics/metrics-integration/metrics-prometheus/src/main/java/org/apache/servicecomb/metrics/prometheus/MetricsCollector.java b/metrics/metrics-integration/metrics-prometheus/src/main/java/org/apache/servicecomb/metrics/prometheus/MetricsCollector.java
index 932863e..08e5135 100644
--- a/metrics/metrics-integration/metrics-prometheus/src/main/java/org/apache/servicecomb/metrics/prometheus/MetricsCollector.java
+++ b/metrics/metrics-integration/metrics-prometheus/src/main/java/org/apache/servicecomb/metrics/prometheus/MetricsCollector.java
@@ -20,14 +20,9 @@ package org.apache.servicecomb.metrics.prometheus;
 import java.util.ArrayList;
 import java.util.List;
 import java.util.Map;
-import java.util.stream.Collectors;
+import java.util.Map.Entry;
 
-import org.apache.servicecomb.metrics.common.CallMetric;
-import org.apache.servicecomb.metrics.common.ConsumerInvocationMetric;
-import org.apache.servicecomb.metrics.common.DoubleMetricValue;
-import org.apache.servicecomb.metrics.common.LongMetricValue;
-import org.apache.servicecomb.metrics.common.ProducerInvocationMetric;
-import org.apache.servicecomb.metrics.common.RegistryMetric;
+import org.apache.servicecomb.foundation.metrics.MetricsConst;
 import org.apache.servicecomb.metrics.core.publish.DataSource;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Component;
@@ -56,79 +51,34 @@ public class MetricsCollector extends Collector implements Collector.Describable
   }
 
   private List<MetricFamilySamples> load() {
-    RegistryMetric registryMetric = dataSource.getRegistryMetric();
+    Map<String, Double> registryMetric = dataSource.measure(dataSource.getAppliedWindowTime().get(0), true);
     List<MetricFamilySamples> familySamples = new ArrayList<>();
 
-    List<Sample> instanceSamples = new ArrayList<>();
-    instanceSamples.addAll(convertMetricValues(registryMetric.getInstanceMetric().getSystemMetric().toMap()));
-    instanceSamples.addAll(convertConsumerMetric(registryMetric.getInstanceMetric().getConsumerMetric()));
-    instanceSamples.addAll(convertCallMetric(registryMetric.getInstanceMetric().getConsumerMetric().getConsumerCall()));
-    instanceSamples.addAll(convertProducerMetric(registryMetric.getInstanceMetric().getProducerMetric()));
-    instanceSamples.addAll(convertCallMetric(registryMetric.getInstanceMetric().getProducerMetric().getProducerCall()));
-    familySamples
-        .add(new MetricFamilySamples("Instance Level", Type.UNTYPED, "Instance Level Metrics", instanceSamples));
-
-    if (registryMetric.getConsumerMetrics().size() != 0) {
-      List<Sample> consumerSamples = new ArrayList<>();
-      for (ConsumerInvocationMetric metric : registryMetric.getConsumerMetrics().values()) {
-        consumerSamples.addAll(convertConsumerMetric(metric));
-        consumerSamples.addAll(convertCallMetric(metric.getConsumerCall()));
-      }
-      familySamples
-          .add(new MetricFamilySamples("Consumer Side", Type.UNTYPED, "Consumer Side Metrics", consumerSamples));
-    }
-
-    if (registryMetric.getProducerMetrics().size() != 0) {
-      List<Sample> producerSamples = new ArrayList<>();
-      for (ProducerInvocationMetric metric : registryMetric.getProducerMetrics().values()) {
-        producerSamples.addAll(convertProducerMetric(metric));
-        producerSamples.addAll(convertCallMetric(metric.getProducerCall()));
+    List<Sample> samples = new ArrayList<>();
+    for (Entry<String, Double> metric : registryMetric.entrySet()) {
+      List<String> tagNames = new ArrayList<>();
+      List<String> tagValues = new ArrayList<>();
+      String name = metric.getKey();
+      if (metric.getKey().contains("(")) {
+        String[] nameAndTag = metric.getKey().split("\\(");
+        name = nameAndTag[0];
+        String[] tagAnValues = nameAndTag[1].split("[=,)]");
+        for (int i = 0; i < tagAnValues.length; i += 2) {
+          //we need put operation name in metrics name,not a label
+          if (MetricsConst.TAG_OPERATION.equals(tagAnValues[i])) {
+            name = name + "." + tagAnValues[i + 1];
+          } else if (!"type".equals(tagAnValues[i])) {
+            tagNames.add(tagAnValues[i]);
+            tagValues.add(tagAnValues[i + 1]);
+          }
+        }
       }
-      familySamples
-          .add(new MetricFamilySamples("Producer Side", Type.UNTYPED, "Producer Side Metrics", producerSamples));
+      samples.add(new Sample(formatMetricName(name), tagNames, tagValues, metric.getValue()));
     }
-
+    familySamples.add(new MetricFamilySamples("ServiceComb Metrics", Type.UNTYPED, "ServiceComb Metrics", samples));
     return familySamples;
   }
 
-  private List<Sample> convertConsumerMetric(ConsumerInvocationMetric metric) {
-    return convertMetricValues(metric.getConsumerLatency().toMap());
-  }
-
-  private List<Sample> convertProducerMetric(ProducerInvocationMetric metric) {
-    List<Sample> samples = new ArrayList<>();
-    samples.addAll(convertMetricValues(metric.getExecutionTime().toMap()));
-    samples.addAll(convertMetricValues(metric.getLifeTimeInQueue().toMap()));
-    samples.addAll(convertMetricValues(metric.getProducerLatency().toMap()));
-    samples.add(
-        new Sample(formatMetricName(metric.getPrefix() + ".waitInQueue.count"), new ArrayList<>(), new ArrayList<>(),
-            (double) metric.getWaitInQueue()));
-    return samples;
-  }
-
-  private List<Sample> convertMetricValues(Map<String, Number> metrics) {
-    return metrics.entrySet().stream().map((entry) ->
-        new Sample(formatMetricName(entry.getKey()), new ArrayList<>(), new ArrayList<>(),
-            entry.getValue().doubleValue())).collect(Collectors.toList());
-  }
-
-  private List<Sample> convertCallMetric(CallMetric metric) {
-    List<Sample> samples = new ArrayList<>();
-    String totalName = formatMetricName(metric.getPrefix() + ".total");
-    for (LongMetricValue value : metric.getTotalValues()) {
-      samples.add(new Sample(totalName,
-          new ArrayList<>(value.getDimensions().keySet()), new ArrayList<>(value.getDimensions().values()),
-          (double) value.getValue()));
-    }
-    String tpsName = formatMetricName(metric.getPrefix() + ".tps");
-    for (DoubleMetricValue value : metric.getTpsValues()) {
-      samples.add(new Sample(tpsName,
-          new ArrayList<>(value.getDimensions().keySet()), new ArrayList<>(value.getDimensions().values()),
-          value.getValue()));
-    }
-    return samples;
-  }
-
   //convert name for match prometheus
   private String formatMetricName(String name) {
     return name.replace(".", "_");
diff --git a/metrics/pom.xml b/metrics/pom.xml
index ce33851..9645c0c 100644
--- a/metrics/pom.xml
+++ b/metrics/pom.xml
@@ -32,9 +32,9 @@
   <name>Java Chassis::Metrics</name>
 
   <modules>
-    <module>metrics-common</module>
     <module>metrics-core</module>
     <module>metrics-extension</module>
     <module>metrics-integration</module>
   </modules>
+
 </project>
diff --git a/samples/metrics-extend-healthcheck/src/main/java/org/apache/servicecomb/samples/metrics/extendhealthcheck/CustomHealthCheckerAnnotation.java b/samples/metrics-extend-healthcheck/src/main/java/org/apache/servicecomb/samples/metrics/extendhealthcheck/CustomHealthCheckerAnnotation.java
index 9fd3c6c..c0ac13d 100644
--- a/samples/metrics-extend-healthcheck/src/main/java/org/apache/servicecomb/samples/metrics/extendhealthcheck/CustomHealthCheckerAnnotation.java
+++ b/samples/metrics-extend-healthcheck/src/main/java/org/apache/servicecomb/samples/metrics/extendhealthcheck/CustomHealthCheckerAnnotation.java
@@ -17,8 +17,8 @@
 
 package org.apache.servicecomb.samples.metrics.extendhealthcheck;
 
-import org.apache.servicecomb.metrics.common.HealthCheckResult;
-import org.apache.servicecomb.metrics.common.HealthChecker;
+import org.apache.servicecomb.foundation.metrics.publish.HealthCheckResult;
+import org.apache.servicecomb.foundation.metrics.publish.HealthChecker;
 import org.springframework.stereotype.Component;
 
 //this health check will auto register because spring bean annotation
diff --git a/samples/metrics-extend-healthcheck/src/main/java/org/apache/servicecomb/samples/metrics/extendhealthcheck/MySqlHealthChecker.java b/samples/metrics-extend-healthcheck/src/main/java/org/apache/servicecomb/samples/metrics/extendhealthcheck/MySqlHealthChecker.java
index 66d0852..a1465e3 100644
--- a/samples/metrics-extend-healthcheck/src/main/java/org/apache/servicecomb/samples/metrics/extendhealthcheck/MySqlHealthChecker.java
+++ b/samples/metrics-extend-healthcheck/src/main/java/org/apache/servicecomb/samples/metrics/extendhealthcheck/MySqlHealthChecker.java
@@ -21,8 +21,9 @@ import java.sql.Connection;
 import java.sql.DriverManager;
 import java.sql.SQLException;
 
-import org.apache.servicecomb.metrics.common.HealthCheckResult;
-import org.apache.servicecomb.metrics.common.HealthChecker;
+import org.apache.servicecomb.foundation.metrics.publish.HealthCheckResult;
+import org.apache.servicecomb.foundation.metrics.publish.HealthChecker;
+
 
 //this is a demo health checker for mysql
 public class MySqlHealthChecker implements HealthChecker {
diff --git a/samples/metrics-write-file-sample/metrics-write-file/src/main/java/org/apache/servicecomb/samples/mwf/FileContentConvertor.java b/samples/metrics-write-file-sample/metrics-write-file/src/main/java/org/apache/servicecomb/samples/mwf/FileContentConvertor.java
index b835aad..dc13f9a 100644
--- a/samples/metrics-write-file-sample/metrics-write-file/src/main/java/org/apache/servicecomb/samples/mwf/FileContentConvertor.java
+++ b/samples/metrics-write-file-sample/metrics-write-file/src/main/java/org/apache/servicecomb/samples/mwf/FileContentConvertor.java
@@ -19,9 +19,7 @@ package org.apache.servicecomb.samples.mwf;
 
 import java.util.Map;
 
-import org.apache.servicecomb.metrics.common.RegistryMetric;
-
 //convert metrics to output content
 public interface FileContentConvertor {
-  Map<String, String> convert(RegistryMetric registryMetric);
+  Map<String, String> convert(Map<String, Double> registryMetric);
 }
diff --git a/samples/metrics-write-file-sample/metrics-write-file/src/main/java/org/apache/servicecomb/samples/mwf/SimpleFileContentConvertor.java b/samples/metrics-write-file-sample/metrics-write-file/src/main/java/org/apache/servicecomb/samples/mwf/SimpleFileContentConvertor.java
index 839fe03..aa5d909 100644
--- a/samples/metrics-write-file-sample/metrics-write-file/src/main/java/org/apache/servicecomb/samples/mwf/SimpleFileContentConvertor.java
+++ b/samples/metrics-write-file-sample/metrics-write-file/src/main/java/org/apache/servicecomb/samples/mwf/SimpleFileContentConvertor.java
@@ -23,7 +23,7 @@ import java.util.HashMap;
 import java.util.Map;
 import java.util.Map.Entry;
 
-import org.apache.servicecomb.metrics.common.RegistryMetric;
+import org.apache.servicecomb.foundation.metrics.MetricsConst;
 
 import com.netflix.config.DynamicPropertyFactory;
 
@@ -41,12 +41,11 @@ public class SimpleFileContentConvertor implements FileContentConvertor {
   }
 
   @Override
-  public Map<String, String> convert(RegistryMetric registryMetric) {
+  public Map<String, String> convert(Map<String, Double> registryMetric) {
     Map<String, String> pickedMetrics = new HashMap<>();
-    for (Entry<String, Number> metric : registryMetric.toMap().entrySet()) {
-      pickedMetrics.put(metric.getKey(),
-          String.format(doubleStringFormatter,
-              round(metric.getValue().doubleValue(), doubleRoundPlaces)));
+    for (Entry<String, Double> metric : registryMetric.entrySet()) {
+      pickedMetrics.put(convertMetricKey(metric.getKey()),
+          String.format(doubleStringFormatter, round(metric.getValue(), doubleRoundPlaces)));
     }
     return pickedMetrics;
   }
@@ -58,4 +57,26 @@ public class SimpleFileContentConvertor implements FileContentConvertor {
     }
     return 0;
   }
+
+  private String convertMetricKey(String key) {
+    String[] nameAndTag = key.split("\\(");
+    Map<String, String> tags = new HashMap<>();
+    String[] tagAnValues = nameAndTag[1].split("[=,)]");
+    for (int i = 0; i < tagAnValues.length; i += 2) {
+      tags.put(tagAnValues[i], tagAnValues[i + 1]);
+    }
+    if (nameAndTag[0].startsWith(MetricsConst.JVM)) {
+      return "jvm." + tags.get(MetricsConst.TAG_NAME);
+    } else {
+      StringBuilder builder = new StringBuilder();
+      builder.append(tags.get(MetricsConst.TAG_OPERATION));
+      builder.append(".");
+      builder.append(tags.get(MetricsConst.TAG_ROLE));
+      builder.append(".");
+      builder.append(tags.get(MetricsConst.TAG_STAGE));
+      builder.append(".");
+      builder.append(tags.get(MetricsConst.TAG_STATISTIC));
+      return builder.toString();
+    }
+  }
 }
diff --git a/samples/metrics-write-file-sample/metrics-write-file/src/main/java/org/apache/servicecomb/samples/mwf/WriteFileInitializer.java b/samples/metrics-write-file-sample/metrics-write-file/src/main/java/org/apache/servicecomb/samples/mwf/WriteFileInitializer.java
index a277328..f97d255 100644
--- a/samples/metrics-write-file-sample/metrics-write-file/src/main/java/org/apache/servicecomb/samples/mwf/WriteFileInitializer.java
+++ b/samples/metrics-write-file-sample/metrics-write-file/src/main/java/org/apache/servicecomb/samples/mwf/WriteFileInitializer.java
@@ -24,7 +24,6 @@ import java.util.concurrent.Executors;
 
 import org.apache.commons.lang3.StringUtils;
 import org.apache.servicecomb.foundation.common.net.NetUtils;
-import org.apache.servicecomb.metrics.common.RegistryMetric;
 import org.apache.servicecomb.metrics.core.MetricsConfig;
 import org.apache.servicecomb.metrics.core.publish.DataSource;
 import org.apache.servicecomb.serviceregistry.RegistryUtils;
@@ -87,8 +86,8 @@ public class WriteFileInitializer {
         .scheduleWithFixedDelay(poller, 0, metricPoll, MILLISECONDS);
   }
 
-  public void run() {
-    RegistryMetric registryMetric = dataSource.getRegistryMetric();
+  private void run() {
+    Map<String, Double> registryMetric = dataSource.measure(dataSource.getAppliedWindowTime().get(0), true);
     Map<String, String> convertedMetrics = convertor.convert(registryMetric);
     Map<String, String> formattedMetrics = formatter.format(convertedMetrics);
 
diff --git a/samples/metrics-write-file-sample/metrics-write-file/src/test/java/org/apache/servicecomb/samples/mwf/TestWriteFile.java b/samples/metrics-write-file-sample/metrics-write-file/src/test/java/org/apache/servicecomb/samples/mwf/TestWriteFile.java
deleted file mode 100644
index 67f4b44..0000000
--- a/samples/metrics-write-file-sample/metrics-write-file/src/test/java/org/apache/servicecomb/samples/mwf/TestWriteFile.java
+++ /dev/null
@@ -1,174 +0,0 @@
-/*
- * 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.servicecomb.samples.mwf;
-
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-import org.apache.servicecomb.metrics.common.CallMetric;
-import org.apache.servicecomb.metrics.common.ConsumerInvocationMetric;
-import org.apache.servicecomb.metrics.common.DoubleMetricValue;
-import org.apache.servicecomb.metrics.common.LongMetricValue;
-import org.apache.servicecomb.metrics.common.RegistryMetric;
-import org.apache.servicecomb.metrics.common.SystemMetric;
-import org.apache.servicecomb.metrics.common.TimerMetric;
-import org.apache.servicecomb.metrics.core.publish.DataSource;
-import org.apache.servicecomb.serviceregistry.Features;
-import org.apache.servicecomb.serviceregistry.RegistryUtils;
-import org.apache.servicecomb.serviceregistry.ServiceRegistry;
-import org.apache.servicecomb.serviceregistry.api.registry.Microservice;
-import org.apache.servicecomb.serviceregistry.api.registry.MicroserviceInstance;
-import org.apache.servicecomb.serviceregistry.cache.InstanceCacheManager;
-import org.apache.servicecomb.serviceregistry.client.ServiceRegistryClient;
-import org.apache.servicecomb.serviceregistry.client.http.MicroserviceInstances;
-import org.apache.servicecomb.serviceregistry.consumer.AppManager;
-import org.junit.Assert;
-import org.junit.Test;
-import org.mockito.Mockito;
-
-import mockit.Expectations;
-
-public class TestWriteFile {
-
-  @Test
-  public void test() {
-
-    new Expectations(RegistryUtils.class) {
-      {
-        RegistryUtils.getServiceRegistry();
-        result = new ServiceRegistry() {
-          @Override
-          public void init() {
-
-          }
-
-          @Override
-          public void run() {
-
-          }
-
-          @Override
-          public void destroy() {
-
-          }
-
-          @Override
-          public Set<String> getCombinedMicroserviceNames() {
-            return null;
-          }
-
-          @Override
-          public Microservice getMicroservice() {
-            return null;
-          }
-
-          @Override
-          public MicroserviceInstance getMicroserviceInstance() {
-            return null;
-          }
-
-          @Override
-          public ServiceRegistryClient getServiceRegistryClient() {
-            return null;
-          }
-
-          @Override
-          public AppManager getAppManager() {
-            return null;
-          }
-
-          @Override
-          public InstanceCacheManager getInstanceCacheManager() {
-            return null;
-          }
-
-          @Override
-          public List<MicroserviceInstance> findServiceInstance(String appId, String microserviceName,
-              String microserviceVersionRule) {
-            return null;
-          }
-
-          @Override
-          public MicroserviceInstances findServiceInstances(String appId, String microserviceName,
-              String microserviceVersionRule, String revision) {
-            return null;
-          }
-
-          @Override
-          public boolean updateMicroserviceProperties(Map<String, String> properties) {
-            return false;
-          }
-
-          @Override
-          public boolean updateInstanceProperties(Map<String, String> instanceProperties) {
-            return false;
-          }
-
-          @Override
-          public Microservice getRemoteMicroservice(String microserviceId) {
-            return null;
-          }
-
-          @Override
-          public Features getFeatures() {
-            return null;
-          }
-        };
-      }
-    };
-
-    StringBuilder builder = new StringBuilder();
-
-    MetricsFileWriter writer =
-        (loggerName, filePrefix, content) -> builder.append(loggerName).append(filePrefix).append(content);
-
-    SystemMetric systemMetric = new SystemMetric(50, 10, 1, 2, 3,
-        4, 5, 6, 7, 8);
-
-    Map<String, ConsumerInvocationMetric> consumerInvocationMetricMap = new HashMap<>();
-    consumerInvocationMetricMap.put("A",
-        new ConsumerInvocationMetric("A", "A",
-            new TimerMetric("A1", 1, 2, 3, 4),
-            new CallMetric("A2", Collections.singletonList(new LongMetricValue("A2", 100L, new HashMap<>())),
-                Collections.singletonList(new DoubleMetricValue("A2", 999.44444, new HashMap<>())))));
-
-    consumerInvocationMetricMap.put("B",
-        new ConsumerInvocationMetric("B", "B",
-            new TimerMetric("B1", 1, 2, 3, 4),
-            new CallMetric("B2", Collections.singletonList(new LongMetricValue("B2", 100L, new HashMap<>())),
-                Collections.singletonList(new DoubleMetricValue("B2", 888.66666, new HashMap<>())))));
-
-    RegistryMetric metric = new RegistryMetric(systemMetric, consumerInvocationMetricMap, new HashMap<>());
-
-    DataSource dataSource = Mockito.mock(DataSource.class);
-    Mockito.when(dataSource.getRegistryMetric()).thenReturn(metric);
-
-    WriteFileInitializer writeFileInitializer = new WriteFileInitializer(writer, dataSource,
-        "localhost", "appId.serviceName");
-
-    writeFileInitializer.run();
-
-    String sb = builder.toString();
-
-    Assert.assertTrue(sb.contains("999.4"));
-    Assert.assertTrue(sb.contains("888.7"));
-  }
-}
diff --git a/transports/transport-highway/src/main/java/org/apache/servicecomb/transport/highway/HighwayServerInvoke.java b/transports/transport-highway/src/main/java/org/apache/servicecomb/transport/highway/HighwayServerInvoke.java
index 843c0fe..37bdcfc 100644
--- a/transports/transport-highway/src/main/java/org/apache/servicecomb/transport/highway/HighwayServerInvoke.java
+++ b/transports/transport-highway/src/main/java/org/apache/servicecomb/transport/highway/HighwayServerInvoke.java
@@ -129,7 +129,7 @@ public class HighwayServerInvoke {
 
     invocation.next(response -> {
       sendResponse(invocation.getContext(), response);
-      invocation.triggerFinishedEvent(response.getStatusCode(), response.isSuccessed());
+      invocation.triggerFinishedEvent(response.getStatusCode());
     });
   }
 

-- 
To stop receiving notification emails like this one, please contact
ningjiang@apache.org.