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

albumenj pushed a commit to branch 3.2
in repository https://gitbox.apache.org/repos/asf/dubbo.git


The following commit(s) were added to refs/heads/3.2 by this push:
     new a9362790a3 Code opt (#11857)
a9362790a3 is described below

commit a9362790a3cc643e58162723faec96d68c0bb370
Author: wxbty <[email protected]>
AuthorDate: Fri Mar 24 10:47:09 2023 +0800

    Code opt (#11857)
    
    * code opt
    
    * code opt
    
    * reuse rt stats
    
    * bugfix
    
    * bugfix
    
    * fix comment
    
    * reuse serviceKey
    
    ---------
    
    Co-authored-by: x-shadow-man <[email protected]>
---
 .../dubbo/metrics/exception/MetricsException.java  | 25 +++++++++
 .../dubbo/metrics/model/MetricsKeyWrapper.java     | 22 ++++++++
 .../dubbo/metrics/model/MetricsSupport.java}       | 56 +++++++------------
 .../dubbo/metrics/model}/ServiceKeyMetric.java     | 17 +++---
 .../collector/stat/MetadataStatComposite.java      |  1 +
 .../collector/stat/RegistryStatComposite.java      | 62 +++++++++++-----------
 .../event/MetricsServiceRegisterListener.java      |  2 +-
 .../collector/RegistryMetricsCollectorTest.java    | 49 +++++++++++++++++
 .../collector/RegistryStatCompositeTest.java       | 10 ++--
 9 files changed, 162 insertions(+), 82 deletions(-)

diff --git 
a/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/exception/MetricsException.java
 
b/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/exception/MetricsException.java
new file mode 100644
index 0000000000..20f238abde
--- /dev/null
+++ 
b/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/exception/MetricsException.java
@@ -0,0 +1,25 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.dubbo.metrics.exception;
+
+public class MetricsException extends RuntimeException {
+
+    public MetricsException(String message) {
+        super(message);
+    }
+}
diff --git 
a/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/model/MetricsKeyWrapper.java
 
b/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/model/MetricsKeyWrapper.java
index 54b791e5a8..b89a7e64fe 100644
--- 
a/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/model/MetricsKeyWrapper.java
+++ 
b/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/model/MetricsKeyWrapper.java
@@ -17,17 +17,32 @@
 
 package org.apache.dubbo.metrics.model;
 
+import java.util.Map;
+
 /**
  * Let {@link MetricsKey MetricsKey}  output dynamic, custom string content
  */
 public class MetricsKeyWrapper {
 
+    /**
+     * Register、subscribe、notify etc
+     */
     private final String type;
+    /**
+     * Metrics key when exporting
+     */
     private final MetricsKey metricsKey;
 
+    private final boolean serviceLevel;
+
     public MetricsKeyWrapper(String type, MetricsKey metricsKey) {
+        this(type, metricsKey, false);
+    }
+
+    public MetricsKeyWrapper(String type, MetricsKey metricsKey, boolean 
serviceLevel) {
         this.type = type;
         this.metricsKey = metricsKey;
+        this.serviceLevel = serviceLevel;
     }
 
     public String getType() {
@@ -42,6 +57,10 @@ public class MetricsKeyWrapper {
         return metricsKey == getMetricsKey() && 
registryOpType.equals(getType());
     }
 
+    public boolean isServiceLevel() {
+        return serviceLevel;
+    }
+
     public String targetKey() {
         try {
             return String.format(metricsKey.getName(), type);
@@ -58,4 +77,7 @@ public class MetricsKeyWrapper {
         }
     }
 
+    public Map<String, String> tagName(String key) {
+        return isServiceLevel() ? MetricsSupport.serviceTags(key) : 
MetricsSupport.applicationTags(key);
+    }
 }
diff --git 
a/dubbo-metrics/dubbo-metrics-metadata/src/main/java/org/apache/dubbo/metrics/metadata/collector/stat/ServiceKeyMetric.java
 
b/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/model/MetricsSupport.java
similarity index 55%
rename from 
dubbo-metrics/dubbo-metrics-metadata/src/main/java/org/apache/dubbo/metrics/metadata/collector/stat/ServiceKeyMetric.java
rename to 
dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/model/MetricsSupport.java
index 7643d7368a..f6820a64b9 100644
--- 
a/dubbo-metrics/dubbo-metrics-metadata/src/main/java/org/apache/dubbo/metrics/metadata/collector/stat/ServiceKeyMetric.java
+++ 
b/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/model/MetricsSupport.java
@@ -15,64 +15,44 @@
  * limitations under the License.
  */
 
-package org.apache.dubbo.metrics.metadata.collector.stat;
+package org.apache.dubbo.metrics.model;
 
-import org.apache.dubbo.metrics.model.Metric;
+import org.apache.dubbo.common.Version;
+import org.apache.dubbo.metrics.exception.MetricsException;
 
 import java.util.HashMap;
 import java.util.Map;
 
 import static 
org.apache.dubbo.common.constants.MetricsConstants.TAG_APPLICATION_NAME;
+import static 
org.apache.dubbo.common.constants.MetricsConstants.TAG_APPLICATION_VERSION_KEY;
 import static org.apache.dubbo.common.constants.MetricsConstants.TAG_HOSTNAME;
 import static 
org.apache.dubbo.common.constants.MetricsConstants.TAG_INTERFACE_KEY;
 import static org.apache.dubbo.common.constants.MetricsConstants.TAG_IP;
 import static org.apache.dubbo.common.utils.NetUtils.getLocalHost;
 import static org.apache.dubbo.common.utils.NetUtils.getLocalHostName;
 
-/**
- * Metric class for interface.
- */
-public class ServiceKeyMetric implements Metric {
-    private final String applicationName;
-    private final String serviceKey;
+public class MetricsSupport {
 
-    public ServiceKeyMetric(String applicationName, String serviceKey) {
-        this.applicationName = applicationName;
-        this.serviceKey = serviceKey;
-    }
+    private static final String version = Version.getVersion();
+    private static final String commitId = Version.getLastCommitId();
 
-    public Map<String, String> getTags() {
+    public static Map<String, String> applicationTags(String applicationName) {
         Map<String, String> tags = new HashMap<>();
         tags.put(TAG_IP, getLocalHost());
         tags.put(TAG_HOSTNAME, getLocalHostName());
         tags.put(TAG_APPLICATION_NAME, applicationName);
-        tags.put(TAG_INTERFACE_KEY, serviceKey);
+        tags.put(TAG_APPLICATION_VERSION_KEY, version);
+        tags.put(MetricsKey.METADATA_GIT_COMMITID_METRIC.getName(), commitId);
         return tags;
     }
 
-    @Override
-    public boolean equals(Object o) {
-        if (this == o) return true;
-        if (o == null || getClass() != o.getClass()) return false;
-
-        ServiceKeyMetric that = (ServiceKeyMetric) o;
-
-        if (!applicationName.equals(that.applicationName)) return false;
-        return serviceKey.equals(that.serviceKey);
-    }
-
-    @Override
-    public int hashCode() {
-        int result = applicationName.hashCode();
-        result = 31 * result + serviceKey.hashCode();
-        return result;
-    }
-
-    @Override
-    public String toString() {
-        return "ServiceKeyMetric{" +
-            "applicationName='" + applicationName + '\'' +
-            ", serviceKey='" + serviceKey + '\'' +
-            '}';
+    public static Map<String, String> serviceTags(String appAndServiceName) {
+        String[] keys = appAndServiceName.split("_");
+        if (keys.length != 2) {
+            throw new MetricsException("Error service name: " + 
appAndServiceName);
+        }
+        Map<String, String> tags = applicationTags(keys[0]);
+        tags.put(TAG_INTERFACE_KEY, keys[1]);
+        return tags;
     }
 }
diff --git 
a/dubbo-metrics/dubbo-metrics-registry/src/main/java/org/apache/dubbo/metrics/registry/collector/stat/ServiceKeyMetric.java
 
b/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/model/ServiceKeyMetric.java
similarity index 89%
rename from 
dubbo-metrics/dubbo-metrics-registry/src/main/java/org/apache/dubbo/metrics/registry/collector/stat/ServiceKeyMetric.java
rename to 
dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/model/ServiceKeyMetric.java
index 9fa387418e..94eaa30edb 100644
--- 
a/dubbo-metrics/dubbo-metrics-registry/src/main/java/org/apache/dubbo/metrics/registry/collector/stat/ServiceKeyMetric.java
+++ 
b/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/model/ServiceKeyMetric.java
@@ -15,9 +15,7 @@
  * limitations under the License.
  */
 
-package org.apache.dubbo.metrics.registry.collector.stat;
-
-import org.apache.dubbo.metrics.model.Metric;
+package org.apache.dubbo.metrics.model;
 
 import java.util.HashMap;
 import java.util.Map;
@@ -41,6 +39,7 @@ public class ServiceKeyMetric implements Metric {
         this.serviceKey = serviceKey;
     }
 
+    @Override
     public Map<String, String> getTags() {
         Map<String, String> tags = new HashMap<>();
         tags.put(TAG_IP, getLocalHost());
@@ -52,12 +51,18 @@ public class ServiceKeyMetric implements Metric {
 
     @Override
     public boolean equals(Object o) {
-        if (this == o) return true;
-        if (o == null || getClass() != o.getClass()) return false;
+        if (this == o) {
+            return true;
+        }
+        if (o == null || getClass() != o.getClass()) {
+            return false;
+        }
 
         ServiceKeyMetric that = (ServiceKeyMetric) o;
 
-        if (!applicationName.equals(that.applicationName)) return false;
+        if (!applicationName.equals(that.applicationName)) {
+            return false;
+        }
         return serviceKey.equals(that.serviceKey);
     }
 
diff --git 
a/dubbo-metrics/dubbo-metrics-metadata/src/main/java/org/apache/dubbo/metrics/metadata/collector/stat/MetadataStatComposite.java
 
b/dubbo-metrics/dubbo-metrics-metadata/src/main/java/org/apache/dubbo/metrics/metadata/collector/stat/MetadataStatComposite.java
index 631176ee53..c58baab23a 100644
--- 
a/dubbo-metrics/dubbo-metrics-metadata/src/main/java/org/apache/dubbo/metrics/metadata/collector/stat/MetadataStatComposite.java
+++ 
b/dubbo-metrics/dubbo-metrics-metadata/src/main/java/org/apache/dubbo/metrics/metadata/collector/stat/MetadataStatComposite.java
@@ -24,6 +24,7 @@ import org.apache.dubbo.metrics.model.ApplicationMetric;
 import org.apache.dubbo.metrics.model.MetricsCategory;
 import org.apache.dubbo.metrics.model.MetricsKey;
 import org.apache.dubbo.metrics.model.MetricsKeyWrapper;
+import org.apache.dubbo.metrics.model.ServiceKeyMetric;
 import org.apache.dubbo.metrics.model.container.AtomicLongContainer;
 import org.apache.dubbo.metrics.model.container.LongAccumulatorContainer;
 import org.apache.dubbo.metrics.model.container.LongContainer;
diff --git 
a/dubbo-metrics/dubbo-metrics-registry/src/main/java/org/apache/dubbo/metrics/registry/collector/stat/RegistryStatComposite.java
 
b/dubbo-metrics/dubbo-metrics-registry/src/main/java/org/apache/dubbo/metrics/registry/collector/stat/RegistryStatComposite.java
index 864499bbc3..2c78106b66 100644
--- 
a/dubbo-metrics/dubbo-metrics-registry/src/main/java/org/apache/dubbo/metrics/registry/collector/stat/RegistryStatComposite.java
+++ 
b/dubbo-metrics/dubbo-metrics-registry/src/main/java/org/apache/dubbo/metrics/registry/collector/stat/RegistryStatComposite.java
@@ -19,10 +19,11 @@ package org.apache.dubbo.metrics.registry.collector.stat;
 
 import org.apache.dubbo.common.utils.ConcurrentHashMapUtils;
 import org.apache.dubbo.metrics.collector.MetricsCollector;
-import org.apache.dubbo.metrics.model.ApplicationMetric;
 import org.apache.dubbo.metrics.model.MetricsCategory;
 import org.apache.dubbo.metrics.model.MetricsKey;
 import org.apache.dubbo.metrics.model.MetricsKeyWrapper;
+import org.apache.dubbo.metrics.model.MetricsSupport;
+import org.apache.dubbo.metrics.model.ServiceKeyMetric;
 import org.apache.dubbo.metrics.model.container.AtomicLongContainer;
 import org.apache.dubbo.metrics.model.container.LongAccumulatorContainer;
 import org.apache.dubbo.metrics.model.container.LongContainer;
@@ -36,7 +37,6 @@ import java.util.Map;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.atomic.AtomicLong;
 import java.util.concurrent.atomic.LongAccumulator;
-import java.util.function.Function;
 import java.util.stream.Collectors;
 
 /**
@@ -49,9 +49,7 @@ public class RegistryStatComposite implements MetricsExport {
 
     public Map<RegistryEvent.ApplicationType, Map<String, AtomicLong>> 
applicationNumStats = new ConcurrentHashMap<>();
     public Map<RegistryEvent.ServiceType, Map<ServiceKeyMetric, AtomicLong>> 
serviceNumStats = new ConcurrentHashMap<>();
-    public Map<RegistryEvent.ServiceType, Map<ServiceKeyMetric, AtomicLong>> 
skStats = new ConcurrentHashMap<>();
-    public List<LongContainer<? extends Number>> appRtStats = new 
ArrayList<>();
-    public List<LongContainer<? extends Number>> serviceRtStats = new 
ArrayList<>();
+    public List<LongContainer<? extends Number>> rtStats = new ArrayList<>();
     public static String OP_TYPE_REGISTER = "register";
     public static String OP_TYPE_SUBSCRIBE = "subscribe";
     public static String OP_TYPE_NOTIFY = "notify";
@@ -66,28 +64,29 @@ public class RegistryStatComposite implements MetricsExport 
{
 
         for (RegistryEvent.ServiceType type : 
RegistryEvent.ServiceType.values()) {
             // Service key
-            skStats.put(type, new ConcurrentHashMap<>());
+            serviceNumStats.put(type, new ConcurrentHashMap<>());
         }
 
+        // App-level
+        rtStats.addAll(initStats(OP_TYPE_REGISTER, false));
+        rtStats.addAll(initStats(OP_TYPE_SUBSCRIBE, false));
+        rtStats.addAll(initStats(OP_TYPE_NOTIFY, false));
 
-        appRtStats.addAll(initStats(OP_TYPE_REGISTER));
-        appRtStats.addAll(initStats(OP_TYPE_SUBSCRIBE));
-        appRtStats.addAll(initStats(OP_TYPE_NOTIFY));
-
-        serviceRtStats.addAll(initStats(OP_TYPE_REGISTER_SERVICE));
-        serviceRtStats.addAll(initStats(OP_TYPE_SUBSCRIBE_SERVICE));
+        // Service-level
+        rtStats.addAll(initStats(OP_TYPE_REGISTER_SERVICE, true));
+        rtStats.addAll(initStats(OP_TYPE_SUBSCRIBE_SERVICE, true));
     }
 
-    private List<LongContainer<? extends Number>> initStats(String 
registryOpType) {
+    private List<LongContainer<? extends Number>> initStats(String 
registryOpType, boolean isServiceLevel) {
         List<LongContainer<? extends Number>> singleRtStats = new 
ArrayList<>();
-        singleRtStats.add(new AtomicLongContainer(new 
MetricsKeyWrapper(registryOpType, MetricsKey.METRIC_RT_LAST)));
-        singleRtStats.add(new LongAccumulatorContainer(new 
MetricsKeyWrapper(registryOpType, MetricsKey.METRIC_RT_MIN), new 
LongAccumulator(Long::min, Long.MAX_VALUE)));
-        singleRtStats.add(new LongAccumulatorContainer(new 
MetricsKeyWrapper(registryOpType, MetricsKey.METRIC_RT_MAX), new 
LongAccumulator(Long::max, Long.MIN_VALUE)));
-        singleRtStats.add(new AtomicLongContainer(new 
MetricsKeyWrapper(registryOpType, MetricsKey.METRIC_RT_SUM), (responseTime, 
longAccumulator) -> longAccumulator.addAndGet(responseTime)));
+        singleRtStats.add(new AtomicLongContainer(new 
MetricsKeyWrapper(registryOpType, MetricsKey.METRIC_RT_LAST, isServiceLevel)));
+        singleRtStats.add(new LongAccumulatorContainer(new 
MetricsKeyWrapper(registryOpType, MetricsKey.METRIC_RT_MIN, isServiceLevel), 
new LongAccumulator(Long::min, Long.MAX_VALUE)));
+        singleRtStats.add(new LongAccumulatorContainer(new 
MetricsKeyWrapper(registryOpType, MetricsKey.METRIC_RT_MAX, isServiceLevel), 
new LongAccumulator(Long::max, Long.MIN_VALUE)));
+        singleRtStats.add(new AtomicLongContainer(new 
MetricsKeyWrapper(registryOpType, MetricsKey.METRIC_RT_SUM, isServiceLevel), 
(responseTime, longAccumulator) -> longAccumulator.addAndGet(responseTime)));
         // AvgContainer is a special counter that stores the number of times 
but outputs function of sum/times
-        AtomicLongContainer avgContainer = new AtomicLongContainer(new 
MetricsKeyWrapper(registryOpType, MetricsKey.METRIC_RT_AVG), (k, v) -> 
v.incrementAndGet());
+        AtomicLongContainer avgContainer = new AtomicLongContainer(new 
MetricsKeyWrapper(registryOpType, MetricsKey.METRIC_RT_AVG, isServiceLevel), 
(k, v) -> v.incrementAndGet());
         avgContainer.setValueSupplier(applicationName -> {
-            LongContainer<? extends Number> totalContainer = 
appRtStats.stream().filter(longContainer -> 
longContainer.isKeyWrapper(MetricsKey.METRIC_RT_SUM, 
registryOpType)).findFirst().get();
+            LongContainer<? extends Number> totalContainer = 
rtStats.stream().filter(longContainer -> 
longContainer.isKeyWrapper(MetricsKey.METRIC_RT_SUM, 
registryOpType)).findFirst().get();
             AtomicLong totalRtTimes = avgContainer.get(applicationName);
             AtomicLong totalRtSum = (AtomicLong) 
totalContainer.get(applicationName);
             return totalRtSum.get() / totalRtTimes.get();
@@ -104,10 +103,10 @@ public class RegistryStatComposite implements 
MetricsExport {
     }
 
     public void setServiceKey(RegistryEvent.ServiceType type, String 
applicationName, String serviceKey, int num) {
-        if (!skStats.containsKey(type)) {
+        if (!serviceNumStats.containsKey(type)) {
             return;
         }
-        skStats.get(type).computeIfAbsent(new 
ServiceKeyMetric(applicationName, serviceKey), k -> new 
AtomicLong(0L)).set(num);
+        serviceNumStats.get(type).computeIfAbsent(new 
ServiceKeyMetric(applicationName, serviceKey), k -> new 
AtomicLong(0L)).set(num);
     }
 
     public void increment(RegistryEvent.ApplicationType type, String 
applicationName) {
@@ -115,10 +114,10 @@ public class RegistryStatComposite implements 
MetricsExport {
     }
 
     public void incrementServiceKey(RegistryEvent.ServiceType type, String 
applicationName, String serviceKey, int size) {
-        if (!skStats.containsKey(type)) {
+        if (!serviceNumStats.containsKey(type)) {
             return;
         }
-        skStats.get(type).computeIfAbsent(new 
ServiceKeyMetric(applicationName, serviceKey), k -> new 
AtomicLong(0L)).getAndAdd(size);
+        serviceNumStats.get(type).computeIfAbsent(new 
ServiceKeyMetric(applicationName, serviceKey), k -> new 
AtomicLong(0L)).getAndAdd(size);
     }
 
     public void incrementSize(RegistryEvent.ApplicationType type, String 
applicationName, int size) {
@@ -130,7 +129,7 @@ public class RegistryStatComposite implements MetricsExport 
{
 
     @SuppressWarnings({"rawtypes", "unchecked"})
     public void calcApplicationRt(String applicationName, String 
registryOpType, Long responseTime) {
-        for (LongContainer container : 
appRtStats.stream().filter(longContainer -> 
longContainer.specifyType(registryOpType)).collect(Collectors.toList())) {
+        for (LongContainer container : rtStats.stream().filter(longContainer 
-> longContainer.specifyType(registryOpType)).collect(Collectors.toList())) {
             Number current = (Number) 
ConcurrentHashMapUtils.computeIfAbsent(container, applicationName, 
container.getInitFunc());
             container.getConsumerFunc().accept(responseTime, current);
         }
@@ -138,7 +137,7 @@ public class RegistryStatComposite implements MetricsExport 
{
 
     @SuppressWarnings({"rawtypes", "unchecked"})
     public void calcServiceKeyRt(String applicationName, String serviceKey, 
String registryOpType, Long responseTime) {
-        for (LongContainer container : 
serviceRtStats.stream().filter(longContainer -> 
longContainer.specifyType(registryOpType)).collect(Collectors.toList())) {
+        for (LongContainer container : rtStats.stream().filter(longContainer 
-> longContainer.specifyType(registryOpType)).collect(Collectors.toList())) {
             Number current = (Number) 
ConcurrentHashMapUtils.computeIfAbsent(container, applicationName + "_" + 
serviceKey, container.getInitFunc());
             container.getConsumerFunc().accept(responseTime, current);
         }
@@ -161,17 +160,16 @@ public class RegistryStatComposite implements 
MetricsExport {
     @SuppressWarnings({"rawtypes"})
     public List<GaugeMetricSample> exportRtMetrics() {
         List<GaugeMetricSample> result = new ArrayList<>();
-        doExportRt(result, appRtStats, ApplicationMetric::getTagsByName);
-        doExportRt(result, serviceRtStats, ApplicationMetric::getServiceTags);
+        doExportRt(result, rtStats);
         return result;
     }
 
     @SuppressWarnings({"rawtypes"})
-    private void doExportRt(List<GaugeMetricSample> list, List<LongContainer<? 
extends Number>> rtStats, Function<String, Map<String, String>> tagNameFunc) {
+    private void doExportRt(List<GaugeMetricSample> list, List<LongContainer<? 
extends Number>> rtStats) {
         for (LongContainer<? extends Number> rtContainer : rtStats) {
             MetricsKeyWrapper metricsKeyWrapper = 
rtContainer.getMetricsKeyWrapper();
             for (Map.Entry<String, ? extends Number> entry : 
rtContainer.entrySet()) {
-                list.add(new 
GaugeMetricSample<>(metricsKeyWrapper.targetKey(), 
metricsKeyWrapper.targetDesc(), tagNameFunc.apply(entry.getKey()), 
MetricsCategory.RT, entry.getKey().intern(), value -> 
rtContainer.getValueSupplier().apply(value.intern())));
+                list.add(new 
GaugeMetricSample<>(metricsKeyWrapper.targetKey(), 
metricsKeyWrapper.targetDesc(), metricsKeyWrapper.tagName(entry.getKey()), 
MetricsCategory.RT, entry.getKey().intern(), value -> 
rtContainer.getValueSupplier().apply(value.intern())));
             }
         }
     }
@@ -179,8 +177,8 @@ public class RegistryStatComposite implements MetricsExport 
{
     @SuppressWarnings({"rawtypes"})
     public List<GaugeMetricSample> exportSkMetrics() {
         List<GaugeMetricSample> list = new ArrayList<>();
-        for (RegistryEvent.ServiceType type : skStats.keySet()) {
-            Map<ServiceKeyMetric, AtomicLong> stringAtomicLongMap = 
skStats.get(type);
+        for (RegistryEvent.ServiceType type : serviceNumStats.keySet()) {
+            Map<ServiceKeyMetric, AtomicLong> stringAtomicLongMap = 
serviceNumStats.get(type);
             for (ServiceKeyMetric serviceKeyMetric : 
stringAtomicLongMap.keySet()) {
                 list.add(new GaugeMetricSample<>(type.getMetricsKey(), 
serviceKeyMetric.getTags(), MetricsCategory.REGISTRY, stringAtomicLongMap, 
value -> value.get(serviceKeyMetric).get()));
             }
@@ -190,6 +188,6 @@ public class RegistryStatComposite implements MetricsExport 
{
 
     @SuppressWarnings({"rawtypes"})
     public GaugeMetricSample convertToSample(String applicationName, 
RegistryEvent.ApplicationType type, MetricsCategory category, AtomicLong 
targetNumber) {
-        return new GaugeMetricSample<>(type.getMetricsKey(), 
ApplicationMetric.getTagsByName(applicationName), category, targetNumber, 
AtomicLong::get);
+        return new GaugeMetricSample<>(type.getMetricsKey(), 
MetricsSupport.applicationTags(applicationName), category, targetNumber, 
AtomicLong::get);
     }
 }
diff --git 
a/dubbo-metrics/dubbo-metrics-registry/src/main/java/org/apache/dubbo/metrics/registry/event/MetricsServiceRegisterListener.java
 
b/dubbo-metrics/dubbo-metrics-registry/src/main/java/org/apache/dubbo/metrics/registry/event/MetricsServiceRegisterListener.java
index e99ce7a75d..45aba8c226 100644
--- 
a/dubbo-metrics/dubbo-metrics-registry/src/main/java/org/apache/dubbo/metrics/registry/event/MetricsServiceRegisterListener.java
+++ 
b/dubbo-metrics/dubbo-metrics-registry/src/main/java/org/apache/dubbo/metrics/registry/event/MetricsServiceRegisterListener.java
@@ -46,6 +46,6 @@ public class MetricsServiceRegisterListener implements 
MetricsLifeListener<Regis
     @Override
     public void onEventError(RegistryEvent.MetricsServiceRegisterEvent event) {
         
event.getCollector().incrementServiceKey(event.getSource().getApplicationName(),
 event.getServiceKey(), RegistryEvent.ServiceType.R_SERVICE_FAILED, 
event.getSize());
-        
event.getCollector().addApplicationRT(event.getSource().getApplicationName(), 
OP_TYPE_REGISTER_SERVICE, event.getTimePair().calc());
+        
event.getCollector().addServiceKeyRT(event.getSource().getApplicationName(),event.getServiceKey(),
 OP_TYPE_REGISTER_SERVICE, event.getTimePair().calc());
     }
 }
diff --git 
a/dubbo-metrics/dubbo-metrics-registry/src/test/java/org/apache/dubbo/metrics/registry/metrics/collector/RegistryMetricsCollectorTest.java
 
b/dubbo-metrics/dubbo-metrics-registry/src/test/java/org/apache/dubbo/metrics/registry/metrics/collector/RegistryMetricsCollectorTest.java
index 7b78456f2b..c44e860a67 100644
--- 
a/dubbo-metrics/dubbo-metrics-registry/src/test/java/org/apache/dubbo/metrics/registry/metrics/collector/RegistryMetricsCollectorTest.java
+++ 
b/dubbo-metrics/dubbo-metrics-registry/src/test/java/org/apache/dubbo/metrics/registry/metrics/collector/RegistryMetricsCollectorTest.java
@@ -39,6 +39,7 @@ import java.util.stream.Collectors;
 
 import static 
org.apache.dubbo.common.constants.MetricsConstants.TAG_APPLICATION_NAME;
 import static 
org.apache.dubbo.metrics.registry.collector.stat.RegistryStatComposite.OP_TYPE_REGISTER;
+import static 
org.apache.dubbo.metrics.registry.collector.stat.RegistryStatComposite.OP_TYPE_REGISTER_SERVICE;
 
 
 class RegistryMetricsCollectorTest {
@@ -109,5 +110,53 @@ class RegistryMetricsCollectorTest {
         Assertions.assertEquals(sampleMap.get(new 
MetricsKeyWrapper(OP_TYPE_REGISTER, MetricsKey.METRIC_RT_SUM).targetKey()), c1 
+ c2);
     }
 
+    @Test
+    void testServicePushMetrics() throws InterruptedException {
+
+        TimePair timePair = TimePair.start();
+        GlobalMetricsEventMulticaster eventMulticaster = 
applicationModel.getBeanFactory().getOrRegisterBean(GlobalMetricsEventMulticaster.class);
+        RegistryMetricsCollector collector = 
applicationModel.getBeanFactory().getOrRegisterBean(RegistryMetricsCollector.class);
+        collector.setCollectEnabled(true);
+        String serviceName = "demo.gameService";
+
+        eventMulticaster.publishEvent(new 
RegistryEvent.MetricsServiceRegisterEvent(applicationModel, 
timePair,serviceName,2));
+        List<MetricSample> metricSamples = collector.collect();
+
+        // push success +1
+        Assertions.assertEquals(1, metricSamples.size());
+        Assertions.assertTrue(metricSamples.get(0) instanceof 
GaugeMetricSample);
+
+        eventMulticaster.publishFinishEvent(new 
RegistryEvent.MetricsServiceRegisterEvent(applicationModel, 
timePair,serviceName,2));
+        // push finish rt +1
+        metricSamples = collector.collect();
+        //num(total+success) + rt(5) = 7
+        Assertions.assertEquals(7, metricSamples.size());
+        long c1 = timePair.calc();
+        TimePair lastTimePair = TimePair.start();
+        eventMulticaster.publishEvent(new 
RegistryEvent.MetricsServiceRegisterEvent(applicationModel, 
lastTimePair,serviceName,2));
+        Thread.sleep(50);
+        // push error rt +1
+        eventMulticaster.publishErrorEvent(new 
RegistryEvent.MetricsServiceRegisterEvent(applicationModel, 
lastTimePair,serviceName,2));
+        long c2 = lastTimePair.calc();
+        metricSamples = collector.collect();
+
+        // num(total+success+error) + rt(5)
+        Assertions.assertEquals(8, metricSamples.size());
+
+        // calc rt
+        for (MetricSample sample : metricSamples) {
+            Map<String, String> tags = sample.getTags();
+            Assertions.assertEquals(tags.get(TAG_APPLICATION_NAME), 
applicationModel.getApplicationName());
+        }
+
+        @SuppressWarnings("rawtypes")
+        Map<String, Long> sampleMap = 
metricSamples.stream().collect(Collectors.toMap(MetricSample::getName, k -> 
((GaugeMetricSample) k).applyAsLong()));
+
+        Assertions.assertEquals(sampleMap.get(new 
MetricsKeyWrapper(OP_TYPE_REGISTER_SERVICE, 
MetricsKey.METRIC_RT_LAST).targetKey()), lastTimePair.calc());
+        Assertions.assertEquals(sampleMap.get(new 
MetricsKeyWrapper(OP_TYPE_REGISTER_SERVICE, 
MetricsKey.METRIC_RT_MIN).targetKey()), Math.min(c1, c2));
+        Assertions.assertEquals(sampleMap.get(new 
MetricsKeyWrapper(OP_TYPE_REGISTER_SERVICE, 
MetricsKey.METRIC_RT_MAX).targetKey()), Math.max(c1, c2));
+        Assertions.assertEquals(sampleMap.get(new 
MetricsKeyWrapper(OP_TYPE_REGISTER_SERVICE, 
MetricsKey.METRIC_RT_AVG).targetKey()), (c1 + c2) / 2);
+        Assertions.assertEquals(sampleMap.get(new 
MetricsKeyWrapper(OP_TYPE_REGISTER_SERVICE, 
MetricsKey.METRIC_RT_SUM).targetKey()), c1 + c2);
+    }
 
 }
diff --git 
a/dubbo-metrics/dubbo-metrics-registry/src/test/java/org/apache/dubbo/metrics/registry/metrics/collector/RegistryStatCompositeTest.java
 
b/dubbo-metrics/dubbo-metrics-registry/src/test/java/org/apache/dubbo/metrics/registry/metrics/collector/RegistryStatCompositeTest.java
index 7d4753aa1b..036f8ae4e5 100644
--- 
a/dubbo-metrics/dubbo-metrics-registry/src/test/java/org/apache/dubbo/metrics/registry/metrics/collector/RegistryStatCompositeTest.java
+++ 
b/dubbo-metrics/dubbo-metrics-registry/src/test/java/org/apache/dubbo/metrics/registry/metrics/collector/RegistryStatCompositeTest.java
@@ -37,11 +37,11 @@ public class RegistryStatCompositeTest {
     void testInit() {
         RegistryStatComposite statComposite = new RegistryStatComposite();
         Assertions.assertEquals(statComposite.applicationNumStats.size(), 
RegistryEvent.ApplicationType.values().length);
-        //(rt)5 * (register,subscribe,notify)3
-        Assertions.assertEquals(5 * 3, statComposite.appRtStats.size());
+        //(rt)5 * 
(register,subscribe,notify,register.service,subscribe.service)5
+        Assertions.assertEquals(5 * 5, statComposite.rtStats.size());
         statComposite.applicationNumStats.values().forEach((v ->
             Assertions.assertEquals(v, new ConcurrentHashMap<>())));
-        statComposite.appRtStats.forEach(rtContainer ->
+        statComposite.rtStats.forEach(rtContainer ->
         {
             for (Map.Entry<String, ? extends Number> entry : 
rtContainer.entrySet()) {
                 Assertions.assertEquals(0L, 
rtContainer.getValueSupplier().apply(entry.getKey()));
@@ -60,8 +60,8 @@ public class RegistryStatCompositeTest {
     void testCalcRt() {
         RegistryStatComposite statComposite = new RegistryStatComposite();
         statComposite.calcApplicationRt(applicationName, OP_TYPE_NOTIFY, 10L);
-        
Assertions.assertTrue(statComposite.appRtStats.stream().anyMatch(longContainer 
-> longContainer.specifyType(OP_TYPE_NOTIFY)));
-        Optional<LongContainer<? extends Number>> subContainer = 
statComposite.appRtStats.stream().filter(longContainer -> 
longContainer.specifyType(OP_TYPE_NOTIFY)).findFirst();
+        
Assertions.assertTrue(statComposite.rtStats.stream().anyMatch(longContainer -> 
longContainer.specifyType(OP_TYPE_NOTIFY)));
+        Optional<LongContainer<? extends Number>> subContainer = 
statComposite.rtStats.stream().filter(longContainer -> 
longContainer.specifyType(OP_TYPE_NOTIFY)).findFirst();
         subContainer.ifPresent(v -> Assertions.assertEquals(10L, 
v.get(applicationName).longValue()));
     }
 }

Reply via email to