You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@servicecomb.apache.org by GitBox <gi...@apache.org> on 2018/03/27 12:15:34 UTC

[GitHub] liubao68 closed pull request #609: [SCB-383] Metrics subscribe invocation life event and statistics

liubao68 closed pull request #609: [SCB-383] Metrics subscribe invocation life event and statistics
URL: https://github.com/apache/incubator-servicecomb-java-chassis/pull/609
 
 
   

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

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

diff --git a/core/src/main/java/org/apache/servicecomb/core/event/InvocationStartEvent.java b/core/src/main/java/org/apache/servicecomb/core/event/InvocationStartEvent.java
index 5b93e66d0..e83c4470e 100644
--- a/core/src/main/java/org/apache/servicecomb/core/event/InvocationStartEvent.java
+++ b/core/src/main/java/org/apache/servicecomb/core/event/InvocationStartEvent.java
@@ -22,7 +22,6 @@
   private Invocation invocation;
 
   public InvocationStartEvent(Invocation invocation) {
-    super();
     this.invocation = invocation;
   }
 
diff --git a/foundations/foundation-common/src/main/java/org/apache/servicecomb/foundation/common/event/EventManager.java b/foundations/foundation-common/src/main/java/org/apache/servicecomb/foundation/common/event/EventManager.java
index d50e76778..9672a92dc 100644
--- a/foundations/foundation-common/src/main/java/org/apache/servicecomb/foundation/common/event/EventManager.java
+++ b/foundations/foundation-common/src/main/java/org/apache/servicecomb/foundation/common/event/EventManager.java
@@ -27,6 +27,10 @@
 public class EventManager {
   public static EventBus eventBus = new SimpleEventBus();
 
+  public static EventBus getEventBus() {
+    return eventBus;
+  }
+
   /**
    * Registering listener.
    */
diff --git a/foundations/foundation-metrics/src/main/java/org/apache/servicecomb/foundation/metrics/MetricsBootstrap.java b/foundations/foundation-metrics/src/main/java/org/apache/servicecomb/foundation/metrics/MetricsBootstrap.java
new file mode 100644
index 000000000..233526467
--- /dev/null
+++ b/foundations/foundation-metrics/src/main/java/org/apache/servicecomb/foundation/metrics/MetricsBootstrap.java
@@ -0,0 +1,82 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.servicecomb.foundation.metrics;
+
+import java.util.List;
+import java.util.concurrent.Executors;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.TimeUnit;
+
+import org.apache.servicecomb.foundation.common.utils.SPIServiceUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.collect.Lists;
+import com.google.common.eventbus.EventBus;
+import com.google.common.util.concurrent.ThreadFactoryBuilder;
+import com.netflix.spectator.api.CompositeRegistry;
+import com.netflix.spectator.api.Meter;
+
+public class MetricsBootstrap {
+  private static final Logger LOGGER = LoggerFactory.getLogger(MetricsBootstrap.class);
+
+  private CompositeRegistry globalRegistry;
+
+  private EventBus eventBus;
+
+  private MetricsBootstrapConfig config = new MetricsBootstrapConfig();
+
+  private ScheduledExecutorService executorService;
+
+  public void start(CompositeRegistry globalRegistry, EventBus eventBus) {
+    this.globalRegistry = globalRegistry;
+    this.eventBus = eventBus;
+    this.executorService = Executors.newScheduledThreadPool(1,
+        new ThreadFactoryBuilder()
+            .setNameFormat("spectator-poller-%d")
+            .build());
+
+    loadMetricsInitializers();
+    startPoll();
+  }
+
+  public void shutdown() {
+    executorService.shutdown();
+  }
+
+  protected void loadMetricsInitializers() {
+    SPIServiceUtils.getSortedService(MetricsInitializer.class).forEach(initializer -> {
+      LOGGER.info("Found MetricsInitializer: {}", initializer.getClass().getName());
+
+      initializer.init(globalRegistry, eventBus, config);
+    });
+  }
+
+  protected void startPoll() {
+    executorService.scheduleAtFixedRate(this::pollMeters,
+        0,
+        config.getMsPollInterval(),
+        TimeUnit.MILLISECONDS);
+  }
+
+  protected void pollMeters() {
+    List<Meter> meters = Lists.newArrayList(globalRegistry.iterator());
+    PolledEvent event = new PolledEvent(meters);
+
+    eventBus.post(event);
+  }
+}
diff --git a/foundations/foundation-metrics/src/main/java/org/apache/servicecomb/foundation/metrics/MetricsBootstrapConfig.java b/foundations/foundation-metrics/src/main/java/org/apache/servicecomb/foundation/metrics/MetricsBootstrapConfig.java
new file mode 100644
index 000000000..41baa95b6
--- /dev/null
+++ b/foundations/foundation-metrics/src/main/java/org/apache/servicecomb/foundation/metrics/MetricsBootstrapConfig.java
@@ -0,0 +1,36 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.servicecomb.foundation.metrics;
+
+import com.netflix.config.DynamicPropertyFactory;
+
+public class MetricsBootstrapConfig {
+  public static final String METRICS_WINDOW_TIME = "servicecomb.metrics.window_time";
+
+  public static final int DEFAULT_METRICS_WINDOW_TIME = 5000;
+
+  private long msPollInterval;
+
+  public MetricsBootstrapConfig() {
+    msPollInterval =
+        DynamicPropertyFactory.getInstance().getIntProperty(METRICS_WINDOW_TIME, DEFAULT_METRICS_WINDOW_TIME).get();;
+  }
+
+  public long getMsPollInterval() {
+    return msPollInterval;
+  }
+}
diff --git a/foundations/foundation-metrics/src/main/java/org/apache/servicecomb/foundation/metrics/MetricsInitializer.java b/foundations/foundation-metrics/src/main/java/org/apache/servicecomb/foundation/metrics/MetricsInitializer.java
new file mode 100644
index 000000000..5e1aaef6c
--- /dev/null
+++ b/foundations/foundation-metrics/src/main/java/org/apache/servicecomb/foundation/metrics/MetricsInitializer.java
@@ -0,0 +1,27 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.servicecomb.foundation.metrics;
+
+import com.google.common.eventbus.EventBus;
+import com.netflix.spectator.api.CompositeRegistry;
+
+public interface MetricsInitializer {
+  /** 
+   * if create new registry, must add to globalRegistry
+   */
+  void init(CompositeRegistry globalRegistry, EventBus eventBus, MetricsBootstrapConfig config);
+}
diff --git a/foundations/foundation-metrics/src/main/java/org/apache/servicecomb/foundation/metrics/PolledEvent.java b/foundations/foundation-metrics/src/main/java/org/apache/servicecomb/foundation/metrics/PolledEvent.java
new file mode 100644
index 000000000..b2aa0709b
--- /dev/null
+++ b/foundations/foundation-metrics/src/main/java/org/apache/servicecomb/foundation/metrics/PolledEvent.java
@@ -0,0 +1,37 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.servicecomb.foundation.metrics;
+
+import java.util.List;
+
+import com.netflix.spectator.api.Meter;
+
+public class PolledEvent {
+  private List<Meter> meters;
+
+  public PolledEvent(List<Meter> meters) {
+    this.meters = meters;
+  }
+
+  public List<Meter> getMeters() {
+    return meters;
+  }
+
+  public void setMeters(List<Meter> meters) {
+    this.meters = meters;
+  }
+}
diff --git a/foundations/foundation-metrics/src/test/java/org/apache/servicecomb/foundation/metrics/TestMetricsBootstrap.java b/foundations/foundation-metrics/src/test/java/org/apache/servicecomb/foundation/metrics/TestMetricsBootstrap.java
new file mode 100644
index 000000000..b8280f45c
--- /dev/null
+++ b/foundations/foundation-metrics/src/test/java/org/apache/servicecomb/foundation/metrics/TestMetricsBootstrap.java
@@ -0,0 +1,95 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.servicecomb.foundation.metrics;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import org.apache.servicecomb.foundation.common.utils.SPIServiceUtils;
+import org.hamcrest.Matchers;
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Test;
+
+import com.google.common.eventbus.EventBus;
+import com.google.common.eventbus.Subscribe;
+import com.netflix.spectator.api.CompositeRegistry;
+import com.netflix.spectator.api.Meter;
+
+import mockit.Expectations;
+import mockit.Mocked;
+
+public class TestMetricsBootstrap {
+  MetricsBootstrap bootstrap = new MetricsBootstrap();
+
+  @Mocked
+  CompositeRegistry globalRegistry;
+
+  EventBus eventBus = new EventBus();
+
+  @After
+  public void teardown() {
+    bootstrap.shutdown();
+  }
+
+  @Test
+  public void loadMetricsInitializers() {
+    List<MetricsInitializer> initList = new ArrayList<>();
+    MetricsInitializer metricsInitializer = new MetricsInitializer() {
+      @Override
+      public void init(CompositeRegistry globalRegistry, EventBus eventBus, MetricsBootstrapConfig config) {
+        initList.add(this);
+      }
+    };
+    new Expectations(SPIServiceUtils.class) {
+      {
+        SPIServiceUtils.getSortedService(MetricsInitializer.class);
+        result = Arrays.asList(metricsInitializer, metricsInitializer);
+      }
+    };
+
+    bootstrap.start(globalRegistry, eventBus);
+
+    Assert.assertThat(initList, Matchers.contains(metricsInitializer, metricsInitializer));
+  }
+
+  @Test
+  public void pollMeters() {
+    bootstrap.start(globalRegistry, eventBus);
+
+    List<Meter> meters = new ArrayList<>();
+    new Expectations() {
+      {
+        globalRegistry.iterator();
+        result = meters.iterator();
+      }
+    };
+
+    PolledEvent result = new PolledEvent(null);
+    eventBus.register(new Object() {
+      @Subscribe
+      public void onEvent(PolledEvent event) {
+        result.setMeters(event.getMeters());
+      }
+    });
+
+    bootstrap.pollMeters();
+
+    Assert.assertEquals(meters, result.getMeters());
+  }
+}
diff --git a/foundations/foundation-test-scaffolding/pom.xml b/foundations/foundation-test-scaffolding/pom.xml
index cf5592fbc..abfe02492 100644
--- a/foundations/foundation-test-scaffolding/pom.xml
+++ b/foundations/foundation-test-scaffolding/pom.xml
@@ -44,5 +44,9 @@
       <groupId>io.vertx</groupId>
       <artifactId>vertx-web</artifactId>
     </dependency>
+    <dependency>
+      <groupId>com.netflix.spectator</groupId>
+      <artifactId>spectator-reg-servo</artifactId>
+    </dependency>
   </dependencies>
 </project>
diff --git a/foundations/foundation-test-scaffolding/src/main/java/com/netflix/spectator/api/SpectatorUtils.java b/foundations/foundation-test-scaffolding/src/main/java/com/netflix/spectator/api/SpectatorUtils.java
new file mode 100644
index 000000000..7a2f78514
--- /dev/null
+++ b/foundations/foundation-test-scaffolding/src/main/java/com/netflix/spectator/api/SpectatorUtils.java
@@ -0,0 +1,23 @@
+/*
+ * 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 com.netflix.spectator.api;
+
+public class SpectatorUtils {
+  public static CompositeRegistry createCompositeRegistry(Clock clock) {
+    return new CompositeRegistry(clock);
+  }
+}
diff --git a/java-chassis-dependencies/pom.xml b/java-chassis-dependencies/pom.xml
index e9ae9ecfc..b7b622785 100644
--- a/java-chassis-dependencies/pom.xml
+++ b/java-chassis-dependencies/pom.xml
@@ -360,7 +360,7 @@
       <dependency>
         <groupId>com.netflix.spectator</groupId>
         <artifactId>spectator-reg-servo</artifactId>
-        <version>0.62.0</version>
+        <version>0.63.0</version>
       </dependency>
       <dependency>
         <groupId>com.google.inject</groupId>
diff --git a/java-chassis-distribution/src/release/LICENSE b/java-chassis-distribution/src/release/LICENSE
index 8fb6c3663..8243952fa 100644
--- a/java-chassis-distribution/src/release/LICENSE
+++ b/java-chassis-distribution/src/release/LICENSE
@@ -432,7 +432,7 @@ rxnetty-contexts (https://github.com/ReactiveX/RxNetty) io.reactivex:rxnetty-con
 rxnetty-servo (https://github.com/ReactiveX/RxNetty) io.reactivex:rxnetty-servo:jar:0.4.9
 servo-core (https://github.com/Netflix/servo) com.netflix.servo:servo-core:jar:0.10.1
 servo-internal (https://github.com/Netflix/servo) com.netflix.servo:servo-internal:jar:0.10.1
-spectator-reg-servo (https://github.com/Netflix/spectator) com.netflix.spectator:spectator-reg-servo:0.62.0
+spectator-reg-servo (https://github.com/Netflix/spectator) com.netflix.spectator:spectator-reg-servo:0.63.0
 spectator-api (https://github.com/Netflix/spectator) com.netflix.spectator:spectator-api:0.62.0
 spring-cloud-starter (https://projects.spring.io/spring-cloud) org.springframework.cloud:spring-cloud-starter:jar:1.1.8.RELEASE
 spring-cloud-starter-archaius (https://projects.spring.io/spring-cloud) org.springframework.cloud:spring-cloud-starter-archaius:jar:1.2.6.RELEASE
diff --git a/metrics/metrics-core/pom.xml b/metrics/metrics-core/pom.xml
index 8e4d3a4ec..f4d1e761b 100644
--- a/metrics/metrics-core/pom.xml
+++ b/metrics/metrics-core/pom.xml
@@ -16,8 +16,7 @@
   ~ limitations under the License.
   -->
 
-<project xmlns="http://maven.apache.org/POM/4.0.0"
-  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
   <parent>
     <artifactId>metrics</artifactId>
@@ -48,6 +47,11 @@
       <artifactId>slf4j-log4j12</artifactId>
       <scope>test</scope>
     </dependency>
+    <dependency>
+      <groupId>org.apache.servicecomb</groupId>
+      <artifactId>foundation-test-scaffolding</artifactId>
+    </dependency>
+
   </dependencies>
 
 </project>
diff --git a/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/DefaultMetricsInitializer.java b/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/DefaultMetricsInitializer.java
new file mode 100644
index 000000000..12e090e82
--- /dev/null
+++ b/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/DefaultMetricsInitializer.java
@@ -0,0 +1,82 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.servicecomb.metrics.core;
+
+import org.apache.servicecomb.core.Invocation;
+import org.apache.servicecomb.core.event.InvocationFinishEvent;
+import org.apache.servicecomb.core.event.InvocationStartEvent;
+import org.apache.servicecomb.foundation.metrics.MetricsBootstrapConfig;
+import org.apache.servicecomb.foundation.metrics.MetricsInitializer;
+import org.apache.servicecomb.metrics.core.meter.ConsumerMeters;
+import org.apache.servicecomb.metrics.core.meter.ProducerMeters;
+import org.apache.servicecomb.metrics.core.meter.invocation.AbstractInvocationMeters;
+
+import com.google.common.eventbus.AllowConcurrentEvents;
+import com.google.common.eventbus.EventBus;
+import com.google.common.eventbus.Subscribe;
+import com.netflix.spectator.api.CompositeRegistry;
+import com.netflix.spectator.api.Registry;
+import com.netflix.spectator.servo.ServoRegistry;
+
+public class DefaultMetricsInitializer implements MetricsInitializer {
+  public static final String METRICS_WINDOW_TIME = "servicecomb.metrics.window_time";
+
+  public static final int DEFAULT_METRICS_WINDOW_TIME = 5000;
+
+  private Registry registry;
+
+  private ConsumerMeters consumerMeters;
+
+  private ProducerMeters producerMeters;
+
+  @Override
+  public void init(CompositeRegistry globalRegistry, EventBus eventBus, MetricsBootstrapConfig config) {
+    registry = createRegistry(config);
+
+    this.consumerMeters = new ConsumerMeters(registry);
+    this.producerMeters = new ProducerMeters(registry);
+
+    globalRegistry.add(registry);
+    eventBus.register(this);
+  }
+
+  protected Registry createRegistry(MetricsBootstrapConfig config) {
+    System.getProperties().setProperty("servo.pollers", String.valueOf(config.getMsPollInterval()));
+    return new ServoRegistry();
+  }
+
+  protected AbstractInvocationMeters findInvocationMeters(Invocation invocation) {
+    if (invocation.isConsumer()) {
+      return consumerMeters.getInvocationMeters();
+    }
+    return producerMeters.getInvocationMeters();
+  }
+
+  @Subscribe
+  @AllowConcurrentEvents
+  public void onInvocationStart(InvocationStartEvent event) {
+    AbstractInvocationMeters invocationMeters = findInvocationMeters(event.getInvocation());
+    invocationMeters.onInvocationStart(event);
+  }
+
+  @Subscribe
+  @AllowConcurrentEvents
+  public void onInvocationFinish(InvocationFinishEvent event) {
+    AbstractInvocationMeters invocationMeters = findInvocationMeters(event.getInvocation());
+    invocationMeters.onInvocationFinish(event);
+  }
+}
diff --git a/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/MetricsBootListener.java b/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/MetricsBootListener.java
new file mode 100644
index 000000000..48c2837b3
--- /dev/null
+++ b/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/MetricsBootListener.java
@@ -0,0 +1,38 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.servicecomb.metrics.core;
+
+import org.apache.servicecomb.core.BootListener;
+import org.apache.servicecomb.foundation.common.event.EventManager;
+import org.apache.servicecomb.foundation.metrics.MetricsBootstrap;
+import org.springframework.stereotype.Component;
+
+import com.netflix.spectator.api.Spectator;
+
+@Component
+public class MetricsBootListener implements BootListener {
+  private MetricsBootstrap metricsBootstrap = new MetricsBootstrap();
+
+  @Override
+  public void onBootEvent(BootEvent event) {
+    if (!EventType.AFTER_REGISTRY.equals(event.getEventType())) {
+      return;
+    }
+
+    metricsBootstrap.start(Spectator.globalRegistry(), EventManager.getEventBus());
+  }
+}
diff --git a/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/meter/ConsumerMeters.java b/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/meter/ConsumerMeters.java
new file mode 100644
index 000000000..b249fdcd6
--- /dev/null
+++ b/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/meter/ConsumerMeters.java
@@ -0,0 +1,34 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.servicecomb.metrics.core.meter;
+
+import org.apache.servicecomb.metrics.core.meter.invocation.AbstractInvocationMeters;
+import org.apache.servicecomb.metrics.core.meter.invocation.ConsumerInvocationMeters;
+
+import com.netflix.spectator.api.Registry;
+
+public class ConsumerMeters {
+  private AbstractInvocationMeters invocationMeters;
+
+  public ConsumerMeters(Registry registry) {
+    invocationMeters = new ConsumerInvocationMeters(registry);
+  }
+
+  public AbstractInvocationMeters getInvocationMeters() {
+    return invocationMeters;
+  }
+}
diff --git a/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/meter/ProducerMeters.java b/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/meter/ProducerMeters.java
new file mode 100644
index 000000000..e867f8ed9
--- /dev/null
+++ b/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/meter/ProducerMeters.java
@@ -0,0 +1,34 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.servicecomb.metrics.core.meter;
+
+import org.apache.servicecomb.metrics.core.meter.invocation.AbstractInvocationMeters;
+import org.apache.servicecomb.metrics.core.meter.invocation.ProducerInvocationMeters;
+
+import com.netflix.spectator.api.Registry;
+
+public class ProducerMeters {
+  private AbstractInvocationMeters invocationMeters;
+
+  public ProducerMeters(Registry registry) {
+    invocationMeters = new ProducerInvocationMeters(registry);
+  }
+
+  public AbstractInvocationMeters getInvocationMeters() {
+    return invocationMeters;
+  }
+}
diff --git a/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/meter/invocation/AbstractInvocationMeter.java b/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/meter/invocation/AbstractInvocationMeter.java
new file mode 100644
index 000000000..d2ae51043
--- /dev/null
+++ b/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/meter/invocation/AbstractInvocationMeter.java
@@ -0,0 +1,39 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.servicecomb.metrics.core.meter.invocation;
+
+import java.util.concurrent.TimeUnit;
+
+import org.apache.servicecomb.core.Invocation;
+import org.apache.servicecomb.core.event.InvocationFinishEvent;
+import org.apache.servicecomb.swagger.invocation.Response;
+
+import com.netflix.spectator.api.Id;
+import com.netflix.spectator.api.Registry;
+import com.netflix.spectator.api.Timer;
+
+public abstract class AbstractInvocationMeter {
+  private Timer totalTimer;
+
+  public AbstractInvocationMeter(Registry registry, Id id, Invocation invocation, Response response) {
+    totalTimer = registry.timer(id.withTag(MeterInvocationConst.TAG_STAGE, MeterInvocationConst.STAGE_TOTAL));
+  }
+
+  public void onInvocationFinish(InvocationFinishEvent event) {
+    totalTimer.record(event.getNanoCurrent() - event.getInvocation().getStartTime(), TimeUnit.NANOSECONDS);
+  }
+}
diff --git a/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/meter/invocation/AbstractInvocationMeters.java b/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/meter/invocation/AbstractInvocationMeters.java
new file mode 100644
index 000000000..43df8382b
--- /dev/null
+++ b/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/meter/invocation/AbstractInvocationMeters.java
@@ -0,0 +1,79 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.servicecomb.metrics.core.meter.invocation;
+
+import java.util.Map;
+
+import org.apache.servicecomb.core.Invocation;
+import org.apache.servicecomb.core.event.InvocationFinishEvent;
+import org.apache.servicecomb.core.event.InvocationStartEvent;
+import org.apache.servicecomb.foundation.common.concurrent.ConcurrentHashMapEx;
+import org.apache.servicecomb.swagger.invocation.Response;
+
+import com.netflix.spectator.api.Id;
+import com.netflix.spectator.api.Registry;
+
+public abstract class AbstractInvocationMeters {
+  protected Registry registry;
+
+  private Map<String, AbstractInvocationMeter> metersMap = new ConcurrentHashMapEx<>();
+
+  // not care for concurrency, just for make build key faster 
+  private int maxKeyLen = 64;
+
+  public AbstractInvocationMeters(Registry registry) {
+    this.registry = registry;
+  }
+
+  protected AbstractInvocationMeter getOrCreateMeters(Invocation invocation, Response response) {
+    // build string key is faster then use Id to locate timer directly
+    StringBuilder keyBuilder = new StringBuilder(maxKeyLen);
+    keyBuilder
+        .append(invocation.getInvocationType().name())
+        .append(invocation.getRealTransportName())
+        .append(invocation.getMicroserviceQualifiedName())
+        .append(response.getStatusCode());
+    if (keyBuilder.length() > maxKeyLen) {
+      maxKeyLen = keyBuilder.length();
+    }
+
+    return metersMap.computeIfAbsent(keyBuilder.toString(), k -> {
+      Id id = registry.createId(MeterInvocationConst.INVOCATION_NAME,
+          MeterInvocationConst.TAG_ROLE,
+          invocation.getInvocationType().name(),
+          MeterInvocationConst.TAG_TRANSPORT,
+          invocation.getRealTransportName(),
+          MeterInvocationConst.TAG_OPERATION,
+          invocation.getMicroserviceQualifiedName(),
+          MeterInvocationConst.TAG_STATUS,
+          String.valueOf(response.getStatusCode()));
+
+      return createMeter(id, invocation, response);
+    });
+  }
+
+  protected abstract AbstractInvocationMeter createMeter(Id id, Invocation invocation,
+      Response response);
+
+  public void onInvocationStart(InvocationStartEvent event) {
+  }
+
+  public void onInvocationFinish(InvocationFinishEvent event) {
+    AbstractInvocationMeter meters = getOrCreateMeters(event.getInvocation(), event.getResponse());
+    meters.onInvocationFinish(event);
+  }
+}
diff --git a/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/meter/invocation/ConsumerInvocationMeter.java b/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/meter/invocation/ConsumerInvocationMeter.java
new file mode 100644
index 000000000..0f473a072
--- /dev/null
+++ b/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/meter/invocation/ConsumerInvocationMeter.java
@@ -0,0 +1,29 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.servicecomb.metrics.core.meter.invocation;
+
+import org.apache.servicecomb.core.Invocation;
+import org.apache.servicecomb.swagger.invocation.Response;
+
+import com.netflix.spectator.api.Id;
+import com.netflix.spectator.api.Registry;
+
+public class ConsumerInvocationMeter extends AbstractInvocationMeter {
+  public ConsumerInvocationMeter(Registry registry, Id id, Invocation invocation, Response response) {
+    super(registry, id, invocation, response);
+  }
+}
diff --git a/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/meter/invocation/ConsumerInvocationMeters.java b/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/meter/invocation/ConsumerInvocationMeters.java
new file mode 100644
index 000000000..dd24ecb71
--- /dev/null
+++ b/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/meter/invocation/ConsumerInvocationMeters.java
@@ -0,0 +1,34 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.servicecomb.metrics.core.meter.invocation;
+
+import org.apache.servicecomb.core.Invocation;
+import org.apache.servicecomb.swagger.invocation.Response;
+
+import com.netflix.spectator.api.Id;
+import com.netflix.spectator.api.Registry;
+
+public class ConsumerInvocationMeters extends AbstractInvocationMeters {
+  public ConsumerInvocationMeters(Registry registry) {
+    super(registry);
+  }
+
+  @Override
+  protected AbstractInvocationMeter createMeter(Id id, Invocation invocation, Response response) {
+    return new ConsumerInvocationMeter(registry, id, invocation, response);
+  }
+}
diff --git a/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/meter/invocation/MeterInvocationConst.java b/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/meter/invocation/MeterInvocationConst.java
new file mode 100644
index 000000000..3d208c3cc
--- /dev/null
+++ b/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/meter/invocation/MeterInvocationConst.java
@@ -0,0 +1,42 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.servicecomb.metrics.core.meter.invocation;
+
+import com.netflix.spectator.api.Statistic;
+
+public interface MeterInvocationConst {
+  final String INVOCATION_NAME = "servicecomb.invocation";
+
+  // consumer or producer
+  final String TAG_ROLE = "role";
+
+  final String TAG_OPERATION = "operation";
+
+  final String TAG_TRANSPORT = "transport";
+
+  final String TAG_STAGE = "stage";
+
+  final String TAG_STATUS = "status";
+
+  final String TAG_STATISTIC = Statistic.count.key();
+
+  final String STAGE_TOTAL = "total";
+
+  final String STAGE_EXECUTOR_QUEUE = "queue";
+
+  final String STAGE_EXECUTION = "execution";
+}
diff --git a/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/meter/invocation/ProducerInvocationMeter.java b/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/meter/invocation/ProducerInvocationMeter.java
new file mode 100644
index 000000000..11062659c
--- /dev/null
+++ b/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/meter/invocation/ProducerInvocationMeter.java
@@ -0,0 +1,51 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.servicecomb.metrics.core.meter.invocation;
+
+import java.util.concurrent.TimeUnit;
+
+import org.apache.servicecomb.core.Invocation;
+import org.apache.servicecomb.core.event.InvocationFinishEvent;
+import org.apache.servicecomb.swagger.invocation.Response;
+
+import com.netflix.spectator.api.Id;
+import com.netflix.spectator.api.Registry;
+import com.netflix.spectator.api.Timer;
+
+public class ProducerInvocationMeter extends AbstractInvocationMeter {
+  private Timer executorQueueTimer;
+
+  private Timer executionTimer;
+
+  public ProducerInvocationMeter(Registry registry, Id id, Invocation invocation, Response response) {
+    super(registry, id, invocation, response);
+
+    executorQueueTimer =
+        registry.timer(id.withTag(MeterInvocationConst.TAG_STAGE, MeterInvocationConst.STAGE_EXECUTOR_QUEUE));
+    executionTimer =
+        registry.timer(id.withTag(MeterInvocationConst.TAG_STAGE, MeterInvocationConst.STAGE_EXECUTION));
+  }
+
+  @Override
+  public void onInvocationFinish(InvocationFinishEvent event) {
+    super.onInvocationFinish(event);
+
+    Invocation invocation = event.getInvocation();
+    executorQueueTimer.record(invocation.getStartExecutionTime() - invocation.getStartTime(), TimeUnit.NANOSECONDS);
+    executionTimer.record(event.getNanoCurrent() - invocation.getStartExecutionTime(), TimeUnit.NANOSECONDS);
+  }
+}
diff --git a/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/meter/invocation/ProducerInvocationMeters.java b/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/meter/invocation/ProducerInvocationMeters.java
new file mode 100644
index 000000000..56031d0d3
--- /dev/null
+++ b/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/meter/invocation/ProducerInvocationMeters.java
@@ -0,0 +1,34 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.servicecomb.metrics.core.meter.invocation;
+
+import org.apache.servicecomb.core.Invocation;
+import org.apache.servicecomb.swagger.invocation.Response;
+
+import com.netflix.spectator.api.Id;
+import com.netflix.spectator.api.Registry;
+
+public class ProducerInvocationMeters extends AbstractInvocationMeters {
+  public ProducerInvocationMeters(Registry registry) {
+    super(registry);
+  }
+
+  @Override
+  protected AbstractInvocationMeter createMeter(Id id, Invocation invocation, Response response) {
+    return new ProducerInvocationMeter(registry, id, invocation, response);
+  }
+}
diff --git a/metrics/metrics-core/src/main/resources/META-INF/services/org.apache.servicecomb.foundation.metrics.MetricsInitializer b/metrics/metrics-core/src/main/resources/META-INF/services/org.apache.servicecomb.foundation.metrics.MetricsInitializer
new file mode 100644
index 000000000..2bf2069c6
--- /dev/null
+++ b/metrics/metrics-core/src/main/resources/META-INF/services/org.apache.servicecomb.foundation.metrics.MetricsInitializer
@@ -0,0 +1,18 @@
+#
+# 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.DefaultMetricsInitializer
diff --git a/metrics/metrics-core/src/test/java/org/apache/servicecomb/metrics/core/TestDefaultMetricsInitializer.java b/metrics/metrics-core/src/test/java/org/apache/servicecomb/metrics/core/TestDefaultMetricsInitializer.java
new file mode 100644
index 000000000..2c48866c2
--- /dev/null
+++ b/metrics/metrics-core/src/test/java/org/apache/servicecomb/metrics/core/TestDefaultMetricsInitializer.java
@@ -0,0 +1,138 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.servicecomb.metrics.core;
+
+import org.apache.servicecomb.core.Const;
+import org.apache.servicecomb.core.Invocation;
+import org.apache.servicecomb.core.event.InvocationFinishEvent;
+import org.apache.servicecomb.foundation.metrics.MetricsBootstrapConfig;
+import org.apache.servicecomb.foundation.metrics.publish.spectator.MeasurementGroupConfig;
+import org.apache.servicecomb.foundation.metrics.publish.spectator.MeasurementTree;
+import org.apache.servicecomb.metrics.core.meter.invocation.MeterInvocationConst;
+import org.apache.servicecomb.swagger.invocation.InvocationType;
+import org.apache.servicecomb.swagger.invocation.Response;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+import com.google.common.eventbus.EventBus;
+import com.netflix.spectator.api.CompositeRegistry;
+import com.netflix.spectator.api.DefaultRegistry;
+import com.netflix.spectator.api.ManualClock;
+import com.netflix.spectator.api.Registry;
+import com.netflix.spectator.api.SpectatorUtils;
+
+import mockit.Expectations;
+import mockit.Mocked;
+
+public class TestDefaultMetricsInitializer {
+  EventBus eventBus = new EventBus();
+
+  ManualClock clock = new ManualClock();
+
+  CompositeRegistry globalRegistry = SpectatorUtils.createCompositeRegistry(new ManualClock());
+
+  DefaultMetricsInitializer metricsInitializer = new DefaultMetricsInitializer() {
+    protected Registry createRegistry(MetricsBootstrapConfig config) {
+      return new DefaultRegistry(new ManualClock());
+    };
+  };
+
+  MetricsBootstrapConfig config = new MetricsBootstrapConfig();
+
+  @Mocked
+  private Invocation invocation;
+
+  @Mocked
+  private Response response;
+
+
+  @Before
+  public void setup() {
+    metricsInitializer.init(globalRegistry, eventBus, config);
+  }
+
+  @Test
+  public void consumerInvocation(@Mocked InvocationFinishEvent event) {
+    new Expectations() {
+      {
+        invocation.isConsumer();
+        result = true;
+        invocation.getInvocationType();
+        result = InvocationType.CONSUMER;
+        invocation.getRealTransportName();
+        result = Const.RESTFUL;
+        invocation.getMicroserviceQualifiedName();
+        result = "m.s.o";
+        invocation.getStartTime();
+        result = 1;
+        event.getInvocation();
+        result = invocation;
+        event.getNanoCurrent();
+        result = 10;
+      }
+    };
+
+    eventBus.post(event);
+    eventBus.post(event);
+
+    MeasurementTree tree = new MeasurementTree();
+    tree.from(globalRegistry.iterator(), new MeasurementGroupConfig(MeterInvocationConst.INVOCATION_NAME));
+    Assert.assertEquals(
+        "[Measurement(servicecomb.invocation:operation=m.s.o:role=CONSUMER:stage=total:statistic=count:status=0:transport=rest,0,2.0), "
+            + "Measurement(servicecomb.invocation:operation=m.s.o:role=CONSUMER:stage=total:statistic=totalTime:status=0:transport=rest,0,18.0)]",
+        tree.findChild(MeterInvocationConst.INVOCATION_NAME).getMeasurements().toString());
+  }
+
+  @Test
+  public void producerInvocation(@Mocked InvocationFinishEvent event) {
+    new Expectations() {
+      {
+        invocation.isConsumer();
+        result = false;
+        invocation.getInvocationType();
+        result = InvocationType.PRODUCER;
+        invocation.getRealTransportName();
+        result = Const.RESTFUL;
+        invocation.getMicroserviceQualifiedName();
+        result = "m.s.o";
+        invocation.getStartTime();
+        result = 1;
+        invocation.getStartExecutionTime();
+        result = 3;
+        event.getNanoCurrent();
+        result = 10;
+        event.getInvocation();
+        result = invocation;
+      }
+    };
+
+    eventBus.post(event);
+    eventBus.post(event);
+
+    MeasurementTree tree = new MeasurementTree();
+    tree.from(globalRegistry.iterator(), new MeasurementGroupConfig(MeterInvocationConst.INVOCATION_NAME));
+    Assert.assertEquals(
+        "[Measurement(servicecomb.invocation:operation=m.s.o:role=PRODUCER:stage=execution:statistic=count:status=0:transport=rest,0,2.0), "
+            + "Measurement(servicecomb.invocation:operation=m.s.o:role=PRODUCER:stage=execution:statistic=totalTime:status=0:transport=rest,0,14.0), "
+            + "Measurement(servicecomb.invocation:operation=m.s.o:role=PRODUCER:stage=total:statistic=count:status=0:transport=rest,0,2.0), "
+            + "Measurement(servicecomb.invocation:operation=m.s.o:role=PRODUCER:stage=total:statistic=totalTime:status=0:transport=rest,0,18.0), "
+            + "Measurement(servicecomb.invocation:operation=m.s.o:role=PRODUCER:stage=queue:statistic=count:status=0:transport=rest,0,2.0), "
+            + "Measurement(servicecomb.invocation:operation=m.s.o:role=PRODUCER:stage=queue:statistic=totalTime:status=0:transport=rest,0,4.0)]",
+        tree.findChild(MeterInvocationConst.INVOCATION_NAME).getMeasurements().toString());
+  }
+}


 

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


With regards,
Apache Git Services