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:46 UTC

[incubator-servicecomb-java-chassis] 05/07: SCB-327 fix pr comment

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 33d4c103f07f30eb9cce8dab448e1a9355b54195
Author: zhengyangyong <ya...@huawei.com>
AuthorDate: Sat Feb 24 15:46:53 2018 +0800

    SCB-327 fix pr comment
    
    Signed-off-by: zhengyangyong <ya...@huawei.com>
---
 .../common/rest/AbstractRestInvocation.java        |  4 +-
 .../org/apache/servicecomb/core/Invocation.java    |  7 +-
 .../core/provider/consumer/InvokerUtils.java       |  4 +-
 .../demo/springmvc/client/SpringmvcClient.java     |  2 +-
 .../demo/perf/PerfMetricsFilePublisher.java        | 87 ++++++++++------------
 .../foundation/common/event/EventBus.java          | 14 ++++
 .../foundation/common/event/EventListener.java     |  1 +
 .../foundation/common/utils/EventUtils.java        | 37 ---------
 .../foundation/common/event/TestEventBus.java      | 21 ++++--
 .../foundation/metrics/publish/MetricsLoader.java  |  6 +-
 .../foundation/metrics/publish/TestMetricNode.java | 16 ++--
 .../metrics/publish/TestMetricsLoader.java         | 13 ----
 metrics/metrics-common/pom.xml                     |  0
 .../servicecomb/metrics/core/MonitorManager.java   | 16 +++-
 .../event/InvocationFinishedEventListener.java     | 11 ++-
 .../InvocationStartExecutionEventListener.java     |  9 ++-
 .../core/event/InvocationStartedEventListener.java |  9 ++-
 .../core/publish/HealthCheckerPublisher.java       |  2 +-
 .../metrics/core/publish/MetricsPublisher.java     | 16 ----
 ...rvicecomb.foundation.common.event.EventListener | 37 +++++++++
 .../metrics/core/TestEventAndRunner.java           | 61 ++++++++-------
 .../metrics/core/TestHealthCheckerPublisher.java   |  2 +-
 .../samples/mwf/SimpleFileContentConvertor.java    |  2 +-
 .../transport/highway/HighwayServerInvoke.java     |  4 +-
 24 files changed, 201 insertions(+), 180 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 4e1ce24..3db3879 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
@@ -39,7 +39,7 @@ import org.apache.servicecomb.core.Invocation;
 import org.apache.servicecomb.core.definition.MicroserviceMeta;
 import org.apache.servicecomb.core.definition.OperationMeta;
 import org.apache.servicecomb.core.metrics.InvocationStartedEvent;
-import org.apache.servicecomb.foundation.common.utils.EventUtils;
+import org.apache.servicecomb.foundation.common.event.EventBus;
 import org.apache.servicecomb.foundation.common.utils.JsonUtils;
 import org.apache.servicecomb.foundation.vertx.http.HttpServletRequestEx;
 import org.apache.servicecomb.foundation.vertx.http.HttpServletResponseEx;
@@ -116,7 +116,7 @@ public abstract class AbstractRestInvocation {
 
     InvocationStartedEvent startedEvent = new InvocationStartedEvent(operationMeta.getMicroserviceQualifiedName(),
         InvocationType.PRODUCER, System.nanoTime());
-    EventUtils.triggerEvent(startedEvent);
+    EventBus.getInstance().triggerEvent(startedEvent);
 
     operationMeta.getExecutor().execute(() -> {
       synchronized (this.requestEx) {
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 6db9279..d26c903 100644
--- a/core/src/main/java/org/apache/servicecomb/core/Invocation.java
+++ b/core/src/main/java/org/apache/servicecomb/core/Invocation.java
@@ -27,7 +27,7 @@ import org.apache.servicecomb.core.definition.SchemaMeta;
 import org.apache.servicecomb.core.metrics.InvocationFinishedEvent;
 import org.apache.servicecomb.core.metrics.InvocationStartExecutionEvent;
 import org.apache.servicecomb.core.provider.consumer.ReferenceConfig;
-import org.apache.servicecomb.foundation.common.utils.EventUtils;
+import org.apache.servicecomb.foundation.common.event.EventBus;
 import org.apache.servicecomb.swagger.invocation.AsyncResponse;
 import org.apache.servicecomb.swagger.invocation.InvocationType;
 import org.apache.servicecomb.swagger.invocation.SwaggerInvocation;
@@ -188,13 +188,14 @@ public class Invocation extends SwaggerInvocation {
   public void triggerStartExecutionEvent() {
     if (InvocationType.PRODUCER.equals(invocationType)) {
       this.startExecutionTime = System.nanoTime();
-      EventUtils.triggerEvent(new InvocationStartExecutionEvent(operationMeta.getMicroserviceQualifiedName()));
+      EventBus.getInstance()
+          .triggerEvent(new InvocationStartExecutionEvent(operationMeta.getMicroserviceQualifiedName()));
     }
   }
 
   public void triggerFinishedEvent(int statusCode) {
     long finishedTime = System.nanoTime();
-    EventUtils
+    EventBus.getInstance()
         .triggerEvent(new InvocationFinishedEvent(operationMeta.getMicroserviceQualifiedName(), this.invocationType,
             startExecutionTime - startTime, finishedTime - startExecutionTime,
             finishedTime - startTime, statusCode));
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 8977e87..8a48299 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
@@ -21,7 +21,7 @@ import org.apache.servicecomb.core.Invocation;
 import org.apache.servicecomb.core.definition.SchemaMeta;
 import org.apache.servicecomb.core.invocation.InvocationFactory;
 import org.apache.servicecomb.core.metrics.InvocationStartedEvent;
-import org.apache.servicecomb.foundation.common.utils.EventUtils;
+import org.apache.servicecomb.foundation.common.event.EventBus;
 import org.apache.servicecomb.swagger.invocation.AsyncResponse;
 import org.apache.servicecomb.swagger.invocation.InvocationType;
 import org.apache.servicecomb.swagger.invocation.Response;
@@ -114,7 +114,7 @@ public final class InvokerUtils {
 
   private static void triggerStartedEvent(Invocation invocation) {
     long startTime = System.nanoTime();
-    EventUtils.triggerEvent(new InvocationStartedEvent(invocation.getMicroserviceQualifiedName(),
+    EventBus.getInstance().triggerEvent(new InvocationStartedEvent(invocation.getMicroserviceQualifiedName(),
         InvocationType.CONSUMER, startTime));
     invocation.setStartTime(startTime);
   }
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 6c938e5..68074c6 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
@@ -104,7 +104,7 @@ public class SpringmvcClient {
           .check(true, metrics.get("jvm(name=heapUsed,statistic=gauge)") != 0);
       TestMgr.check(true, metrics.size() > 0);
       TestMgr.check(true, metrics.get(
-          "servicecomb.invocation(operation=springmvc.codeFirst.saySomething,role=PRODUCER,stage=total,statistic=count,status=200)")
+          "servicecomb.invocation(operation=springmvc.codeFirst.saySomething,role=producer,stage=total,statistic=count,status=200)")
           >= 0);
     } catch (Exception e) {
       TestMgr.check("true", "false");
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 2c6fc42..537577e 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
@@ -20,7 +20,6 @@ import java.util.Map;
 import java.util.Map.Entry;
 import java.util.concurrent.TimeUnit;
 
-import org.apache.servicecomb.foundation.common.exceptions.ServiceCombException;
 import org.apache.servicecomb.foundation.metrics.MetricsConst;
 import org.apache.servicecomb.foundation.metrics.publish.MetricNode;
 import org.apache.servicecomb.foundation.metrics.publish.MetricsLoader;
@@ -70,57 +69,51 @@ public class PerfMetricsFilePublisher {
   }
 
   private void collectMetrics(MetricsLoader loader, StringBuilder sb) {
-    MetricNode treeNode;
-    try {
-      treeNode = loader
+    if (loader.containsId(MetricsConst.SERVICECOMB_INVOCATION)) {
+      MetricNode treeNode = loader
           .getMetricTree(MetricsConst.SERVICECOMB_INVOCATION, MetricsConst.TAG_ROLE, MetricsConst.TAG_OPERATION,
               MetricsConst.TAG_STATUS);
-    }
-    //before receive any request,there are no MetricsConst.SERVICECOMB_INVOCATION,so getMetricTree will throw ServiceCombException
-    catch (ServiceCombException ignored) {
-      return;
-    }
-
-    if (treeNode != null && treeNode.getChildren().size() != 0) {
-      MetricNode consumerNode = treeNode.getChildren().get(String.valueOf(InvocationType.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(MetricsConst.TAG_STAGE, MetricsConst.STAGE_TOTAL,
-                        MetricsConst.TAG_STATISTIC, "tps"),
-                statusNode.getValue()
-                    .getFirstMatchMetricValue(TimeUnit.MILLISECONDS, MetricsConst.TAG_STAGE, MetricsConst.STAGE_TOTAL,
-                        MetricsConst.TAG_STATISTIC, "latency"),
-                statusNode.getKey(), operationNode.getKey()));
+      if (treeNode != null && treeNode.getChildren().size() != 0) {
+        MetricNode consumerNode = treeNode.getChildren().get(String.valueOf(InvocationType.CONSUMER).toLowerCase());
+        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(MetricsConst.TAG_STAGE, MetricsConst.STAGE_TOTAL,
+                          MetricsConst.TAG_STATISTIC, "tps"),
+                  statusNode.getValue()
+                      .getFirstMatchMetricValue(TimeUnit.MILLISECONDS, MetricsConst.TAG_STAGE, MetricsConst.STAGE_TOTAL,
+                          MetricsConst.TAG_STATISTIC, "latency"),
+                  statusNode.getKey(), operationNode.getKey()));
+            }
           }
         }
-      }
 
-      MetricNode producerNode = treeNode.getChildren().get(String.valueOf(InvocationType.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(MetricsConst.TAG_STAGE, MetricsConst.STAGE_TOTAL,
-                        MetricsConst.TAG_STATISTIC, "tps"),
-                statusNode.getValue()
-                    .getFirstMatchMetricValue(TimeUnit.MILLISECONDS, MetricsConst.TAG_STAGE, MetricsConst.STAGE_TOTAL,
-                        MetricsConst.TAG_STATISTIC, "latency"),
-                statusNode.getValue()
-                    .getFirstMatchMetricValue(TimeUnit.MILLISECONDS, MetricsConst.TAG_STAGE, MetricsConst.STAGE_QUEUE,
-                        MetricsConst.TAG_STATISTIC, "latency"),
-                statusNode.getValue()
-                    .getFirstMatchMetricValue(TimeUnit.MILLISECONDS, MetricsConst.TAG_STAGE,
-                        MetricsConst.STAGE_EXECUTION,
-                        MetricsConst.TAG_STATISTIC, "latency"),
-                statusNode.getKey(), operationNode.getKey()));
+        MetricNode producerNode = treeNode.getChildren().get(String.valueOf(InvocationType.PRODUCER).toLowerCase());
+        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(MetricsConst.TAG_STAGE, MetricsConst.STAGE_TOTAL,
+                          MetricsConst.TAG_STATISTIC, "tps"),
+                  statusNode.getValue()
+                      .getFirstMatchMetricValue(TimeUnit.MILLISECONDS, MetricsConst.TAG_STAGE, MetricsConst.STAGE_TOTAL,
+                          MetricsConst.TAG_STATISTIC, "latency"),
+                  statusNode.getValue()
+                      .getFirstMatchMetricValue(TimeUnit.MILLISECONDS, MetricsConst.TAG_STAGE, MetricsConst.STAGE_QUEUE,
+                          MetricsConst.TAG_STATISTIC, "latency"),
+                  statusNode.getValue()
+                      .getFirstMatchMetricValue(TimeUnit.MILLISECONDS, MetricsConst.TAG_STAGE,
+                          MetricsConst.STAGE_EXECUTION,
+                          MetricsConst.TAG_STATISTIC, "latency"),
+                  statusNode.getKey(), operationNode.getKey()));
+            }
           }
         }
       }
diff --git a/foundations/foundation-common/src/main/java/org/apache/servicecomb/foundation/common/event/EventBus.java b/foundations/foundation-common/src/main/java/org/apache/servicecomb/foundation/common/event/EventBus.java
index c76b179..603cdfe 100644
--- a/foundations/foundation-common/src/main/java/org/apache/servicecomb/foundation/common/event/EventBus.java
+++ b/foundations/foundation-common/src/main/java/org/apache/servicecomb/foundation/common/event/EventBus.java
@@ -23,10 +23,24 @@ import java.util.Map;
 import java.util.concurrent.CopyOnWriteArrayList;
 
 import org.apache.servicecomb.foundation.common.concurrent.ConcurrentHashMapEx;
+import org.apache.servicecomb.foundation.common.utils.SPIServiceUtils;
 
 public class EventBus {
   private final Map<Class, List<EventListener>> allEventListeners = new ConcurrentHashMapEx<>();
 
+  private static final EventBus INSTANCE = new EventBus();
+
+  public static EventBus getInstance() {
+    return INSTANCE;
+  }
+
+  private EventBus() {
+    List<EventListener> listeners = SPIServiceUtils.getAllService(EventListener.class);
+    for (EventListener listener : listeners) {
+      this.registerEventListener(listener.getEventClass(), listener);
+    }
+  }
+
   public <T> void registerEventListener(Class<T> cls, EventListener<T> eventListener) {
     List<EventListener> eventListeners = allEventListeners
         .computeIfAbsent(cls, f -> new CopyOnWriteArrayList<>());
diff --git a/foundations/foundation-common/src/main/java/org/apache/servicecomb/foundation/common/event/EventListener.java b/foundations/foundation-common/src/main/java/org/apache/servicecomb/foundation/common/event/EventListener.java
index 475ed2d..7924e1d 100644
--- a/foundations/foundation-common/src/main/java/org/apache/servicecomb/foundation/common/event/EventListener.java
+++ b/foundations/foundation-common/src/main/java/org/apache/servicecomb/foundation/common/event/EventListener.java
@@ -19,6 +19,7 @@ package org.apache.servicecomb.foundation.common.event;
 
 //Common event listener interface,java chassis component can trigger event let high level component perceive data change.
 public interface EventListener<T> {
+  Class<T> getEventClass();
 
   //process event data
   void process(T data);
diff --git a/foundations/foundation-common/src/main/java/org/apache/servicecomb/foundation/common/utils/EventUtils.java b/foundations/foundation-common/src/main/java/org/apache/servicecomb/foundation/common/utils/EventUtils.java
deleted file mode 100644
index 26902db..0000000
--- a/foundations/foundation-common/src/main/java/org/apache/servicecomb/foundation/common/utils/EventUtils.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.foundation.common.utils;
-
-import org.apache.servicecomb.foundation.common.event.EventBus;
-import org.apache.servicecomb.foundation.common.event.EventListener;
-
-public final class EventUtils {
-  private static final EventBus eventBus = new EventBus();
-
-  public static <T> void registerEventListener(Class<T> cls, EventListener<T> eventListener) {
-    eventBus.registerEventListener(cls, eventListener);
-  }
-
-  public static <T> void unregisterEventListener(Class<T> cls, EventListener<T> eventListener) {
-    eventBus.unregisterEventListener(cls, eventListener);
-  }
-
-  public static <T> void triggerEvent(T event) {
-    eventBus.triggerEvent(event);
-  }
-}
diff --git a/foundations/foundation-common/src/test/java/org/apache/servicecomb/foundation/common/event/TestEventBus.java b/foundations/foundation-common/src/test/java/org/apache/servicecomb/foundation/common/event/TestEventBus.java
index 14b508a..d373a6b 100644
--- a/foundations/foundation-common/src/test/java/org/apache/servicecomb/foundation/common/event/TestEventBus.java
+++ b/foundations/foundation-common/src/test/java/org/apache/servicecomb/foundation/common/event/TestEventBus.java
@@ -22,7 +22,6 @@ import static org.awaitility.Awaitility.await;
 import java.util.concurrent.TimeUnit;
 import java.util.concurrent.atomic.AtomicBoolean;
 
-import org.apache.servicecomb.foundation.common.utils.EventUtils;
 import org.junit.Assert;
 import org.junit.Test;
 
@@ -32,19 +31,29 @@ public class TestEventBus {
   public void test() throws InterruptedException {
     AtomicBoolean eventReceived = new AtomicBoolean(false);
 
-    EventListener<String> listener = data -> eventReceived.set(true);
+    EventListener<String> listener = new EventListener<String>() {
+      @Override
+      public Class<String> getEventClass() {
+        return String.class;
+      }
 
-    EventUtils.registerEventListener(String.class, listener);
+      @Override
+      public void process(String data) {
+        eventReceived.set(true);
+      }
+    };
 
-    EventUtils.triggerEvent("xxx");
+    EventBus.getInstance().registerEventListener(String.class, listener);
+
+    EventBus.getInstance().triggerEvent("xxx");
     await().atMost(1, TimeUnit.SECONDS)
         .until(eventReceived::get);
     Assert.assertTrue(eventReceived.get());
 
     eventReceived.set(false);
 
-    EventUtils.unregisterEventListener(String.class, listener);
-    EventUtils.triggerEvent("xxx");
+    EventBus.getInstance().unregisterEventListener(String.class, listener);
+    EventBus.getInstance().triggerEvent("xxx");
     Thread.sleep(1000);
     Assert.assertFalse(eventReceived.get());
   }
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
index 2aac335..ff0040e 100644
--- 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
@@ -39,12 +39,16 @@ public class MetricsLoader {
   }
 
   public MetricNode getMetricTree(String id, String... groupTagKeys) {
-    if (metrics.containsKey(id)) {
+    if (containsId(id)) {
       return new MetricNode(metrics.get(id), groupTagKeys);
     }
     throw new ServiceCombException("no such id : " + id);
   }
 
+  public boolean containsId(String id) {
+    return metrics.containsKey(id);
+  }
+
   public double getFirstMatchMetricValue(String name, String tagKey, String tagValue) {
     if (metrics.containsKey(name)) {
       for (Metric metric : this.metrics.get(name)) {
diff --git a/foundations/foundation-metrics/src/test/java/org/apache/servicecomb/foundation/metrics/publish/TestMetricNode.java b/foundations/foundation-metrics/src/test/java/org/apache/servicecomb/foundation/metrics/publish/TestMetricNode.java
index 543d697..09fc2ec 100644
--- a/foundations/foundation-metrics/src/test/java/org/apache/servicecomb/foundation/metrics/publish/TestMetricNode.java
+++ b/foundations/foundation-metrics/src/test/java/org/apache/servicecomb/foundation/metrics/publish/TestMetricNode.java
@@ -40,26 +40,30 @@ public class TestMetricNode {
     metrics.put("Y(K1=1000,K2=2000,K3=3000)", 800.0);
 
     MetricsLoader loader = new MetricsLoader(metrics);
-
     MetricNode node = loader.getMetricTree("X", "K1");
-
     MetricNode node_k1 = node.getChildrenNode("1");
+
+    //check metrics list
     Assert.assertEquals(3, node_k1.getMetrics().size());
+
+    //check getFirstMatchMetricValue with single Tag
     Assert.assertEquals(100, node_k1.getFirstMatchMetricValue("K2", "2"), 0);
     Assert.assertEquals(100 * 1000, node_k1.getFirstMatchMetricValue(TimeUnit.MILLISECONDS, "K2", "2"), 0);
     Assert.assertEquals(100 * 1000, node_k1.getFirstMatchMetricValue(TimeUnit.MILLISECONDS, "K2", "2"), 0);
 
+    //check getFirstMatchMetricValue with multi Tag
     Assert.assertEquals(200, node_k1.getFirstMatchMetricValue("K3", "30", "K2", "20"), 0);
     Assert.assertEquals(200 * 1000, node_k1.getFirstMatchMetricValue(TimeUnit.MILLISECONDS, "K3", "30", "K2", "20"), 0);
     Assert.assertEquals(110.0, node_k1.getFirstMatchMetricValue("K2", "2", "K3", "30000"), 0);
     Assert
         .assertEquals(110 * 1000, node_k1.getFirstMatchMetricValue(TimeUnit.MILLISECONDS, "K2", "2", "K3", "30000"), 0);
 
-    Assert.assertEquals(200, node_k1.getFirstMatchMetricValue("K3", "30", "K2", "20"), 0);
-    Assert.assertEquals(200 * 1000, node_k1.getFirstMatchMetricValue(TimeUnit.MILLISECONDS, "K3", "30", "K2", "20"), 0);
-
+    //check direct get statistic value
     Assert.assertEquals(100, node_k1.getMatchStatisticMetricValue("A"), 0);
     Assert.assertEquals(100 * 1000, node_k1.getMatchStatisticMetricValue(TimeUnit.MILLISECONDS, "A"), 0);
-    Assert.assertEquals(100 * 1000, node_k1.getMatchStatisticMetricValue(TimeUnit.MILLISECONDS, "A"), 0);
+
+    //check generate new MetricNode from existed MetricNode
+    MetricNode newNode = new MetricNode(node_k1.getMetrics(), "K2", "K3");
+    Assert.assertEquals(1, newNode.getChildrenNode("2").getChildrenNode("3").getMetrics().size(), 0);
   }
 }
\ No newline at end of file
diff --git a/foundations/foundation-metrics/src/test/java/org/apache/servicecomb/foundation/metrics/publish/TestMetricsLoader.java b/foundations/foundation-metrics/src/test/java/org/apache/servicecomb/foundation/metrics/publish/TestMetricsLoader.java
index 4305b76..8c7a6a2 100644
--- a/foundations/foundation-metrics/src/test/java/org/apache/servicecomb/foundation/metrics/publish/TestMetricsLoader.java
+++ b/foundations/foundation-metrics/src/test/java/org/apache/servicecomb/foundation/metrics/publish/TestMetricsLoader.java
@@ -38,21 +38,8 @@ public class TestMetricsLoader {
     metrics.put("Y(K1=1000,K2=2000,K3=3000)", 800.0);
 
     MetricsLoader loader = new MetricsLoader(metrics);
-
     Assert.assertEquals(200.0, loader.getFirstMatchMetricValue("X", "K3", "30"), 0);
-
     MetricNode node = loader.getMetricTree("X", "K1");
-
     Assert.assertEquals(2, node.getChildren().size());
-
-    MetricNode node_k1 = node.getChildrenNode("1");
-
-    Assert.assertEquals(200, node_k1.getFirstMatchMetricValue("K2", "20", "K3", "30"), 0);
-
-    Assert.assertEquals(100, node_k1.getFirstMatchMetricValue("K2", "2"), 0);
-
-    MetricNode newGroup = new MetricNode(node_k1.getMetrics(), "K2", "K3");
-
-    Assert.assertEquals(1, newGroup.getChildrenNode("2").getChildrenNode("3").getMetrics().size(), 0);
   }
 }
diff --git a/metrics/metrics-common/pom.xml b/metrics/metrics-common/pom.xml
deleted file mode 100644
index e69de29..0000000
diff --git a/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/MonitorManager.java b/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/MonitorManager.java
index 5bdd409..76ac3ba 100644
--- a/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/MonitorManager.java
+++ b/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/MonitorManager.java
@@ -50,6 +50,8 @@ public class MonitorManager {
 
   private final Map<String, Counter> counters;
 
+  private final Map<String, Counter> stepCounters;
+
   private final Map<String, MaxGauge> maxGauges;
 
   private final Map<String, Gauge> gauges;
@@ -66,6 +68,7 @@ public class MonitorManager {
 
   private MonitorManager() {
     this.counters = new ConcurrentHashMapEx<>();
+    this.stepCounters = new ConcurrentHashMapEx<>();
     this.maxGauges = new ConcurrentHashMapEx<>();
     this.gauges = new ConcurrentHashMapEx<>();
     this.timers = new ConcurrentHashMapEx<>();
@@ -79,10 +82,17 @@ public class MonitorManager {
     System.getProperties().setProperty("servo.pollers", time > 0 ? String.valueOf(time) : "5000");
   }
 
-  public Counter getCounter(boolean isStepCounter, String name, String... tags) {
+  public Counter getCounter(String name, String... tags) {
     return counters.computeIfAbsent(getMonitorKey(name, tags), f -> {
-      Counter counter =
-          isStepCounter ? new StepCounter(getConfig(name, tags)) : new BasicCounter(getConfig(name, tags));
+      Counter counter = new BasicCounter(getConfig(name, tags));
+      basicMonitorRegistry.register(counter);
+      return counter;
+    });
+  }
+
+  public Counter getStepCounter(String name, String... tags) {
+    return stepCounters.computeIfAbsent(getMonitorKey(name, tags), f -> {
+      Counter counter = new StepCounter(getConfig(name, tags));
       basicMonitorRegistry.register(counter);
       return counter;
     });
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 4f83d7c..02e218e 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
@@ -28,9 +28,14 @@ import org.apache.servicecomb.swagger.invocation.InvocationType;
 
 public class InvocationFinishedEventListener implements EventListener<InvocationFinishedEvent> {
   @Override
+  public Class<InvocationFinishedEvent> getEventClass() {
+    return InvocationFinishedEvent.class;
+  }
+
+  @Override
   public void process(InvocationFinishedEvent data) {
     String[] tags = new String[] {MetricsConst.TAG_OPERATION, data.getOperationName(),
-        MetricsConst.TAG_ROLE, String.valueOf(data.getInvocationType()),
+        MetricsConst.TAG_ROLE, String.valueOf(data.getInvocationType()).toLowerCase(),
         MetricsConst.TAG_STATUS, String.valueOf(data.getStatusCode())};
     this.updateLatency(MetricsConst.STAGE_TOTAL, data.getTotalElapsedNanoTime(), tags);
     this.updateCount(tags);
@@ -53,9 +58,9 @@ public class InvocationFinishedEventListener implements EventListener<Invocation
 
   private void updateCount(String... basicTags) {
     String[] tags = ArrayUtils.addAll(basicTags, MetricsConst.TAG_STAGE, MetricsConst.STAGE_TOTAL);
-    MonitorManager.getInstance().getCounter(true, MetricsConst.SERVICECOMB_INVOCATION,
+    MonitorManager.getInstance().getStepCounter(MetricsConst.SERVICECOMB_INVOCATION,
         ArrayUtils.addAll(tags, MetricsConst.TAG_STATISTIC, "tps")).increment();
-    MonitorManager.getInstance().getCounter(false, MetricsConst.SERVICECOMB_INVOCATION,
+    MonitorManager.getInstance().getCounter(MetricsConst.SERVICECOMB_INVOCATION,
         ArrayUtils.addAll(tags, MetricsConst.TAG_STATISTIC, "count")).increment();
   }
 }
diff --git a/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/event/InvocationStartExecutionEventListener.java b/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/event/InvocationStartExecutionEventListener.java
index af3eeb4..ba6becc 100644
--- a/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/event/InvocationStartExecutionEventListener.java
+++ b/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/event/InvocationStartExecutionEventListener.java
@@ -25,11 +25,16 @@ import org.apache.servicecomb.swagger.invocation.InvocationType;
 
 public class InvocationStartExecutionEventListener implements EventListener<InvocationStartExecutionEvent> {
   @Override
+  public Class<InvocationStartExecutionEvent> getEventClass() {
+    return InvocationStartExecutionEvent.class;
+  }
+
+  @Override
   public void process(InvocationStartExecutionEvent data) {
-    MonitorManager.getInstance().getCounter(false, MetricsConst.SERVICECOMB_INVOCATION,
+    MonitorManager.getInstance().getCounter(MetricsConst.SERVICECOMB_INVOCATION,
         MetricsConst.TAG_OPERATION, data.getOperationName(),
         MetricsConst.TAG_STAGE, MetricsConst.STAGE_QUEUE,
-        MetricsConst.TAG_ROLE, String.valueOf(InvocationType.PRODUCER),
+        MetricsConst.TAG_ROLE, String.valueOf(InvocationType.PRODUCER).toLowerCase(),
         MetricsConst.TAG_STATISTIC, "waitInQueue").increment(-1);
   }
 }
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 e3ce689..69dc087 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
@@ -25,12 +25,17 @@ import org.apache.servicecomb.swagger.invocation.InvocationType;
 
 public class InvocationStartedEventListener implements EventListener<InvocationStartedEvent> {
   @Override
+  public Class<InvocationStartedEvent> getEventClass() {
+    return InvocationStartedEvent.class;
+  }
+
+  @Override
   public void process(InvocationStartedEvent data) {
     if (InvocationType.PRODUCER.equals(data.getInvocationType())) {
-      MonitorManager.getInstance().getCounter(false, MetricsConst.SERVICECOMB_INVOCATION,
+      MonitorManager.getInstance().getCounter(MetricsConst.SERVICECOMB_INVOCATION,
           MetricsConst.TAG_OPERATION, data.getOperationName(),
           MetricsConst.TAG_STAGE, MetricsConst.STAGE_QUEUE,
-          MetricsConst.TAG_ROLE, String.valueOf(InvocationType.PRODUCER),
+          MetricsConst.TAG_ROLE, String.valueOf(InvocationType.PRODUCER).toLowerCase(),
           MetricsConst.TAG_STATISTIC, "waitInQueue").increment();
     }
   }
diff --git a/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/publish/HealthCheckerPublisher.java b/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/publish/HealthCheckerPublisher.java
index 8497936..0d566ee 100644
--- a/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/publish/HealthCheckerPublisher.java
+++ b/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/publish/HealthCheckerPublisher.java
@@ -65,7 +65,7 @@ public class HealthCheckerPublisher {
 
   @RequestMapping(path = "/detail", method = RequestMethod.GET)
   @CrossOrigin
-  public Map<String, HealthCheckResult> checkHealthDetail() {
+  public Map<String, HealthCheckResult> checkHealthDetails() {
     return manager.check();
   }
 }
diff --git a/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/publish/MetricsPublisher.java b/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/publish/MetricsPublisher.java
index 17bb613..56a5cb0 100644
--- a/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/publish/MetricsPublisher.java
+++ b/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/publish/MetricsPublisher.java
@@ -19,14 +19,7 @@ package org.apache.servicecomb.metrics.core.publish;
 
 import java.util.Map;
 
-import org.apache.servicecomb.core.metrics.InvocationFinishedEvent;
-import org.apache.servicecomb.core.metrics.InvocationStartExecutionEvent;
-import org.apache.servicecomb.core.metrics.InvocationStartedEvent;
-import org.apache.servicecomb.foundation.common.utils.EventUtils;
 import org.apache.servicecomb.metrics.core.MonitorManager;
-import org.apache.servicecomb.metrics.core.event.InvocationFinishedEventListener;
-import org.apache.servicecomb.metrics.core.event.InvocationStartExecutionEventListener;
-import org.apache.servicecomb.metrics.core.event.InvocationStartedEventListener;
 import org.apache.servicecomb.provider.rest.common.RestSchema;
 import org.springframework.web.bind.annotation.CrossOrigin;
 import org.springframework.web.bind.annotation.RequestMapping;
@@ -38,15 +31,6 @@ import io.swagger.annotations.ApiResponses;
 @RestSchema(schemaId = "metricsEndpoint")
 @RequestMapping(path = "/metrics")
 public class MetricsPublisher {
-
-  public MetricsPublisher() {
-    //init
-    EventUtils.registerEventListener(InvocationFinishedEvent.class, new InvocationFinishedEventListener());
-    EventUtils.registerEventListener(InvocationStartExecutionEvent.class, new InvocationStartExecutionEventListener());
-    EventUtils.registerEventListener(InvocationStartedEvent.class, new InvocationStartedEventListener());
-    MonitorManager.getInstance();
-  }
-
   @ApiResponses({
       @ApiResponse(code = 400, response = String.class, message = "illegal request content"),
   })
diff --git a/metrics/metrics-core/src/main/resources/META-INF/services/org.apache.servicecomb.foundation.common.event.EventListener b/metrics/metrics-core/src/main/resources/META-INF/services/org.apache.servicecomb.foundation.common.event.EventListener
new file mode 100644
index 0000000..b63d298
--- /dev/null
+++ b/metrics/metrics-core/src/main/resources/META-INF/services/org.apache.servicecomb.foundation.common.event.EventListener
@@ -0,0 +1,37 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License.  You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+#
+# 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.
+#
+
+org.apache.servicecomb.metrics.core.event.InvocationStartExecutionEventListener
+org.apache.servicecomb.metrics.core.event.InvocationStartedEventListener
+org.apache.servicecomb.metrics.core.event.InvocationFinishedEventListener
\ No newline at end of file
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 d179202..88efd35 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
@@ -23,13 +23,10 @@ import java.util.concurrent.TimeUnit;
 import org.apache.servicecomb.core.metrics.InvocationFinishedEvent;
 import org.apache.servicecomb.core.metrics.InvocationStartExecutionEvent;
 import org.apache.servicecomb.core.metrics.InvocationStartedEvent;
-import org.apache.servicecomb.foundation.common.utils.EventUtils;
+import org.apache.servicecomb.foundation.common.event.EventBus;
 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.InvocationFinishedEventListener;
-import org.apache.servicecomb.metrics.core.event.InvocationStartExecutionEventListener;
-import org.apache.servicecomb.metrics.core.event.InvocationStartedEventListener;
 import org.apache.servicecomb.swagger.invocation.InvocationType;
 import org.junit.Assert;
 import org.junit.Test;
@@ -40,46 +37,42 @@ public class TestEventAndRunner {
   public void test() throws InterruptedException {
     //init
     System.getProperties().setProperty(MetricsConfig.METRICS_WINDOW_TIME, "2000");
-    EventUtils.registerEventListener(InvocationFinishedEvent.class, new InvocationFinishedEventListener());
-    EventUtils.registerEventListener(InvocationStartExecutionEvent.class, new InvocationStartExecutionEventListener());
-    EventUtils.registerEventListener(InvocationStartedEvent.class, new InvocationStartedEventListener());
-    MonitorManager.getInstance();
 
     //==========================================================================
     //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 InvocationStartExecutionEvent("fun1"));
-    EventUtils
+    EventBus.getInstance().triggerEvent(new InvocationStartedEvent("fun1", InvocationType.PRODUCER, System.nanoTime()));
+    EventBus.getInstance().triggerEvent(new InvocationStartExecutionEvent("fun1"));
+    EventBus.getInstance()
         .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 InvocationStartExecutionEvent("fun1"));
-    EventUtils
+    EventBus.getInstance().triggerEvent(new InvocationStartedEvent("fun1", InvocationType.PRODUCER, System.nanoTime()));
+    EventBus.getInstance().triggerEvent(new InvocationStartExecutionEvent("fun1"));
+    EventBus.getInstance()
         .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 InvocationStartExecutionEvent("fun1"));
-    EventUtils
+    EventBus.getInstance().triggerEvent(new InvocationStartedEvent("fun1", InvocationType.PRODUCER, System.nanoTime()));
+    EventBus.getInstance().triggerEvent(new InvocationStartExecutionEvent("fun1"));
+    EventBus.getInstance()
         .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
+    EventBus.getInstance()
         .triggerEvent(new InvocationFinishedEvent("fun2", InvocationType.CONSUMER, 0, 0,
             TimeUnit.MILLISECONDS.toNanos(300), 200));
 
     //==========================================================================
     //fun3 is a PRODUCER invocation call uncompleted
-    EventUtils.triggerEvent(new InvocationStartedEvent("fun3", InvocationType.PRODUCER, System.nanoTime()));
-    EventUtils.triggerEvent(new InvocationStartExecutionEvent("fun3"));
+    EventBus.getInstance().triggerEvent(new InvocationStartedEvent("fun3", InvocationType.PRODUCER, System.nanoTime()));
+    EventBus.getInstance().triggerEvent(new InvocationStartExecutionEvent("fun3"));
 
     //==========================================================================
     //fun4 is a PRODUCER call only started and no processing start and finished
-    EventUtils.triggerEvent(new InvocationStartedEvent("fun4", InvocationType.PRODUCER, System.nanoTime()));
+    EventBus.getInstance().triggerEvent(new InvocationStartedEvent("fun4", InvocationType.PRODUCER, System.nanoTime()));
 
     //==========================================================================
 
@@ -90,7 +83,8 @@ public class TestEventAndRunner {
             MetricsConst.TAG_STAGE);
     //checkHealth ProducerMetrics
     //fun1
-    MetricNode node1_queue = node.getChildrenNode("fun1").getChildrenNode(String.valueOf(InvocationType.PRODUCER))
+    MetricNode node1_queue = node.getChildrenNode("fun1")
+        .getChildrenNode(String.valueOf(InvocationType.PRODUCER).toLowerCase())
         .getChildrenNode(MetricsConst.STAGE_QUEUE);
     Assert.assertEquals(0, node1_queue.getMatchStatisticMetricValue("waitInQueue"), 0);
     MetricNode node1_queue_status = new MetricNode(node1_queue.getMetrics(), MetricsConst.TAG_STATUS);
@@ -99,7 +93,8 @@ public class TestEventAndRunner {
     Assert.assertEquals(300,
         node1_queue_status.getChildrenNode("500").getMatchStatisticMetricValue(TimeUnit.MILLISECONDS, "latency"), 0);
 
-    MetricNode node1_exec = node.getChildrenNode("fun1").getChildrenNode(String.valueOf(InvocationType.PRODUCER))
+    MetricNode node1_exec = node.getChildrenNode("fun1")
+        .getChildrenNode(String.valueOf(InvocationType.PRODUCER).toLowerCase())
         .getChildrenNode(MetricsConst.STAGE_EXECUTION);
     MetricNode node1_exec_status = new MetricNode(node1_exec.getMetrics(), MetricsConst.TAG_STATUS);
     Assert.assertEquals(300,
@@ -107,7 +102,8 @@ public class TestEventAndRunner {
     Assert.assertEquals(400,
         node1_exec_status.getChildrenNode("500").getMatchStatisticMetricValue(TimeUnit.MILLISECONDS, "latency"), 0);
 
-    MetricNode node1_whole = node.getChildrenNode("fun1").getChildrenNode(String.valueOf(InvocationType.PRODUCER))
+    MetricNode node1_whole = node.getChildrenNode("fun1")
+        .getChildrenNode(String.valueOf(InvocationType.PRODUCER).toLowerCase())
         .getChildrenNode(MetricsConst.STAGE_TOTAL);
     MetricNode node1_whole_status = new MetricNode(node1_whole.getMetrics(), MetricsConst.TAG_STATUS);
     Assert.assertEquals(500,
@@ -119,7 +115,8 @@ public class TestEventAndRunner {
 
     //checkHealth ConsumerMetrics
     //fun2
-    MetricNode node2_whole = node.getChildrenNode("fun2").getChildrenNode(String.valueOf(InvocationType.CONSUMER))
+    MetricNode node2_whole = node.getChildrenNode("fun2")
+        .getChildrenNode(String.valueOf(InvocationType.CONSUMER).toLowerCase())
         .getChildrenNode(MetricsConst.STAGE_TOTAL);
     MetricNode node2_whole_status = new MetricNode(node2_whole.getMetrics(), MetricsConst.TAG_STATUS);
     Assert.assertEquals(300,
@@ -127,12 +124,14 @@ public class TestEventAndRunner {
     Assert.assertEquals(1, node2_whole_status.getChildrenNode("200").getMatchStatisticMetricValue("count"), 0);
 
     //fun3
-    MetricNode node3_queue = node.getChildrenNode("fun3").getChildrenNode(String.valueOf(InvocationType.PRODUCER))
+    MetricNode node3_queue = node.getChildrenNode("fun3")
+        .getChildrenNode(String.valueOf(InvocationType.PRODUCER).toLowerCase())
         .getChildrenNode(MetricsConst.STAGE_QUEUE);
     Assert.assertEquals(0, node3_queue.getMatchStatisticMetricValue("waitInQueue"), 0);
 
     //fun4
-    MetricNode node4_queue = node.getChildrenNode("fun4").getChildrenNode(String.valueOf(InvocationType.PRODUCER))
+    MetricNode node4_queue = node.getChildrenNode("fun4")
+        .getChildrenNode(String.valueOf(InvocationType.PRODUCER).toLowerCase())
         .getChildrenNode(MetricsConst.STAGE_QUEUE);
     Assert.assertEquals(1, node4_queue.getMatchStatisticMetricValue("waitInQueue"), 0);
 
@@ -145,7 +144,7 @@ public class TestEventAndRunner {
         .getMetricTree(MetricsConst.SERVICECOMB_INVOCATION, MetricsConst.TAG_OPERATION, MetricsConst.TAG_ROLE,
             MetricsConst.TAG_STAGE);
 
-    node1_queue = node.getChildrenNode("fun1").getChildrenNode(String.valueOf(InvocationType.PRODUCER))
+    node1_queue = node.getChildrenNode("fun1").getChildrenNode(String.valueOf(InvocationType.PRODUCER).toLowerCase())
         .getChildrenNode(MetricsConst.STAGE_QUEUE);
     node1_queue_status = new MetricNode(node1_queue.getMetrics(), MetricsConst.TAG_STATUS);
     Assert.assertEquals(300,
@@ -153,7 +152,7 @@ public class TestEventAndRunner {
     Assert.assertEquals(300,
         node1_queue_status.getChildrenNode("500").getMatchStatisticMetricValue(TimeUnit.MILLISECONDS, "max"), 0);
 
-    node1_exec = node.getChildrenNode("fun1").getChildrenNode(String.valueOf(InvocationType.PRODUCER))
+    node1_exec = node.getChildrenNode("fun1").getChildrenNode(String.valueOf(InvocationType.PRODUCER).toLowerCase())
         .getChildrenNode(MetricsConst.STAGE_EXECUTION);
     node1_exec_status = new MetricNode(node1_exec.getMetrics(), MetricsConst.TAG_STATUS);
     Assert.assertEquals(400,
@@ -161,7 +160,7 @@ public class TestEventAndRunner {
     Assert.assertEquals(400,
         node1_exec_status.getChildrenNode("500").getMatchStatisticMetricValue(TimeUnit.MILLISECONDS, "max"), 0);
 
-    node1_whole = node.getChildrenNode("fun1").getChildrenNode(String.valueOf(InvocationType.PRODUCER))
+    node1_whole = node.getChildrenNode("fun1").getChildrenNode(String.valueOf(InvocationType.PRODUCER).toLowerCase())
         .getChildrenNode(MetricsConst.STAGE_TOTAL);
     node1_whole_status = new MetricNode(node1_whole.getMetrics(), MetricsConst.TAG_STATUS);
     Assert.assertEquals(700,
@@ -174,7 +173,7 @@ public class TestEventAndRunner {
 
     //checkHealth ConsumerMetrics
     //fun2
-    node2_whole = node.getChildrenNode("fun2").getChildrenNode(String.valueOf(InvocationType.CONSUMER))
+    node2_whole = node.getChildrenNode("fun2").getChildrenNode(String.valueOf(InvocationType.CONSUMER).toLowerCase())
         .getChildrenNode(MetricsConst.STAGE_TOTAL);
     node2_whole_status = new MetricNode(node2_whole.getMetrics(), MetricsConst.TAG_STATUS);
     Assert.assertEquals(300,
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 a29bac6..794c0dd 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
@@ -59,7 +59,7 @@ public class TestHealthCheckerPublisher {
 
     Assert.assertEquals(false, publisher.checkHealth());
 
-    Map<String, HealthCheckResult> content = publisher.checkHealthDetail();
+    Map<String, HealthCheckResult> content = publisher.checkHealthDetails();
 
     Assert.assertEquals(true, content.get("test").isHealthy());
     Assert.assertEquals("info", content.get("test").getInformation());
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 aa5d909..1f9c21f 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
@@ -71,7 +71,7 @@ public class SimpleFileContentConvertor implements FileContentConvertor {
       StringBuilder builder = new StringBuilder();
       builder.append(tags.get(MetricsConst.TAG_OPERATION));
       builder.append(".");
-      builder.append(tags.get(MetricsConst.TAG_ROLE));
+      builder.append(tags.get(MetricsConst.TAG_ROLE).toLowerCase());
       builder.append(".");
       builder.append(tags.get(MetricsConst.TAG_STAGE));
       builder.append(".");
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 d340aa4..0450187 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
@@ -30,7 +30,7 @@ import org.apache.servicecomb.core.definition.MicroserviceMetaManager;
 import org.apache.servicecomb.core.definition.OperationMeta;
 import org.apache.servicecomb.core.definition.SchemaMeta;
 import org.apache.servicecomb.core.metrics.InvocationStartedEvent;
-import org.apache.servicecomb.foundation.common.utils.EventUtils;
+import org.apache.servicecomb.foundation.common.event.EventBus;
 import org.apache.servicecomb.foundation.vertx.tcp.TcpConnection;
 import org.apache.servicecomb.swagger.invocation.InvocationType;
 import org.apache.servicecomb.swagger.invocation.Response;
@@ -164,7 +164,7 @@ public class HighwayServerInvoke {
   public void execute() {
     InvocationStartedEvent startedEvent = new InvocationStartedEvent(operationMeta.getMicroserviceQualifiedName(),
         InvocationType.PRODUCER, System.nanoTime());
-    EventUtils.triggerEvent(startedEvent);
+    EventBus.getInstance().triggerEvent(startedEvent);
     operationMeta.getExecutor().execute(() -> runInExecutor(startedEvent));
   }
 }

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