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

songxiaosheng 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 b81c141486 Refactor Metrics Key&Collector (#12083)
b81c141486 is described below

commit b81c141486386b751d04cb6fa799bba9844f71ca
Author: wxbty <[email protected]>
AuthorDate: Fri Apr 14 13:20:19 2023 +0800

    Refactor Metrics Key&Collector (#12083)
    
    * tmp
    
    * tmp
    
    * tmp
    
    * composite
    
    * add licence
    
    * remove
    
    * style
    
    * style
    
    * tmp
    
    * Refactor Metrics Key&Collector
    
    * fix ci
    
    * fix ci
    
    * fix ci
    
    * fix ci
    
    * fix
    
    * remove unuse
    
    * code opt, remove unuse && magic num
    
    ---------
    
    Co-authored-by: x-shadow-man <[email protected]>
    Co-authored-by: songxiaosheng <[email protected]>
---
 .../rpc/cluster/directory/AbstractDirectory.java   |  14 +-
 .../org/apache/dubbo/metrics/MetricsConstants.java |   2 +
 .../collector/ApplicationMetricsCollector.java     |  10 +-
 .../metrics/collector/CombMetricsCollector.java    |  89 +++++++++++++
 .../dubbo/metrics/collector/MetricsCollector.java  |   4 +-
 .../collector/ServiceMetricsCollector.java}        |  34 ++---
 .../apache/dubbo/metrics/event/MetricsEvent.java   |  25 +++-
 .../dubbo/metrics/event/MetricsEventBus.java       |  12 +-
 .../metrics/event/MetricsEventMulticaster.java     |   4 +-
 .../event/SimpleMetricsEventMulticaster.java       |   4 +-
 .../metrics/listener/AbstractMetricsListener.java  |  70 ++++++++++
 .../listener/MetricsApplicationListener.java       |  54 ++++++++
 .../metrics/listener/MetricsLifeListener.java      |   4 +-
 .../metrics/listener/MetricsServiceListener.java   |  56 ++++++++
 .../dubbo/metrics/model/key/CategoryOverall.java}  |  41 +++---
 .../apache/dubbo/metrics/model/key/MetricsCat.java |  54 ++++++++
 .../dubbo/metrics/model/key/MetricsKeyWrapper.java |   4 -
 .../dubbo/metrics/model/key/TypeWrapper.java       |  10 +-
 .../event/SimpleMetricsEventMulticasterTest.java   |  12 +-
 .../metrics/metadata/MetadataMetricsConstants.java |  20 ++-
 .../collector/MetadataMetricsCollector.java        |  55 ++------
 .../metrics/metadata/event/MetadataEvent.java      |  53 +++-----
 .../metrics/metadata/event/MetadataListener.java   |  67 ----------
 .../event/MetadataMetricsEventMulticaster.java     |  87 ++++++-------
 .../metrics/metadata/type/ApplicationType.java     |  52 --------
 .../metadata/MetadataStatCompositeTest.java        |  14 +-
 .../metrics/registry/RegistryMetricsConstants.java |  34 ++++-
 .../collector/RegistryMetricsCollector.java        |  63 ++-------
 .../metrics/registry/event/RegistryEvent.java      |  82 ++----------
 .../metrics/registry/event/RegistryListener.java   |  67 ----------
 .../event/RegistryMetricsEventMulticaster.java     | 141 ++++++++++-----------
 .../metrics/registry/event/type/ServiceType.java   |  50 --------
 .../collector/RegistryMetricsSampleTest.java       |   7 +-
 .../collector/RegistryStatCompositeTest.java       |  12 +-
 34 files changed, 638 insertions(+), 669 deletions(-)

diff --git 
a/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/directory/AbstractDirectory.java
 
b/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/directory/AbstractDirectory.java
index ee15fc6382..a1ea668291 100644
--- 
a/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/directory/AbstractDirectory.java
+++ 
b/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/directory/AbstractDirectory.java
@@ -28,8 +28,8 @@ import org.apache.dubbo.common.utils.ConcurrentHashSet;
 import org.apache.dubbo.common.utils.NetUtils;
 import org.apache.dubbo.common.utils.StringUtils;
 import org.apache.dubbo.metrics.event.MetricsEventBus;
+import org.apache.dubbo.metrics.model.key.MetricsKey;
 import org.apache.dubbo.metrics.registry.event.RegistryEvent;
-import org.apache.dubbo.metrics.registry.event.type.ServiceType;
 import org.apache.dubbo.rpc.Invocation;
 import org.apache.dubbo.rpc.Invoker;
 import org.apache.dubbo.rpc.RpcContext;
@@ -502,13 +502,13 @@ public abstract class AbstractDirectory<T> implements 
Directory<T> {
             .collect(Collectors.joining(","));
     }
 
-    private Map<ServiceType, Map<String, Integer>> getSummary() {
-        Map<ServiceType, Map<String, Integer>> summaryMap = new HashMap<>();
+    private Map<MetricsKey, Map<String, Integer>> getSummary() {
+        Map<MetricsKey, Map<String, Integer>> summaryMap = new HashMap<>();
 
-        summaryMap.put(ServiceType.D_VALID, 
groupByServiceKey(getValidInvokers()));
-        summaryMap.put(ServiceType.D_DISABLE, 
groupByServiceKey(getDisabledInvokers()));
-        summaryMap.put(ServiceType.D_TO_RECONNECT, 
groupByServiceKey(getInvokersToReconnect()));
-        summaryMap.put(ServiceType.D_ALL, groupByServiceKey(getInvokers()));
+        summaryMap.put(MetricsKey.DIRECTORY_METRIC_NUM_VALID, 
groupByServiceKey(getValidInvokers()));
+        summaryMap.put(MetricsKey.DIRECTORY_METRIC_NUM_DISABLE, 
groupByServiceKey(getDisabledInvokers()));
+        summaryMap.put(MetricsKey.DIRECTORY_METRIC_NUM_TO_RECONNECT, 
groupByServiceKey(getInvokersToReconnect()));
+        summaryMap.put(MetricsKey.DIRECTORY_METRIC_NUM_ALL, 
groupByServiceKey(getInvokers()));
         return summaryMap;
     }
 
diff --git 
a/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/MetricsConstants.java
 
b/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/MetricsConstants.java
index 7b5c4598c0..a4c7516321 100644
--- 
a/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/MetricsConstants.java
+++ 
b/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/MetricsConstants.java
@@ -24,4 +24,6 @@ public interface MetricsConstants {
     String ATTACHMENT_KEY_LAST_NUM_MAP = "lastNumMap";
     String ATTACHMENT_DIRECTORY_MAP = "dirNum";
 
+    int SELF_INCREMENT_SIZE = 1;
+
 }
diff --git 
a/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/collector/ApplicationMetricsCollector.java
 
b/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/collector/ApplicationMetricsCollector.java
index 118b87cda9..a9ac60df2e 100644
--- 
a/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/collector/ApplicationMetricsCollector.java
+++ 
b/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/collector/ApplicationMetricsCollector.java
@@ -17,7 +17,8 @@
 
 package org.apache.dubbo.metrics.collector;
 
-import org.apache.dubbo.metrics.event.MetricsEvent;
+import org.apache.dubbo.metrics.event.TimeCounterEvent;
+import org.apache.dubbo.metrics.model.key.MetricsKey;
 
 /**
  * Application-level collector.
@@ -25,10 +26,11 @@ import org.apache.dubbo.metrics.event.MetricsEvent;
  *
  * @Params <T>  metrics type
  */
-public interface ApplicationMetricsCollector<T, E extends MetricsEvent> 
extends MetricsCollector<E> {
+public interface ApplicationMetricsCollector<E extends TimeCounterEvent> 
extends MetricsCollector<E> {
 
-    void increment(String applicationName, T type);
+    void increment(String applicationName, MetricsKey metricsKey);
+
+    void addRt(String applicationName, String registryOpType, Long 
responseTime);
 
-    void addApplicationRT(String applicationName, String registryOpType, Long 
responseTime);
 }
 
diff --git 
a/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/collector/CombMetricsCollector.java
 
b/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/collector/CombMetricsCollector.java
new file mode 100644
index 0000000000..f9eb9ac5c6
--- /dev/null
+++ 
b/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/collector/CombMetricsCollector.java
@@ -0,0 +1,89 @@
+/*
+ * 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.collector;
+
+import org.apache.dubbo.metrics.data.BaseStatComposite;
+import org.apache.dubbo.metrics.event.MetricsEventMulticaster;
+import org.apache.dubbo.metrics.event.TimeCounterEvent;
+import org.apache.dubbo.metrics.model.MetricsCategory;
+import org.apache.dubbo.metrics.model.key.MetricsKey;
+import org.apache.dubbo.metrics.model.sample.GaugeMetricSample;
+
+import java.util.List;
+
+import static org.apache.dubbo.metrics.MetricsConstants.SELF_INCREMENT_SIZE;
+
+public abstract class CombMetricsCollector<E extends TimeCounterEvent> 
implements ApplicationMetricsCollector<E>, ServiceMetricsCollector<E> {
+
+    private final BaseStatComposite stats;
+    private MetricsEventMulticaster eventMulticaster;
+
+
+    public CombMetricsCollector(BaseStatComposite stats) {
+        this.stats = stats;
+    }
+
+    protected void setEventMulticaster(MetricsEventMulticaster 
eventMulticaster) {
+        this.eventMulticaster = eventMulticaster;
+    }
+
+    @Override
+    public void setNum(MetricsKey metricsKey, String applicationName, String 
serviceKey, int num) {
+        this.stats.setServiceKey(metricsKey, applicationName, serviceKey, num);
+    }
+
+    @Override
+    public void increment(String applicationName, MetricsKey metricsKey) {
+        this.stats.incrementApp(metricsKey, applicationName, 
SELF_INCREMENT_SIZE);
+    }
+
+    public void increment(String applicationName, String serviceKey, 
MetricsKey metricsKey, int size) {
+        this.stats.incrementServiceKey(metricsKey, applicationName, 
serviceKey, size);
+    }
+
+    @Override
+    public void addRt(String applicationName, String registryOpType, Long 
responseTime) {
+        stats.calcApplicationRt(applicationName, registryOpType, responseTime);
+    }
+
+    public void addRt(String applicationName, String serviceKey, String 
registryOpType, Long responseTime) {
+        stats.calcServiceKeyRt(applicationName, serviceKey, registryOpType, 
responseTime);
+    }
+
+    @SuppressWarnings({"rawtypes"})
+    protected List<GaugeMetricSample> export(MetricsCategory category) {
+        return stats.export(category);
+    }
+
+    @Override
+    public void onEvent(TimeCounterEvent event) {
+        eventMulticaster.publishEvent(event);
+    }
+
+
+    @Override
+    public void onEventFinish(TimeCounterEvent event) {
+        eventMulticaster.publishFinishEvent(event);
+    }
+
+    @Override
+    public void onEventError(TimeCounterEvent event) {
+        eventMulticaster.publishErrorEvent(event);
+    }
+}
+
diff --git 
a/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/collector/MetricsCollector.java
 
b/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/collector/MetricsCollector.java
index 3436d4f829..8675faf5f3 100644
--- 
a/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/collector/MetricsCollector.java
+++ 
b/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/collector/MetricsCollector.java
@@ -18,7 +18,7 @@
 package org.apache.dubbo.metrics.collector;
 
 import org.apache.dubbo.common.extension.SPI;
-import org.apache.dubbo.metrics.event.MetricsEvent;
+import org.apache.dubbo.metrics.event.TimeCounterEvent;
 import org.apache.dubbo.metrics.listener.MetricsLifeListener;
 import org.apache.dubbo.metrics.model.sample.MetricSample;
 
@@ -29,7 +29,7 @@ import java.util.List;
  * An interface of collector to collect framework internal metrics.
  */
 @SPI
-public interface MetricsCollector<E extends MetricsEvent> extends 
MetricsLifeListener<E> {
+public interface MetricsCollector<E extends TimeCounterEvent> extends 
MetricsLifeListener<E> {
 
     default boolean isCollectEnabled() {
         return false;
diff --git 
a/dubbo-metrics/dubbo-metrics-registry/src/main/java/org/apache/dubbo/metrics/registry/event/type/ApplicationType.java
 
b/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/collector/ServiceMetricsCollector.java
similarity index 56%
rename from 
dubbo-metrics/dubbo-metrics-registry/src/main/java/org/apache/dubbo/metrics/registry/event/type/ApplicationType.java
rename to 
dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/collector/ServiceMetricsCollector.java
index 1827c13554..b4876716bf 100644
--- 
a/dubbo-metrics/dubbo-metrics-registry/src/main/java/org/apache/dubbo/metrics/registry/event/type/ApplicationType.java
+++ 
b/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/collector/ServiceMetricsCollector.java
@@ -15,31 +15,23 @@
  * limitations under the License.
  */
 
-package org.apache.dubbo.metrics.registry.event.type;
+package org.apache.dubbo.metrics.collector;
 
+import org.apache.dubbo.metrics.event.TimeCounterEvent;
 import org.apache.dubbo.metrics.model.key.MetricsKey;
 
-public enum ApplicationType {
-    R_TOTAL(MetricsKey.REGISTER_METRIC_REQUESTS),
-    R_SUCCEED(MetricsKey.REGISTER_METRIC_REQUESTS_SUCCEED),
-    R_FAILED(MetricsKey.REGISTER_METRIC_REQUESTS_FAILED),
-
-    S_TOTAL(MetricsKey.SUBSCRIBE_METRIC_NUM),
-    S_SUCCEED(MetricsKey.SUBSCRIBE_METRIC_NUM_SUCCEED),
-    S_FAILED(MetricsKey.SUBSCRIBE_METRIC_NUM_FAILED),
-
-    N_TOTAL(MetricsKey.NOTIFY_METRIC_REQUESTS),
-    ;
-
-    private final MetricsKey metricsKey;
-
+/**
+ * Application-level collector.
+ * registration center, configuration center and other scenarios
+ *
+ * @Params <T>  metrics type
+ */
+public interface ServiceMetricsCollector<E extends TimeCounterEvent> extends 
MetricsCollector<E> {
 
-    ApplicationType(MetricsKey metricsKey) {
-        this.metricsKey = metricsKey;
-    }
+    void increment(String applicationName, String serviceKey, MetricsKey 
metricsKey, int size);
 
-    public MetricsKey getMetricsKey() {
-        return metricsKey;
-    }
+    void setNum(MetricsKey metricsKey, String applicationName, String 
serviceKey, int num);
 
+    void addRt(String applicationName, String serviceKey, String 
registryOpType, Long responseTime);
 }
+
diff --git 
a/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/event/MetricsEvent.java
 
b/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/event/MetricsEvent.java
index 091211ae40..26396c8acd 100644
--- 
a/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/event/MetricsEvent.java
+++ 
b/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/event/MetricsEvent.java
@@ -17,10 +17,14 @@
 
 package org.apache.dubbo.metrics.event;
 
+import org.apache.dubbo.metrics.exception.MetricsNeverHappenException;
 import org.apache.dubbo.metrics.model.MethodMetric;
 import org.apache.dubbo.metrics.model.key.TypeWrapper;
 import org.apache.dubbo.rpc.model.ApplicationModel;
 
+import java.util.HashMap;
+import java.util.Map;
+
 /**
  * BaseMetricsEvent.
  */
@@ -33,7 +37,8 @@ public abstract class MetricsEvent {
     private boolean available = true;
     protected TypeWrapper typeWrapper;
 
-    @SuppressWarnings({"unchecked"})
+    private final Map<String, Object> attachment = new HashMap<>(8);
+
     public MetricsEvent(ApplicationModel source) {
         if (source == null) {
             this.source = ApplicationModel.defaultModel();
@@ -44,6 +49,18 @@ public abstract class MetricsEvent {
         }
     }
 
+    @SuppressWarnings("unchecked")
+    public <T> T getAttachmentValue(String key) {
+        if (!attachment.containsKey(key)) {
+            throw new MetricsNeverHappenException("Attachment key [" + key + 
"] not found");
+        }
+        return (T) attachment.get(key);
+    }
+
+    public void putAttachment(String key, Object value) {
+        attachment.put(key, value);
+    }
+
     public void setAvailable(boolean available) {
         this.available = available;
     }
@@ -61,6 +78,10 @@ public abstract class MetricsEvent {
         return source;
     }
 
+    public String appName() {
+        return getSource().getApplicationName();
+    }
+
     public boolean isAssignableFrom(Object type) {
         return typeWrapper.isAssignableFrom(type);
     }
@@ -84,7 +105,7 @@ public abstract class MetricsEvent {
         CODEC_EXCEPTION("CODEC_EXCEPTION_%s"),
         ;
 
-        private String name;
+        private final String name;
 
         public final String getName() {
             return this.name;
diff --git 
a/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/event/MetricsEventBus.java
 
b/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/event/MetricsEventBus.java
index dc83e994ab..193f7feb37 100644
--- 
a/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/event/MetricsEventBus.java
+++ 
b/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/event/MetricsEventBus.java
@@ -89,24 +89,28 @@ public class MetricsEventBus {
             return targetSupplier.get();
         }
         dispatcher.publishEvent(event);
+        if (!(event instanceof TimeCounterEvent)) {
+            return targetSupplier.get();
+        }
+        TimeCounterEvent timeCounterEvent = (TimeCounterEvent) event;
         T result;
         if (trFunction == null) {
             try {
                 result = targetSupplier.get();
             } catch (Throwable e) {
-                dispatcher.publishErrorEvent(event);
+                dispatcher.publishErrorEvent(timeCounterEvent);
                 throw e;
             }
             event.customAfterPost(result);
-            dispatcher.publishFinishEvent(event);
+            dispatcher.publishFinishEvent(timeCounterEvent);
         } else {
             // Custom failure status
             result = targetSupplier.get();
             if (trFunction.apply(result)) {
                 event.customAfterPost(result);
-                dispatcher.publishFinishEvent(event);
+                dispatcher.publishFinishEvent(timeCounterEvent);
             } else {
-                dispatcher.publishErrorEvent(event);
+                dispatcher.publishErrorEvent(timeCounterEvent);
             }
         }
         return result;
diff --git 
a/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/event/MetricsEventMulticaster.java
 
b/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/event/MetricsEventMulticaster.java
index 166301f0c6..459b0744e3 100644
--- 
a/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/event/MetricsEventMulticaster.java
+++ 
b/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/event/MetricsEventMulticaster.java
@@ -25,7 +25,7 @@ public interface MetricsEventMulticaster {
 
     void publishEvent(MetricsEvent event);
 
-    void publishFinishEvent(MetricsEvent event);
+    void publishFinishEvent(TimeCounterEvent event);
 
-    void publishErrorEvent(MetricsEvent event);
+    void publishErrorEvent(TimeCounterEvent event);
 }
diff --git 
a/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/event/SimpleMetricsEventMulticaster.java
 
b/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/event/SimpleMetricsEventMulticaster.java
index 70179a7445..57b12cd6dd 100644
--- 
a/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/event/SimpleMetricsEventMulticaster.java
+++ 
b/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/event/SimpleMetricsEventMulticaster.java
@@ -60,13 +60,13 @@ public class SimpleMetricsEventMulticaster implements 
MetricsEventMulticaster {
 
     @Override
     @SuppressWarnings({"unchecked"})
-    public void publishFinishEvent(MetricsEvent event) {
+    public void publishFinishEvent(TimeCounterEvent event) {
         publishTimeEvent(event, metricsLifeListener -> 
metricsLifeListener.onEventFinish(event));
     }
 
     @Override
     @SuppressWarnings({"unchecked"})
-    public void publishErrorEvent(MetricsEvent event) {
+    public void publishErrorEvent(TimeCounterEvent event) {
         publishTimeEvent(event, metricsLifeListener -> 
metricsLifeListener.onEventError(event));
     }
 
diff --git 
a/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/listener/AbstractMetricsListener.java
 
b/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/listener/AbstractMetricsListener.java
new file mode 100644
index 0000000000..c588a33ade
--- /dev/null
+++ 
b/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/listener/AbstractMetricsListener.java
@@ -0,0 +1,70 @@
+/*
+ * 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.listener;
+
+import org.apache.dubbo.metrics.event.MetricsEvent;
+import org.apache.dubbo.metrics.event.TimeCounterEvent;
+import org.apache.dubbo.metrics.model.key.MetricsKey;
+
+import java.util.function.Consumer;
+
+public abstract class AbstractMetricsListener implements 
MetricsLifeListener<TimeCounterEvent> {
+
+    private final MetricsKey metricsKey;
+
+    public AbstractMetricsListener(MetricsKey metricsKey) {
+        this.metricsKey = metricsKey;
+    }
+
+    @Override
+    public boolean isSupport(MetricsEvent event) {
+        return event.isAvailable() && event.isAssignableFrom(metricsKey);
+    }
+
+    public static AbstractMetricsListener onEvent(MetricsKey metricsKey, 
Consumer<TimeCounterEvent> postFunc) {
+
+        return new AbstractMetricsListener(metricsKey) {
+            @Override
+            public void onEvent(TimeCounterEvent event) {
+                postFunc.accept(event);
+            }
+        };
+    }
+
+    public static AbstractMetricsListener onFinish(MetricsKey metricsKey, 
Consumer<TimeCounterEvent> finishFunc) {
+
+        return new AbstractMetricsListener(metricsKey) {
+            @Override
+            public void onEventFinish(TimeCounterEvent event) {
+                finishFunc.accept(event);
+            }
+        };
+    }
+
+    public static AbstractMetricsListener onError(MetricsKey metricsKey, 
Consumer<TimeCounterEvent> errorFunc) {
+
+        return new AbstractMetricsListener(metricsKey) {
+            @Override
+            public void onEventError(TimeCounterEvent event) {
+                errorFunc.accept(event);
+            }
+        };
+    }
+
+
+}
diff --git 
a/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/listener/MetricsApplicationListener.java
 
b/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/listener/MetricsApplicationListener.java
new file mode 100644
index 0000000000..d5b6d77ec0
--- /dev/null
+++ 
b/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/listener/MetricsApplicationListener.java
@@ -0,0 +1,54 @@
+/*
+ * 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.listener;
+
+import org.apache.dubbo.metrics.collector.CombMetricsCollector;
+import org.apache.dubbo.metrics.event.TimeCounterEvent;
+import org.apache.dubbo.metrics.model.key.MetricsKey;
+import org.apache.dubbo.metrics.model.key.MetricsPlaceType;
+
+public  class MetricsApplicationListener extends AbstractMetricsListener {
+
+    public MetricsApplicationListener(MetricsKey metricsKey) {
+        super(metricsKey);
+    }
+
+    public static AbstractMetricsListener onPostEventBuild(MetricsKey 
metricsKey, CombMetricsCollector<TimeCounterEvent> collector) {
+        return AbstractMetricsListener.onEvent(metricsKey,
+            event -> collector.increment(event.appName(), metricsKey)
+        );
+    }
+
+    public static AbstractMetricsListener onFinishEventBuild(MetricsKey 
metricsKey, MetricsPlaceType placeType, CombMetricsCollector<TimeCounterEvent> 
collector) {
+        return AbstractMetricsListener.onFinish(metricsKey,
+            event -> {
+                collector.increment(event.appName(), metricsKey);
+                collector.addRt(event.appName(), placeType.getType(), 
event.getTimePair().calc());
+            }
+        );
+    }
+
+    public static AbstractMetricsListener onErrorEventBuild(MetricsKey 
metricsKey, MetricsPlaceType placeType, CombMetricsCollector<TimeCounterEvent> 
collector) {
+        return AbstractMetricsListener.onError(metricsKey,
+            event -> {
+                collector.increment(event.appName(), metricsKey);
+                collector.addRt(event.appName(), placeType.getType(), 
event.getTimePair().calc());
+            }
+        );
+    }
+}
diff --git 
a/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/listener/MetricsLifeListener.java
 
b/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/listener/MetricsLifeListener.java
index bee82056be..294be1885a 100644
--- 
a/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/listener/MetricsLifeListener.java
+++ 
b/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/listener/MetricsLifeListener.java
@@ -17,12 +17,12 @@
 
 package org.apache.dubbo.metrics.listener;
 
-import org.apache.dubbo.metrics.event.MetricsEvent;
+import org.apache.dubbo.metrics.event.TimeCounterEvent;
 
 /**
  * Metrics Listener.
  */
-public interface MetricsLifeListener<E extends MetricsEvent> extends 
MetricsListener<E> {
+public interface MetricsLifeListener<E extends TimeCounterEvent> extends 
MetricsListener<E> {
 
     default void onEventFinish(E event) {
     }
diff --git 
a/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/listener/MetricsServiceListener.java
 
b/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/listener/MetricsServiceListener.java
new file mode 100644
index 0000000000..07a76ab19b
--- /dev/null
+++ 
b/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/listener/MetricsServiceListener.java
@@ -0,0 +1,56 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.dubbo.metrics.listener;
+
+import org.apache.dubbo.metrics.collector.ServiceMetricsCollector;
+import org.apache.dubbo.metrics.event.TimeCounterEvent;
+import org.apache.dubbo.metrics.model.key.MetricsKey;
+import org.apache.dubbo.metrics.model.key.MetricsPlaceType;
+
+import static org.apache.dubbo.metrics.MetricsConstants.ATTACHMENT_KEY_SERVICE;
+import static org.apache.dubbo.metrics.MetricsConstants.SELF_INCREMENT_SIZE;
+
+public class MetricsServiceListener extends AbstractMetricsListener {
+
+    public MetricsServiceListener(MetricsKey metricsKey) {
+        super(metricsKey);
+    }
+
+    public static AbstractMetricsListener onPostEventBuild(MetricsKey 
metricsKey, ServiceMetricsCollector<TimeCounterEvent> collector) {
+        return AbstractMetricsListener.onEvent(metricsKey,
+            event -> collector.increment(event.appName(), 
event.getAttachmentValue(ATTACHMENT_KEY_SERVICE), metricsKey, 
SELF_INCREMENT_SIZE)
+        );
+    }
+
+    public static AbstractMetricsListener onFinishEventBuild(MetricsKey 
metricsKey, MetricsPlaceType placeType, 
ServiceMetricsCollector<TimeCounterEvent> collector) {
+        return AbstractMetricsListener.onFinish(metricsKey,
+            event -> incrAndAddRt(metricsKey, placeType, collector, event)
+        );
+    }
+
+    public static AbstractMetricsListener onErrorEventBuild(MetricsKey 
metricsKey, MetricsPlaceType placeType, 
ServiceMetricsCollector<TimeCounterEvent> collector) {
+        return AbstractMetricsListener.onError(metricsKey,
+            event -> incrAndAddRt(metricsKey, placeType, collector, event)
+        );
+    }
+
+    private static void incrAndAddRt(MetricsKey metricsKey, MetricsPlaceType 
placeType, ServiceMetricsCollector<TimeCounterEvent> collector, 
TimeCounterEvent event) {
+        collector.increment(event.appName(), 
event.getAttachmentValue(ATTACHMENT_KEY_SERVICE), metricsKey, 
SELF_INCREMENT_SIZE);
+        collector.addRt(event.appName(), 
event.getAttachmentValue(ATTACHMENT_KEY_SERVICE), placeType.getType(), 
event.getTimePair().calc());
+    }
+}
diff --git 
a/dubbo-metrics/dubbo-metrics-metadata/src/main/java/org/apache/dubbo/metrics/metadata/type/ServiceType.java
 
b/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/model/key/CategoryOverall.java
similarity index 52%
rename from 
dubbo-metrics/dubbo-metrics-metadata/src/main/java/org/apache/dubbo/metrics/metadata/type/ServiceType.java
rename to 
dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/model/key/CategoryOverall.java
index fddcfad104..007a904b72 100644
--- 
a/dubbo-metrics/dubbo-metrics-metadata/src/main/java/org/apache/dubbo/metrics/metadata/type/ServiceType.java
+++ 
b/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/model/key/CategoryOverall.java
@@ -15,36 +15,35 @@
  * limitations under the License.
  */
 
-package org.apache.dubbo.metrics.metadata.type;
+package org.apache.dubbo.metrics.model.key;
 
-import org.apache.dubbo.metrics.model.key.MetricsKey;
+import io.micrometer.common.lang.Nullable;
 
-public enum ServiceType {
+public class CategoryOverall {
 
-    S_P_TOTAL(MetricsKey.STORE_PROVIDER_METADATA),
-    S_P_SUCCEED(MetricsKey.STORE_PROVIDER_METADATA_SUCCEED),
-    S_P_FAILED(MetricsKey.STORE_PROVIDER_METADATA_FAILED),
+    private final MetricsCat post;
+    private MetricsCat finish;
+    private MetricsCat error;
 
-    ;
-
-    private final MetricsKey metricsKey;
-    private final boolean isIncrement;
-
-
-    ServiceType(MetricsKey metricsKey) {
-        this(metricsKey, true);
+    public CategoryOverall(MetricsPlaceType placeType, MetricsCat post, 
@Nullable MetricsCat finish, @Nullable MetricsCat error) {
+        this.post = post.setPlaceType(placeType);
+        if (finish != null) {
+            this.finish = finish.setPlaceType(placeType);
+        }
+        if (error != null) {
+            this.error = error.setPlaceType(placeType);
+        }
     }
 
-    ServiceType(MetricsKey metricsKey, boolean isIncrement) {
-        this.metricsKey = metricsKey;
-        this.isIncrement = isIncrement;
+    public MetricsCat getPost() {
+        return post;
     }
 
-    public MetricsKey getMetricsKey() {
-        return metricsKey;
+    public MetricsCat getFinish() {
+        return finish;
     }
 
-    public boolean isIncrement() {
-        return isIncrement;
+    public MetricsCat getError() {
+        return error;
     }
 }
diff --git 
a/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/model/key/MetricsCat.java
 
b/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/model/key/MetricsCat.java
new file mode 100644
index 0000000000..a6301bbd85
--- /dev/null
+++ 
b/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/model/key/MetricsCat.java
@@ -0,0 +1,54 @@
+/*
+ * 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.model.key;
+
+import org.apache.dubbo.metrics.collector.CombMetricsCollector;
+import org.apache.dubbo.metrics.event.TimeCounterEvent;
+import org.apache.dubbo.metrics.listener.AbstractMetricsListener;
+
+import java.util.function.BiFunction;
+import java.util.function.Function;
+
+public class MetricsCat {
+
+    private MetricsPlaceType placeType;
+    private final Function<CombMetricsCollector<TimeCounterEvent>, 
AbstractMetricsListener> eventFunc;
+
+    public MetricsCat(MetricsKey metricsKey, BiFunction<MetricsKey, 
CombMetricsCollector<TimeCounterEvent>, AbstractMetricsListener> biFunc) {
+        this.eventFunc = collector -> biFunc.apply(metricsKey, collector);
+    }
+
+    public MetricsCat(MetricsKey metricsKey, TpFunction<MetricsKey, 
MetricsPlaceType, CombMetricsCollector<TimeCounterEvent>, 
AbstractMetricsListener> tpFunc) {
+        this.eventFunc = collector -> tpFunc.apply(metricsKey, placeType, 
collector);
+    }
+
+    public MetricsCat setPlaceType(MetricsPlaceType placeType) {
+        this.placeType = placeType;
+        return this;
+    }
+
+    public Function<CombMetricsCollector<TimeCounterEvent>, 
AbstractMetricsListener> getEventFunc() {
+        return eventFunc;
+    }
+
+
+    @FunctionalInterface
+    public interface TpFunction<T, U, K, R> {
+        R apply(T t, U u, K k);
+    }
+}
diff --git 
a/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/model/key/MetricsKeyWrapper.java
 
b/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/model/key/MetricsKeyWrapper.java
index d734328e48..c3862f5f38 100644
--- 
a/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/model/key/MetricsKeyWrapper.java
+++ 
b/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/model/key/MetricsKeyWrapper.java
@@ -34,10 +34,6 @@ public class MetricsKeyWrapper {
 
     private final MetricsPlaceType placeType;
 
-    public MetricsKeyWrapper(String type, MetricsKey metricsKey) {
-        this(metricsKey, MetricsPlaceType.of(type, MetricsLevel.APP));
-    }
-
     public MetricsKeyWrapper(MetricsKey metricsKey, MetricsPlaceType 
placeType) {
         this.metricsKey = metricsKey;
         this.placeType = placeType;
diff --git 
a/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/model/key/TypeWrapper.java
 
b/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/model/key/TypeWrapper.java
index 643e063608..812db8f8e6 100644
--- 
a/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/model/key/TypeWrapper.java
+++ 
b/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/model/key/TypeWrapper.java
@@ -21,11 +21,11 @@ import org.apache.dubbo.common.utils.Assert;
 
 public class TypeWrapper {
     private final MetricsLevel level;
-    private final Object postType;
-    private final Object finishType;
-    private final Object errorType;
+    private final MetricsKey postType;
+    private final MetricsKey finishType;
+    private final MetricsKey errorType;
 
-    public TypeWrapper(MetricsLevel level, Object postType, Object finishType, 
Object errorType) {
+    public TypeWrapper(MetricsLevel level, MetricsKey postType, MetricsKey 
finishType, MetricsKey errorType) {
         this.level = level;
         this.postType = postType;
         this.finishType = finishType;
@@ -36,7 +36,7 @@ public class TypeWrapper {
         return level;
     }
 
-    public Object getErrorType() {
+    public MetricsKey getErrorType() {
         return errorType;
     }
 
diff --git 
a/dubbo-metrics/dubbo-metrics-api/src/test/java/org/apache/dubbo/metrics/event/SimpleMetricsEventMulticasterTest.java
 
b/dubbo-metrics/dubbo-metrics-api/src/test/java/org/apache/dubbo/metrics/event/SimpleMetricsEventMulticasterTest.java
index 394034b3bb..16ad2edf05 100644
--- 
a/dubbo-metrics/dubbo-metrics-api/src/test/java/org/apache/dubbo/metrics/event/SimpleMetricsEventMulticasterTest.java
+++ 
b/dubbo-metrics/dubbo-metrics-api/src/test/java/org/apache/dubbo/metrics/event/SimpleMetricsEventMulticasterTest.java
@@ -33,7 +33,7 @@ public class SimpleMetricsEventMulticasterTest {
     private SimpleMetricsEventMulticaster eventMulticaster;
     private Object[] objects;
     private final Object obj = new Object();
-    private MetricsEvent requestEvent;
+    private TimeCounterEvent requestEvent;
 
     @BeforeEach
     public void setup() {
@@ -52,7 +52,7 @@ public class SimpleMetricsEventMulticasterTest {
         ConfigManager configManager = new ConfigManager(applicationModel);
         configManager.setApplication(applicationConfig);
         applicationModel.setConfigManager(configManager);
-        requestEvent = new MetricsEvent(applicationModel) {
+        requestEvent = new TimeCounterEvent(applicationModel) {
         };
     }
 
@@ -75,20 +75,20 @@ public class SimpleMetricsEventMulticasterTest {
         Assertions.assertSame(obj, objects[0]);
 
         //do onEventFinish with MetricsLifeListener
-        eventMulticaster.addListener((new MetricsLifeListener<MetricsEvent>() {
+        eventMulticaster.addListener((new 
MetricsLifeListener<TimeCounterEvent>() {
 
             @Override
-            public void onEvent(MetricsEvent event) {
+            public void onEvent(TimeCounterEvent event) {
 
             }
 
             @Override
-            public void onEventFinish(MetricsEvent event) {
+            public void onEventFinish(TimeCounterEvent event) {
                 objects[0] = new Object();
             }
 
             @Override
-            public void onEventError(MetricsEvent event) {
+            public void onEventError(TimeCounterEvent event) {
 
             }
         }));
diff --git 
a/dubbo-metrics/dubbo-metrics-metadata/src/main/java/org/apache/dubbo/metrics/metadata/MetadataMetricsConstants.java
 
b/dubbo-metrics/dubbo-metrics-metadata/src/main/java/org/apache/dubbo/metrics/metadata/MetadataMetricsConstants.java
index 8f095d58fc..4b3f650899 100644
--- 
a/dubbo-metrics/dubbo-metrics-metadata/src/main/java/org/apache/dubbo/metrics/metadata/MetadataMetricsConstants.java
+++ 
b/dubbo-metrics/dubbo-metrics-metadata/src/main/java/org/apache/dubbo/metrics/metadata/MetadataMetricsConstants.java
@@ -17,15 +17,22 @@
 
 package org.apache.dubbo.metrics.metadata;
 
-import org.apache.dubbo.metrics.metadata.type.ApplicationType;
-import org.apache.dubbo.metrics.metadata.type.ServiceType;
 import org.apache.dubbo.metrics.model.key.MetricsKey;
 import org.apache.dubbo.metrics.model.key.MetricsLevel;
 import org.apache.dubbo.metrics.model.key.MetricsPlaceType;
 
 import java.util.Arrays;
 import java.util.List;
-import java.util.stream.Collectors;
+
+import static 
org.apache.dubbo.metrics.model.key.MetricsKey.METADATA_PUSH_METRIC_NUM;
+import static 
org.apache.dubbo.metrics.model.key.MetricsKey.METADATA_PUSH_METRIC_NUM_FAILED;
+import static 
org.apache.dubbo.metrics.model.key.MetricsKey.METADATA_PUSH_METRIC_NUM_SUCCEED;
+import static 
org.apache.dubbo.metrics.model.key.MetricsKey.METADATA_SUBSCRIBE_METRIC_NUM;
+import static 
org.apache.dubbo.metrics.model.key.MetricsKey.METADATA_SUBSCRIBE_METRIC_NUM_FAILED;
+import static 
org.apache.dubbo.metrics.model.key.MetricsKey.METADATA_SUBSCRIBE_METRIC_NUM_SUCCEED;
+import static 
org.apache.dubbo.metrics.model.key.MetricsKey.STORE_PROVIDER_METADATA;
+import static 
org.apache.dubbo.metrics.model.key.MetricsKey.STORE_PROVIDER_METADATA_FAILED;
+import static 
org.apache.dubbo.metrics.model.key.MetricsKey.STORE_PROVIDER_METADATA_SUCCEED;
 
 public interface MetadataMetricsConstants {
 
@@ -34,8 +41,11 @@ public interface MetadataMetricsConstants {
     MetricsPlaceType OP_TYPE_STORE_PROVIDER_INTERFACE = 
MetricsPlaceType.of("store.provider.interface", MetricsLevel.SERVICE);
 
     // App-level
-    List<MetricsKey> appKeys = 
Arrays.stream(ApplicationType.values()).map(ApplicationType::getMetricsKey).collect(Collectors.toList());
+    List<MetricsKey> APP_LEVEL_KEYS = Arrays.asList(METADATA_PUSH_METRIC_NUM, 
METADATA_PUSH_METRIC_NUM_SUCCEED, METADATA_PUSH_METRIC_NUM_FAILED,
+        METADATA_SUBSCRIBE_METRIC_NUM, METADATA_SUBSCRIBE_METRIC_NUM_SUCCEED, 
METADATA_SUBSCRIBE_METRIC_NUM_FAILED);
 
     // Service-level
-    List<MetricsKey> serviceKeys = 
Arrays.stream(ServiceType.values()).map(ServiceType::getMetricsKey).collect(Collectors.toList());
+    List<MetricsKey> SERVICE_LEVEL_KEYS = 
Arrays.asList(STORE_PROVIDER_METADATA,
+        STORE_PROVIDER_METADATA_SUCCEED, STORE_PROVIDER_METADATA_FAILED
+    );
 }
diff --git 
a/dubbo-metrics/dubbo-metrics-metadata/src/main/java/org/apache/dubbo/metrics/metadata/collector/MetadataMetricsCollector.java
 
b/dubbo-metrics/dubbo-metrics-metadata/src/main/java/org/apache/dubbo/metrics/metadata/collector/MetadataMetricsCollector.java
index 81d85024f6..e7ac434c5a 100644
--- 
a/dubbo-metrics/dubbo-metrics-metadata/src/main/java/org/apache/dubbo/metrics/metadata/collector/MetadataMetricsCollector.java
+++ 
b/dubbo-metrics/dubbo-metrics-metadata/src/main/java/org/apache/dubbo/metrics/metadata/collector/MetadataMetricsCollector.java
@@ -19,19 +19,17 @@ package org.apache.dubbo.metrics.metadata.collector;
 
 import org.apache.dubbo.common.extension.Activate;
 import org.apache.dubbo.config.context.ConfigManager;
-import org.apache.dubbo.metrics.collector.ApplicationMetricsCollector;
+import org.apache.dubbo.metrics.collector.CombMetricsCollector;
 import org.apache.dubbo.metrics.collector.MetricsCollector;
 import org.apache.dubbo.metrics.data.ApplicationStatComposite;
 import org.apache.dubbo.metrics.data.BaseStatComposite;
 import org.apache.dubbo.metrics.data.RtStatComposite;
 import org.apache.dubbo.metrics.data.ServiceStatComposite;
 import org.apache.dubbo.metrics.event.MetricsEvent;
-import org.apache.dubbo.metrics.event.MetricsEventMulticaster;
+import org.apache.dubbo.metrics.event.TimeCounterEvent;
 import org.apache.dubbo.metrics.metadata.MetadataMetricsConstants;
 import org.apache.dubbo.metrics.metadata.event.MetadataEvent;
 import org.apache.dubbo.metrics.metadata.event.MetadataMetricsEventMulticaster;
-import org.apache.dubbo.metrics.metadata.type.ApplicationType;
-import org.apache.dubbo.metrics.metadata.type.ServiceType;
 import org.apache.dubbo.metrics.model.MetricsCategory;
 import org.apache.dubbo.metrics.model.sample.MetricSample;
 import org.apache.dubbo.rpc.model.ApplicationModel;
@@ -49,23 +47,21 @@ import static 
org.apache.dubbo.metrics.metadata.MetadataMetricsConstants.OP_TYPE
  * Registry implementation of {@link MetricsCollector}
  */
 @Activate
-public class MetadataMetricsCollector implements 
ApplicationMetricsCollector<ApplicationType, MetadataEvent> {
+public class MetadataMetricsCollector extends 
CombMetricsCollector<TimeCounterEvent> {
 
     private Boolean collectEnabled = null;
-    private final BaseStatComposite stats;
-    private final MetricsEventMulticaster metadataEventMulticaster;
     private final ApplicationModel applicationModel;
 
     public MetadataMetricsCollector(ApplicationModel applicationModel) {
-        this.stats = new BaseStatComposite() {
+        super(new BaseStatComposite() {
             @Override
             protected void init(ApplicationStatComposite 
applicationStatComposite, ServiceStatComposite serviceStatComposite, 
RtStatComposite rtStatComposite) {
-                
applicationStatComposite.init(MetadataMetricsConstants.appKeys);
-                
serviceStatComposite.init(MetadataMetricsConstants.serviceKeys);
+                
applicationStatComposite.init(MetadataMetricsConstants.APP_LEVEL_KEYS);
+                
serviceStatComposite.init(MetadataMetricsConstants.SERVICE_LEVEL_KEYS);
                 rtStatComposite.init(OP_TYPE_PUSH, OP_TYPE_SUBSCRIBE, 
OP_TYPE_STORE_PROVIDER_INTERFACE);
             }
-        };
-        this.metadataEventMulticaster = new MetadataMetricsEventMulticaster();
+        });
+        super.setEventMulticaster(new MetadataMetricsEventMulticaster(this));
         this.applicationModel = applicationModel;
     }
 
@@ -84,31 +80,13 @@ public class MetadataMetricsCollector implements 
ApplicationMetricsCollector<App
         return Optional.ofNullable(collectEnabled).orElse(true);
     }
 
-    @Override
-    public void increment(String applicationName, ApplicationType 
registryType) {
-        this.stats.incrementApp(registryType.getMetricsKey(), 
applicationName,1);
-    }
-
-    public void incrementServiceKey(String applicationName, String serviceKey, 
ServiceType registryType, int size) {
-        this.stats.incrementServiceKey(registryType.getMetricsKey(), 
applicationName, serviceKey, size);
-    }
-
-    @Override
-    public void addApplicationRT(String applicationName, String 
registryOpType, Long responseTime) {
-        stats.calcApplicationRt(applicationName, registryOpType, responseTime);
-    }
-
-    public void addServiceKeyRT(String applicationName, String serviceKey, 
String registryOpType, Long responseTime) {
-        stats.calcServiceKeyRt(applicationName, serviceKey, registryOpType, 
responseTime);
-    }
-
     @Override
     public List<MetricSample> collect() {
         List<MetricSample> list = new ArrayList<>();
         if (!isCollectEnabled()) {
             return list;
         }
-        list.addAll(stats.export(MetricsCategory.METADATA));
+        list.addAll(super.export(MetricsCategory.METADATA));
         return list;
     }
 
@@ -117,19 +95,4 @@ public class MetadataMetricsCollector implements 
ApplicationMetricsCollector<App
         return event instanceof MetadataEvent;
     }
 
-    @Override
-    public void onEvent(MetadataEvent event) {
-        metadataEventMulticaster.publishEvent(event);
-    }
-
-
-    @Override
-    public void onEventFinish(MetadataEvent event) {
-        metadataEventMulticaster.publishFinishEvent(event);
-    }
-
-    @Override
-    public void onEventError(MetadataEvent event) {
-        metadataEventMulticaster.publishErrorEvent(event);
-    }
 }
diff --git 
a/dubbo-metrics/dubbo-metrics-metadata/src/main/java/org/apache/dubbo/metrics/metadata/event/MetadataEvent.java
 
b/dubbo-metrics/dubbo-metrics-metadata/src/main/java/org/apache/dubbo/metrics/metadata/event/MetadataEvent.java
index b4b279457b..4e1937197f 100644
--- 
a/dubbo-metrics/dubbo-metrics-metadata/src/main/java/org/apache/dubbo/metrics/metadata/event/MetadataEvent.java
+++ 
b/dubbo-metrics/dubbo-metrics-metadata/src/main/java/org/apache/dubbo/metrics/metadata/event/MetadataEvent.java
@@ -19,68 +19,47 @@ package org.apache.dubbo.metrics.metadata.event;
 
 import org.apache.dubbo.common.beans.factory.ScopeBeanFactory;
 import org.apache.dubbo.metrics.event.TimeCounterEvent;
-import org.apache.dubbo.metrics.exception.MetricsNeverHappenException;
 import org.apache.dubbo.metrics.metadata.collector.MetadataMetricsCollector;
-import org.apache.dubbo.metrics.metadata.type.ApplicationType;
-import org.apache.dubbo.metrics.metadata.type.ServiceType;
 import org.apache.dubbo.metrics.model.key.MetricsLevel;
 import org.apache.dubbo.metrics.model.key.TypeWrapper;
 import org.apache.dubbo.rpc.model.ApplicationModel;
 
-import java.util.HashMap;
-import java.util.Map;
-
 import static org.apache.dubbo.metrics.MetricsConstants.ATTACHMENT_KEY_SERVICE;
+import static 
org.apache.dubbo.metrics.model.key.MetricsKey.METADATA_PUSH_METRIC_NUM;
+import static 
org.apache.dubbo.metrics.model.key.MetricsKey.METADATA_PUSH_METRIC_NUM_FAILED;
+import static 
org.apache.dubbo.metrics.model.key.MetricsKey.METADATA_PUSH_METRIC_NUM_SUCCEED;
+import static 
org.apache.dubbo.metrics.model.key.MetricsKey.METADATA_SUBSCRIBE_METRIC_NUM;
+import static 
org.apache.dubbo.metrics.model.key.MetricsKey.METADATA_SUBSCRIBE_METRIC_NUM_FAILED;
+import static 
org.apache.dubbo.metrics.model.key.MetricsKey.METADATA_SUBSCRIBE_METRIC_NUM_SUCCEED;
+import static 
org.apache.dubbo.metrics.model.key.MetricsKey.STORE_PROVIDER_METADATA;
+import static 
org.apache.dubbo.metrics.model.key.MetricsKey.STORE_PROVIDER_METADATA_FAILED;
+import static 
org.apache.dubbo.metrics.model.key.MetricsKey.STORE_PROVIDER_METADATA_SUCCEED;
 
 /**
  * Registry related events
  */
 public class MetadataEvent extends TimeCounterEvent {
-    private final MetadataMetricsCollector collector;
-    private final Map<String, Object> attachment = new HashMap<>(8);
-
     public MetadataEvent(ApplicationModel applicationModel, TypeWrapper 
typeWrapper) {
         super(applicationModel);
         super.typeWrapper = typeWrapper;
         ScopeBeanFactory beanFactory = applicationModel.getBeanFactory();
-        if (beanFactory.isDestroyed()) {
-            this.collector = null;
-        } else {
-            this.collector = 
beanFactory.getBean(MetadataMetricsCollector.class);
-            super.setAvailable(this.collector != null && 
collector.isCollectEnabled());
-        }
-    }
-
-    @SuppressWarnings("unchecked")
-    public <T> T getAttachmentValue(String key) {
-        if (!attachment.containsKey(key)) {
-            throw new MetricsNeverHappenException("Attachment key [" + key + 
"] not found");
+        MetadataMetricsCollector collector;
+        if (!beanFactory.isDestroyed()) {
+            collector = beanFactory.getBean(MetadataMetricsCollector.class);
+            super.setAvailable(collector != null && 
collector.isCollectEnabled());
         }
-        return (T) attachment.get(key);
-    }
-
-    public void putAttachment(String key, Object value) {
-        attachment.put(key, value);
-    }
-
-    public ApplicationModel getSource() {
-        return source;
-    }
-
-    public MetadataMetricsCollector getCollector() {
-        return collector;
     }
 
     public static MetadataEvent toPushEvent(ApplicationModel applicationModel) 
{
-        return new MetadataEvent(applicationModel, new 
TypeWrapper(MetricsLevel.APP, ApplicationType.P_TOTAL, 
ApplicationType.P_SUCCEED, ApplicationType.P_FAILED));
+        return new MetadataEvent(applicationModel, new 
TypeWrapper(MetricsLevel.APP, METADATA_PUSH_METRIC_NUM, 
METADATA_PUSH_METRIC_NUM_SUCCEED, METADATA_PUSH_METRIC_NUM_FAILED));
     }
 
     public static MetadataEvent toSubscribeEvent(ApplicationModel 
applicationModel) {
-        return new MetadataEvent(applicationModel, new 
TypeWrapper(MetricsLevel.APP, ApplicationType.S_TOTAL, 
ApplicationType.S_SUCCEED, ApplicationType.S_FAILED));
+        return new MetadataEvent(applicationModel, new 
TypeWrapper(MetricsLevel.APP, METADATA_SUBSCRIBE_METRIC_NUM, 
METADATA_SUBSCRIBE_METRIC_NUM_SUCCEED, METADATA_SUBSCRIBE_METRIC_NUM_FAILED));
     }
 
     public static MetadataEvent toServiceSubscribeEvent(ApplicationModel 
applicationModel, String serviceKey) {
-        MetadataEvent metadataEvent = new MetadataEvent(applicationModel, new 
TypeWrapper(MetricsLevel.APP, ServiceType.S_P_TOTAL, ServiceType.S_P_SUCCEED, 
ServiceType.S_P_FAILED));
+        MetadataEvent metadataEvent = new MetadataEvent(applicationModel, new 
TypeWrapper(MetricsLevel.APP, STORE_PROVIDER_METADATA, 
STORE_PROVIDER_METADATA_SUCCEED, STORE_PROVIDER_METADATA_FAILED));
         metadataEvent.putAttachment(ATTACHMENT_KEY_SERVICE, serviceKey);
         return metadataEvent;
     }
diff --git 
a/dubbo-metrics/dubbo-metrics-metadata/src/main/java/org/apache/dubbo/metrics/metadata/event/MetadataListener.java
 
b/dubbo-metrics/dubbo-metrics-metadata/src/main/java/org/apache/dubbo/metrics/metadata/event/MetadataListener.java
deleted file mode 100644
index 68a8574fe7..0000000000
--- 
a/dubbo-metrics/dubbo-metrics-metadata/src/main/java/org/apache/dubbo/metrics/metadata/event/MetadataListener.java
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.dubbo.metrics.metadata.event;
-
-import org.apache.dubbo.metrics.event.MetricsEvent;
-import org.apache.dubbo.metrics.listener.MetricsLifeListener;
-
-import java.util.function.BiConsumer;
-
-public abstract class MetadataListener implements 
MetricsLifeListener<MetadataEvent> {
-
-    private final Object enumType;
-
-    public MetadataListener(Object enumType) {
-        this.enumType = enumType;
-    }
-
-    @Override
-    public boolean isSupport(MetricsEvent event) {
-        return event.isAvailable() && event.isAssignableFrom(enumType);
-    }
-
-    static <T> MetadataListener onEvent(T enumType, BiConsumer<MetadataEvent, 
T> postFunc) {
-
-        return new MetadataListener(enumType) {
-            @Override
-            public void onEvent(MetadataEvent event) {
-                postFunc.accept(event, enumType);
-            }
-        };
-    }
-
-    static <T> MetadataListener onFinish(T enumType, BiConsumer<MetadataEvent, 
T> finishFunc) {
-
-        return new MetadataListener(enumType) {
-            @Override
-            public void onEventFinish(MetadataEvent event) {
-                finishFunc.accept(event, enumType);
-            }
-        };
-    }
-
-    static <T> MetadataListener onError(T enumType, BiConsumer<MetadataEvent, 
T> errorFunc) {
-
-        return new MetadataListener(enumType) {
-            @Override
-            public void onEventError(MetadataEvent event) {
-                errorFunc.accept(event, enumType);
-            }
-        };
-    }
-}
diff --git 
a/dubbo-metrics/dubbo-metrics-metadata/src/main/java/org/apache/dubbo/metrics/metadata/event/MetadataMetricsEventMulticaster.java
 
b/dubbo-metrics/dubbo-metrics-metadata/src/main/java/org/apache/dubbo/metrics/metadata/event/MetadataMetricsEventMulticaster.java
index 2dd84a21d3..89a2af4ffa 100644
--- 
a/dubbo-metrics/dubbo-metrics-metadata/src/main/java/org/apache/dubbo/metrics/metadata/event/MetadataMetricsEventMulticaster.java
+++ 
b/dubbo-metrics/dubbo-metrics-metadata/src/main/java/org/apache/dubbo/metrics/metadata/event/MetadataMetricsEventMulticaster.java
@@ -17,10 +17,16 @@
 
 package org.apache.dubbo.metrics.metadata.event;
 
-import org.apache.dubbo.metrics.MetricsConstants;
 import org.apache.dubbo.metrics.event.SimpleMetricsEventMulticaster;
-import org.apache.dubbo.metrics.metadata.type.ApplicationType;
-import org.apache.dubbo.metrics.metadata.type.ServiceType;
+import org.apache.dubbo.metrics.listener.MetricsApplicationListener;
+import org.apache.dubbo.metrics.listener.MetricsServiceListener;
+import org.apache.dubbo.metrics.metadata.collector.MetadataMetricsCollector;
+import org.apache.dubbo.metrics.model.key.CategoryOverall;
+import org.apache.dubbo.metrics.model.key.MetricsCat;
+import org.apache.dubbo.metrics.model.key.MetricsKey;
+
+import java.util.Arrays;
+import java.util.List;
 
 import static 
org.apache.dubbo.metrics.metadata.MetadataMetricsConstants.OP_TYPE_PUSH;
 import static 
org.apache.dubbo.metrics.metadata.MetadataMetricsConstants.OP_TYPE_STORE_PROVIDER_INTERFACE;
@@ -28,60 +34,47 @@ import static 
org.apache.dubbo.metrics.metadata.MetadataMetricsConstants.OP_TYPE
 
 public final class MetadataMetricsEventMulticaster extends 
SimpleMetricsEventMulticaster {
 
-    public MetadataMetricsEventMulticaster() {
-        // MetricsPushListener
-        super.addListener(onPostEventBuild(ApplicationType.P_TOTAL));
-        super.addListener(onFinishEventBuild(ApplicationType.P_SUCCEED, 
OP_TYPE_PUSH.getType()));
-        super.addListener(onErrorEventBuild(ApplicationType.P_FAILED, 
OP_TYPE_PUSH.getType()));
+    public MetadataMetricsEventMulticaster(MetadataMetricsCollector collector) 
{
 
-        // MetricsSubscribeListener
-        super.addListener(onPostEventBuild(ApplicationType.S_TOTAL));
-        super.addListener(onFinishEventBuild(ApplicationType.S_SUCCEED, 
OP_TYPE_SUBSCRIBE.getType()));
-        super.addListener(onErrorEventBuild(ApplicationType.S_FAILED, 
OP_TYPE_SUBSCRIBE.getType()));
-
-        // StoreProviderMetadataListener
-        super.addListener(MetadataListener.onEvent(ServiceType.S_P_TOTAL,
-            this::incrServiceKey
-        ));
-        super.addListener(MetadataListener.onFinish(ServiceType.S_P_SUCCEED,
-            this::incrAndRt
-        ));
-        super.addListener(MetadataListener.onError(ServiceType.S_P_FAILED,
-            this::incrAndRt
-        ));
+        CategorySet.ALL.forEach(categorySet ->
+        {
+            
super.addListener(categorySet.getPost().getEventFunc().apply(collector));
+            if (categorySet.getFinish() != null) {
+                
super.addListener(categorySet.getFinish().getEventFunc().apply(collector));
+            }
+            if (categorySet.getError() != null) {
+                
super.addListener(categorySet.getError().getEventFunc().apply(collector));
+            }
+        });
 
-    }
 
-    private void incrAndRt(MetadataEvent event, ServiceType type) {
-        incrServiceKey(event, type);
-        
event.getCollector().addServiceKeyRT(event.getSource().getApplicationName(), 
event.getAttachmentValue(MetricsConstants.ATTACHMENT_KEY_SERVICE), 
OP_TYPE_STORE_PROVIDER_INTERFACE.getType(), event.getTimePair().calc());
     }
 
-    private void incrServiceKey(MetadataEvent event, ServiceType type) {
-        
event.getCollector().incrementServiceKey(event.getSource().getApplicationName(),
 event.getAttachmentValue(MetricsConstants.ATTACHMENT_KEY_SERVICE), type, 1);
+    interface CategorySet {
+        CategoryOverall APPLICATION_PUSH = new CategoryOverall(OP_TYPE_PUSH, 
MCat.APPLICATION_PUSH_POST, MCat.APPLICATION_PUSH_FINISH, 
MCat.APPLICATION_PUSH_ERROR);
+        CategoryOverall APPLICATION_SUBSCRIBE = new 
CategoryOverall(OP_TYPE_SUBSCRIBE, MCat.APPLICATION_SUBSCRIBE_POST, 
MCat.APPLICATION_SUBSCRIBE_FINISH, MCat.APPLICATION_SUBSCRIBE_ERROR);
+        CategoryOverall SERVICE_SUBSCRIBE = new 
CategoryOverall(OP_TYPE_STORE_PROVIDER_INTERFACE, MCat.SERVICE_SUBSCRIBE_POST, 
MCat.SERVICE_SUBSCRIBE_FINISH, MCat.SERVICE_SUBSCRIBE_ERROR);
+
+        List<CategoryOverall> ALL = Arrays.asList(APPLICATION_PUSH, 
APPLICATION_SUBSCRIBE, SERVICE_SUBSCRIBE);
     }
 
+    interface MCat {
+        // MetricsPushListener
+        MetricsCat APPLICATION_PUSH_POST = new 
MetricsCat(MetricsKey.METADATA_PUSH_METRIC_NUM, 
MetricsApplicationListener::onPostEventBuild);
+        MetricsCat APPLICATION_PUSH_FINISH = new 
MetricsCat(MetricsKey.METADATA_PUSH_METRIC_NUM_SUCCEED, 
MetricsApplicationListener::onFinishEventBuild);
+        MetricsCat APPLICATION_PUSH_ERROR = new 
MetricsCat(MetricsKey.METADATA_PUSH_METRIC_NUM_FAILED, 
MetricsApplicationListener::onErrorEventBuild);
+
+        // MetricsSubscribeListener
+        MetricsCat APPLICATION_SUBSCRIBE_POST = new 
MetricsCat(MetricsKey.METADATA_SUBSCRIBE_METRIC_NUM, 
MetricsApplicationListener::onPostEventBuild);
+        MetricsCat APPLICATION_SUBSCRIBE_FINISH = new 
MetricsCat(MetricsKey.METADATA_SUBSCRIBE_METRIC_NUM_SUCCEED, 
MetricsApplicationListener::onFinishEventBuild);
+        MetricsCat APPLICATION_SUBSCRIBE_ERROR = new 
MetricsCat(MetricsKey.METADATA_SUBSCRIBE_METRIC_NUM_FAILED, 
MetricsApplicationListener::onErrorEventBuild);
 
-    private MetadataListener onPostEventBuild(ApplicationType applicationType) 
{
-        return MetadataListener.onEvent(applicationType,
-            (event, type) -> 
event.getCollector().increment(event.getSource().getApplicationName(), type)
-        );
-    }
+        // MetricsSubscribeListener
+        MetricsCat SERVICE_SUBSCRIBE_POST = new 
MetricsCat(MetricsKey.STORE_PROVIDER_METADATA, 
MetricsServiceListener::onPostEventBuild);
+        MetricsCat SERVICE_SUBSCRIBE_FINISH = new 
MetricsCat(MetricsKey.STORE_PROVIDER_METADATA_SUCCEED, 
MetricsServiceListener::onFinishEventBuild);
+        MetricsCat SERVICE_SUBSCRIBE_ERROR = new 
MetricsCat(MetricsKey.STORE_PROVIDER_METADATA_FAILED, 
MetricsServiceListener::onErrorEventBuild);
 
-    private MetadataListener onFinishEventBuild(ApplicationType 
applicationType, String registryOpType) {
-        return MetadataListener.onFinish(applicationType,
-            (event, type) -> incrAndRt(event, applicationType, registryOpType)
-        );
     }
 
-    private MetadataListener onErrorEventBuild(ApplicationType 
applicationType, String registryOpType) {
-        return MetadataListener.onError(applicationType,
-            (event, type) -> incrAndRt(event, applicationType, registryOpType)
-        );
-    }
 
-    private void incrAndRt(MetadataEvent event, ApplicationType 
applicationType, String registryOpType) {
-        event.getCollector().increment(event.getSource().getApplicationName(), 
applicationType);
-        
event.getCollector().addApplicationRT(event.getSource().getApplicationName(), 
registryOpType, event.getTimePair().calc());
-    }
 }
diff --git 
a/dubbo-metrics/dubbo-metrics-metadata/src/main/java/org/apache/dubbo/metrics/metadata/type/ApplicationType.java
 
b/dubbo-metrics/dubbo-metrics-metadata/src/main/java/org/apache/dubbo/metrics/metadata/type/ApplicationType.java
deleted file mode 100644
index ca00398738..0000000000
--- 
a/dubbo-metrics/dubbo-metrics-metadata/src/main/java/org/apache/dubbo/metrics/metadata/type/ApplicationType.java
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.dubbo.metrics.metadata.type;
-
-
-import org.apache.dubbo.metrics.model.key.MetricsKey;
-
-public enum ApplicationType {
-    P_TOTAL(MetricsKey.METADATA_PUSH_METRIC_NUM),
-    P_SUCCEED(MetricsKey.METADATA_PUSH_METRIC_NUM_SUCCEED),
-    P_FAILED(MetricsKey.METADATA_PUSH_METRIC_NUM_FAILED),
-
-    S_TOTAL(MetricsKey.METADATA_SUBSCRIBE_METRIC_NUM),
-    S_SUCCEED(MetricsKey.METADATA_SUBSCRIBE_METRIC_NUM_SUCCEED),
-    S_FAILED(MetricsKey.METADATA_SUBSCRIBE_METRIC_NUM_FAILED),
-
-    ;
-    private final MetricsKey metricsKey;
-    private final boolean isIncrement;
-
-    ApplicationType(MetricsKey metricsKey) {
-        this(metricsKey, true);
-    }
-
-    ApplicationType(MetricsKey metricsKey, boolean isIncrement) {
-        this.metricsKey = metricsKey;
-        this.isIncrement = isIncrement;
-    }
-
-    public MetricsKey getMetricsKey() {
-        return metricsKey;
-    }
-
-    public boolean isIncrement() {
-        return isIncrement;
-    }
-}
diff --git 
a/dubbo-metrics/dubbo-metrics-metadata/src/test/java/org/apache/dubbo/metrics/metadata/MetadataStatCompositeTest.java
 
b/dubbo-metrics/dubbo-metrics-metadata/src/test/java/org/apache/dubbo/metrics/metadata/MetadataStatCompositeTest.java
index 9f8cd91c51..52b7741a26 100644
--- 
a/dubbo-metrics/dubbo-metrics-metadata/src/test/java/org/apache/dubbo/metrics/metadata/MetadataStatCompositeTest.java
+++ 
b/dubbo-metrics/dubbo-metrics-metadata/src/test/java/org/apache/dubbo/metrics/metadata/MetadataStatCompositeTest.java
@@ -21,8 +21,8 @@ import org.apache.dubbo.metrics.data.ApplicationStatComposite;
 import org.apache.dubbo.metrics.data.BaseStatComposite;
 import org.apache.dubbo.metrics.data.RtStatComposite;
 import org.apache.dubbo.metrics.data.ServiceStatComposite;
-import org.apache.dubbo.metrics.metadata.type.ApplicationType;
 import org.apache.dubbo.metrics.model.container.LongContainer;
+import org.apache.dubbo.metrics.model.key.MetricsKey;
 import org.junit.jupiter.api.Assertions;
 import org.junit.jupiter.api.Test;
 
@@ -42,15 +42,16 @@ public class MetadataStatCompositeTest {
         @Override
         protected void init(ApplicationStatComposite applicationStatComposite, 
ServiceStatComposite
             serviceStatComposite, RtStatComposite rtStatComposite) {
-            applicationStatComposite.init(MetadataMetricsConstants.appKeys);
-            serviceStatComposite.init(MetadataMetricsConstants.serviceKeys);
+            
applicationStatComposite.init(MetadataMetricsConstants.APP_LEVEL_KEYS);
+            
serviceStatComposite.init(MetadataMetricsConstants.SERVICE_LEVEL_KEYS);
             rtStatComposite.init(OP_TYPE_PUSH, OP_TYPE_SUBSCRIBE, 
OP_TYPE_STORE_PROVIDER_INTERFACE);
         }
     };
 
     @Test
     void testInit() {
-        
Assertions.assertEquals(statComposite.getApplicationStatComposite().getApplicationNumStats().size(),
 ApplicationType.values().length);
+        
Assertions.assertEquals(statComposite.getApplicationStatComposite().getApplicationNumStats().size(),
 MetadataMetricsConstants.APP_LEVEL_KEYS.size());
+
         //(rt)5 * (push,subscribe,service)3
         Assertions.assertEquals(5 * 3, 
statComposite.getRtStatComposite().getRtStats().size());
         
statComposite.getApplicationStatComposite().getApplicationNumStats().values().forEach((v
 ->
@@ -65,8 +66,9 @@ public class MetadataStatCompositeTest {
 
     @Test
     void testIncrement() {
-        statComposite.incrementApp(ApplicationType.P_TOTAL.getMetricsKey(), 
applicationName, 1);
-        Assertions.assertEquals(1L, 
statComposite.getApplicationStatComposite().getApplicationNumStats().get(ApplicationType.P_TOTAL.getMetricsKey()).get(applicationName).get());
+        statComposite.incrementApp(MetricsKey.METADATA_PUSH_METRIC_NUM, 
applicationName, 1);
+
+        Assertions.assertEquals(1L, 
statComposite.getApplicationStatComposite().getApplicationNumStats().get(MetricsKey.METADATA_PUSH_METRIC_NUM).get(applicationName).get());
     }
 
     @Test
diff --git 
a/dubbo-metrics/dubbo-metrics-registry/src/main/java/org/apache/dubbo/metrics/registry/RegistryMetricsConstants.java
 
b/dubbo-metrics/dubbo-metrics-registry/src/main/java/org/apache/dubbo/metrics/registry/RegistryMetricsConstants.java
index 28b012076a..58d46c2294 100644
--- 
a/dubbo-metrics/dubbo-metrics-registry/src/main/java/org/apache/dubbo/metrics/registry/RegistryMetricsConstants.java
+++ 
b/dubbo-metrics/dubbo-metrics-registry/src/main/java/org/apache/dubbo/metrics/registry/RegistryMetricsConstants.java
@@ -20,25 +20,49 @@ package org.apache.dubbo.metrics.registry;
 import org.apache.dubbo.metrics.model.key.MetricsKey;
 import org.apache.dubbo.metrics.model.key.MetricsLevel;
 import org.apache.dubbo.metrics.model.key.MetricsPlaceType;
-import org.apache.dubbo.metrics.registry.event.type.ApplicationType;
-import org.apache.dubbo.metrics.registry.event.type.ServiceType;
 
 import java.util.Arrays;
 import java.util.List;
-import java.util.stream.Collectors;
+
+import static 
org.apache.dubbo.metrics.model.key.MetricsKey.DIRECTORY_METRIC_NUM_ALL;
+import static 
org.apache.dubbo.metrics.model.key.MetricsKey.DIRECTORY_METRIC_NUM_DISABLE;
+import static 
org.apache.dubbo.metrics.model.key.MetricsKey.DIRECTORY_METRIC_NUM_TO_RECONNECT;
+import static 
org.apache.dubbo.metrics.model.key.MetricsKey.DIRECTORY_METRIC_NUM_VALID;
+import static 
org.apache.dubbo.metrics.model.key.MetricsKey.NOTIFY_METRIC_NUM_LAST;
+import static 
org.apache.dubbo.metrics.model.key.MetricsKey.NOTIFY_METRIC_REQUESTS;
+import static 
org.apache.dubbo.metrics.model.key.MetricsKey.REGISTER_METRIC_REQUESTS;
+import static 
org.apache.dubbo.metrics.model.key.MetricsKey.REGISTER_METRIC_REQUESTS_FAILED;
+import static 
org.apache.dubbo.metrics.model.key.MetricsKey.REGISTER_METRIC_REQUESTS_SUCCEED;
+import static 
org.apache.dubbo.metrics.model.key.MetricsKey.SERVICE_REGISTER_METRIC_REQUESTS;
+import static 
org.apache.dubbo.metrics.model.key.MetricsKey.SERVICE_REGISTER_METRIC_REQUESTS_FAILED;
+import static 
org.apache.dubbo.metrics.model.key.MetricsKey.SERVICE_REGISTER_METRIC_REQUESTS_SUCCEED;
+import static 
org.apache.dubbo.metrics.model.key.MetricsKey.SERVICE_SUBSCRIBE_METRIC_NUM;
+import static 
org.apache.dubbo.metrics.model.key.MetricsKey.SERVICE_SUBSCRIBE_METRIC_NUM_FAILED;
+import static 
org.apache.dubbo.metrics.model.key.MetricsKey.SERVICE_SUBSCRIBE_METRIC_NUM_SUCCEED;
+import static 
org.apache.dubbo.metrics.model.key.MetricsKey.SUBSCRIBE_METRIC_NUM;
+import static 
org.apache.dubbo.metrics.model.key.MetricsKey.SUBSCRIBE_METRIC_NUM_FAILED;
+import static 
org.apache.dubbo.metrics.model.key.MetricsKey.SUBSCRIBE_METRIC_NUM_SUCCEED;
 
 public interface RegistryMetricsConstants {
 
     MetricsPlaceType OP_TYPE_REGISTER = MetricsPlaceType.of("register", 
MetricsLevel.APP);
     MetricsPlaceType OP_TYPE_SUBSCRIBE = MetricsPlaceType.of("subscribe", 
MetricsLevel.APP);
     MetricsPlaceType OP_TYPE_NOTIFY = MetricsPlaceType.of("notify", 
MetricsLevel.APP);
+    MetricsPlaceType OP_TYPE_DIRECTORY = MetricsPlaceType.of("directory", 
MetricsLevel.APP);
     MetricsPlaceType OP_TYPE_REGISTER_SERVICE = 
MetricsPlaceType.of("register.service", MetricsLevel.SERVICE);
     MetricsPlaceType OP_TYPE_SUBSCRIBE_SERVICE = 
MetricsPlaceType.of("subscribe.service", MetricsLevel.SERVICE);
 
     // App-level
-    List<MetricsKey> appKeys = 
Arrays.stream(ApplicationType.values()).map(ApplicationType::getMetricsKey).collect(Collectors.toList());
+    List<MetricsKey> APP_LEVEL_KEYS = Arrays.asList(REGISTER_METRIC_REQUESTS, 
REGISTER_METRIC_REQUESTS_SUCCEED, REGISTER_METRIC_REQUESTS_FAILED,
+        SUBSCRIBE_METRIC_NUM, SUBSCRIBE_METRIC_NUM_SUCCEED, 
SUBSCRIBE_METRIC_NUM_FAILED,
+        NOTIFY_METRIC_REQUESTS);
 
     // Service-level
-    List<MetricsKey> serviceKeys = 
Arrays.stream(ServiceType.values()).map(ServiceType::getMetricsKey).collect(Collectors.toList());
+    List<MetricsKey> SERVICE_LEVEL_KEYS = Arrays.asList(NOTIFY_METRIC_NUM_LAST,
+        SERVICE_REGISTER_METRIC_REQUESTS, 
SERVICE_REGISTER_METRIC_REQUESTS_SUCCEED, 
SERVICE_REGISTER_METRIC_REQUESTS_FAILED,
+        SERVICE_SUBSCRIBE_METRIC_NUM, SERVICE_SUBSCRIBE_METRIC_NUM_SUCCEED, 
SERVICE_SUBSCRIBE_METRIC_NUM_FAILED,
+        DIRECTORY_METRIC_NUM_VALID, DIRECTORY_METRIC_NUM_TO_RECONNECT, 
DIRECTORY_METRIC_NUM_DISABLE, DIRECTORY_METRIC_NUM_ALL
+    );
+
 
 }
diff --git 
a/dubbo-metrics/dubbo-metrics-registry/src/main/java/org/apache/dubbo/metrics/registry/collector/RegistryMetricsCollector.java
 
b/dubbo-metrics/dubbo-metrics-registry/src/main/java/org/apache/dubbo/metrics/registry/collector/RegistryMetricsCollector.java
index f55d580c09..6f79d83bb0 100644
--- 
a/dubbo-metrics/dubbo-metrics-registry/src/main/java/org/apache/dubbo/metrics/registry/collector/RegistryMetricsCollector.java
+++ 
b/dubbo-metrics/dubbo-metrics-registry/src/main/java/org/apache/dubbo/metrics/registry/collector/RegistryMetricsCollector.java
@@ -19,26 +19,23 @@ package org.apache.dubbo.metrics.registry.collector;
 
 import org.apache.dubbo.common.extension.Activate;
 import org.apache.dubbo.config.context.ConfigManager;
-import org.apache.dubbo.metrics.collector.ApplicationMetricsCollector;
+import org.apache.dubbo.metrics.collector.CombMetricsCollector;
 import org.apache.dubbo.metrics.collector.MetricsCollector;
 import org.apache.dubbo.metrics.data.ApplicationStatComposite;
 import org.apache.dubbo.metrics.data.BaseStatComposite;
 import org.apache.dubbo.metrics.data.RtStatComposite;
 import org.apache.dubbo.metrics.data.ServiceStatComposite;
 import org.apache.dubbo.metrics.event.MetricsEvent;
-import org.apache.dubbo.metrics.event.MetricsEventMulticaster;
+import org.apache.dubbo.metrics.event.TimeCounterEvent;
 import org.apache.dubbo.metrics.model.MetricsCategory;
 import org.apache.dubbo.metrics.model.sample.MetricSample;
 import org.apache.dubbo.metrics.registry.RegistryMetricsConstants;
 import org.apache.dubbo.metrics.registry.event.RegistryEvent;
 import org.apache.dubbo.metrics.registry.event.RegistryMetricsEventMulticaster;
-import org.apache.dubbo.metrics.registry.event.type.ApplicationType;
-import org.apache.dubbo.metrics.registry.event.type.ServiceType;
 import org.apache.dubbo.rpc.model.ApplicationModel;
 
 import java.util.ArrayList;
 import java.util.List;
-import java.util.Map;
 import java.util.Optional;
 
 import static 
org.apache.dubbo.metrics.registry.RegistryMetricsConstants.OP_TYPE_NOTIFY;
@@ -52,23 +49,21 @@ import static 
org.apache.dubbo.metrics.registry.RegistryMetricsConstants.OP_TYPE
  * Registry implementation of {@link MetricsCollector}
  */
 @Activate
-public class RegistryMetricsCollector implements 
ApplicationMetricsCollector<ApplicationType, RegistryEvent> {
+public class RegistryMetricsCollector extends 
CombMetricsCollector<TimeCounterEvent> {
 
     private Boolean collectEnabled = null;
-    private final BaseStatComposite stats;
-    private final MetricsEventMulticaster registryMulticaster;
     private final ApplicationModel applicationModel;
 
     public RegistryMetricsCollector(ApplicationModel applicationModel) {
-        this.stats = new BaseStatComposite() {
+        super(new BaseStatComposite() {
             @Override
             protected void init(ApplicationStatComposite 
applicationStatComposite, ServiceStatComposite serviceStatComposite, 
RtStatComposite rtStatComposite) {
-                
applicationStatComposite.init(RegistryMetricsConstants.appKeys);
-                
serviceStatComposite.init(RegistryMetricsConstants.serviceKeys);
+                
applicationStatComposite.init(RegistryMetricsConstants.APP_LEVEL_KEYS);
+                
serviceStatComposite.init(RegistryMetricsConstants.SERVICE_LEVEL_KEYS);
                 rtStatComposite.init(OP_TYPE_REGISTER, OP_TYPE_SUBSCRIBE, 
OP_TYPE_NOTIFY, OP_TYPE_REGISTER_SERVICE, OP_TYPE_SUBSCRIBE_SERVICE);
             }
-        };
-        this.registryMulticaster = new RegistryMetricsEventMulticaster();
+        });
+        super.setEventMulticaster(new RegistryMetricsEventMulticaster(this));
         this.applicationModel = applicationModel;
     }
 
@@ -87,32 +82,6 @@ public class RegistryMetricsCollector implements 
ApplicationMetricsCollector<App
         return Optional.ofNullable(collectEnabled).orElse(true);
     }
 
-    public void setNum(ServiceType registryType, String applicationName, 
Map<String, Integer> lastNumMap) {
-        lastNumMap.forEach((serviceKey, num) ->
-            this.stats.setServiceKey(registryType.getMetricsKey(), 
applicationName, serviceKey, num));
-    }
-
-    public void setNum(ApplicationType registryType, String applicationName, 
Integer num) {
-        this.stats.setApplicationKey(registryType.getMetricsKey(), 
applicationName, num);
-    }
-
-    @Override
-    public void increment(String applicationName, ApplicationType 
registryType) {
-        this.stats.incrementApp(registryType.getMetricsKey(), applicationName, 
1);
-    }
-
-    public void incrementServiceKey(String applicationName, String serviceKey, 
ServiceType registryType, int size) {
-        this.stats.incrementServiceKey(registryType.getMetricsKey(), 
applicationName, serviceKey, size);
-    }
-
-    @Override
-    public void addApplicationRT(String applicationName, String 
registryOpType, Long responseTime) {
-        stats.calcApplicationRt(applicationName, registryOpType, responseTime);
-    }
-
-    public void addServiceKeyRT(String applicationName, String serviceKey, 
String registryOpType, Long responseTime) {
-        stats.calcServiceKeyRt(applicationName, serviceKey, registryOpType, 
responseTime);
-    }
 
     @Override
     public List<MetricSample> collect() {
@@ -120,7 +89,7 @@ public class RegistryMetricsCollector implements 
ApplicationMetricsCollector<App
         if (!isCollectEnabled()) {
             return list;
         }
-        list.addAll(stats.export(MetricsCategory.REGISTRY));
+        list.addAll(super.export(MetricsCategory.REGISTRY));
         return list;
     }
 
@@ -129,19 +98,5 @@ public class RegistryMetricsCollector implements 
ApplicationMetricsCollector<App
         return event instanceof RegistryEvent;
     }
 
-    @Override
-    public void onEvent(RegistryEvent event) {
-        registryMulticaster.publishEvent(event);
-    }
-
 
-    @Override
-    public void onEventFinish(RegistryEvent event) {
-        registryMulticaster.publishFinishEvent(event);
-    }
-
-    @Override
-    public void onEventError(RegistryEvent event) {
-        registryMulticaster.publishErrorEvent(event);
-    }
 }
diff --git 
a/dubbo-metrics/dubbo-metrics-registry/src/main/java/org/apache/dubbo/metrics/registry/event/RegistryEvent.java
 
b/dubbo-metrics/dubbo-metrics-registry/src/main/java/org/apache/dubbo/metrics/registry/event/RegistryEvent.java
index e48493a957..351303fc75 100644
--- 
a/dubbo-metrics/dubbo-metrics-registry/src/main/java/org/apache/dubbo/metrics/registry/event/RegistryEvent.java
+++ 
b/dubbo-metrics/dubbo-metrics-registry/src/main/java/org/apache/dubbo/metrics/registry/event/RegistryEvent.java
@@ -19,15 +19,12 @@ package org.apache.dubbo.metrics.registry.event;
 
 import org.apache.dubbo.common.beans.factory.ScopeBeanFactory;
 import org.apache.dubbo.metrics.event.TimeCounterEvent;
-import org.apache.dubbo.metrics.exception.MetricsNeverHappenException;
+import org.apache.dubbo.metrics.model.key.MetricsKey;
 import org.apache.dubbo.metrics.model.key.MetricsLevel;
 import org.apache.dubbo.metrics.model.key.TypeWrapper;
 import org.apache.dubbo.metrics.registry.collector.RegistryMetricsCollector;
-import org.apache.dubbo.metrics.registry.event.type.ApplicationType;
-import org.apache.dubbo.metrics.registry.event.type.ServiceType;
 import org.apache.dubbo.rpc.model.ApplicationModel;
 
-import java.util.HashMap;
 import java.util.Map;
 
 import static 
org.apache.dubbo.metrics.MetricsConstants.ATTACHMENT_DIRECTORY_MAP;
@@ -40,84 +37,29 @@ import static 
org.apache.dubbo.metrics.MetricsConstants.ATTACHMENT_KEY_SIZE;
  * Registry related events
  */
 public class RegistryEvent extends TimeCounterEvent {
-    private final RegistryMetricsCollector collector;
-    private final Map<String, Object> attachment = new HashMap<>(8);
-
     public RegistryEvent(ApplicationModel applicationModel, TypeWrapper 
typeWrapper) {
         super(applicationModel);
         super.typeWrapper = typeWrapper;
         ScopeBeanFactory beanFactory = getSource().getBeanFactory();
-        if (beanFactory.isDestroyed()) {
-            this.collector = null;
-        } else {
-            this.collector = 
beanFactory.getBean(RegistryMetricsCollector.class);
-            super.setAvailable(this.collector != null && 
collector.isCollectEnabled());
-        }
-    }
-
-
-    public ApplicationModel getSource() {
-        return source;
-    }
-
-    public RegistryMetricsCollector getCollector() {
-        return collector;
-    }
-
-    @SuppressWarnings("unchecked")
-    public <T> T getAttachmentValue(String key) {
-        if (!attachment.containsKey(key)) {
-            throw new MetricsNeverHappenException("Attachment key [" + key + 
"] not found");
+        RegistryMetricsCollector collector;
+        if (!beanFactory.isDestroyed()) {
+            collector = beanFactory.getBean(RegistryMetricsCollector.class);
+            super.setAvailable(collector != null && 
collector.isCollectEnabled());
         }
-        return (T) attachment.get(key);
-    }
-
-    public void putAttachment(String key, Object value) {
-        attachment.put(key, value);
     }
 
-    public void setLastNum(ServiceType type) {
-        getCollector().setNum(type, getSource().getApplicationName(), 
getAttachmentValue(ATTACHMENT_KEY_LAST_NUM_MAP));
-    }
-
-    public void addApplicationRT(String opType) {
-        getCollector().addApplicationRT(getSource().getApplicationName(), 
opType, getTimePair().calc());
-
-    }
-
-    public void setNum(ApplicationType type, String attachmentKey) {
-        getCollector().setNum(type, getSource().getApplicationName(), 
getAttachmentValue(attachmentKey));
-    }
-
-    public void incrementServiceKey(ServiceType type, String attServiceKey, 
String attSize) {
-        incrementServiceKey(type, attServiceKey, (int) 
getAttachmentValue(attSize));
-    }
-
-    public void incrementServiceKey(ServiceType type, String attServiceKey, 
int size) {
-        getCollector().incrementServiceKey(getSource().getApplicationName(), 
getAttachmentValue(attServiceKey), type, size);
-    }
-
-    public void addServiceKeyRT(String attServiceKey, String attSize) {
-        getCollector().addServiceKeyRT(getSource().getApplicationName(), 
getAttachmentValue(attServiceKey), attSize, getTimePair().calc());
-    }
-
-    public void increment(ApplicationType type) {
-        getCollector().increment(getSource().getApplicationName(), type);
-    }
-
-
     public static RegistryEvent toRegisterEvent(ApplicationModel 
applicationModel) {
-        return new RegistryEvent(applicationModel, new 
TypeWrapper(MetricsLevel.APP, ApplicationType.R_TOTAL, 
ApplicationType.R_SUCCEED, ApplicationType.R_FAILED));
+        return new RegistryEvent(applicationModel, new 
TypeWrapper(MetricsLevel.APP, MetricsKey.REGISTER_METRIC_REQUESTS, 
MetricsKey.REGISTER_METRIC_REQUESTS_SUCCEED, 
MetricsKey.REGISTER_METRIC_REQUESTS_FAILED));
     }
 
 
     public static RegistryEvent toSubscribeEvent(ApplicationModel 
applicationModel) {
-        return new RegistryEvent(applicationModel, new 
TypeWrapper(MetricsLevel.APP, ApplicationType.S_TOTAL, 
ApplicationType.S_SUCCEED, ApplicationType.S_FAILED));
+        return new RegistryEvent(applicationModel, new 
TypeWrapper(MetricsLevel.APP, MetricsKey.SUBSCRIBE_METRIC_NUM, 
MetricsKey.SUBSCRIBE_METRIC_NUM_SUCCEED, 
MetricsKey.SUBSCRIBE_METRIC_NUM_FAILED));
     }
 
 
     public static RegistryEvent toNotifyEvent(ApplicationModel 
applicationModel) {
-        return new RegistryEvent(applicationModel, new 
TypeWrapper(MetricsLevel.APP, ApplicationType.N_TOTAL, ServiceType.N_LAST_NUM, 
null)) {
+        return new RegistryEvent(applicationModel, new 
TypeWrapper(MetricsLevel.APP, MetricsKey.NOTIFY_METRIC_REQUESTS, 
MetricsKey.NOTIFY_METRIC_NUM_LAST, null)) {
             @Override
             public void customAfterPost(Object postResult) {
                 super.putAttachment(ATTACHMENT_KEY_LAST_NUM_MAP, postResult);
@@ -126,20 +68,20 @@ public class RegistryEvent extends TimeCounterEvent {
     }
 
     public static RegistryEvent toRsEvent(ApplicationModel applicationModel, 
String serviceKey, int size) {
-        RegistryEvent ddEvent = new RegistryEvent(applicationModel, new 
TypeWrapper(MetricsLevel.SERVICE, ServiceType.R_SERVICE_TOTAL, 
ServiceType.R_SERVICE_SUCCEED, ServiceType.R_SERVICE_FAILED));
+        RegistryEvent ddEvent = new RegistryEvent(applicationModel, new 
TypeWrapper(MetricsLevel.SERVICE, MetricsKey.SERVICE_REGISTER_METRIC_REQUESTS, 
MetricsKey.SERVICE_REGISTER_METRIC_REQUESTS_SUCCEED, 
MetricsKey.SERVICE_REGISTER_METRIC_REQUESTS_FAILED));
         ddEvent.putAttachment(ATTACHMENT_KEY_SERVICE, serviceKey);
         ddEvent.putAttachment(ATTACHMENT_KEY_SIZE, size);
         return ddEvent;
     }
 
     public static RegistryEvent toSsEvent(ApplicationModel applicationModel, 
String serviceKey) {
-        RegistryEvent ddEvent = new RegistryEvent(applicationModel, new 
TypeWrapper(MetricsLevel.SERVICE, ServiceType.S_SERVICE_TOTAL, 
ServiceType.S_SERVICE_SUCCEED, ServiceType.S_SERVICE_FAILED));
+        RegistryEvent ddEvent = new RegistryEvent(applicationModel, new 
TypeWrapper(MetricsLevel.SERVICE, MetricsKey.SERVICE_SUBSCRIBE_METRIC_NUM, 
MetricsKey.SERVICE_SUBSCRIBE_METRIC_NUM_SUCCEED, 
MetricsKey.SERVICE_SUBSCRIBE_METRIC_NUM_FAILED));
         ddEvent.putAttachment(ATTACHMENT_KEY_SERVICE, serviceKey);
         return ddEvent;
     }
 
-    public static RegistryEvent refreshDirectoryEvent(ApplicationModel 
applicationModel, Map<ServiceType, Map<String, Integer>> summaryMap) {
-        RegistryEvent registryEvent = new RegistryEvent(applicationModel, new 
TypeWrapper(MetricsLevel.APP, ServiceType.D_VALID, null, null));
+    public static RegistryEvent refreshDirectoryEvent(ApplicationModel 
applicationModel, Map<MetricsKey, Map<String, Integer>> summaryMap) {
+        RegistryEvent registryEvent = new RegistryEvent(applicationModel, new 
TypeWrapper(MetricsLevel.APP, MetricsKey.DIRECTORY_METRIC_NUM_VALID, null, 
null));
         registryEvent.putAttachment(ATTACHMENT_DIRECTORY_MAP, summaryMap);
         return registryEvent;
     }
diff --git 
a/dubbo-metrics/dubbo-metrics-registry/src/main/java/org/apache/dubbo/metrics/registry/event/RegistryListener.java
 
b/dubbo-metrics/dubbo-metrics-registry/src/main/java/org/apache/dubbo/metrics/registry/event/RegistryListener.java
deleted file mode 100644
index beff249b1c..0000000000
--- 
a/dubbo-metrics/dubbo-metrics-registry/src/main/java/org/apache/dubbo/metrics/registry/event/RegistryListener.java
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.dubbo.metrics.registry.event;
-
-import org.apache.dubbo.metrics.event.MetricsEvent;
-import org.apache.dubbo.metrics.listener.MetricsLifeListener;
-
-import java.util.function.BiConsumer;
-
-public abstract class RegistryListener implements 
MetricsLifeListener<RegistryEvent> {
-
-    private final Object enumType;
-
-    public RegistryListener(Object enumType) {
-        this.enumType = enumType;
-    }
-
-    @Override
-    public boolean isSupport(MetricsEvent event) {
-        return event.isAvailable() && event.isAssignableFrom(enumType);
-    }
-
-    static <T> RegistryListener onEvent(T enumType, BiConsumer<RegistryEvent, 
T> postFunc) {
-
-        return new RegistryListener(enumType) {
-            @Override
-            public void onEvent(RegistryEvent event) {
-                postFunc.accept(event, enumType);
-            }
-        };
-    }
-
-    static <T> RegistryListener onFinish(T enumType, BiConsumer<RegistryEvent, 
T> finishFunc) {
-
-        return new RegistryListener(enumType) {
-            @Override
-            public void onEventFinish(RegistryEvent event) {
-                finishFunc.accept(event, enumType);
-            }
-        };
-    }
-
-    static <T> RegistryListener onError(T enumType, BiConsumer<RegistryEvent, 
T> errorFunc) {
-
-        return new RegistryListener(enumType) {
-            @Override
-            public void onEventError(RegistryEvent event) {
-                errorFunc.accept(event, enumType);
-            }
-        };
-    }
-}
diff --git 
a/dubbo-metrics/dubbo-metrics-registry/src/main/java/org/apache/dubbo/metrics/registry/event/RegistryMetricsEventMulticaster.java
 
b/dubbo-metrics/dubbo-metrics-registry/src/main/java/org/apache/dubbo/metrics/registry/event/RegistryMetricsEventMulticaster.java
index e576c35339..9ad2ba77af 100644
--- 
a/dubbo-metrics/dubbo-metrics-registry/src/main/java/org/apache/dubbo/metrics/registry/event/RegistryMetricsEventMulticaster.java
+++ 
b/dubbo-metrics/dubbo-metrics-registry/src/main/java/org/apache/dubbo/metrics/registry/event/RegistryMetricsEventMulticaster.java
@@ -18,14 +18,22 @@
 package org.apache.dubbo.metrics.registry.event;
 
 import org.apache.dubbo.metrics.event.SimpleMetricsEventMulticaster;
-import org.apache.dubbo.metrics.registry.event.type.ApplicationType;
-import org.apache.dubbo.metrics.registry.event.type.ServiceType;
-
+import org.apache.dubbo.metrics.listener.AbstractMetricsListener;
+import org.apache.dubbo.metrics.listener.MetricsApplicationListener;
+import org.apache.dubbo.metrics.listener.MetricsServiceListener;
+import org.apache.dubbo.metrics.model.key.CategoryOverall;
+import org.apache.dubbo.metrics.model.key.MetricsCat;
+import org.apache.dubbo.metrics.model.key.MetricsKey;
+import org.apache.dubbo.metrics.registry.collector.RegistryMetricsCollector;
+
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
 import java.util.Map;
 
 import static 
org.apache.dubbo.metrics.MetricsConstants.ATTACHMENT_DIRECTORY_MAP;
-import static org.apache.dubbo.metrics.MetricsConstants.ATTACHMENT_KEY_SERVICE;
-import static org.apache.dubbo.metrics.MetricsConstants.ATTACHMENT_KEY_SIZE;
+import static 
org.apache.dubbo.metrics.MetricsConstants.ATTACHMENT_KEY_LAST_NUM_MAP;
+import static 
org.apache.dubbo.metrics.registry.RegistryMetricsConstants.OP_TYPE_DIRECTORY;
 import static 
org.apache.dubbo.metrics.registry.RegistryMetricsConstants.OP_TYPE_NOTIFY;
 import static 
org.apache.dubbo.metrics.registry.RegistryMetricsConstants.OP_TYPE_REGISTER;
 import static 
org.apache.dubbo.metrics.registry.RegistryMetricsConstants.OP_TYPE_REGISTER_SERVICE;
@@ -34,91 +42,82 @@ import static 
org.apache.dubbo.metrics.registry.RegistryMetricsConstants.OP_TYPE
 
 public final class RegistryMetricsEventMulticaster extends 
SimpleMetricsEventMulticaster {
 
-    public RegistryMetricsEventMulticaster() {
+
+    public RegistryMetricsEventMulticaster(RegistryMetricsCollector collector) 
{
+
+        CategorySet.ALL.forEach(categorySet ->
+        {
+            
super.addListener(categorySet.getPost().getEventFunc().apply(collector));
+            if (categorySet.getFinish() != null) {
+                
super.addListener(categorySet.getFinish().getEventFunc().apply(collector));
+            }
+            if (categorySet.getError() != null) {
+                
super.addListener(categorySet.getError().getEventFunc().apply(collector));
+            }
+        });
+    }
+
+    interface CategorySet {
+        CategoryOverall APPLICATION_REGISTER = new 
CategoryOverall(OP_TYPE_REGISTER, MCat.APPLICATION_REGISTER_POST, 
MCat.APPLICATION_REGISTER_FINISH, MCat.APPLICATION_REGISTER_ERROR);
+        CategoryOverall APPLICATION_SUBSCRIBE = new 
CategoryOverall(OP_TYPE_SUBSCRIBE, MCat.APPLICATION_SUBSCRIBE_POST, 
MCat.APPLICATION_SUBSCRIBE_FINISH, MCat.APPLICATION_SUBSCRIBE_ERROR);
+        CategoryOverall APPLICATION_NOTIFY = new 
CategoryOverall(OP_TYPE_NOTIFY, MCat.APPLICATION_NOTIFY_POST, 
MCat.APPLICATION_NOTIFY_FINISH, null);
+        CategoryOverall SERVICE_DIRECTORY = new 
CategoryOverall(OP_TYPE_DIRECTORY, MCat.APPLICATION_DIRECTORY_POST, null, null);
+        CategoryOverall SERVICE_REGISTER = new 
CategoryOverall(OP_TYPE_REGISTER_SERVICE, MCat.SERVICE_REGISTER_POST, 
MCat.SERVICE_REGISTER_FINISH, MCat.SERVICE_REGISTER_ERROR);
+        CategoryOverall SERVICE_SUBSCRIBE = new 
CategoryOverall(OP_TYPE_SUBSCRIBE_SERVICE, MCat.SERVICE_SUBSCRIBE_POST, 
MCat.SERVICE_SUBSCRIBE_FINISH, MCat.SERVICE_SUBSCRIBE_ERROR);
+
+        List<CategoryOverall> ALL = Arrays.asList(APPLICATION_REGISTER, 
APPLICATION_SUBSCRIBE, APPLICATION_NOTIFY, SERVICE_DIRECTORY, SERVICE_REGISTER, 
SERVICE_SUBSCRIBE);
+    }
+
+
+    interface MCat {
         // MetricsRegisterListener
-        super.addListener(onPostEventBuild(ApplicationType.R_TOTAL));
-        super.addListener(onFinishEventBuild(ApplicationType.R_SUCCEED, 
OP_TYPE_REGISTER.getType()));
-        super.addListener(onErrorEventBuild(ApplicationType.R_FAILED, 
OP_TYPE_REGISTER.getType()));
+        MetricsCat APPLICATION_REGISTER_POST = new 
MetricsCat(MetricsKey.REGISTER_METRIC_REQUESTS, 
MetricsApplicationListener::onPostEventBuild);
+        MetricsCat APPLICATION_REGISTER_FINISH = new 
MetricsCat(MetricsKey.REGISTER_METRIC_REQUESTS_SUCCEED, 
MetricsApplicationListener::onFinishEventBuild);
+        MetricsCat APPLICATION_REGISTER_ERROR = new 
MetricsCat(MetricsKey.REGISTER_METRIC_REQUESTS_FAILED, 
MetricsApplicationListener::onErrorEventBuild);
 
         // MetricsSubscribeListener
-        super.addListener(onPostEventBuild(ApplicationType.S_TOTAL));
-        super.addListener(onFinishEventBuild(ApplicationType.S_SUCCEED, 
OP_TYPE_SUBSCRIBE.getType()));
-        super.addListener(onErrorEventBuild(ApplicationType.S_FAILED, 
OP_TYPE_SUBSCRIBE.getType()));
+        MetricsCat APPLICATION_SUBSCRIBE_POST = new 
MetricsCat(MetricsKey.SUBSCRIBE_METRIC_NUM, 
MetricsApplicationListener::onPostEventBuild);
+        MetricsCat APPLICATION_SUBSCRIBE_FINISH = new 
MetricsCat(MetricsKey.SUBSCRIBE_METRIC_NUM_SUCCEED, 
MetricsApplicationListener::onFinishEventBuild);
+        MetricsCat APPLICATION_SUBSCRIBE_ERROR = new 
MetricsCat(MetricsKey.SUBSCRIBE_METRIC_NUM_FAILED, 
MetricsApplicationListener::onErrorEventBuild);
 
         // MetricsNotifyListener
-        super.addListener(onPostEventBuild(ApplicationType.N_TOTAL));
-        super.addListener(
-            RegistryListener.onFinish(ServiceType.N_LAST_NUM,
-                (event, type) -> {
-                    event.setLastNum(type);
-                    event.addApplicationRT(OP_TYPE_NOTIFY.getType());
+        MetricsCat APPLICATION_NOTIFY_POST = new 
MetricsCat(MetricsKey.NOTIFY_METRIC_REQUESTS, 
MetricsApplicationListener::onPostEventBuild);
+        MetricsCat APPLICATION_NOTIFY_FINISH = new 
MetricsCat(MetricsKey.NOTIFY_METRIC_NUM_LAST,
+            (key, placeType, collector) -> 
AbstractMetricsListener.onFinish(key,
+                event -> {
+                    collector.addRt(event.appName(), placeType.getType(), 
event.getTimePair().calc());
+                    Map<String, Integer> lastNumMap = 
Collections.unmodifiableMap(event.getAttachmentValue(ATTACHMENT_KEY_LAST_NUM_MAP));
+                    lastNumMap.forEach(
+                        (k, v) -> collector.setNum(key, event.appName(), k, 
v));
+
                 }
             ));
 
 
-        // MetricsDirectoryListener
-        super.addListener(RegistryListener.onEvent(ServiceType.D_VALID,
-            (event, type) ->
+        MetricsCat APPLICATION_DIRECTORY_POST = new 
MetricsCat(MetricsKey.DIRECTORY_METRIC_NUM_VALID, (key, placeType, collector) 
-> AbstractMetricsListener.onEvent(key,
+            event ->
             {
-                Map<ServiceType, Map<String, Integer>> summaryMap = 
event.getAttachmentValue(ATTACHMENT_DIRECTORY_MAP);
-                summaryMap.forEach((serviceType, map) ->
-                    event.getCollector().setNum(serviceType, 
event.getSource().getApplicationName(), map));
+                Map<MetricsKey, Map<String, Integer>> summaryMap = 
event.getAttachmentValue(ATTACHMENT_DIRECTORY_MAP);
+                summaryMap.forEach((metricsKey, map) ->
+                    map.forEach(
+                        (k, v) -> collector.setNum(metricsKey, 
event.appName(), k, v)));
             }
         ));
 
-        // MetricsServiceRegisterListener
-        super.addListener(RegistryListener.onEvent(ServiceType.R_SERVICE_TOTAL,
-            this::incrSkSize
-        ));
-        
super.addListener(RegistryListener.onFinish(ServiceType.R_SERVICE_SUCCEED, 
this::onRegisterRtEvent));
-        
super.addListener(RegistryListener.onError(ServiceType.R_SERVICE_FAILED, 
this::onRegisterRtEvent));
-
-        // MetricsServiceSubscribeListener
-        
super.addListener(RegistryListener.onEvent(ServiceType.S_SERVICE_TOTAL, 
this::incrSk));
-        
super.addListener(RegistryListener.onFinish(ServiceType.S_SERVICE_SUCCEED, 
this::onRtEvent));
-        
super.addListener(RegistryListener.onError(ServiceType.S_SERVICE_FAILED, 
this::onRtEvent));
-    }
 
-    private RegistryListener onPostEventBuild(ApplicationType applicationType) 
{
-        return RegistryListener.onEvent(applicationType,
-            (event, type) -> 
event.getCollector().increment(event.getSource().getApplicationName(), type)
-        );
-    }
-
-    private RegistryListener onFinishEventBuild(ApplicationType 
applicationType, String registryOpType) {
-        return RegistryListener.onFinish(applicationType,
-            (event, type) -> {
-                event.increment(type);
-                event.addApplicationRT(registryOpType);
-            }
-        );
-    }
+        // MetricsServiceRegisterListener
+        MetricsCat SERVICE_REGISTER_POST = new 
MetricsCat(MetricsKey.SERVICE_REGISTER_METRIC_REQUESTS, 
MetricsServiceListener::onPostEventBuild);
+        MetricsCat SERVICE_REGISTER_FINISH = new 
MetricsCat(MetricsKey.SERVICE_REGISTER_METRIC_REQUESTS_SUCCEED, 
MetricsServiceListener::onFinishEventBuild);
+        MetricsCat SERVICE_REGISTER_ERROR = new 
MetricsCat(MetricsKey.SERVICE_REGISTER_METRIC_REQUESTS_FAILED, 
MetricsServiceListener::onErrorEventBuild);
 
-    private RegistryListener onErrorEventBuild(ApplicationType 
applicationType, String registryOpType) {
-        return RegistryListener.onError(applicationType,
-            (event, type) -> {
-                event.increment(type);
-                event.addApplicationRT(registryOpType);
-            }
-        );
-    }
 
+        // MetricsServiceSubscribeListener
+        MetricsCat SERVICE_SUBSCRIBE_POST = new 
MetricsCat(MetricsKey.SERVICE_SUBSCRIBE_METRIC_NUM, 
MetricsServiceListener::onPostEventBuild);
+        MetricsCat SERVICE_SUBSCRIBE_FINISH = new 
MetricsCat(MetricsKey.SERVICE_SUBSCRIBE_METRIC_NUM_SUCCEED, 
MetricsServiceListener::onFinishEventBuild);
+        MetricsCat SERVICE_SUBSCRIBE_ERROR = new 
MetricsCat(MetricsKey.SERVICE_SUBSCRIBE_METRIC_NUM_FAILED, 
MetricsServiceListener::onErrorEventBuild);
 
-    private void incrSk(RegistryEvent event, ServiceType type) {
-        event.incrementServiceKey(type, ATTACHMENT_KEY_SERVICE, 1);
-    }
 
-    private void incrSkSize(RegistryEvent event, ServiceType type) {
-        event.incrementServiceKey(type, ATTACHMENT_KEY_SERVICE, 
ATTACHMENT_KEY_SIZE);
     }
 
-    private void onRtEvent(RegistryEvent event, ServiceType type) {
-        incrSk(event, type);
-        event.addServiceKeyRT(ATTACHMENT_KEY_SERVICE, 
OP_TYPE_SUBSCRIBE_SERVICE.getType());
-    }
 
-    private void onRegisterRtEvent(RegistryEvent event, ServiceType type) {
-        incrSkSize(event, type);
-        event.addServiceKeyRT(ATTACHMENT_KEY_SERVICE, 
OP_TYPE_REGISTER_SERVICE.getType());
-    }
 }
diff --git 
a/dubbo-metrics/dubbo-metrics-registry/src/main/java/org/apache/dubbo/metrics/registry/event/type/ServiceType.java
 
b/dubbo-metrics/dubbo-metrics-registry/src/main/java/org/apache/dubbo/metrics/registry/event/type/ServiceType.java
deleted file mode 100644
index eda455087a..0000000000
--- 
a/dubbo-metrics/dubbo-metrics-registry/src/main/java/org/apache/dubbo/metrics/registry/event/type/ServiceType.java
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.dubbo.metrics.registry.event.type;
-
-import org.apache.dubbo.metrics.model.key.MetricsKey;
-
-public enum ServiceType {
-
-    N_LAST_NUM(MetricsKey.NOTIFY_METRIC_NUM_LAST),
-
-    R_SERVICE_TOTAL(MetricsKey.SERVICE_REGISTER_METRIC_REQUESTS),
-    R_SERVICE_SUCCEED(MetricsKey.SERVICE_REGISTER_METRIC_REQUESTS_SUCCEED),
-    R_SERVICE_FAILED(MetricsKey.SERVICE_REGISTER_METRIC_REQUESTS_FAILED),
-
-    S_SERVICE_TOTAL(MetricsKey.SERVICE_SUBSCRIBE_METRIC_NUM),
-    S_SERVICE_SUCCEED(MetricsKey.SERVICE_SUBSCRIBE_METRIC_NUM_SUCCEED),
-    S_SERVICE_FAILED(MetricsKey.SERVICE_SUBSCRIBE_METRIC_NUM_FAILED),
-
-    D_VALID(MetricsKey.DIRECTORY_METRIC_NUM_VALID),
-    D_TO_RECONNECT(MetricsKey.DIRECTORY_METRIC_NUM_TO_RECONNECT),
-    D_DISABLE(MetricsKey.DIRECTORY_METRIC_NUM_DISABLE),
-    D_ALL(MetricsKey.DIRECTORY_METRIC_NUM_ALL),
-    ;
-
-    private final MetricsKey metricsKey;
-
-    ServiceType(MetricsKey metricsKey) {
-        this.metricsKey = metricsKey;
-    }
-
-    public MetricsKey getMetricsKey() {
-        return metricsKey;
-    }
-
-}
diff --git 
a/dubbo-metrics/dubbo-metrics-registry/src/test/java/org/apache/dubbo/metrics/registry/metrics/collector/RegistryMetricsSampleTest.java
 
b/dubbo-metrics/dubbo-metrics-registry/src/test/java/org/apache/dubbo/metrics/registry/metrics/collector/RegistryMetricsSampleTest.java
index 354822f270..579a859ffe 100644
--- 
a/dubbo-metrics/dubbo-metrics-registry/src/test/java/org/apache/dubbo/metrics/registry/metrics/collector/RegistryMetricsSampleTest.java
+++ 
b/dubbo-metrics/dubbo-metrics-registry/src/test/java/org/apache/dubbo/metrics/registry/metrics/collector/RegistryMetricsSampleTest.java
@@ -23,7 +23,6 @@ import org.apache.dubbo.metrics.model.key.MetricsKeyWrapper;
 import org.apache.dubbo.metrics.model.sample.GaugeMetricSample;
 import org.apache.dubbo.metrics.model.sample.MetricSample;
 import org.apache.dubbo.metrics.registry.collector.RegistryMetricsCollector;
-import org.apache.dubbo.metrics.registry.event.type.ApplicationType;
 import org.apache.dubbo.rpc.model.ApplicationModel;
 import org.apache.dubbo.rpc.model.FrameworkModel;
 import org.junit.jupiter.api.AfterEach;
@@ -65,8 +64,8 @@ class RegistryMetricsSampleTest {
         RegistryMetricsCollector collector = new 
RegistryMetricsCollector(applicationModel);
         collector.setCollectEnabled(true);
         String applicationName = applicationModel.getApplicationName();
-        collector.addApplicationRT(applicationName, 
OP_TYPE_REGISTER.getType(), 10L);
-        collector.addApplicationRT(applicationName, 
OP_TYPE_REGISTER.getType(), 0L);
+        collector.addRt(applicationName, OP_TYPE_REGISTER.getType(), 10L);
+        collector.addRt(applicationName, OP_TYPE_REGISTER.getType(), 0L);
 
         List<MetricSample> samples = collector.collect();
         for (MetricSample sample : samples) {
@@ -89,7 +88,7 @@ class RegistryMetricsSampleTest {
         RegistryMetricsCollector collector = new 
RegistryMetricsCollector(applicationModel);
         collector.setCollectEnabled(true);
         String applicationName = applicationModel.getApplicationName();
-        collector.increment(applicationName, ApplicationType.R_TOTAL);
+        collector.increment(applicationName, 
MetricsKey.REGISTER_METRIC_REQUESTS);
     }
 
 }
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 1016020887..ba44ab6c15 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
@@ -23,7 +23,6 @@ import org.apache.dubbo.metrics.data.RtStatComposite;
 import org.apache.dubbo.metrics.data.ServiceStatComposite;
 import org.apache.dubbo.metrics.model.container.LongContainer;
 import org.apache.dubbo.metrics.registry.RegistryMetricsConstants;
-import org.apache.dubbo.metrics.registry.event.type.ApplicationType;
 import org.junit.jupiter.api.Assertions;
 import org.junit.jupiter.api.Test;
 
@@ -31,6 +30,7 @@ import java.util.Map;
 import java.util.Optional;
 import java.util.concurrent.ConcurrentHashMap;
 
+import static 
org.apache.dubbo.metrics.model.key.MetricsKey.REGISTER_METRIC_REQUESTS;
 import static 
org.apache.dubbo.metrics.registry.RegistryMetricsConstants.OP_TYPE_NOTIFY;
 import static 
org.apache.dubbo.metrics.registry.RegistryMetricsConstants.OP_TYPE_REGISTER;
 import static 
org.apache.dubbo.metrics.registry.RegistryMetricsConstants.OP_TYPE_REGISTER_SERVICE;
@@ -43,15 +43,15 @@ public class RegistryStatCompositeTest {
     private final BaseStatComposite statComposite = new BaseStatComposite() {
         @Override
         protected void init(ApplicationStatComposite applicationStatComposite, 
ServiceStatComposite serviceStatComposite, RtStatComposite rtStatComposite) {
-            applicationStatComposite.init(RegistryMetricsConstants.appKeys);
-            serviceStatComposite.init(RegistryMetricsConstants.serviceKeys);
+            
applicationStatComposite.init(RegistryMetricsConstants.APP_LEVEL_KEYS);
+            
serviceStatComposite.init(RegistryMetricsConstants.SERVICE_LEVEL_KEYS);
             rtStatComposite.init(OP_TYPE_REGISTER, OP_TYPE_SUBSCRIBE, 
OP_TYPE_NOTIFY, OP_TYPE_REGISTER_SERVICE, OP_TYPE_SUBSCRIBE_SERVICE);
         }
     };
 
     @Test
     void testInit() {
-        
Assertions.assertEquals(statComposite.getApplicationStatComposite().getApplicationNumStats().size(),
 ApplicationType.values().length);
+        
Assertions.assertEquals(statComposite.getApplicationStatComposite().getApplicationNumStats().size(),
 RegistryMetricsConstants.APP_LEVEL_KEYS.size());
         //(rt)5 * 
(register,subscribe,notify,register.service,subscribe.service)5
         Assertions.assertEquals(5 * 5, 
statComposite.getRtStatComposite().getRtStats().size());
         
statComposite.getApplicationStatComposite().getApplicationNumStats().values().forEach((v
 ->
@@ -66,8 +66,8 @@ public class RegistryStatCompositeTest {
 
     @Test
     void testIncrement() {
-        statComposite.incrementApp(ApplicationType.R_TOTAL.getMetricsKey(), 
applicationName, 1);
-        Assertions.assertEquals(1L, 
statComposite.getApplicationStatComposite().getApplicationNumStats().get(ApplicationType.R_TOTAL.getMetricsKey()).get(applicationName).get());
+        statComposite.incrementApp(REGISTER_METRIC_REQUESTS, applicationName, 
1);
+        Assertions.assertEquals(1L, 
statComposite.getApplicationStatComposite().getApplicationNumStats().get(REGISTER_METRIC_REQUESTS).get(applicationName).get());
     }
 
     @Test

Reply via email to