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 2017/12/27 01:26:25 UTC

[incubator-servicecomb-java-chassis] 11/12: JAV-539 & SCB-9 minor refactor

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 09723c5e1780f9c542151d8854d4a1f9aa50e03e
Author: zhengyangyong <ya...@huawei.com>
AuthorDate: Mon Dec 25 15:46:18 2017 +0800

    JAV-539 & SCB-9 minor refactor
    
    Signed-off-by: zhengyangyong <ya...@huawei.com>
---
 .../common/rest/AbstractRestInvocation.java        |   5 +-
 .../common/rest/TestAbstractRestInvocation.java    |  13 +--
 .../core/metrics/InvocationFinishedEvent.java      |  18 ++--
 .../metrics/InvocationStartProcessingEvent.java    |  15 +--
 .../core/metrics/InvocationStartedEvent.java       |  10 +-
 .../event/InvocationFinishedEventListener.java     |   6 +-
 .../InvocationStartProcessingEventListener.java    |  11 +-
 .../core/event/InvocationStartedEventListener.java |  13 ++-
 .../core/metric/ConsumerInvocationMetric.java      |  18 +---
 .../core/metric/InstanceCalculationMetric.java     | 117 ---------------------
 .../metrics/core/metric/InstanceMetric.java        |   9 +-
 .../metrics/core/metric/InvocationMetric.java      |  21 +---
 .../core/metric/ProducerInvocationMetric.java      |  20 ++--
 .../metrics/core/metric/RegistryMetric.java        |  42 +++++---
 .../metrics/core/metric/SystemMetric.java          |  19 ++++
 .../metrics/core/monitor/BasicMonitor.java         |  41 --------
 .../metrics/core/monitor/CallMonitor.java          |  11 +-
 .../core/monitor/ConsumerInvocationMonitor.java    |  46 ++++++++
 .../metrics/core/monitor/DefaultSystemMonitor.java |   2 +-
 .../metrics/core/monitor/InvocationMonitor.java    |  99 ++---------------
 .../core/monitor/InvocationMonitorType.java        |  25 -----
 .../core/monitor/ProducerInvocationMonitor.java    |  74 +++++++++++++
 .../metrics/core/monitor/RegistryMonitor.java      |  32 ++++--
 .../metrics/core/monitor/SystemMonitor.java        |   2 +-
 .../metrics/core/monitor/TimerMonitor.java         |  19 +++-
 .../metrics/core/TestEventAndRunner.java           |  20 ++--
 .../transport/highway/HighwayServerInvoke.java     |   3 +-
 27 files changed, 302 insertions(+), 409 deletions(-)

diff --git a/common/common-rest/src/main/java/io/servicecomb/common/rest/AbstractRestInvocation.java b/common/common-rest/src/main/java/io/servicecomb/common/rest/AbstractRestInvocation.java
index f7f5134..8fae4ef 100644
--- a/common/common-rest/src/main/java/io/servicecomb/common/rest/AbstractRestInvocation.java
+++ b/common/common-rest/src/main/java/io/servicecomb/common/rest/AbstractRestInvocation.java
@@ -51,6 +51,7 @@ import io.servicecomb.foundation.metrics.performance.QueueMetricsData;
 import io.servicecomb.foundation.vertx.http.HttpServletRequestEx;
 import io.servicecomb.foundation.vertx.http.HttpServletResponseEx;
 import io.servicecomb.foundation.vertx.stream.BufferOutputStream;
+import io.servicecomb.swagger.invocation.InvocationType;
 import io.servicecomb.swagger.invocation.Response;
 import io.servicecomb.swagger.invocation.exception.InvocationException;
 
@@ -109,7 +110,7 @@ public abstract class AbstractRestInvocation {
     OperationMeta operationMeta = restOperationMeta.getOperationMeta();
 
     InvocationStartedEvent startedEvent = new InvocationStartedEvent(operationMeta.getMicroserviceQualifiedName(),
-        System.nanoTime());
+        InvocationType.PRODUCER, System.nanoTime());
     EventUtils.triggerEvent(startedEvent);
 
     QueueMetrics metricsData = initMetrics(operationMeta);
@@ -226,7 +227,7 @@ public abstract class AbstractRestInvocation {
       }
     }
     responseEx.setStatus(response.getStatusCode(), response.getReasonPhrase());
-    responseEx.setContentType(produceProcessor.getName()+"; charset=utf-8");
+    responseEx.setContentType(produceProcessor.getName() + "; charset=utf-8");
 
     Object body = response.getResult();
     if (response.isFailed()) {
diff --git a/common/common-rest/src/test/java/io/servicecomb/common/rest/TestAbstractRestInvocation.java b/common/common-rest/src/test/java/io/servicecomb/common/rest/TestAbstractRestInvocation.java
index ddab596..278c331 100644
--- a/common/common-rest/src/test/java/io/servicecomb/common/rest/TestAbstractRestInvocation.java
+++ b/common/common-rest/src/test/java/io/servicecomb/common/rest/TestAbstractRestInvocation.java
@@ -51,13 +51,11 @@ import io.servicecomb.core.definition.SchemaMeta;
 import io.servicecomb.core.executor.ReactiveExecutor;
 import io.servicecomb.core.provider.consumer.ReferenceConfig;
 import io.servicecomb.foundation.common.utils.JsonUtils;
-import io.servicecomb.foundation.metrics.MetricsServoRegistry;
-import io.servicecomb.foundation.metrics.performance.QueueMetrics;
-import io.servicecomb.foundation.metrics.performance.QueueMetricsData;
 import io.servicecomb.foundation.vertx.http.AbstractHttpServletRequest;
 import io.servicecomb.foundation.vertx.http.HttpServletRequestEx;
 import io.servicecomb.foundation.vertx.http.HttpServletResponseEx;
 import io.servicecomb.swagger.invocation.AsyncResponse;
+import io.servicecomb.swagger.invocation.InvocationType;
 import io.servicecomb.swagger.invocation.Response;
 import io.servicecomb.swagger.invocation.exception.CommonExceptionData;
 import io.servicecomb.swagger.invocation.exception.InvocationException;
@@ -374,7 +372,6 @@ public class TestAbstractRestInvocation {
     restInvocation.sendResponseQuietly(response);
 
     Assert.assertSame(response, result.value);
-
   }
 
   @Test
@@ -625,7 +622,7 @@ public class TestAbstractRestInvocation {
     Error error = new Error("run on executor");
     restInvocation = new AbstractRestInvocationForTest() {
       @Override
-      protected void runOnExecutor(QueueMetrics metricsData,InvocationStartedEvent startedEvent) {
+      protected void runOnExecutor(InvocationStartedEvent startedEvent) {
         throw error;
       }
 
@@ -662,7 +659,7 @@ public class TestAbstractRestInvocation {
 
     restInvocation = new AbstractRestInvocationForTest() {
       @Override
-      protected void runOnExecutor(QueueMetrics metricsData,InvocationStartedEvent startedEvent) {
+      protected void runOnExecutor(InvocationStartedEvent startedEvent) {
         throw new Error("run on executor");
       }
 
@@ -698,7 +695,7 @@ public class TestAbstractRestInvocation {
     Holder<Boolean> result = new Holder<>();
     restInvocation = new AbstractRestInvocationForTest() {
       @Override
-      protected void runOnExecutor(QueueMetrics metricsData,InvocationStartedEvent startedEvent) {
+      protected void runOnExecutor(InvocationStartedEvent startedEvent) {
         result.value = true;
       }
     };
@@ -729,7 +726,7 @@ public class TestAbstractRestInvocation {
     restInvocation.requestEx = requestEx;
     restInvocation.restOperationMeta = restOperation;
 
-    restInvocation.runOnExecutor(null, new InvocationStartedEvent("", System.nanoTime()));
+    restInvocation.runOnExecutor(null,new InvocationStartedEvent("", InvocationType.PRODUCER, System.nanoTime()));
     Assert.assertTrue(result.value);
     Assert.assertSame(invocation, restInvocation.invocation);
   }
diff --git a/core/src/main/java/io/servicecomb/core/metrics/InvocationFinishedEvent.java b/core/src/main/java/io/servicecomb/core/metrics/InvocationFinishedEvent.java
index 90260ca..077e9a8 100644
--- a/core/src/main/java/io/servicecomb/core/metrics/InvocationFinishedEvent.java
+++ b/core/src/main/java/io/servicecomb/core/metrics/InvocationFinishedEvent.java
@@ -23,13 +23,21 @@ import io.servicecomb.swagger.invocation.InvocationType;
 public class InvocationFinishedEvent implements Event {
   private final String operationName;
 
+  private final InvocationType invocationType;
+
   private final long finishedTime;
 
   private final long processElapsedNanoTime;
 
   private final long totalElapsedNanoTime;
 
-  private final InvocationType invocationType;
+  public String getOperationName() {
+    return operationName;
+  }
+
+  public InvocationType getInvocationType() {
+    return invocationType;
+  }
 
   public long getProcessElapsedNanoTime() {
     return processElapsedNanoTime;
@@ -39,14 +47,6 @@ public class InvocationFinishedEvent implements Event {
     return totalElapsedNanoTime;
   }
 
-  public InvocationType getInvocationType() {
-    return invocationType;
-  }
-
-  public String getOperationName() {
-    return operationName;
-  }
-
   public InvocationFinishedEvent(String operationName, InvocationType invocationType, long finishedTime,
       long processElapsedNanoTime,
       long totalElapsedNanoTime) {
diff --git a/core/src/main/java/io/servicecomb/core/metrics/InvocationStartProcessingEvent.java b/core/src/main/java/io/servicecomb/core/metrics/InvocationStartProcessingEvent.java
index 3d39982..9f8ec94 100644
--- a/core/src/main/java/io/servicecomb/core/metrics/InvocationStartProcessingEvent.java
+++ b/core/src/main/java/io/servicecomb/core/metrics/InvocationStartProcessingEvent.java
@@ -23,16 +23,12 @@ import io.servicecomb.swagger.invocation.InvocationType;
 public class InvocationStartProcessingEvent implements Event {
   private final String operationName;
 
+  private final InvocationType invocationType;
+
   private final long startProcessingTime;
 
   private final long inQueueNanoTime;
 
-  private final InvocationType invocationType;
-
-  public long getInQueueNanoTime() {
-    return inQueueNanoTime;
-  }
-
   public String getOperationName() {
     return operationName;
   }
@@ -41,7 +37,12 @@ public class InvocationStartProcessingEvent implements Event {
     return invocationType;
   }
 
-  public InvocationStartProcessingEvent(String operationName, InvocationType invocationType, long startProcessingTime, long inQueueNanoTime) {
+  public long getInQueueNanoTime() {
+    return inQueueNanoTime;
+  }
+
+  public InvocationStartProcessingEvent(String operationName, InvocationType invocationType, long startProcessingTime,
+      long inQueueNanoTime) {
     this.operationName = operationName;
     this.invocationType = invocationType;
     this.startProcessingTime = startProcessingTime;
diff --git a/core/src/main/java/io/servicecomb/core/metrics/InvocationStartedEvent.java b/core/src/main/java/io/servicecomb/core/metrics/InvocationStartedEvent.java
index 09b205b..b233a62 100644
--- a/core/src/main/java/io/servicecomb/core/metrics/InvocationStartedEvent.java
+++ b/core/src/main/java/io/servicecomb/core/metrics/InvocationStartedEvent.java
@@ -18,22 +18,30 @@
 package io.servicecomb.core.metrics;
 
 import io.servicecomb.foundation.common.event.Event;
+import io.servicecomb.swagger.invocation.InvocationType;
 
 public class InvocationStartedEvent implements Event {
   private final String operationName;
 
+  private final InvocationType invocationType;
+
   private final long startedTime;
 
   public String getOperationName() {
     return operationName;
   }
 
+  public InvocationType getInvocationType() {
+    return invocationType;
+  }
+
   public long getStartedTime() {
     return startedTime;
   }
 
-  public InvocationStartedEvent(String operationName, long startedTime) {
+  public InvocationStartedEvent(String operationName, InvocationType invocationType, long startedTime) {
     this.operationName = operationName;
+    this.invocationType = invocationType;
     this.startedTime = startedTime;
   }
 }
diff --git a/metrics/metrics-core/src/main/java/io/servicecomb/metrics/core/event/InvocationFinishedEventListener.java b/metrics/metrics-core/src/main/java/io/servicecomb/metrics/core/event/InvocationFinishedEventListener.java
index 63ecc99..4c03dc8 100644
--- a/metrics/metrics-core/src/main/java/io/servicecomb/metrics/core/event/InvocationFinishedEventListener.java
+++ b/metrics/metrics-core/src/main/java/io/servicecomb/metrics/core/event/InvocationFinishedEventListener.java
@@ -20,7 +20,8 @@ package io.servicecomb.metrics.core.event;
 import io.servicecomb.core.metrics.InvocationFinishedEvent;
 import io.servicecomb.foundation.common.event.Event;
 import io.servicecomb.foundation.common.event.EventListener;
-import io.servicecomb.metrics.core.monitor.InvocationMonitor;
+import io.servicecomb.metrics.core.monitor.ConsumerInvocationMonitor;
+import io.servicecomb.metrics.core.monitor.ProducerInvocationMonitor;
 import io.servicecomb.metrics.core.monitor.RegistryMonitor;
 import io.servicecomb.swagger.invocation.InvocationType;
 
@@ -40,11 +41,12 @@ public class InvocationFinishedEventListener implements EventListener {
   @Override
   public void process(Event data) {
     InvocationFinishedEvent event = (InvocationFinishedEvent) data;
-    InvocationMonitor monitor = registryMonitor.getInvocationMonitor(event.getOperationName());
     if (InvocationType.PRODUCER.equals(event.getInvocationType())) {
+      ProducerInvocationMonitor monitor = registryMonitor.getProducerInvocationMonitor(event.getOperationName());
       monitor.getExecutionTime().update(event.getProcessElapsedNanoTime());
       monitor.getProducerLatency().update(event.getTotalElapsedNanoTime());
     } else {
+      ConsumerInvocationMonitor monitor = registryMonitor.getConsumerInvocationMonitor(event.getOperationName());
       monitor.getConsumerLatency().update(event.getTotalElapsedNanoTime());
     }
   }
diff --git a/metrics/metrics-core/src/main/java/io/servicecomb/metrics/core/event/InvocationStartProcessingEventListener.java b/metrics/metrics-core/src/main/java/io/servicecomb/metrics/core/event/InvocationStartProcessingEventListener.java
index d0288f4..dd29b3b 100644
--- a/metrics/metrics-core/src/main/java/io/servicecomb/metrics/core/event/InvocationStartProcessingEventListener.java
+++ b/metrics/metrics-core/src/main/java/io/servicecomb/metrics/core/event/InvocationStartProcessingEventListener.java
@@ -20,7 +20,7 @@ package io.servicecomb.metrics.core.event;
 import io.servicecomb.core.metrics.InvocationStartProcessingEvent;
 import io.servicecomb.foundation.common.event.Event;
 import io.servicecomb.foundation.common.event.EventListener;
-import io.servicecomb.metrics.core.monitor.InvocationMonitor;
+import io.servicecomb.metrics.core.monitor.ProducerInvocationMonitor;
 import io.servicecomb.metrics.core.monitor.RegistryMonitor;
 import io.servicecomb.swagger.invocation.InvocationType;
 
@@ -40,15 +40,10 @@ public class InvocationStartProcessingEventListener implements EventListener {
   @Override
   public void process(Event data) {
     InvocationStartProcessingEvent event = (InvocationStartProcessingEvent) data;
-    InvocationMonitor monitor = registryMonitor.getInvocationMonitor(event.getOperationName());
-    //TODO:current java chassis unable know invocation type before starting process,so all type WaitInQueue increment(-1) (decrement)
-    monitor.getWaitInQueue().increment(-1);
-    monitor.setInvocationMonitorType(event.getInvocationType());
     if (InvocationType.PRODUCER.equals(event.getInvocationType())) {
+      ProducerInvocationMonitor monitor = registryMonitor.getProducerInvocationMonitor(event.getOperationName());
+      monitor.getWaitInQueue().increment(-1);
       monitor.getLifeTimeInQueue().update(event.getInQueueNanoTime());
-      monitor.getProducerCall().increment();
-    } else {
-      monitor.getConsumerCall().increment();
     }
   }
 }
diff --git a/metrics/metrics-core/src/main/java/io/servicecomb/metrics/core/event/InvocationStartedEventListener.java b/metrics/metrics-core/src/main/java/io/servicecomb/metrics/core/event/InvocationStartedEventListener.java
index ffb97b1..7602c82 100644
--- a/metrics/metrics-core/src/main/java/io/servicecomb/metrics/core/event/InvocationStartedEventListener.java
+++ b/metrics/metrics-core/src/main/java/io/servicecomb/metrics/core/event/InvocationStartedEventListener.java
@@ -20,7 +20,10 @@ package io.servicecomb.metrics.core.event;
 import io.servicecomb.core.metrics.InvocationStartedEvent;
 import io.servicecomb.foundation.common.event.Event;
 import io.servicecomb.foundation.common.event.EventListener;
+import io.servicecomb.metrics.core.monitor.ConsumerInvocationMonitor;
+import io.servicecomb.metrics.core.monitor.ProducerInvocationMonitor;
 import io.servicecomb.metrics.core.monitor.RegistryMonitor;
+import io.servicecomb.swagger.invocation.InvocationType;
 
 public class InvocationStartedEventListener implements EventListener {
 
@@ -38,7 +41,13 @@ public class InvocationStartedEventListener implements EventListener {
   @Override
   public void process(Event data) {
     InvocationStartedEvent event = (InvocationStartedEvent) data;
-    //TODO:current java chassis unable know invocation type before starting process,so all type WaitInQueue increment
-    registryMonitor.getInvocationMonitor(event.getOperationName()).getWaitInQueue().increment();
+    if (InvocationType.PRODUCER.equals(event.getInvocationType())) {
+      ProducerInvocationMonitor monitor = registryMonitor.getProducerInvocationMonitor(event.getOperationName());
+      monitor.getWaitInQueue().increment();
+      monitor.getProducerCall().increment();
+    } else {
+      ConsumerInvocationMonitor monitor = registryMonitor.getConsumerInvocationMonitor(event.getOperationName());
+      monitor.getConsumerCall().increment();
+    }
   }
 }
diff --git a/metrics/metrics-core/src/main/java/io/servicecomb/metrics/core/metric/ConsumerInvocationMetric.java b/metrics/metrics-core/src/main/java/io/servicecomb/metrics/core/metric/ConsumerInvocationMetric.java
index b184cc9..0c0ddfe 100644
--- a/metrics/metrics-core/src/main/java/io/servicecomb/metrics/core/metric/ConsumerInvocationMetric.java
+++ b/metrics/metrics-core/src/main/java/io/servicecomb/metrics/core/metric/ConsumerInvocationMetric.java
@@ -33,25 +33,17 @@ public class ConsumerInvocationMetric extends InvocationMetric {
     return consumerCall;
   }
 
-  public ConsumerInvocationMetric(String operationName, String prefix, long waitInQueue,
+  public ConsumerInvocationMetric(String operationName, String prefix,
       TimerMetric consumerLatency, CallMetric consumerCall) {
-    super(operationName, prefix, waitInQueue);
+    super(operationName, prefix);
     this.consumerLatency = consumerLatency;
     this.consumerCall = consumerCall;
   }
 
-  @Override
-  public InstanceCalculationMetric merge(InstanceCalculationMetric metric) {
-    metric.getConsumerMetrics().put(this.getOperationName(), this);
-    return new InstanceCalculationMetric(metric.getTotalWaitInQueue(),
-        metric.getProducerWaitInQueue(),
-        metric.getConsumerMetrics(), metric.getProducerMetrics(),
-        metric.getLifeTimeInQueue(),
-        metric.getExecutionTime(),
+  public ConsumerInvocationMetric merge(ConsumerInvocationMetric metric) {
+    return new ConsumerInvocationMetric(this.getOperationName(), this.getPrefix(),
         metric.getConsumerLatency().merge(consumerLatency),
-        metric.getProducerLatency(),
-        metric.getConsumerCall().merge(consumerCall),
-        metric.getProducerCall());
+        metric.getConsumerCall().merge(consumerCall));
   }
 
   public Map<String, Number> toMap() {
diff --git a/metrics/metrics-core/src/main/java/io/servicecomb/metrics/core/metric/InstanceCalculationMetric.java b/metrics/metrics-core/src/main/java/io/servicecomb/metrics/core/metric/InstanceCalculationMetric.java
deleted file mode 100644
index d923449..0000000
--- a/metrics/metrics-core/src/main/java/io/servicecomb/metrics/core/metric/InstanceCalculationMetric.java
+++ /dev/null
@@ -1,117 +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 io.servicecomb.metrics.core.metric;
-
-import java.util.HashMap;
-import java.util.Map;
-
-import io.servicecomb.metrics.core.MetricsConst;
-
-public class InstanceCalculationMetric {
-  private final Map<String, ConsumerInvocationMetric> consumerMetrics;
-
-  private final Map<String, ProducerInvocationMetric> producerMetrics;
-
-  //TODO:current java chassis unable know invocation type before starting process,totalWaitInQueue = ProducerInvocation + UnknownTypeInvocation
-  private final long totalWaitInQueue;
-
-  private final long producerWaitInQueue;
-
-  private final TimerMetric lifeTimeInQueue;
-
-  private final TimerMetric executionTime;
-
-  private final TimerMetric consumerLatency;
-
-  private final TimerMetric producerLatency;
-
-  private final CallMetric consumerCall;
-
-  private final CallMetric producerCall;
-
-  public long getTotalWaitInQueue() {
-    return totalWaitInQueue;
-  }
-
-  public long getProducerWaitInQueue() {
-    return producerWaitInQueue;
-  }
-
-  public Map<String, ConsumerInvocationMetric> getConsumerMetrics() {
-    return consumerMetrics;
-  }
-
-  public Map<String, ProducerInvocationMetric> getProducerMetrics() {
-    return producerMetrics;
-  }
-
-  public TimerMetric getLifeTimeInQueue() {
-    return lifeTimeInQueue;
-  }
-
-  public TimerMetric getExecutionTime() {
-    return executionTime;
-  }
-
-  public TimerMetric getConsumerLatency() {
-    return consumerLatency;
-  }
-
-  public TimerMetric getProducerLatency() {
-    return producerLatency;
-  }
-
-  public CallMetric getConsumerCall() {
-    return consumerCall;
-  }
-
-  public CallMetric getProducerCall() {
-    return producerCall;
-  }
-
-  public InstanceCalculationMetric() {
-    this.totalWaitInQueue = 0;
-    this.producerWaitInQueue = 0;
-    this.consumerMetrics = new HashMap<>();
-    this.producerMetrics = new HashMap<>();
-    this.lifeTimeInQueue = new TimerMetric(MetricsConst.INSTANCE_PRODUCER_PREFIX + ".lifeTimeInQueue");
-    this.executionTime = new TimerMetric(MetricsConst.INSTANCE_PRODUCER_PREFIX + ".executionTime");
-    this.consumerLatency = new TimerMetric(MetricsConst.INSTANCE_CONSUMER_PREFIX + ".consumerLatency");
-    this.producerLatency = new TimerMetric(MetricsConst.INSTANCE_PRODUCER_PREFIX + ".producerLatency");
-    this.consumerCall = new CallMetric(MetricsConst.INSTANCE_CONSUMER_PREFIX + ".consumerCall");
-    this.producerCall = new CallMetric(MetricsConst.INSTANCE_PRODUCER_PREFIX + ".producerCall");
-  }
-
-  public InstanceCalculationMetric(long totalWaitInQueue, long producerWaitInQueue,
-      Map<String, ConsumerInvocationMetric> consumerMetrics,
-      Map<String, ProducerInvocationMetric> producerMetrics,
-      TimerMetric lifeTimeInQueue, TimerMetric executionTime,
-      TimerMetric consumerLatency, TimerMetric producerLatency,
-      CallMetric consumerCall, CallMetric producerCall) {
-    this.totalWaitInQueue = totalWaitInQueue;
-    this.producerWaitInQueue = producerWaitInQueue;
-    this.consumerMetrics = consumerMetrics;
-    this.producerMetrics = producerMetrics;
-    this.lifeTimeInQueue = lifeTimeInQueue;
-    this.executionTime = executionTime;
-    this.consumerLatency = consumerLatency;
-    this.producerLatency = producerLatency;
-    this.consumerCall = consumerCall;
-    this.producerCall = producerCall;
-  }
-}
diff --git a/metrics/metrics-core/src/main/java/io/servicecomb/metrics/core/metric/InstanceMetric.java b/metrics/metrics-core/src/main/java/io/servicecomb/metrics/core/metric/InstanceMetric.java
index 283a664..614fa48 100644
--- a/metrics/metrics-core/src/main/java/io/servicecomb/metrics/core/metric/InstanceMetric.java
+++ b/metrics/metrics-core/src/main/java/io/servicecomb/metrics/core/metric/InstanceMetric.java
@@ -18,18 +18,12 @@
 package io.servicecomb.metrics.core.metric;
 
 public class InstanceMetric {
-  private final long waitInQueue;
-
   private final SystemMetric systemMetric;
 
   private final ConsumerInvocationMetric consumerMetric;
 
   private final ProducerInvocationMetric producerMetric;
 
-  public long getWaitInQueue() {
-    return waitInQueue;
-  }
-
   public SystemMetric getSystemMetric() {
     return systemMetric;
   }
@@ -42,10 +36,9 @@ public class InstanceMetric {
     return producerMetric;
   }
 
-  public InstanceMetric(long waitInQueue, SystemMetric systemMetric,
+  public InstanceMetric(SystemMetric systemMetric,
       ConsumerInvocationMetric consumerMetric,
       ProducerInvocationMetric producerMetric) {
-    this.waitInQueue = waitInQueue;
     this.systemMetric = systemMetric;
     this.consumerMetric = consumerMetric;
     this.producerMetric = producerMetric;
diff --git a/metrics/metrics-core/src/main/java/io/servicecomb/metrics/core/metric/InvocationMetric.java b/metrics/metrics-core/src/main/java/io/servicecomb/metrics/core/metric/InvocationMetric.java
index a33c093..c452a4e 100644
--- a/metrics/metrics-core/src/main/java/io/servicecomb/metrics/core/metric/InvocationMetric.java
+++ b/metrics/metrics-core/src/main/java/io/servicecomb/metrics/core/metric/InvocationMetric.java
@@ -22,8 +22,6 @@ public class InvocationMetric {
 
   private final String prefix;
 
-  private final long waitInQueue;
-
   public String getOperationName() {
     return operationName;
   }
@@ -32,25 +30,8 @@ public class InvocationMetric {
     return prefix;
   }
 
-  public long getWaitInQueue() {
-    return waitInQueue;
-  }
-
-  public InvocationMetric(String operationName, String prefix, long waitInQueue) {
+  public InvocationMetric(String operationName, String prefix) {
     this.operationName = operationName;
     this.prefix = prefix;
-    this.waitInQueue = waitInQueue;
-  }
-
-  public InstanceCalculationMetric merge(InstanceCalculationMetric metric) {
-    return new InstanceCalculationMetric(metric.getTotalWaitInQueue() + waitInQueue,
-        metric.getProducerWaitInQueue(),
-        metric.getConsumerMetrics(), metric.getProducerMetrics(),
-        metric.getLifeTimeInQueue(),
-        metric.getExecutionTime(),
-        metric.getConsumerLatency(),
-        metric.getProducerLatency(),
-        metric.getConsumerCall(),
-        metric.getProducerCall());
   }
 }
diff --git a/metrics/metrics-core/src/main/java/io/servicecomb/metrics/core/metric/ProducerInvocationMetric.java b/metrics/metrics-core/src/main/java/io/servicecomb/metrics/core/metric/ProducerInvocationMetric.java
index b2d53cb..0692e90 100644
--- a/metrics/metrics-core/src/main/java/io/servicecomb/metrics/core/metric/ProducerInvocationMetric.java
+++ b/metrics/metrics-core/src/main/java/io/servicecomb/metrics/core/metric/ProducerInvocationMetric.java
@@ -21,6 +21,8 @@ import java.util.HashMap;
 import java.util.Map;
 
 public class ProducerInvocationMetric extends InvocationMetric {
+  private final long waitInQueue;
+
   private final TimerMetric lifeTimeInQueue;
 
   private final TimerMetric executionTime;
@@ -29,6 +31,10 @@ public class ProducerInvocationMetric extends InvocationMetric {
 
   private final CallMetric producerCall;
 
+  public long getWaitInQueue() {
+    return waitInQueue;
+  }
+
   public TimerMetric getLifeTimeInQueue() {
     return lifeTimeInQueue;
   }
@@ -47,24 +53,20 @@ public class ProducerInvocationMetric extends InvocationMetric {
 
   public ProducerInvocationMetric(String operationName, String prefix, long waitInQueue,
       TimerMetric lifeTimeInQueue, TimerMetric executionTime, TimerMetric producerLatency, CallMetric producerCall) {
-    super(operationName, prefix, waitInQueue);
+    super(operationName, prefix);
+    this.waitInQueue = waitInQueue;
     this.lifeTimeInQueue = lifeTimeInQueue;
     this.executionTime = executionTime;
     this.producerLatency = producerLatency;
     this.producerCall = producerCall;
   }
 
-  @Override
-  public InstanceCalculationMetric merge(InstanceCalculationMetric metric) {
-    metric.getProducerMetrics().put(this.getOperationName(), this);
-    return new InstanceCalculationMetric(metric.getTotalWaitInQueue() + getWaitInQueue(),
-        metric.getProducerWaitInQueue() + getWaitInQueue(),
-        metric.getConsumerMetrics(), metric.getProducerMetrics(),
+  public ProducerInvocationMetric merge(ProducerInvocationMetric metric) {
+    return new ProducerInvocationMetric(this.getOperationName(), this.getPrefix(),
+        this.getWaitInQueue() + metric.getWaitInQueue(),
         metric.getLifeTimeInQueue().merge(lifeTimeInQueue),
         metric.getExecutionTime().merge(executionTime),
-        metric.getConsumerLatency(),
         metric.getProducerLatency().merge(producerLatency),
-        metric.getConsumerCall(),
         metric.getProducerCall().merge(producerCall));
   }
 
diff --git a/metrics/metrics-core/src/main/java/io/servicecomb/metrics/core/metric/RegistryMetric.java b/metrics/metrics-core/src/main/java/io/servicecomb/metrics/core/metric/RegistryMetric.java
index 745a324..7bafee7 100644
--- a/metrics/metrics-core/src/main/java/io/servicecomb/metrics/core/metric/RegistryMetric.java
+++ b/metrics/metrics-core/src/main/java/io/servicecomb/metrics/core/metric/RegistryMetric.java
@@ -42,31 +42,41 @@ public class RegistryMetric {
     return producerMetrics;
   }
 
-  public RegistryMetric(SystemMetric systemMetric, Map<String, InvocationMetric> invocationMetrics) {
+  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_PRODUCER_PREFIX + ".producerLatency"),
+        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
-    InstanceCalculationMetric calculationMetric = new InstanceCalculationMetric();
-    for (InvocationMetric metric : invocationMetrics.values()) {
-      calculationMetric = metric.merge(calculationMetric);
+    for (ConsumerInvocationMetric metric : consumerMetrics.values()) {
+      instanceConsumerInvocationMetric = instanceConsumerInvocationMetric.merge(metric);
+    }
+    for (ProducerInvocationMetric metric : producerMetrics.values()) {
+      instanceProducerInvocationMetric = instanceProducerInvocationMetric.merge(metric);
     }
 
-    this.instanceMetric = new InstanceMetric(calculationMetric.getTotalWaitInQueue(), systemMetric,
-        new ConsumerInvocationMetric("instance", MetricsConst.INSTANCE_CONSUMER_PREFIX,
-            calculationMetric.getProducerWaitInQueue(),
-            calculationMetric.getConsumerLatency(), calculationMetric.getConsumerCall()),
-        new ProducerInvocationMetric("instance", MetricsConst.INSTANCE_PRODUCER_PREFIX,
-            calculationMetric.getProducerWaitInQueue(),
-            calculationMetric.getLifeTimeInQueue(), calculationMetric.getExecutionTime(),
-            calculationMetric.getProducerLatency(), calculationMetric.getProducerCall()));
-    this.producerMetrics = calculationMetric.getProducerMetrics();
-    this.consumerMetrics = calculationMetric.getConsumerMetrics();
+    this.instanceMetric = new InstanceMetric(systemMetric,
+        instanceConsumerInvocationMetric, instanceProducerInvocationMetric);
   }
 
   public Map<String, Number> toMap() {
     Map<String, Number> metrics = new HashMap<>();
+    metrics.putAll(instanceMetric.getSystemMetric().toMap());
     metrics.putAll(instanceMetric.getConsumerMetric().toMap());
     metrics.putAll(instanceMetric.getProducerMetric().toMap());
-    //will override waitInQueue.count value
-    metrics.put(MetricsConst.INSTANCE_PRODUCER_PREFIX + ".waitInQueue.count", instanceMetric.getWaitInQueue());
     for (ConsumerInvocationMetric metric : consumerMetrics.values()) {
       metrics.putAll(metric.toMap());
     }
diff --git a/metrics/metrics-core/src/main/java/io/servicecomb/metrics/core/metric/SystemMetric.java b/metrics/metrics-core/src/main/java/io/servicecomb/metrics/core/metric/SystemMetric.java
index be7725d..68fff72 100644
--- a/metrics/metrics-core/src/main/java/io/servicecomb/metrics/core/metric/SystemMetric.java
+++ b/metrics/metrics-core/src/main/java/io/servicecomb/metrics/core/metric/SystemMetric.java
@@ -17,6 +17,9 @@
 
 package io.servicecomb.metrics.core.metric;
 
+import java.util.HashMap;
+import java.util.Map;
+
 public class SystemMetric {
   private final double cpuLoad;
 
@@ -92,4 +95,20 @@ public class SystemMetric {
     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-core/src/main/java/io/servicecomb/metrics/core/monitor/BasicMonitor.java b/metrics/metrics-core/src/main/java/io/servicecomb/metrics/core/monitor/BasicMonitor.java
deleted file mode 100644
index c881865..0000000
--- a/metrics/metrics-core/src/main/java/io/servicecomb/metrics/core/monitor/BasicMonitor.java
+++ /dev/null
@@ -1,41 +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 io.servicecomb.metrics.core.monitor;
-
-import java.util.concurrent.TimeUnit;
-
-public class BasicMonitor {
-
-  //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 double adjustValue(double value) {
-    return value < 0 ? 0 : value;
-  }
-
-  //same as above
-  public long adjustValue(long value) {
-    return value < 0 ? 0 : value;
-  }
-
-  //Counting use System.nano get more precise time
-  //so we need change unit to millisecond when ouput
-  public long convertNanosecondToMillisecond(long nanoValue) {
-    return TimeUnit.NANOSECONDS.toMillis(nanoValue);
-  }
-}
diff --git a/metrics/metrics-core/src/main/java/io/servicecomb/metrics/core/monitor/CallMonitor.java b/metrics/metrics-core/src/main/java/io/servicecomb/metrics/core/monitor/CallMonitor.java
index ee62a54..76778ca 100644
--- a/metrics/metrics-core/src/main/java/io/servicecomb/metrics/core/monitor/CallMonitor.java
+++ b/metrics/metrics-core/src/main/java/io/servicecomb/metrics/core/monitor/CallMonitor.java
@@ -23,7 +23,7 @@ import com.netflix.servo.monitor.StepCounter;
 
 import io.servicecomb.metrics.core.metric.CallMetric;
 
-public class CallMonitor extends BasicMonitor {
+public class CallMonitor {
   private final String prefix;
 
   private final BasicCounter total;
@@ -41,8 +41,15 @@ public class CallMonitor extends BasicMonitor {
     tps.increment();
   }
 
-  public CallMetric toCallMetric(int windowTimeIndex) {
+  public CallMetric toMetric(int windowTimeIndex) {
     return new CallMetric(this.prefix, total.getValue(windowTimeIndex).longValue(),
         this.adjustValue(tps.getValue(windowTimeIndex).doubleValue()));
   }
+
+  //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 double adjustValue(double value) {
+    return value < 0 ? 0 : value;
+  }
 }
diff --git a/metrics/metrics-core/src/main/java/io/servicecomb/metrics/core/monitor/ConsumerInvocationMonitor.java b/metrics/metrics-core/src/main/java/io/servicecomb/metrics/core/monitor/ConsumerInvocationMonitor.java
new file mode 100644
index 0000000..a297ec4
--- /dev/null
+++ b/metrics/metrics-core/src/main/java/io/servicecomb/metrics/core/monitor/ConsumerInvocationMonitor.java
@@ -0,0 +1,46 @@
+/*
+ * 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 io.servicecomb.metrics.core.monitor;
+
+import io.servicecomb.metrics.core.MetricsConst;
+import io.servicecomb.metrics.core.metric.ConsumerInvocationMetric;
+
+public class ConsumerInvocationMonitor extends InvocationMonitor {
+  private final TimerMonitor consumerLatency;
+
+  private final CallMonitor consumerCall;
+
+  public TimerMonitor getConsumerLatency() {
+    return consumerLatency;
+  }
+
+  public CallMonitor getConsumerCall() {
+    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 ConsumerInvocationMetric toMetric(int windowTimeIndex) {
+    return new ConsumerInvocationMetric(this.getOperationName(), this.getPrefix(),
+        consumerLatency.toMetric(windowTimeIndex), consumerCall.toMetric(windowTimeIndex));
+  }
+}
diff --git a/metrics/metrics-core/src/main/java/io/servicecomb/metrics/core/monitor/DefaultSystemMonitor.java b/metrics/metrics-core/src/main/java/io/servicecomb/metrics/core/monitor/DefaultSystemMonitor.java
index 16b475b..d027a2c 100644
--- a/metrics/metrics-core/src/main/java/io/servicecomb/metrics/core/monitor/DefaultSystemMonitor.java
+++ b/metrics/metrics-core/src/main/java/io/servicecomb/metrics/core/monitor/DefaultSystemMonitor.java
@@ -98,7 +98,7 @@ public class DefaultSystemMonitor implements SystemMonitor {
   }
 
   @Override
-  public SystemMetric toSystemMetric() {
+  public SystemMetric toMetric() {
     return new SystemMetric(getCpuLoad(),
         getCpuRunningThreads(), getHeapInit(), getHeapMax(), getHeapCommit(), getHeapUsed(),
         getNonHeapInit(), getNonHeapMax(), getNonHeapCommit(), getNonHeapUsed());
diff --git a/metrics/metrics-core/src/main/java/io/servicecomb/metrics/core/monitor/InvocationMonitor.java b/metrics/metrics-core/src/main/java/io/servicecomb/metrics/core/monitor/InvocationMonitor.java
index f5430f7..c3c19a1 100644
--- a/metrics/metrics-core/src/main/java/io/servicecomb/metrics/core/monitor/InvocationMonitor.java
+++ b/metrics/metrics-core/src/main/java/io/servicecomb/metrics/core/monitor/InvocationMonitor.java
@@ -17,108 +17,21 @@
 
 package io.servicecomb.metrics.core.monitor;
 
-import com.netflix.servo.monitor.BasicCounter;
-import com.netflix.servo.monitor.MonitorConfig;
-
-import io.servicecomb.metrics.core.MetricsConst;
-import io.servicecomb.metrics.core.metric.ConsumerInvocationMetric;
-import io.servicecomb.metrics.core.metric.InvocationMetric;
-import io.servicecomb.metrics.core.metric.ProducerInvocationMetric;
-import io.servicecomb.swagger.invocation.InvocationType;
-
-public class InvocationMonitor extends BasicMonitor {
+public class InvocationMonitor {
   private final String operationName;
 
-  private final String consumerPrefix;
-
-  private final String producerPrefix;
-
-  private final BasicCounter waitInQueue;
-
-  private final TimerMonitor lifeTimeInQueue;
-
-  private final TimerMonitor executionTime;
-
-  private final TimerMonitor producerLatency;
-
-  private final TimerMonitor consumerLatency;
-
-  private final CallMonitor producerCall;
-
-  private final CallMonitor consumerCall;
-
-  private InvocationMonitorType invocationMonitorType = InvocationMonitorType.UNKNOWN;
-
-  //TODO:current java chassis unable know invocation type before starting process,so we need set it,can improve later
-  public void setInvocationMonitorType(InvocationType invocationType) {
-    if (InvocationMonitorType.UNKNOWN.equals(this.invocationMonitorType)) {
-      this.invocationMonitorType = invocationType == InvocationType.PRODUCER ?
-          InvocationMonitorType.PRODUCER : InvocationMonitorType.CONSUMER;
-    }
-  }
+  private final String prefix;
 
   public String getOperationName() {
     return operationName;
   }
 
-  public TimerMonitor getConsumerLatency() {
-    return consumerLatency;
-  }
-
-  public TimerMonitor getLifeTimeInQueue() {
-    return lifeTimeInQueue;
+  public String getPrefix() {
+    return prefix;
   }
 
-  public TimerMonitor getExecutionTime() {
-    return executionTime;
-  }
-
-  public TimerMonitor getProducerLatency() {
-    return producerLatency;
-  }
-
-  public CallMonitor getConsumerCall() {
-    return consumerCall;
-  }
-
-  public CallMonitor getProducerCall() {
-    return producerCall;
-  }
-
-  public BasicCounter getWaitInQueue() {
-    return waitInQueue;
-  }
-
-  public InvocationMonitor(String operationName) {
+  public InvocationMonitor(String operationName, String prefix) {
     this.operationName = operationName;
-    this.consumerPrefix = String.format(MetricsConst.CONSUMER_PREFIX_TEMPLATE, operationName);
-    this.producerPrefix = String.format(MetricsConst.PRODUCER_PREFIX_TEMPLATE, operationName);
-    this.waitInQueue = new BasicCounter(MonitorConfig.builder(producerPrefix + ".waitInQueue.count").build());
-
-    this.consumerLatency = new TimerMonitor(consumerPrefix + ".consumerLatency");
-    this.consumerCall = new CallMonitor(consumerPrefix + ".consumerCall");
-
-    this.lifeTimeInQueue = new TimerMonitor(producerPrefix + ".lifeTimeInQueue");
-    this.executionTime = new TimerMonitor(producerPrefix + ".executionTime");
-    this.producerLatency = new TimerMonitor(producerPrefix + ".producerLatency");
-    this.producerCall = new CallMonitor(producerPrefix + ".producerCall");
-  }
-
-  public InvocationMetric toInvocationMetric(int windowTimeIndex) {
-    InvocationMetric metric;
-    long queueCount = waitInQueue.getValue(windowTimeIndex).longValue();
-    if (invocationMonitorType.equals(InvocationMonitorType.PRODUCER)) {
-      metric = new ProducerInvocationMetric(operationName, producerPrefix, queueCount,
-          lifeTimeInQueue.toTimerMetric(windowTimeIndex),
-          executionTime.toTimerMetric(windowTimeIndex),
-          producerLatency.toTimerMetric(windowTimeIndex),
-          producerCall.toCallMetric(windowTimeIndex));
-    } else if (invocationMonitorType.equals(InvocationMonitorType.CONSUMER)) {
-      metric = new ConsumerInvocationMetric(operationName, consumerPrefix, queueCount,
-          consumerLatency.toTimerMetric(windowTimeIndex), consumerCall.toCallMetric(windowTimeIndex));
-    } else {
-      metric = new InvocationMetric(operationName, consumerPrefix, queueCount);
-    }
-    return metric;
+    this.prefix = prefix;
   }
 }
diff --git a/metrics/metrics-core/src/main/java/io/servicecomb/metrics/core/monitor/InvocationMonitorType.java b/metrics/metrics-core/src/main/java/io/servicecomb/metrics/core/monitor/InvocationMonitorType.java
deleted file mode 100644
index d0408f7..0000000
--- a/metrics/metrics-core/src/main/java/io/servicecomb/metrics/core/monitor/InvocationMonitorType.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 io.servicecomb.metrics.core.monitor;
-
-public enum InvocationMonitorType {
-  //when InvocationStartedEvent received,InvocationType is unknown
-  UNKNOWN,
-  CONSUMER,
-  PRODUCER
-}
diff --git a/metrics/metrics-core/src/main/java/io/servicecomb/metrics/core/monitor/ProducerInvocationMonitor.java b/metrics/metrics-core/src/main/java/io/servicecomb/metrics/core/monitor/ProducerInvocationMonitor.java
new file mode 100644
index 0000000..b1f945f
--- /dev/null
+++ b/metrics/metrics-core/src/main/java/io/servicecomb/metrics/core/monitor/ProducerInvocationMonitor.java
@@ -0,0 +1,74 @@
+/*
+ * 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 io.servicecomb.metrics.core.monitor;
+
+import com.netflix.servo.monitor.BasicCounter;
+import com.netflix.servo.monitor.MonitorConfig;
+
+import io.servicecomb.metrics.core.MetricsConst;
+import io.servicecomb.metrics.core.metric.ProducerInvocationMetric;
+
+public class ProducerInvocationMonitor extends InvocationMonitor {
+  private final BasicCounter waitInQueue;
+
+  private final TimerMonitor lifeTimeInQueue;
+
+  private final TimerMonitor executionTime;
+
+  private final TimerMonitor producerLatency;
+
+  private final CallMonitor producerCall;
+
+  public BasicCounter getWaitInQueue() {
+    return waitInQueue;
+  }
+
+  public TimerMonitor getLifeTimeInQueue() {
+    return lifeTimeInQueue;
+  }
+
+  public TimerMonitor getExecutionTime() {
+    return executionTime;
+  }
+
+  public TimerMonitor getProducerLatency() {
+    return producerLatency;
+  }
+
+  public CallMonitor getProducerCall() {
+    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 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));
+  }
+}
diff --git a/metrics/metrics-core/src/main/java/io/servicecomb/metrics/core/monitor/RegistryMonitor.java b/metrics/metrics-core/src/main/java/io/servicecomb/metrics/core/monitor/RegistryMonitor.java
index c1060de..0772463 100644
--- a/metrics/metrics-core/src/main/java/io/servicecomb/metrics/core/monitor/RegistryMonitor.java
+++ b/metrics/metrics-core/src/main/java/io/servicecomb/metrics/core/monitor/RegistryMonitor.java
@@ -24,31 +24,43 @@ import java.util.concurrent.ConcurrentHashMap;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Component;
 
-import io.servicecomb.metrics.core.metric.InvocationMetric;
+import io.servicecomb.metrics.core.metric.ConsumerInvocationMetric;
+import io.servicecomb.metrics.core.metric.ProducerInvocationMetric;
 import io.servicecomb.metrics.core.metric.RegistryMetric;
 
 @Component
-public class RegistryMonitor extends BasicMonitor {
+public class RegistryMonitor {
 
   private final SystemMonitor systemMonitor;
 
-  private final Map<String, InvocationMonitor> invocationMonitors;
+  private final Map<String, ConsumerInvocationMonitor> consumerInvocationMonitors;
+
+  private final Map<String, ProducerInvocationMonitor> producerInvocationMonitors;
 
   @Autowired
   public RegistryMonitor(SystemMonitor systemMonitor) {
     this.systemMonitor = systemMonitor;
-    this.invocationMonitors = new ConcurrentHashMap<>();
+    this.consumerInvocationMonitors = new ConcurrentHashMap<>();
+    this.producerInvocationMonitors = new ConcurrentHashMap<>();
+  }
+
+  public ConsumerInvocationMonitor getConsumerInvocationMonitor(String operationName) {
+    return consumerInvocationMonitors.computeIfAbsent(operationName, i -> new ConsumerInvocationMonitor(operationName));
   }
 
-  public InvocationMonitor getInvocationMonitor(String operationName) {
-    return invocationMonitors.computeIfAbsent(operationName, i -> new InvocationMonitor(operationName));
+  public ProducerInvocationMonitor getProducerInvocationMonitor(String operationName) {
+    return producerInvocationMonitors.computeIfAbsent(operationName, i -> new ProducerInvocationMonitor(operationName));
   }
 
   public RegistryMetric toRegistryMetric(int windowTimeIndex) {
-    Map<String, InvocationMetric> invocationMetrics = new HashMap<>();
-    for (InvocationMonitor monitor : invocationMonitors.values()) {
-      invocationMetrics.put(monitor.getOperationName(), monitor.toInvocationMetric(windowTimeIndex));
+    Map<String, ConsumerInvocationMetric> consumerInvocationMetrics = new HashMap<>();
+    for (ConsumerInvocationMonitor monitor : this.consumerInvocationMonitors.values()) {
+      consumerInvocationMetrics.put(monitor.getOperationName(), monitor.toMetric(windowTimeIndex));
+    }
+    Map<String, ProducerInvocationMetric> producerInvocationMetrics = new HashMap<>();
+    for (ProducerInvocationMonitor monitor : this.producerInvocationMonitors.values()) {
+      producerInvocationMetrics.put(monitor.getOperationName(), monitor.toMetric(windowTimeIndex));
     }
-    return new RegistryMetric(systemMonitor.toSystemMetric(), invocationMetrics);
+    return new RegistryMetric(systemMonitor.toMetric(), consumerInvocationMetrics, producerInvocationMetrics);
   }
 }
diff --git a/metrics/metrics-core/src/main/java/io/servicecomb/metrics/core/monitor/SystemMonitor.java b/metrics/metrics-core/src/main/java/io/servicecomb/metrics/core/monitor/SystemMonitor.java
index c35e6cc..1780e3f 100644
--- a/metrics/metrics-core/src/main/java/io/servicecomb/metrics/core/monitor/SystemMonitor.java
+++ b/metrics/metrics-core/src/main/java/io/servicecomb/metrics/core/monitor/SystemMonitor.java
@@ -40,5 +40,5 @@ public interface SystemMonitor {
 
   long getNonHeapUsed();
 
-  SystemMetric toSystemMetric();
+  SystemMetric toMetric();
 }
diff --git a/metrics/metrics-core/src/main/java/io/servicecomb/metrics/core/monitor/TimerMonitor.java b/metrics/metrics-core/src/main/java/io/servicecomb/metrics/core/monitor/TimerMonitor.java
index 9917b5e..1a15571 100644
--- a/metrics/metrics-core/src/main/java/io/servicecomb/metrics/core/monitor/TimerMonitor.java
+++ b/metrics/metrics-core/src/main/java/io/servicecomb/metrics/core/monitor/TimerMonitor.java
@@ -17,6 +17,8 @@
 
 package io.servicecomb.metrics.core.monitor;
 
+import java.util.concurrent.TimeUnit;
+
 import com.netflix.servo.monitor.MaxGauge;
 import com.netflix.servo.monitor.MinGauge;
 import com.netflix.servo.monitor.MonitorConfig;
@@ -24,7 +26,7 @@ import com.netflix.servo.monitor.StepCounter;
 
 import io.servicecomb.metrics.core.metric.TimerMetric;
 
-public class TimerMonitor extends BasicMonitor {
+public class TimerMonitor {
   private final String prefix;
 
   //nanosecond sum
@@ -55,11 +57,24 @@ public class TimerMonitor extends BasicMonitor {
     max = new MaxGauge(MonitorConfig.builder(prefix + ".max").build());
   }
 
-  public TimerMetric toTimerMetric(int windowTimeIndex) {
+  public TimerMetric toMetric(int windowTimeIndex) {
     return new TimerMetric(this.prefix,
         this.convertNanosecondToMillisecond(this.adjustValue(total.getCount(windowTimeIndex))),
         this.adjustValue(count.getCount(windowTimeIndex)),
         this.convertNanosecondToMillisecond(this.adjustValue(min.getValue(windowTimeIndex))),
         this.convertNanosecondToMillisecond(this.adjustValue(max.getValue(windowTimeIndex))));
   }
+
+  //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 long adjustValue(long value) {
+    return value < 0 ? 0 : value;
+  }
+
+  //Counting use System.nano get more precise time
+  //so we need change unit to millisecond when ouput
+  public long convertNanosecondToMillisecond(long nanoValue) {
+    return TimeUnit.NANOSECONDS.toMillis(nanoValue);
+  }
 }
diff --git a/metrics/metrics-core/src/test/java/io/servicecomb/metrics/core/TestEventAndRunner.java b/metrics/metrics-core/src/test/java/io/servicecomb/metrics/core/TestEventAndRunner.java
index 8618757..d9a7e2b 100644
--- a/metrics/metrics-core/src/test/java/io/servicecomb/metrics/core/TestEventAndRunner.java
+++ b/metrics/metrics-core/src/test/java/io/servicecomb/metrics/core/TestEventAndRunner.java
@@ -75,7 +75,7 @@ public class TestEventAndRunner {
     new DefaultEventListenerManager(monitor);
 
     //fun1 is a PRODUCER invocation call twice and all is completed
-    EventUtils.triggerEvent(new InvocationStartedEvent("fun1", System.nanoTime()));
+    EventUtils.triggerEvent(new InvocationStartedEvent("fun1", InvocationType.PRODUCER, System.nanoTime()));
     EventUtils.triggerEvent(
         new InvocationStartProcessingEvent("fun1", InvocationType.PRODUCER, System.nanoTime(),
             TimeUnit.MILLISECONDS.toNanos(100)));
@@ -83,7 +83,7 @@ public class TestEventAndRunner {
         .triggerEvent(new InvocationFinishedEvent("fun1", InvocationType.PRODUCER, System.nanoTime(),
             TimeUnit.MILLISECONDS.toNanos(200), TimeUnit.MILLISECONDS.toNanos(300)));
 
-    EventUtils.triggerEvent(new InvocationStartedEvent("fun1", System.nanoTime()));
+    EventUtils.triggerEvent(new InvocationStartedEvent("fun1", InvocationType.PRODUCER, System.nanoTime()));
     EventUtils.triggerEvent(
         new InvocationStartProcessingEvent("fun1", InvocationType.PRODUCER, System.nanoTime(),
             TimeUnit.MILLISECONDS.toNanos(300)));
@@ -92,13 +92,13 @@ public class TestEventAndRunner {
             TimeUnit.MILLISECONDS.toNanos(400), TimeUnit.MILLISECONDS.toNanos(700)));
 
     //fun3 is a PRODUCER invocation call uncompleted
-    EventUtils.triggerEvent(new InvocationStartedEvent("fun3", System.nanoTime()));
+    EventUtils.triggerEvent(new InvocationStartedEvent("fun3", InvocationType.PRODUCER, System.nanoTime()));
     EventUtils.triggerEvent(
         new InvocationStartProcessingEvent("fun3", InvocationType.PRODUCER, System.nanoTime(),
             TimeUnit.MILLISECONDS.toNanos(500)));
 
     //fun2 is a CONSUMER invocation call once and completed
-    EventUtils.triggerEvent(new InvocationStartedEvent("fun2", System.nanoTime()));
+    EventUtils.triggerEvent(new InvocationStartedEvent("fun2", InvocationType.CONSUMER, System.nanoTime()));
     EventUtils.triggerEvent(
         new InvocationStartProcessingEvent("fun2", InvocationType.CONSUMER, System.nanoTime(),
             TimeUnit.MILLISECONDS.toNanos(100)));
@@ -107,7 +107,7 @@ public class TestEventAndRunner {
             TimeUnit.MILLISECONDS.toNanos(200), TimeUnit.MILLISECONDS.toNanos(300)));
 
     //fun4 is a invocation call only started and no processing start and finished
-    EventUtils.triggerEvent(new InvocationStartedEvent("fun4", System.nanoTime()));
+    EventUtils.triggerEvent(new InvocationStartedEvent("fun4", InvocationType.PRODUCER, System.nanoTime()));
 
     //sim lease one window time
     Thread.sleep(1000);
@@ -115,8 +115,7 @@ public class TestEventAndRunner {
     RegistryMetric model = dataSource.getRegistryMetric();
 
     //check InstanceMetric
-    Assert.assertEquals(model.getInstanceMetric().getWaitInQueue(), 1);
-    Assert.assertEquals(model.getInstanceMetric().getProducerMetric().getWaitInQueue(), 0);
+    Assert.assertEquals(model.getInstanceMetric().getProducerMetric().getWaitInQueue(), 1);
     Assert.assertEquals(model.getInstanceMetric().getProducerMetric().getLifeTimeInQueue().getCount(), 3);
     Assert.assertEquals(model.getInstanceMetric().getProducerMetric().getLifeTimeInQueue().getTotal(),
         900, 0);
@@ -147,8 +146,8 @@ public class TestEventAndRunner {
     Assert.assertEquals(model.getInstanceMetric().getProducerMetric().getProducerLatency().getMin(),
         300, 0);
 
-    Assert.assertEquals(model.getInstanceMetric().getProducerMetric().getProducerCall().getTps(), 3, 0);
-    Assert.assertEquals(model.getInstanceMetric().getProducerMetric().getProducerCall().getTotal(), 3);
+    Assert.assertEquals(model.getInstanceMetric().getProducerMetric().getProducerCall().getTps(), 4, 0);
+    Assert.assertEquals(model.getInstanceMetric().getProducerMetric().getProducerCall().getTotal(), 4);
 
     Assert.assertEquals(model.getInstanceMetric().getConsumerMetric().getConsumerLatency().getCount(), 1);
     Assert.assertEquals(model.getInstanceMetric().getConsumerMetric().getConsumerLatency().getTotal(),
@@ -235,7 +234,6 @@ public class TestEventAndRunner {
 
     //check ConsumerMetrics
     //no need
-    Assert.assertEquals(model.getConsumerMetrics().get("fun2").getWaitInQueue(), 0);
     Assert.assertEquals(model.getConsumerMetrics().get("fun2").getConsumerLatency().getCount(), 1);
     Assert.assertEquals(model.getConsumerMetrics().get("fun2").getConsumerLatency().getTotal(),
         300, 0);
@@ -250,7 +248,7 @@ public class TestEventAndRunner {
     Assert.assertEquals(model.getConsumerMetrics().get("fun2").getConsumerCall().getTotal(), 1);
 
     Map<String, Number> metrics = model.toMap();
-    Assert.assertEquals(metrics.size(), 68);
+    Assert.assertEquals(metrics.size(), 72);
 
     Assert.assertEquals(model.getInstanceMetric().getSystemMetric().getCpuLoad(), 1.0, 0);
     Assert.assertEquals(model.getInstanceMetric().getSystemMetric().getCpuRunningThreads(), 2, 0);
diff --git a/transports/transport-highway/src/main/java/io/servicecomb/transport/highway/HighwayServerInvoke.java b/transports/transport-highway/src/main/java/io/servicecomb/transport/highway/HighwayServerInvoke.java
index 68e95e3..8a14252 100644
--- a/transports/transport-highway/src/main/java/io/servicecomb/transport/highway/HighwayServerInvoke.java
+++ b/transports/transport-highway/src/main/java/io/servicecomb/transport/highway/HighwayServerInvoke.java
@@ -39,6 +39,7 @@ import io.servicecomb.foundation.metrics.MetricsServoRegistry;
 import io.servicecomb.foundation.metrics.performance.QueueMetrics;
 import io.servicecomb.foundation.metrics.performance.QueueMetricsData;
 import io.servicecomb.foundation.vertx.tcp.TcpConnection;
+import io.servicecomb.swagger.invocation.InvocationType;
 import io.servicecomb.swagger.invocation.Response;
 import io.servicecomb.swagger.invocation.exception.InvocationException;
 import io.servicecomb.transport.highway.message.RequestHeader;
@@ -167,7 +168,7 @@ public class HighwayServerInvoke {
    */
   public void execute() {
     InvocationStartedEvent startedEvent = new InvocationStartedEvent(operationMeta.getMicroserviceQualifiedName(),
-        System.nanoTime());
+        InvocationType.PRODUCER, System.nanoTime());
     EventUtils.triggerEvent(startedEvent);
     QueueMetrics metricsData = initMetrics(operationMeta);
     operationMeta.getExecutor().execute(() -> runInExecutor(metricsData,startedEvent));

-- 
To stop receiving notification emails like this one, please contact
"commits@servicecomb.apache.org" <co...@servicecomb.apache.org>.